From e5f185b934121f2e66db7796d83ec36c6566ebfe Mon Sep 17 00:00:00 2001 From: Richard Meadows Date: Thu, 4 Aug 2016 18:09:21 +0100 Subject: [PATCH] [loader] initial commit of bootloader --- loader/.dir-locals.el | 32 + loader/.gdbinit | 5 + loader/.gitignore | 34 + loader/LICENSE-samd20-gcc-blackmagic.md | 26 + loader/LICENSE.md | 27 + loader/Makefile | 277 + loader/README-samd20-gcc-blackmagic.md | 147 + loader/README.md | 27 + loader/chip/cmsis/arm_math.h | 7059 +++++++++++++++++++++++ loader/chip/cmsis/core_cm0plus.h | 778 +++ loader/chip/cmsis/core_cmFunc.h | 616 ++ loader/chip/cmsis/core_cmInstr.h | 618 ++ loader/chip/samd20e14.ld | 29 + loader/chip/samd20e15.ld | 29 + loader/chip/samd20e16.ld | 29 + loader/chip/samd20e17.ld | 29 + loader/chip/samd20e18.ld | 29 + loader/chip/samd20g14.ld | 29 + loader/chip/samd20g15.ld | 29 + loader/chip/samd20g16.ld | 29 + loader/chip/samd20g17.ld | 29 + loader/chip/samd20g18.ld | 29 + loader/chip/samd20j14.ld | 29 + loader/chip/samd20j15.ld | 29 + loader/chip/samd20j16.ld | 29 + loader/chip/samd20j17.ld | 29 + loader/chip/samd20j18.ld | 29 + loader/chip/sections.ld | 179 + loader/chip/startup_samd20.c | 205 + loader/chip/system_samd20.c | 78 + loader/chip/system_samd20.h | 62 + loader/config.mk | 54 + loader/inc/adc/adc.h | 1794 ++++++ loader/inc/analogue.h | 36 + loader/inc/flash.h | 35 + loader/inc/hw_config | 1 + loader/inc/hw_config.h | 1 + loader/inc/init.h | 61 + loader/inc/loader.h | 30 + loader/inc/memory.h | 60 + loader/inc/rtc.h | 40 + loader/inc/sercom/i2c.h | 49 + loader/inc/sercom/i2c_common.h | 553 ++ loader/inc/sercom/i2c_master.h | 592 ++ loader/inc/sercom/old/i2c_common.h | 557 ++ loader/inc/sercom/old/i2c_master.h | 593 ++ loader/inc/sercom/sercom.h | 127 + loader/inc/sercom/sercom_pinout.h | 82 + loader/inc/sercom/spi.h | 1133 ++++ loader/inc/sercom/usart.h | 568 ++ loader/inc/system/clock.h | 854 +++ loader/inc/system/clock_config_check.h | 373 ++ loader/inc/system/conf_clocks.h | 164 + loader/inc/system/events.h | 335 ++ loader/inc/system/extint.h | 437 ++ loader/inc/system/gclk.h | 145 + loader/inc/system/interrupt.h | 75 + loader/inc/system/pinmux.h | 221 + loader/inc/system/port.h | 307 + loader/inc/system/rtc_count.h | 732 +++ loader/inc/system/system.h | 358 ++ loader/inc/system/wdt.h | 221 + loader/inc/util/mrecursion.h | 581 ++ loader/inc/watchdog.h | 56 + loader/inc/xosc.h | 64 + loader/samd20/component/ac.h | 559 ++ loader/samd20/component/adc.h | 699 +++ loader/samd20/component/dac.h | 283 + loader/samd20/component/dsu.h | 628 ++ loader/samd20/component/eic.h | 681 +++ loader/samd20/component/evsys.h | 466 ++ loader/samd20/component/gclk.h | 322 ++ loader/samd20/component/nvmctrl.h | 521 ++ loader/samd20/component/pac.h | 104 + loader/samd20/component/pm.h | 515 ++ loader/samd20/component/port.h | 395 ++ loader/samd20/component/rtc.h | 1062 ++++ loader/samd20/component/sercom.h | 1224 ++++ loader/samd20/component/sysctrl.h | 688 +++ loader/samd20/component/tc.h | 684 +++ loader/samd20/component/wdt.h | 303 + loader/samd20/instance/ac.h | 87 + loader/samd20/instance/adc.h | 98 + loader/samd20/instance/dac.h | 73 + loader/samd20/instance/dsu.h | 109 + loader/samd20/instance/eic.h | 81 + loader/samd20/instance/evsys.h | 165 + loader/samd20/instance/gclk.h | 79 + loader/samd20/instance/nvmctrl.h | 92 + loader/samd20/instance/pac0.h | 59 + loader/samd20/instance/pac1.h | 59 + loader/samd20/instance/pac2.h | 59 + loader/samd20/instance/pm.h | 87 + loader/samd20/instance/port.h | 136 + loader/samd20/instance/rtc.h | 117 + loader/samd20/instance/sercom0.h | 132 + loader/samd20/instance/sercom1.h | 132 + loader/samd20/instance/sercom2.h | 132 + loader/samd20/instance/sercom3.h | 132 + loader/samd20/instance/sercom4.h | 132 + loader/samd20/instance/sercom5.h | 132 + loader/samd20/instance/sysctrl.h | 110 + loader/samd20/instance/tc0.h | 105 + loader/samd20/instance/tc1.h | 105 + loader/samd20/instance/tc2.h | 105 + loader/samd20/instance/tc3.h | 105 + loader/samd20/instance/tc4.h | 105 + loader/samd20/instance/tc5.h | 105 + loader/samd20/instance/tc6.h | 105 + loader/samd20/instance/tc7.h | 105 + loader/samd20/instance/wdt.h | 71 + loader/samd20/pio/samd20e14.h | 552 ++ loader/samd20/pio/samd20e15.h | 552 ++ loader/samd20/pio/samd20e16.h | 552 ++ loader/samd20/pio/samd20e17.h | 552 ++ loader/samd20/pio/samd20e18.h | 552 ++ loader/samd20/pio/samd20e1f.h | 552 ++ loader/samd20/pio/samd20g14.h | 812 +++ loader/samd20/pio/samd20g15.h | 812 +++ loader/samd20/pio/samd20g16.h | 812 +++ loader/samd20/pio/samd20g17.h | 812 +++ loader/samd20/pio/samd20g18.h | 812 +++ loader/samd20/pio/samd20j14.h | 1024 ++++ loader/samd20/pio/samd20j15.h | 1024 ++++ loader/samd20/pio/samd20j16.h | 1024 ++++ loader/samd20/pio/samd20j17.h | 1024 ++++ loader/samd20/pio/samd20j18.h | 1024 ++++ loader/samd20/samd20.h | 88 + loader/samd20/samd20e14.h | 500 ++ loader/samd20/samd20e15.h | 500 ++ loader/samd20/samd20e16.h | 500 ++ loader/samd20/samd20e17.h | 500 ++ loader/samd20/samd20e18.h | 500 ++ loader/samd20/samd20g14.h | 524 ++ loader/samd20/samd20g15.h | 524 ++ loader/samd20/samd20g16.h | 524 ++ loader/samd20/samd20g17.h | 524 ++ loader/samd20/samd20g18.h | 524 ++ loader/samd20/samd20j14.h | 524 ++ loader/samd20/samd20j15.h | 524 ++ loader/samd20/samd20j16.h | 524 ++ loader/samd20/samd20j17.h | 524 ++ loader/samd20/samd20j18.h | 524 ++ loader/src/adc/adc.c | 674 +++ loader/src/analogue.c | 202 + loader/src/flash.c | 116 + loader/src/init.c | 159 + loader/src/loader.c | 45 + loader/src/main.c | 72 + loader/src/memory.c | 200 + loader/src/rtc.c | 77 + loader/src/sercom/i2c.c | 105 + loader/src/sercom/i2c_master.c | 739 +++ loader/src/sercom/sercom.c | 304 + loader/src/sercom/spi.c | 1076 ++++ loader/src/sercom/usart.c | 777 +++ loader/src/system/clock.c | 857 +++ loader/src/system/events.c | 180 + loader/src/system/extint.c | 311 + loader/src/system/gclk.c | 454 ++ loader/src/system/interrupt.c | 78 + loader/src/system/pinmux.c | 213 + loader/src/system/port.c | 125 + loader/src/system/rtc_count.c | 427 ++ loader/src/system/wdt.c | 170 + loader/src/watchdog.c | 168 + loader/src/xosc.c | 260 + loader/test/Makefile | 26 + loader/test/README.md | 62 + loader/test/main.py | 2233 +++++++ loader/test/tc/times_two.h | 20 + loader/test/tc/times_two.py | 38 + loader/test/template/template.h | 33 + loader/test/template/template.py | 41 + loader/test/tests.py | 223 + loader/test/tmain.c | 78 + 176 files changed, 65005 insertions(+) create mode 100644 loader/.dir-locals.el create mode 100644 loader/.gdbinit create mode 100644 loader/.gitignore create mode 100644 loader/LICENSE-samd20-gcc-blackmagic.md create mode 100644 loader/LICENSE.md create mode 100644 loader/Makefile create mode 100644 loader/README-samd20-gcc-blackmagic.md create mode 100644 loader/README.md create mode 100644 loader/chip/cmsis/arm_math.h create mode 100644 loader/chip/cmsis/core_cm0plus.h create mode 100644 loader/chip/cmsis/core_cmFunc.h create mode 100644 loader/chip/cmsis/core_cmInstr.h create mode 100644 loader/chip/samd20e14.ld create mode 100644 loader/chip/samd20e15.ld create mode 100644 loader/chip/samd20e16.ld create mode 100644 loader/chip/samd20e17.ld create mode 100644 loader/chip/samd20e18.ld create mode 100644 loader/chip/samd20g14.ld create mode 100644 loader/chip/samd20g15.ld create mode 100644 loader/chip/samd20g16.ld create mode 100644 loader/chip/samd20g17.ld create mode 100644 loader/chip/samd20g18.ld create mode 100644 loader/chip/samd20j14.ld create mode 100644 loader/chip/samd20j15.ld create mode 100644 loader/chip/samd20j16.ld create mode 100644 loader/chip/samd20j17.ld create mode 100644 loader/chip/samd20j18.ld create mode 100644 loader/chip/sections.ld create mode 100644 loader/chip/startup_samd20.c create mode 100644 loader/chip/system_samd20.c create mode 100644 loader/chip/system_samd20.h create mode 100644 loader/config.mk create mode 100644 loader/inc/adc/adc.h create mode 100644 loader/inc/analogue.h create mode 100644 loader/inc/flash.h create mode 120000 loader/inc/hw_config create mode 120000 loader/inc/hw_config.h create mode 100644 loader/inc/init.h create mode 100644 loader/inc/loader.h create mode 100644 loader/inc/memory.h create mode 100644 loader/inc/rtc.h create mode 100644 loader/inc/sercom/i2c.h create mode 100644 loader/inc/sercom/i2c_common.h create mode 100644 loader/inc/sercom/i2c_master.h create mode 100644 loader/inc/sercom/old/i2c_common.h create mode 100644 loader/inc/sercom/old/i2c_master.h create mode 100644 loader/inc/sercom/sercom.h create mode 100644 loader/inc/sercom/sercom_pinout.h create mode 100644 loader/inc/sercom/spi.h create mode 100644 loader/inc/sercom/usart.h create mode 100644 loader/inc/system/clock.h create mode 100644 loader/inc/system/clock_config_check.h create mode 100644 loader/inc/system/conf_clocks.h create mode 100644 loader/inc/system/events.h create mode 100644 loader/inc/system/extint.h create mode 100644 loader/inc/system/gclk.h create mode 100644 loader/inc/system/interrupt.h create mode 100644 loader/inc/system/pinmux.h create mode 100644 loader/inc/system/port.h create mode 100644 loader/inc/system/rtc_count.h create mode 100644 loader/inc/system/system.h create mode 100644 loader/inc/system/wdt.h create mode 100644 loader/inc/util/mrecursion.h create mode 100644 loader/inc/watchdog.h create mode 100644 loader/inc/xosc.h create mode 100644 loader/samd20/component/ac.h create mode 100644 loader/samd20/component/adc.h create mode 100644 loader/samd20/component/dac.h create mode 100644 loader/samd20/component/dsu.h create mode 100644 loader/samd20/component/eic.h create mode 100644 loader/samd20/component/evsys.h create mode 100644 loader/samd20/component/gclk.h create mode 100644 loader/samd20/component/nvmctrl.h create mode 100644 loader/samd20/component/pac.h create mode 100644 loader/samd20/component/pm.h create mode 100644 loader/samd20/component/port.h create mode 100644 loader/samd20/component/rtc.h create mode 100644 loader/samd20/component/sercom.h create mode 100644 loader/samd20/component/sysctrl.h create mode 100644 loader/samd20/component/tc.h create mode 100644 loader/samd20/component/wdt.h create mode 100644 loader/samd20/instance/ac.h create mode 100644 loader/samd20/instance/adc.h create mode 100644 loader/samd20/instance/dac.h create mode 100644 loader/samd20/instance/dsu.h create mode 100644 loader/samd20/instance/eic.h create mode 100644 loader/samd20/instance/evsys.h create mode 100644 loader/samd20/instance/gclk.h create mode 100644 loader/samd20/instance/nvmctrl.h create mode 100644 loader/samd20/instance/pac0.h create mode 100644 loader/samd20/instance/pac1.h create mode 100644 loader/samd20/instance/pac2.h create mode 100644 loader/samd20/instance/pm.h create mode 100644 loader/samd20/instance/port.h create mode 100644 loader/samd20/instance/rtc.h create mode 100644 loader/samd20/instance/sercom0.h create mode 100644 loader/samd20/instance/sercom1.h create mode 100644 loader/samd20/instance/sercom2.h create mode 100644 loader/samd20/instance/sercom3.h create mode 100644 loader/samd20/instance/sercom4.h create mode 100644 loader/samd20/instance/sercom5.h create mode 100644 loader/samd20/instance/sysctrl.h create mode 100644 loader/samd20/instance/tc0.h create mode 100644 loader/samd20/instance/tc1.h create mode 100644 loader/samd20/instance/tc2.h create mode 100644 loader/samd20/instance/tc3.h create mode 100644 loader/samd20/instance/tc4.h create mode 100644 loader/samd20/instance/tc5.h create mode 100644 loader/samd20/instance/tc6.h create mode 100644 loader/samd20/instance/tc7.h create mode 100644 loader/samd20/instance/wdt.h create mode 100644 loader/samd20/pio/samd20e14.h create mode 100644 loader/samd20/pio/samd20e15.h create mode 100644 loader/samd20/pio/samd20e16.h create mode 100644 loader/samd20/pio/samd20e17.h create mode 100644 loader/samd20/pio/samd20e18.h create mode 100644 loader/samd20/pio/samd20e1f.h create mode 100644 loader/samd20/pio/samd20g14.h create mode 100644 loader/samd20/pio/samd20g15.h create mode 100644 loader/samd20/pio/samd20g16.h create mode 100644 loader/samd20/pio/samd20g17.h create mode 100644 loader/samd20/pio/samd20g18.h create mode 100644 loader/samd20/pio/samd20j14.h create mode 100644 loader/samd20/pio/samd20j15.h create mode 100644 loader/samd20/pio/samd20j16.h create mode 100644 loader/samd20/pio/samd20j17.h create mode 100644 loader/samd20/pio/samd20j18.h create mode 100644 loader/samd20/samd20.h create mode 100644 loader/samd20/samd20e14.h create mode 100644 loader/samd20/samd20e15.h create mode 100644 loader/samd20/samd20e16.h create mode 100644 loader/samd20/samd20e17.h create mode 100644 loader/samd20/samd20e18.h create mode 100644 loader/samd20/samd20g14.h create mode 100644 loader/samd20/samd20g15.h create mode 100644 loader/samd20/samd20g16.h create mode 100644 loader/samd20/samd20g17.h create mode 100644 loader/samd20/samd20g18.h create mode 100644 loader/samd20/samd20j14.h create mode 100644 loader/samd20/samd20j15.h create mode 100644 loader/samd20/samd20j16.h create mode 100644 loader/samd20/samd20j17.h create mode 100644 loader/samd20/samd20j18.h create mode 100644 loader/src/adc/adc.c create mode 100644 loader/src/analogue.c create mode 100644 loader/src/flash.c create mode 100644 loader/src/init.c create mode 100644 loader/src/loader.c create mode 100644 loader/src/main.c create mode 100644 loader/src/memory.c create mode 100644 loader/src/rtc.c create mode 100644 loader/src/sercom/i2c.c create mode 100644 loader/src/sercom/i2c_master.c create mode 100644 loader/src/sercom/sercom.c create mode 100644 loader/src/sercom/spi.c create mode 100644 loader/src/sercom/usart.c create mode 100644 loader/src/system/clock.c create mode 100644 loader/src/system/events.c create mode 100644 loader/src/system/extint.c create mode 100644 loader/src/system/gclk.c create mode 100644 loader/src/system/interrupt.c create mode 100644 loader/src/system/pinmux.c create mode 100644 loader/src/system/port.c create mode 100644 loader/src/system/rtc_count.c create mode 100644 loader/src/system/wdt.c create mode 100644 loader/src/watchdog.c create mode 100644 loader/src/xosc.c create mode 100644 loader/test/Makefile create mode 100644 loader/test/README.md create mode 100644 loader/test/main.py create mode 100644 loader/test/tc/times_two.h create mode 100644 loader/test/tc/times_two.py create mode 100644 loader/test/template/template.h create mode 100644 loader/test/template/template.py create mode 100644 loader/test/tests.py create mode 100644 loader/test/tmain.c diff --git a/loader/.dir-locals.el b/loader/.dir-locals.el new file mode 100644 index 0000000..d5df947 --- /dev/null +++ b/loader/.dir-locals.el @@ -0,0 +1,32 @@ +;; Emacs settings for this project +;; Copyright (C) 2013 Richard Meadows +;; +;; Permission is hereby granted, free of charge, to any person obtaining +;; a copy of this software and associated documentation files (the +;; "Software"), to deal in the Software without restriction, including +;; without limitation the rights to use, copy, modify, merge, publish, +;; distribute, sublicense, and/or sell copies of the Software, and to +;; permit persons to whom the Software is furnished to do so, subject to +;; the following conditions: +;; +;; The above copyright notice and this permission notice shall be +;; included in all copies or substantial portions of the Software. +;; +;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +;;; Directory Local Variables +;;; See Info node `(emacs) Directory Variables' for more information. + +;; Use a special debugger for arm targets +;; Keep this directory as the default directory when navigating subdirectoies + +((nil + (gud-gdb-command-name . "arm-none-eabi-gdb --annotate=3") + (eval setq default-directory + (locate-dominating-file buffer-file-name ".dir-locals.el")))) diff --git a/loader/.gdbinit b/loader/.gdbinit new file mode 100644 index 0000000..ae44883 --- /dev/null +++ b/loader/.gdbinit @@ -0,0 +1,5 @@ +define blackmagic + target extended-remote /dev/ttyACM$arg0 +end +source gdbscript +source gdbscript-custom diff --git a/loader/.gitignore b/loader/.gitignore new file mode 100644 index 0000000..d3a73e0 --- /dev/null +++ b/loader/.gitignore @@ -0,0 +1,34 @@ +# Backup files +*~ +#*# + +# gdbscript +gdbscript +gdbscript-custom + +# The output directory +out/ + +# Intermediate compilation files +*.o + +# raw backlog data +tools/aprs/rawdata/*rawdata.txt + +# aprs-is id +aprs_id + +# Atmel Developement Kit +xdk* + +# ETAGS file +TAGS + +# CTypesgen +test/ctypesgen + +# Compiled python +*.pyc + +# Compile commands +compile_commands.json \ No newline at end of file diff --git a/loader/LICENSE-samd20-gcc-blackmagic.md b/loader/LICENSE-samd20-gcc-blackmagic.md new file mode 100644 index 0000000..e12c7a8 --- /dev/null +++ b/loader/LICENSE-samd20-gcc-blackmagic.md @@ -0,0 +1,26 @@ +Much of the source code in this project is licensed by ARM or Atmel +with a modified 3-clause BSD license. See file headers for more details. + +Everything else is under a +[MIT License](http://opensource.org/licenses/MIT) as follows: + +Copyright (C) 2014 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/loader/LICENSE.md b/loader/LICENSE.md new file mode 100644 index 0000000..581e38a --- /dev/null +++ b/loader/LICENSE.md @@ -0,0 +1,27 @@ +Where files originate outside of this project (such as those from the +Atmel ASF) they may be license with a modified 3-clause BSD license or +other. In any case the file headers take precidence. + +Everything else is under a +[MIT License](http://opensource.org/licenses/MIT) as follows: + +Copyright (C) 2014, 2015 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/loader/Makefile b/loader/Makefile new file mode 100644 index 0000000..09faaf3 --- /dev/null +++ b/loader/Makefile @@ -0,0 +1,277 @@ +# Compiles firmware written in C and assembler for the Atmel SAM D20 +# Copyright (C) 2014 +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# +# The primary targets in this file are: +# +# all Everything +# print-symlinks DEVICE= Prints any symlinks to a given device +# etags Generates an ETAGS file for the project +# emacs Launches emacs for this project +# verification Runs the ctypesgen needs for verif. scripts +# clean Removes generated files +# +# This makefile is intended to be run from the root of the project. +# + +# External configuration makefile +# +# Edit the project name, and compilation flags etc. in this makefile +# +-include config.mk + +# Directories +# +# These define the locations of the source, nordic sdk and output trees. +# +OUTPUT_PATH := out/ +SOURCE_TREE := src/ +INCLUDE_PATH := inc/ + +# Shell Commands +# +# Listed here for portability. +# +CAT := cat +ECHO := echo +FIND := find +GREP := grep +MKDIR := mkdir -p +RM := rm -r +SED := sed +TR := tr + +# ARM GCC Toolchain +# +# These tools are available from https://launchpad.net/gcc-arm-embedded/ and +# should be placed on your path. ALternatively you could compile your own. +# +TOOLCHAIN := arm-none-eabi +AS := $(TOOLCHAIN)-as +CC := $(TOOLCHAIN)-gcc +DB := $(TOOLCHAIN)-gdb +CXX := $(TOOLCHAIN)-g++ +OBJCOPY := $(TOOLCHAIN)-objcopy +OBJDUMP := $(TOOLCHAIN)-objdump +SIZE := $(TOOLCHAIN)-size + +# The SAM D20 series is based on an ARM Cortex M0+ core +# +# +ARCH_FLAGS := -mcpu=cortex-m0plus -mthumb + +# Flags for float printing +# +# +LDFLAGS += --specs=nano.specs + +# Compilation Flags +# +# Display all warnings. Compile functions and data into their own sections so +# they can be discarded if unused. The linker performs garbage collection of +# unused input sections. +# +CFLAGS += $(COMPILATION_FLAGS) -Wall -Wextra $(ACCEPT_WARN) -std=gnu99 \ + -ffunction-sections -fdata-sections $(ARCH_FLAGS) +ASFLAGS += -Wall $(ARCH_FLAGS) -a=/dev/null +LDFLAGS += $(COMPILATION_FLAGS) $(LINKER_FLAGS) -Wextra $(ARCH_FLAGS) + +# Compilation Defines +# +# These are available for use as macros +# +ifdef TARGET_CHIP +CFLAGS += -D$(TARGET_CHIP) -D__$(TARGET_CHIP)__ +endif +ifdef SEMIHOSTING +CFLAGS += -D__SEMIHOSTING__ +endif + +# Startup and system code +# +# +SYSTEM ?= chip/system_samd20.c chip/startup_samd20.c +INCLUDE_PATH += chip/ chip/cmsis/ samd20/ samd20/component/ test/tc/ + +# Verification suite code +# +# +SYSTEM += test/tmain.c + +# Linker Scripts +# +# +LINKERS ?= chip/$(shell echo $(TARGET_CHIP) | $(TR) A-Z a-z).ld chip/sections.ld + +# Our compilation target +# +# +TARGET := $(OUTPUT_PATH)$(PROJECT_NAME) + +# Build our list of all our sources +# +# The entirety of the source directory are included, along with +# everything in certain directories in the SDK. This has security +# implications: Anything that makes it into your source tree will get +# compiled and linked into your binary. +# +VPATH = $(SOURCE_PATH) +TREE_SOURCES = $(shell $(FIND) $(SOURCE_TREE) -name '*.[csS]') +SOURCES = $(SYSTEM) $(TREE_SOURCES) + +# Translate this list of sources into a list of required objects in +# the output directory. +objects = $(patsubst %.c,%.o,$(patsubst %.s,%.o,$(patsubst %.S,%.o, \ + $(SOURCES)))) +OBJECTS = $(addprefix $(OUTPUT_PATH),$(objects)) + +# Assemble a list of c and h files that are used in this project +# +TAGFILES = $(SOURCES) $(shell $(CAT) $(OBJECTS:.o=.d) \ + | $(SED) -n '/^.*\.h:/p' | $(SED) 's/://g') + +# Default target +# +# +all: $(TARGET).elf etags + +# Rule for generating object and dependancy files from source files. +# +# Creates a directory in the output tree if nessesary. File is only +# compiled, not linked. Dependancy generation is automatic, but only +# for user header files. Every depandancy in the .d is appended to the +# .d as a target, so that if they stop existing the corresponding +# object file will be re-compiled. +# +$(OUTPUT_PATH)%.o: %.c Makefile config.mk + @$(ECHO) + @$(ECHO) 'Compiling $<...' + @$(MKDIR) $(OUTPUT_PATH)$(dir $<) + $(CC) -c -MMD -MP $(CPPFLAGS) $(CFLAGS) $(addprefix -I,$(INCLUDE_PATH)) -o $@ $< + +# Attempt to include the dependancy makefiles for every object in this makefile. +# +# This means that object files depend on the header files they include. +# +-include $(OBJECTS:.o=.d) + +# Rule for generating object files from assembler files +# +# Creates a directory in the output tree if nessesary. The file is only +# assembled, not linked. +# +$(OUTPUT_PATH)%.o: %.s + @$(ECHO) + @$(ECHO) 'Assembling $<...' + @$(MKDIR) $(OUTPUT_PATH)$(dir $<) + $(AS) $(ASFLAGS) -o $@ $< + +# Generate the main build artifact. +# +# A .elf containing all the symbols (i.e. debugging information if the compiler +# / linker was run with -g) is created, alongside an intel hex file. A just +# about human-readable .map is also created. +# +$(TARGET).elf: $(OBJECTS) $(LINKERS) gdbscript Makefile config.mk + @$(ECHO) + @$(ECHO) 'Linking $@...' + $(CC) $(LDFLAGS) $(addprefix -T,$(LINKERS)) -Wl,-Map,$(@:.elf=.map) -o $@ $(OBJECTS) + @$(OBJCOPY) -O binary $@ $(@:.elf=.bin) + @$(OBJCOPY) -O ihex $@ $(@:.elf=.hex) + + @$(ECHO) + $(SIZE) $@ + @$(ECHO) + @$(SIZE) $@ | tail -1 - \ + | awk '{print "ROM Usage: "int(($$1+$$2)/10.24)/100"K"}' + @$(SIZE) $@ | tail -1 - \ + | awk '{print "RAM Usage: "int(($$2+$$3)/10.24)/100"K"}' + + @$(ECHO) + +# Creates debugging command list for gdb +# +# These tell gdb which file to debug and which debugger to use +# +gdbscript: Makefile config.mk + @$(ECHO) "# Load our .elf file into GDB" > gdbscript + @$(ECHO) "file $(TARGET).elf" >> gdbscript +ifdef BLACKMAGIC_PATH + @$(ECHO) "# Connect to a specified blackmagic" >> gdbscript + @$(ECHO) "target extended-remote $(BLACKMAGIC_PATH)" >> gdbscript +endif + +# Prints a list of symlinks to a device +# +# Use it like `make print-symlinks DEVICE=/dev/ttyACM0` +# +.PHONY: print-symlinks +print-symlinks: + @$(ECHO) 'Symlinks to $(DEVICE):' + @udevadm info --query symlink -n $(DEVICE) | \ + $(SED) -e 's/ /\n/' | $(SED) -e 's/^/\t/' + +# Generates an etags file for the project +# +# +etags: $(TAGFILES) + @$(ECHO) "Generating ETAGS..." + @etags $^ + +# Launches emacs with all the files used for this project +# +.PHONY: emacs +emacs: + @emacs $(TAGFILES) Makefile config.mk README.md gdbscript-custom + +# Test +# +TESTCASES := $(shell $(FIND) test/tc -name '*.[h]') + +.PHONY: test +test: test/main.py all + @echo "Running tests..." + @echo $(tc) > test/.testcommand +ifdef tc-gdb-info + $(DB) -q -x test/tests.py +else + @>/dev/null $(DB) -q -x test/tests.py +endif + +# Ctypesgen for test +test/main.py: test/tmain.c $(TESTCASES) + @echo "Generating Python Wrappers...." + @echo + test/ctypesgen/ctypesgen.py -o $@ \ + --cpp="$(CC) -E -DCTYPESGEN $(CPPFLAGS) $(CFLAGS) \ + $(addprefix -I,$(INCLUDE_PATH))" $^ + +# Removes everything in the output directory +# +# +# +.PHONY: clean +clean: + $(RM) $(OUTPUT_PATH)* + $(RM) gdbscript + $(RM) TAGS + $(RM) test/main.py* diff --git a/loader/README-samd20-gcc-blackmagic.md b/loader/README-samd20-gcc-blackmagic.md new file mode 100644 index 0000000..81594fb --- /dev/null +++ b/loader/README-samd20-gcc-blackmagic.md @@ -0,0 +1,147 @@ +## samd20-gcc-blackmagic ## + +A simple GCC setup for Atmel SAM D20 development, intended for use with the +[blackmagic debug probe](https://github.com/gsmcmullin/blackmagic). + +## Prerequisites ## + +[GNU Make](http://www.gnu.org/software/make/) and the following +standard utilities are required: `cat`, `echo`, `find`, `grep`, +`mkdir`, `rm`, `sed` and `tr`. If you're running any sensible desktop +linux then these will already be installed. + +You will also need to aquire +[GNU Tools for ARM Embedded Processors](https://launchpad.net/gcc-arm-embedded/). + +##### On Ubuntu + +``` +sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded +sudo apt-get update && sudo apt-get install gcc-arm-none-eabi +``` + +###### Note about gcc-arm-embedded on Ubuntu 14.04 and later + +If you are using Ubuntu 14.04 and later, please be careful because +there are packages with same name but produced by Debian and inherited +by Ubuntu. Simply follow the above 3 steps, you may end up with +gcc-arm-none-eabi from Ubuntu. So to install gcc-arm-none-eabi from +ARM, steps are: + +``` +1). sudo apt-get remove binutils-arm-none-eabi gcc-arm-none-eabi +2). sudo add-apt-repository ppa:terry.guo/gcc-arm-embedded +3). sudo apt-get update +4). sudo apt-get install gcc-arm-none-eabi=4-8-2014q2-0trusty10 +``` +Meanwhile we are working with Debian to consolidate and unify this toolchain. + +## Usage ## + +### Project Options ### + +[`config.mk`](config.mk) allows configuation for individual +projects. In particular the `PROJECT_NAME` and `TARGET_CHIP` variables +needs to be set. + +### Compiling ### + +`make` + +## Backmagic ## + +### Download ### + +Run `arm-none-eabi-gdb`. If you have set `BLACKMAGIC_PATH` in +[`config.mk`](config.mk) then gdb will attempt to connect to the +blackmagic debugger. Otherwise you can use the `blackmagic` command to +connect a `/dev/ttyACM` device. For example `blackmagic 0` will +connect to a blackmagic at `/dev/ttyACM0`. + +To attach to the SAM D20 chip itself you will need to run something like + +``` +monitor swdp_scan +attach 1 +``` + +You can place these commands in a `gdbscript-custom` file so that in +future they will be run automatically. If `monitor swdp_scan` fails to +detect an attached SAM D20 device then you may need to upgrade the +firmware on your blackmagic to the latest version. + +To download code run + +``` +monitor erase_mass +load +``` + +### Debugging ### + +You can start with the gdb command + +``` +run +``` + +You might want to use the command `set confirm off` so that you're not +prompted each time. You might also want to `set mem +inaccessible-by-default off` so that you can look at memory locations +outside of RAM and ROM. + +These commands can be automated by placing them in a `gdbscript-custom` file. + +### Semihosting ### + +You can build for semihosting by defining the `SEMIHOSTING` variable +in make. Like this: + +``` +make -kB SEMIHOSTING=1 +``` + +This build will be significantly larger (in terms of RAM and ROM). + +For this build, when a debugger is present at startup the +`semihost_printf`, `semihost_puts` and `semihost_putchar` functions +will print to stdio on the host. The Blackmagic Debug Probe supports +this. + +## Emacs ## + +The command `make emacs` can be used to quickly launch an instance of +emacs with all the relavent source code loaded. + +A `TAGS` file can be generated with `make all` or `make tags`, and +this can be used to automat navigate the source code. See the +[emacs manual](https://www.gnu.org/software/emacs/manual/html_node/emacs/Tags.html) +for more details. + +A Directory Local Variables File [`.dir-locals.el`](.dir-locals.el) +exists in the root of the project. This has the following effects +on emacs: + +### Fixed default-directory ### + +The default directory is fixed as the root of the project wherever you +are within the project. As the makefile needs to be run from the root +of the project, this means that `M+x compile` will always run the +top-level makefile no matter which file you are editing. + +### Custom GDB ### + +`M+x gdb` is set to use `arm-none-eabi-gdb` rather than the default GDB for your +machine. + +## Other notes ## + +Wherever possible use +[Function Attributes](http://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html) +and +[Variable Attrubutes](http://gcc.gnu.org/onlinedocs/gcc/Variable-Attributes.html) +rather than editing the project's linker files. + +## Sources & Licensing ## + +See [LICENSE.md](LICENSE-samd20-gcc-blackmagic.md) diff --git a/loader/README.md b/loader/README.md new file mode 100644 index 0000000..aa7777e --- /dev/null +++ b/loader/README.md @@ -0,0 +1,27 @@ +## Bristol Pico Tracker ## + +Bootloader for SAMD20 + +* Waits for battery voltage before starting boot + +## Technical Description ## + +The firmware is written in C and targeted at the highly configurable +Atmel SAMD20 series of ARM Cortex M0+ micromontrollers. The code can +be built using +[GNU Tools for ARM Embedded Processors](https://launchpad.net/gcc-arm-embedded/). +See [README-samd20-gcc-blackmagic.md](README-samd20-gcc-blackmagic.md) +for more details. + +## Test Suite ## + +The test suite is used to run test cases on real hardware. Test cases +are written mostly in python and run using a gdb that has been built +`--with-python`. It is still a work in progress but is quite handy +when debugging. + +See [test/README.md](test/README.md) for more details. + +## Sources & Licensing ## + +See [LICENSE.md](LICENSE.md) diff --git a/loader/chip/cmsis/arm_math.h b/loader/chip/cmsis/arm_math.h new file mode 100644 index 0000000..38713fd --- /dev/null +++ b/loader/chip/cmsis/arm_math.h @@ -0,0 +1,7059 @@ +/* ---------------------------------------------------------------------- + * Copyright (C) 2010-2011 ARM Limited. All rights reserved. + * + * $Date: 15. July 2011 + * $Revision: V1.0.10 + * + * Project: CMSIS DSP Library + * Title: arm_math.h + * + * Description: Public header file for CMSIS DSP Library + * + * Target Processor: Cortex-M4/Cortex-M3/Cortex-M0 + * + * Version 1.0.10 2011/7/15 + * Big Endian support added and Merged M0 and M3/M4 Source code. + * + * Version 1.0.3 2010/11/29 + * Re-organized the CMSIS folders and updated documentation. + * + * Version 1.0.2 2010/11/11 + * Documentation updated. + * + * Version 1.0.1 2010/10/05 + * Production release and review comments incorporated. + * + * Version 1.0.0 2010/09/20 + * Production release and review comments incorporated. + * -------------------------------------------------------------------- */ + +/** + \mainpage CMSIS DSP Software Library + * + * Introduction + * + * This user manual describes the CMSIS DSP software library, + * a suite of common signal processing functions for use on Cortex-M processor based devices. + * + * The library is divided into a number of modules each covering a specific category: + * - Basic math functions + * - Fast math functions + * - Complex math functions + * - Filters + * - Matrix functions + * - Transforms + * - Motor control functions + * - Statistical functions + * - Support functions + * - Interpolation functions + * + * The library has separate functions for operating on 8-bit integers, 16-bit integers, + * 32-bit integer and 32-bit floating-point values. + * + * Processor Support + * + * The library is completely written in C and is fully CMSIS compliant. + * High performance is achieved through maximum use of Cortex-M4 intrinsics. + * + * The supplied library source code also builds and runs on the Cortex-M3 and Cortex-M0 processor, + * with the DSP intrinsics being emulated through software. + * + * + * Toolchain Support + * + * The library has been developed and tested with MDK-ARM version 4.21. + * The library is being tested in GCC and IAR toolchains and updates on this activity will be made available shortly. + * + * Using the Library + * + * The library installer contains prebuilt versions of the libraries in the Lib folder. + * - arm_cortexM4lf_math.lib (Little endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4bf_math.lib (Big endian and Floating Point Unit on Cortex-M4) + * - arm_cortexM4l_math.lib (Little endian on Cortex-M4) + * - arm_cortexM4b_math.lib (Big endian on Cortex-M4) + * - arm_cortexM3l_math.lib (Little endian on Cortex-M3) + * - arm_cortexM3b_math.lib (Big endian on Cortex-M3) + * - arm_cortexM0l_math.lib (Little endian on Cortex-M0) + * - arm_cortexM0b_math.lib (Big endian on Cortex-M3) + * + * The library functions are declared in the public file arm_math.h which is placed in the Include folder. + * Simply include this file and link the appropriate library in the application and begin calling the library functions. The Library supports single + * public header file arm_math.h for Cortex-M4/M3/M0 with little endian and big endian. Same header file will be used for floating point unit(FPU) variants. + * Define the appropriate pre processor MACRO ARM_MATH_CM4 or ARM_MATH_CM3 or + * ARM_MATH_CM0 depending on the target processor in the application. + * + * Examples + * + * The library ships with a number of examples which demonstrate how to use the library functions. + * + * Building the Library + * + * The library installer contains project files to re build libraries on MDK Tool chain in the CMSIS\\DSP_Lib\\Source\\ARM folder. + * - arm_cortexM0b_math.uvproj + * - arm_cortexM0l_math.uvproj + * - arm_cortexM3b_math.uvproj + * - arm_cortexM3l_math.uvproj + * - arm_cortexM4b_math.uvproj + * - arm_cortexM4l_math.uvproj + * - arm_cortexM4bf_math.uvproj + * - arm_cortexM4lf_math.uvproj + * + * Each library project have differant pre-processor macros. + * + * ARM_MATH_CMx: + * Define macro ARM_MATH_CM4 for building the library on Cortex-M4 target, ARM_MATH_CM3 for building library on Cortex-M3 target + * and ARM_MATH_CM0 for building library on cortex-M0 target. + * + * ARM_MATH_BIG_ENDIAN: + * Define macro ARM_MATH_BIG_ENDIAN to build the library for big endian targets. By default library builds for little endian targets. + * + * ARM_MATH_MATRIX_CHECK: + * Define macro for checking on the input and output sizes of matrices + * + * ARM_MATH_ROUNDING: + * Define macro for rounding on support functions + * + * __FPU_PRESENT: + * Initialize macro __FPU_PRESENT = 1 when building on FPU supported Targets. Enable this macro for M4bf and M4lf libraries + * + * + * The project can be built by opening the appropriate project in MDK-ARM 4.21 chain and defining the optional pre processor MACROs detailed above. + * + * Copyright Notice + * + * Copyright (C) 2010 ARM Limited. All rights reserved. + */ + + +/** + * @defgroup groupMath Basic Math Functions + */ + +/** + * @defgroup groupFastMath Fast Math Functions + * This set of functions provides a fast approximation to sine, cosine, and square root. + * As compared to most of the other functions in the CMSIS math library, the fast math functions + * operate on individual values and not arrays. + * There are separate functions for Q15, Q31, and floating-point data. + * + */ + +/** + * @defgroup groupCmplxMath Complex Math Functions + * This set of functions operates on complex data vectors. + * The data in the complex arrays is stored in an interleaved fashion + * (real, imag, real, imag, ...). + * In the API functions, the number of samples in a complex array refers + * to the number of complex values; the array contains twice this number of + * real values. + */ + +/** + * @defgroup groupFilters Filtering Functions + */ + +/** + * @defgroup groupMatrix Matrix Functions + * + * This set of functions provides basic matrix math operations. + * The functions operate on matrix data structures. For example, + * the type + * definition for the floating-point matrix structure is shown + * below: + *
+ *     typedef struct
+ *     {
+ *       uint16_t numRows;     // number of rows of the matrix.
+ *       uint16_t numCols;     // number of columns of the matrix.
+ *       float32_t *pData;     // points to the data of the matrix.
+ *     } arm_matrix_instance_f32;
+ * 
+ * There are similar definitions for Q15 and Q31 data types. + * + * The structure specifies the size of the matrix and then points to + * an array of data. The array is of size numRows X numCols + * and the values are arranged in row order. That is, the + * matrix element (i, j) is stored at: + *
+ *     pData[i*numCols + j]
+ * 
+ * + * \par Init Functions + * There is an associated initialization function for each type of matrix + * data structure. + * The initialization function sets the values of the internal structure fields. + * Refer to the function arm_mat_init_f32(), arm_mat_init_q31() + * and arm_mat_init_q15() for floating-point, Q31 and Q15 types, respectively. + * + * \par + * Use of the initialization function is optional. However, if initialization function is used + * then the instance structure cannot be placed into a const data section. + * To place the instance structure in a const data + * section, manually initialize the data structure. For example: + *
+ * arm_matrix_instance_f32 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q31 S = {nRows, nColumns, pData};
+ * arm_matrix_instance_q15 S = {nRows, nColumns, pData};
+ * 
+ * where nRows specifies the number of rows, nColumns + * specifies the number of columns, and pData points to the + * data array. + * + * \par Size Checking + * By default all of the matrix functions perform size checking on the input and + * output matrices. For example, the matrix addition function verifies that the + * two input matrices and the output matrix all have the same number of rows and + * columns. If the size check fails the functions return: + *
+ *     ARM_MATH_SIZE_MISMATCH
+ * 
+ * Otherwise the functions return + *
+ *     ARM_MATH_SUCCESS
+ * 
+ * There is some overhead associated with this matrix size checking. + * The matrix size checking is enabled via the \#define + *
+ *     ARM_MATH_MATRIX_CHECK
+ * 
+ * within the library project settings. By default this macro is defined + * and size checking is enabled. By changing the project settings and + * undefining this macro size checking is eliminated and the functions + * run a bit faster. With size checking disabled the functions always + * return ARM_MATH_SUCCESS. + */ + +/** + * @defgroup groupTransforms Transform Functions + */ + +/** + * @defgroup groupController Controller Functions + */ + +/** + * @defgroup groupStats Statistics Functions + */ +/** + * @defgroup groupSupport Support Functions + */ + +/** + * @defgroup groupInterpolation Interpolation Functions + * These functions perform 1- and 2-dimensional interpolation of data. + * Linear interpolation is used for 1-dimensional data and + * bilinear interpolation is used for 2-dimensional data. + */ + +/** + * @defgroup groupExamples Examples + */ +#ifndef _ARM_MATH_H +#define _ARM_MATH_H + +#include "compiler.h" + +#define __CMSIS_GENERIC /* disable NVIC and Systick functions */ + +#if defined (ARM_MATH_CM4) + #include "core_cm4.h" +#elif defined (ARM_MATH_CM3) + #include "core_cm3.h" +#elif defined (ARM_MATH_CM0) + #include "core_cm0.h" +#else +#include "ARMCM4.h" +#warning "Define either ARM_MATH_CM4 OR ARM_MATH_CM3...By Default building on ARM_MATH_CM4....." +#endif + +#undef __CMSIS_GENERIC /* enable NVIC and Systick functions */ +#include "string.h" + #include "math.h" +#ifdef __cplusplus +extern "C" +{ +#endif + + + /** + * @brief Macros required for reciprocal calculation in Normalized LMS + */ + +#define DELTA_Q31 (0x100) +#define DELTA_Q15 0x5 +#define INDEX_MASK 0x0000003F +#define PI 3.14159265358979f + + /** + * @brief Macros required for SINE and COSINE Fast math approximations + */ + +#define TABLE_SIZE 256 +#define TABLE_SPACING_Q31 0x800000 +#define TABLE_SPACING_Q15 0x80 + + /** + * @brief Macros required for SINE and COSINE Controller functions + */ + /* 1.31(q31) Fixed value of 2/360 */ + /* -1 to +1 is divided into 360 values so total spacing is (2/360) */ +#define INPUT_SPACING 0xB60B61 + + + /** + * @brief Error status returned by some functions in the library. + */ + + typedef enum + { + ARM_MATH_SUCCESS = 0, /**< No error */ + ARM_MATH_ARGUMENT_ERROR = -1, /**< One or more arguments are incorrect */ + ARM_MATH_LENGTH_ERROR = -2, /**< Length of data buffer is incorrect */ + ARM_MATH_SIZE_MISMATCH = -3, /**< Size of matrices is not compatible with the operation. */ + ARM_MATH_NANINF = -4, /**< Not-a-number (NaN) or infinity is generated */ + ARM_MATH_SINGULAR = -5, /**< Generated by matrix inversion if the input matrix is singular and cannot be inverted. */ + ARM_MATH_TEST_FAILURE = -6 /**< Test Failed */ + } arm_status; + + /** + * @brief 8-bit fractional data type in 1.7 format. + */ + typedef int8_t q7_t; + + /** + * @brief 16-bit fractional data type in 1.15 format. + */ + typedef int16_t q15_t; + + /** + * @brief 32-bit fractional data type in 1.31 format. + */ + typedef int32_t q31_t; + + /** + * @brief 64-bit fractional data type in 1.63 format. + */ + typedef int64_t q63_t; + + /** + * @brief 32-bit floating-point type definition. + */ + typedef float float32_t; + + /** + * @brief 64-bit floating-point type definition. + */ + typedef double float64_t; + + /** + * @brief definition to read/write two 16 bit values. + */ +#define __SIMD32(addr) (*(int32_t **) & (addr)) + +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + /** + * @brief definition to pack two 16 bit values. + */ +#define __PKHBT(ARG1, ARG2, ARG3) ( (((int32_t)(ARG1) << 0) & (int32_t)0x0000FFFF) | \ + (((int32_t)(ARG2) << ARG3) & (int32_t)0xFFFF0000) ) + +#endif + + + /** + * @brief definition to pack four 8 bit values. + */ +#ifndef ARM_MATH_BIG_ENDIAN + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v0) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v1) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v2) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v3) << 24) & (int32_t)0xFF000000) ) +#else + +#define __PACKq7(v0,v1,v2,v3) ( (((int32_t)(v3) << 0) & (int32_t)0x000000FF) | \ + (((int32_t)(v2) << 8) & (int32_t)0x0000FF00) | \ + (((int32_t)(v1) << 16) & (int32_t)0x00FF0000) | \ + (((int32_t)(v0) << 24) & (int32_t)0xFF000000) ) + +#endif + + + /** + * @brief Clips Q63 to Q31 values. + */ + __STATIC_INLINE q31_t clip_q63_to_q31( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFFFFFF ^ ((q31_t) (x >> 63)))) : (q31_t) x; + } + + /** + * @brief Clips Q63 to Q15 values. + */ + __STATIC_INLINE q15_t clip_q63_to_q15( + q63_t x) + { + return ((q31_t) (x >> 32) != ((q31_t) x >> 31)) ? + ((0x7FFF ^ ((q15_t) (x >> 63)))) : (q15_t) (x >> 15); + } + + /** + * @brief Clips Q31 to Q7 values. + */ + __STATIC_INLINE q7_t clip_q31_to_q7( + q31_t x) + { + return ((q31_t) (x >> 24) != ((q31_t) x >> 23)) ? + ((0x7F ^ ((q7_t) (x >> 31)))) : (q7_t) x; + } + + /** + * @brief Clips Q31 to Q15 values. + */ + __STATIC_INLINE q15_t clip_q31_to_q15( + q31_t x) + { + return ((q31_t) (x >> 16) != ((q31_t) x >> 15)) ? + ((0x7FFF ^ ((q15_t) (x >> 31)))) : (q15_t) x; + } + + /** + * @brief Multiplies 32 X 64 and returns 32 bit result in 2.30 format. + */ + + __STATIC_INLINE q63_t mult32x64( + q63_t x, + q31_t y) + { + return ((((q63_t) (x & 0x00000000FFFFFFFF) * y) >> 32) + + (((q63_t) (x >> 32) * y))); + } + + +#if defined (ARM_MATH_CM0) && defined ( __CC_ARM ) +#define __CLZ __clz +#endif + +#if defined (ARM_MATH_CM0) && defined ( __TASKING__ ) +/* No need to redefine __CLZ */ +#endif + +#if defined (ARM_MATH_CM0) && ((defined (__ICCARM__)) ||(defined (__GNUC__)) ) + + __STATIC_INLINE uint32_t __CLZ(q31_t data); + + + __STATIC_INLINE uint32_t __CLZ(q31_t data) + { + uint32_t count = 0; + uint32_t mask = 0x80000000; + + while((data & mask) == 0) + { + count += 1u; + mask = mask >> 1u; + } + + return(count); + + } + +#endif + + /** + * @brief Function to Calculates 1/in(reciprocal) value of Q31 Data type. + */ + + __STATIC_INLINE uint32_t arm_recip_q31( + q31_t in, + q31_t * dst, + q31_t * pRecipTable) + { + + uint32_t out, tempVal; + uint32_t index, i; + uint32_t signBits; + + if(in > 0) + { + signBits = __CLZ(in) - 1; + } + else + { + signBits = __CLZ(-in) - 1; + } + + /* Convert input sample to 1.31 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = (uint32_t) (in >> 24u); + index = (index & INDEX_MASK); + + /* 1.31 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0u; i < 2u; i++) + { + tempVal = (q31_t) (((q63_t) in * out) >> 31u); + tempVal = 0x7FFFFFFF - tempVal; + /* 1.31 with exp 1 */ + //out = (q31_t) (((q63_t) out * tempVal) >> 30u); + out = (q31_t) clip_q63_to_q31(((q63_t) out * tempVal) >> 30u); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1u); + + } + + /** + * @brief Function to Calculates 1/in(reciprocal) value of Q15 Data type. + */ + __STATIC_INLINE uint32_t arm_recip_q15( + q15_t in, + q15_t * dst, + q15_t * pRecipTable) + { + + uint32_t out = 0, tempVal = 0; + uint32_t index = 0, i = 0; + uint32_t signBits = 0; + + if(in > 0) + { + signBits = __CLZ(in) - 17; + } + else + { + signBits = __CLZ(-in) - 17; + } + + /* Convert input sample to 1.15 format */ + in = in << signBits; + + /* calculation of index for initial approximated Val */ + index = in >> 8; + index = (index & INDEX_MASK); + + /* 1.15 with exp 1 */ + out = pRecipTable[index]; + + /* calculation of reciprocal value */ + /* running approximation for two iterations */ + for (i = 0; i < 2; i++) + { + tempVal = (q15_t) (((q31_t) in * out) >> 15); + tempVal = 0x7FFF - tempVal; + /* 1.15 with exp 1 */ + out = (q15_t) (((q31_t) out * tempVal) >> 14); + } + + /* write output */ + *dst = out; + + /* return num of signbits of out = 1/in value */ + return (signBits + 1); + + } + + + /* + * @brief C custom defined intrinisic function for only M0 processors + */ +#if defined(ARM_MATH_CM0) + + __STATIC_INLINE q31_t __SSAT( + q31_t x, + uint32_t y) + { + int32_t posMax, negMin; + uint32_t i; + + posMax = 1; + for (i = 0; i < (y - 1); i++) + { + posMax = posMax * 2; + } + + if(x > 0) + { + posMax = (posMax - 1); + + if(x > posMax) + { + x = posMax; + } + } + else + { + negMin = -posMax; + + if(x < negMin) + { + x = negMin; + } + } + return (x); + + + } + +#endif /* end of ARM_MATH_CM0 */ + + + + /* + * @brief C custom defined intrinsic function for M3 and M0 processors + */ +#if defined (ARM_MATH_CM3) || defined (ARM_MATH_CM0) + + /* + * @brief C custom defined QADD8 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD8( + q31_t x, + q31_t y) + { + + q31_t sum; + q7_t r, s, t, u; + + r = (char) x; + s = (char) y; + + r = __SSAT((q31_t) (r + s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) + ((y << 16) >> 24))), 8); + t = __SSAT(((q31_t) (((x << 8) >> 24) + ((y << 8) >> 24))), 8); + u = __SSAT(((q31_t) ((x >> 24) + (y >> 24))), 8); + + sum = (((q31_t) u << 24) & 0xFF000000) | (((q31_t) t << 16) & 0x00FF0000) | + (((q31_t) s << 8) & 0x0000FF00) | (r & 0x000000FF); + + return sum; + + } + + /* + * @brief C custom defined QSUB8 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB8( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s, t, u; + + r = (char) x; + s = (char) y; + + r = __SSAT((r - s), 8); + s = __SSAT(((q31_t) (((x << 16) >> 24) - ((y << 16) >> 24))), 8) << 8; + t = __SSAT(((q31_t) (((x << 8) >> 24) - ((y << 8) >> 24))), 8) << 16; + u = __SSAT(((q31_t) ((x >> 24) - (y >> 24))), 8) << 24; + + sum = + (u & 0xFF000000) | (t & 0x00FF0000) | (s & 0x0000FF00) | (r & 0x000000FF); + + return sum; + } + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + + /* + * @brief C custom defined QADD16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r + s, 16); + s = __SSAT(((q31_t) ((x >> 16) + (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined SHADD16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHADD16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (s >> 1)); + s = ((q31_t) ((x >> 17) + (y >> 17))) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + + } + + /* + * @brief C custom defined QSUB16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB16( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = __SSAT(r - s, 16); + s = __SSAT(((q31_t) ((x >> 16) - (y >> 16))), 16) << 16; + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SHSUB16 for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHSUB16( + q31_t x, + q31_t y) + { + + q31_t diff; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (s >> 1)); + s = (((x >> 17) - (y >> 17)) << 16); + + diff = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return diff; + } + + /* + * @brief C custom defined QASX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QASX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) + (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x - (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHASX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHASX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) - (y >> 17)); + s = (((x >> 17) + (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + + /* + * @brief C custom defined QSAX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSAX( + q31_t x, + q31_t y) + { + + q31_t sum = 0; + + sum = ((sum + clip_q31_to_q15((q31_t) ((short) (x >> 16) - (short) y))) << 16) + + clip_q31_to_q15((q31_t) ((short) x + (short) (y >> 16))); + + return sum; + } + + /* + * @brief C custom defined SHSAX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SHSAX( + q31_t x, + q31_t y) + { + + q31_t sum; + q31_t r, s; + + r = (short) x; + s = (short) y; + + r = ((r >> 1) + (y >> 17)); + s = (((x >> 17) - (s >> 1)) << 16); + + sum = (s & 0xFFFF0000) | (r & 0x0000FFFF); + + return sum; + } + + /* + * @brief C custom defined SMUSDX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUSDX( + q31_t x, + q31_t y) + { + + return ((q31_t)(((short) x * (short) (y >> 16)) - + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined SMUADX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUADX( + q31_t x, + q31_t y) + { + + return ((q31_t)(((short) x * (short) (y >> 16)) + + ((short) (x >> 16) * (short) y))); + } + + /* + * @brief C custom defined QADD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QADD( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x + y); + } + + /* + * @brief C custom defined QSUB for M3 and M0 processors + */ + __STATIC_INLINE q31_t __QSUB( + q31_t x, + q31_t y) + { + return clip_q63_to_q31((q63_t) x - y); + } + + /* + * @brief C custom defined SMLAD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLAD( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLADX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLADX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLSDX for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMLSDX( + q31_t x, + q31_t y, + q31_t sum) + { + + return (sum - ((short) (x >> 16) * (short) (y)) + + ((short) x * (short) (y >> 16))); + } + + /* + * @brief C custom defined SMLALD for M3 and M0 processors + */ + __STATIC_INLINE q63_t __SMLALD( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) (y >> 16)) + + ((short) x * (short) y)); + } + + /* + * @brief C custom defined SMLALDX for M3 and M0 processors + */ + __STATIC_INLINE q63_t __SMLALDX( + q31_t x, + q31_t y, + q63_t sum) + { + + return (sum + ((short) (x >> 16) * (short) y)) + + ((short) x * (short) (y >> 16)); + } + + /* + * @brief C custom defined SMUAD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUAD( + q31_t x, + q31_t y) + { + + return (((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + /* + * @brief C custom defined SMUSD for M3 and M0 processors + */ + __STATIC_INLINE q31_t __SMUSD( + q31_t x, + q31_t y) + { + + return (-((x >> 16) * (y >> 16)) + + (((x << 16) >> 16) * ((y << 16) >> 16))); + } + + + + +#endif /* (ARM_MATH_CM3) || defined (ARM_MATH_CM0) */ + + + /** + * @brief Instance structure for the Q7 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q7_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q7; + + /** + * @brief Instance structure for the Q15 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + } arm_fir_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of filter coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + } arm_fir_instance_f32; + + + /** + * @brief Processing function for the Q7 FIR filter. + * @param[in] *S points to an instance of the Q7 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q7( + const arm_fir_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q7 FIR filter. + * @param[in,out] *S points to an instance of the Q7 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed. + * @return none + */ + void arm_fir_init_q7( + arm_fir_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 FIR filter. + * @param[in] *S points to an instance of the Q15 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q15 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q15( + const arm_fir_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 FIR filter. + * @param[in,out] *S points to an instance of the Q15 FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. Must be even and greater than or equal to 4. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return The function returns ARM_MATH_SUCCESS if initialization was successful or ARM_MATH_ARGUMENT_ERROR if + * numTaps is not a supported value. + */ + + arm_status arm_fir_init_q15( + arm_fir_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR filter. + * @param[in] *S points to an instance of the Q31 FIR filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the fast Q31 FIR filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_fast_q31( + const arm_fir_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR filter. + * @param[in,out] *S points to an instance of the Q31 FIR structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_q31( + arm_fir_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the floating-point FIR filter. + * @param[in] *S points to an instance of the floating-point FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_f32( + const arm_fir_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR filter. + * @param[in,out] *S points to an instance of the floating-point FIR filter structure. + * @param[in] numTaps Number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of samples that are processed at a time. + * @return none. + */ + void arm_fir_init_f32( + arm_fir_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 Biquad cascade filter. + */ + typedef struct + { + int8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q15_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q15_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + int8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q15; + + + /** + * @brief Instance structure for the Q31 Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q31_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< Additional shift, in bits, applied to each output sample. */ + + } arm_biquad_casd_df1_inst_q31; + + /** + * @brief Instance structure for the floating-point Biquad cascade filter. + */ + typedef struct + { + uint32_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< Points to the array of state coefficients. The array is of length 4*numStages. */ + float32_t *pCoeffs; /**< Points to the array of coefficients. The array is of length 5*numStages. */ + + + } arm_biquad_casd_df1_inst_f32; + + + + /** + * @brief Processing function for the Q15 Biquad cascade filter. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q15 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q15( + arm_biquad_casd_df1_inst_q15 * S, + uint8_t numStages, + q15_t * pCoeffs, + q15_t * pState, + int8_t postShift); + + + /** + * @brief Fast but less precise processing function for the Q15 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q15( + const arm_biquad_casd_df1_inst_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 Biquad cascade filter + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Fast but less precise processing function for the Q31 Biquad cascade filter for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_fast_q31( + const arm_biquad_casd_df1_inst_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 Biquad cascade filter. + * @param[in,out] *S points to an instance of the Q31 Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift Shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cascade_df1_init_q31( + arm_biquad_casd_df1_inst_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q31_t * pState, + int8_t postShift); + + /** + * @brief Processing function for the floating-point Biquad cascade filter. + * @param[in] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df1_f32( + const arm_biquad_casd_df1_inst_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point Biquad cascade filter. + * @param[in,out] *S points to an instance of the floating-point Biquad cascade structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df1_init_f32( + arm_biquad_casd_df1_inst_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + /** + * @brief Instance structure for the floating-point matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + float32_t *pData; /**< points to the data of the matrix. */ + } arm_matrix_instance_f32; + + /** + * @brief Instance structure for the Q15 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q15_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q15; + + /** + * @brief Instance structure for the Q31 matrix structure. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows of the matrix. */ + uint16_t numCols; /**< number of columns of the matrix. */ + q31_t *pData; /**< points to the data of the matrix. */ + + } arm_matrix_instance_q31; + + + + /** + * @brief Floating-point matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix addition. + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_add_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_f32( + const arm_matrix_instance_f32 * pSrc, + arm_matrix_instance_f32 * pDst); + + + /** + * @brief Q15 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q15( + const arm_matrix_instance_q15 * pSrc, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix transpose. + * @param[in] *pSrc points to the input matrix + * @param[out] *pDst points to the output matrix + * @return The function returns either ARM_MATH_SIZE_MISMATCH + * or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_trans_q31( + const arm_matrix_instance_q31 * pSrc, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q15 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @param[in] *pState points to the array for storing intermediate results + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst, + q15_t * pState); + + /** + * @brief Q31 matrix multiplication + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Q31 matrix multiplication (fast variant) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_mult_fast_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Floating-point matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_f32( + const arm_matrix_instance_f32 * pSrcA, + const arm_matrix_instance_f32 * pSrcB, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q15( + const arm_matrix_instance_q15 * pSrcA, + const arm_matrix_instance_q15 * pSrcB, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix subtraction + * @param[in] *pSrcA points to the first input matrix structure + * @param[in] *pSrcB points to the second input matrix structure + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_sub_q31( + const arm_matrix_instance_q31 * pSrcA, + const arm_matrix_instance_q31 * pSrcB, + arm_matrix_instance_q31 * pDst); + + /** + * @brief Floating-point matrix scaling. + * @param[in] *pSrc points to the input matrix + * @param[in] scale scale factor + * @param[out] *pDst points to the output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_f32( + const arm_matrix_instance_f32 * pSrc, + float32_t scale, + arm_matrix_instance_f32 * pDst); + + /** + * @brief Q15 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q15( + const arm_matrix_instance_q15 * pSrc, + q15_t scaleFract, + int32_t shift, + arm_matrix_instance_q15 * pDst); + + /** + * @brief Q31 matrix scaling. + * @param[in] *pSrc points to input matrix + * @param[in] scaleFract fractional portion of the scale factor + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to output matrix structure + * @return The function returns either + * ARM_MATH_SIZE_MISMATCH or ARM_MATH_SUCCESS based on the outcome of size checking. + */ + + arm_status arm_mat_scale_q31( + const arm_matrix_instance_q31 * pSrc, + q31_t scaleFract, + int32_t shift, + arm_matrix_instance_q31 * pDst); + + + /** + * @brief Q31 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q31( + arm_matrix_instance_q31 * S, + uint16_t nRows, + uint16_t nColumns, + q31_t *pData); + + /** + * @brief Q15 matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_q15( + arm_matrix_instance_q15 * S, + uint16_t nRows, + uint16_t nColumns, + q15_t *pData); + + /** + * @brief Floating-point matrix initialization. + * @param[in,out] *S points to an instance of the floating-point matrix structure. + * @param[in] nRows number of rows in the matrix. + * @param[in] nColumns number of columns in the matrix. + * @param[in] *pData points to the matrix data array. + * @return none + */ + + void arm_mat_init_f32( + arm_matrix_instance_f32 * S, + uint16_t nRows, + uint16_t nColumns, + float32_t *pData); + + + + /** + * @brief Instance structure for the Q15 PID Control. + */ + typedef struct + { + q15_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + #ifdef ARM_MATH_CM0 + q15_t A1; + q15_t A2; + #else + q31_t A1; /**< The derived gain A1 = -Kp - 2Kd | Kd.*/ + #endif + q15_t state[3]; /**< The state array of length 3. */ + q15_t Kp; /**< The proportional gain. */ + q15_t Ki; /**< The integral gain. */ + q15_t Kd; /**< The derivative gain. */ + } arm_pid_instance_q15; + + /** + * @brief Instance structure for the Q31 PID Control. + */ + typedef struct + { + q31_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + q31_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + q31_t A2; /**< The derived gain, A2 = Kd . */ + q31_t state[3]; /**< The state array of length 3. */ + q31_t Kp; /**< The proportional gain. */ + q31_t Ki; /**< The integral gain. */ + q31_t Kd; /**< The derivative gain. */ + + } arm_pid_instance_q31; + + /** + * @brief Instance structure for the floating-point PID Control. + */ + typedef struct + { + float32_t A0; /**< The derived gain, A0 = Kp + Ki + Kd . */ + float32_t A1; /**< The derived gain, A1 = -Kp - 2Kd. */ + float32_t A2; /**< The derived gain, A2 = Kd . */ + float32_t state[3]; /**< The state array of length 3. */ + float32_t Kp; /**< The proportional gain. */ + float32_t Ki; /**< The integral gain. */ + float32_t Kd; /**< The derivative gain. */ + } arm_pid_instance_f32; + + + + /** + * @brief Initialization function for the floating-point PID Control. + * @param[in,out] *S points to an instance of the PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_f32( + arm_pid_instance_f32 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @return none + */ + void arm_pid_reset_f32( + arm_pid_instance_f32 * S); + + + /** + * @brief Initialization function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q31( + arm_pid_instance_q31 * S, + int32_t resetStateFlag); + + + /** + * @brief Reset function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @return none + */ + + void arm_pid_reset_q31( + arm_pid_instance_q31 * S); + + /** + * @brief Initialization function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID structure. + * @param[in] resetStateFlag flag to reset the state. 0 = no change in state 1 = reset the state. + * @return none. + */ + void arm_pid_init_q15( + arm_pid_instance_q15 * S, + int32_t resetStateFlag); + + /** + * @brief Reset function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the q15 PID Control structure + * @return none + */ + void arm_pid_reset_q15( + arm_pid_instance_q15 * S); + + + /** + * @brief Instance structure for the floating-point Linear Interpolate function. + */ + typedef struct + { + uint32_t nValues; /**< nValues */ + float32_t x1; /**< x1 */ + float32_t xSpacing; /**< xSpacing */ + float32_t *pYData; /**< pointer to the table of Y values */ + } arm_linear_interp_instance_f32; + + /** + * @brief Instance structure for the floating-point bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + float32_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_f32; + + /** + * @brief Instance structure for the Q31 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q31_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q31; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q15_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q15; + + /** + * @brief Instance structure for the Q15 bilinear interpolation function. + */ + + typedef struct + { + uint16_t numRows; /**< number of rows in the data table. */ + uint16_t numCols; /**< number of columns in the data table. */ + q7_t *pData; /**< points to the data table. */ + } arm_bilinear_interp_instance_q7; + + + /** + * @brief Q7 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector multiplication. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_mult_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q15 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q15; + + /** + * @brief Instance structure for the Q31 CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + } arm_cfft_radix4_instance_q31; + + /** + * @brief Instance structure for the floating-point CFFT/CIFFT function. + */ + + typedef struct + { + uint16_t fftLen; /**< length of the FFT. */ + uint8_t ifftFlag; /**< flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. */ + uint8_t bitReverseFlag; /**< flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + uint16_t *pBitRevTable; /**< points to the bit reversal table. */ + uint16_t twidCoefModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + uint16_t bitRevFactor; /**< bit reversal modifier that supports different size FFTs with the same bit reversal table. */ + float32_t onebyfftLen; /**< value of 1/fftLen. */ + } arm_cfft_radix4_instance_f32; + + /** + * @brief Processing function for the Q15 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q15( + const arm_cfft_radix4_instance_q15 * S, + q15_t * pSrc); + + /** + * @brief Initialization function for the Q15 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q15( + arm_cfft_radix4_instance_q15 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 CFFT/CIFFT. + * @param[in] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_q31( + const arm_cfft_radix4_instance_q31 * S, + q31_t * pSrc); + + /** + * @brief Initialization function for the Q31 CFFT/CIFFT. + * @param[in,out] *S points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_q31( + arm_cfft_radix4_instance_q31 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point CFFT/CIFFT. + * @param[in] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in, out] *pSrc points to the complex data buffer. Processing occurs in-place. + * @return none. + */ + + void arm_cfft_radix4_f32( + const arm_cfft_radix4_instance_f32 * S, + float32_t * pSrc); + + /** + * @brief Initialization function for the floating-point CFFT/CIFFT. + * @param[in,out] *S points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLen length of the FFT. + * @param[in] ifftFlag flag that selects forward (ifftFlag=0) or inverse (ifftFlag=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLen is not a supported value. + */ + + arm_status arm_cfft_radix4_init_f32( + arm_cfft_radix4_instance_f32 * S, + uint16_t fftLen, + uint8_t ifftFlag, + uint8_t bitReverseFlag); + + + + /*---------------------------------------------------------------------- + * Internal functions prototypes FFT function + ----------------------------------------------------------------------*/ + + /** + * @brief Core function for the floating-point CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to the twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier); + + /** + * @brief Core function for the floating-point CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @param[in] onebyfftLen value of 1/fftLen. + * @return none. + */ + + void arm_radix4_butterfly_inverse_f32( + float32_t * pSrc, + uint16_t fftLen, + float32_t * pCoef, + uint16_t twidCoefModifier, + float32_t onebyfftLen); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of floating-point data type. + * @param[in] fftSize length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table. + * @param[in] *pBitRevTab points to the bit reversal table. + * @return none. + */ + + void arm_bitreversal_f32( + float32_t *pSrc, + uint16_t fftSize, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q31 CFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q31( + q31_t *pSrc, + uint32_t fftLen, + q31_t *pCoef, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q31 CIFFT butterfly process. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q31( + q31_t * pSrc, + uint32_t fftLen, + q31_t * pCoef, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q31 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q31( + q31_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Core function for the Q15 CFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief Core function for the Q15 CIFFT butterfly process. + * @param[in, out] *pSrc16 points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] *pCoef16 points to twiddle coefficient buffer. + * @param[in] twidCoefModifier twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. + * @return none. + */ + + void arm_radix4_butterfly_inverse_q15( + q15_t *pSrc16, + uint32_t fftLen, + q15_t *pCoef16, + uint32_t twidCoefModifier); + + /** + * @brief In-place bit reversal function. + * @param[in, out] *pSrc points to the in-place buffer of Q15 data type. + * @param[in] fftLen length of the FFT. + * @param[in] bitRevFactor bit reversal modifier that supports different size FFTs with the same bit reversal table + * @param[in] *pBitRevTab points to bit reversal table. + * @return none. + */ + + void arm_bitreversal_q15( + q15_t * pSrc, + uint32_t fftLen, + uint16_t bitRevFactor, + uint16_t *pBitRevTab); + + /** + * @brief Instance structure for the Q15 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q15_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q15_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q15; + + /** + * @brief Instance structure for the Q31 RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint32_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + q31_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + q31_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_q31; + + /** + * @brief Instance structure for the floating-point RFFT/RIFFT function. + */ + + typedef struct + { + uint32_t fftLenReal; /**< length of the real FFT. */ + uint16_t fftLenBy2; /**< length of the complex FFT. */ + uint8_t ifftFlagR; /**< flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. */ + uint8_t bitReverseFlagR; /**< flag that enables (bitReverseFlagR=1) or disables (bitReverseFlagR=0) bit reversal of output. */ + uint32_t twidCoefRModifier; /**< twiddle coefficient modifier that supports different size FFTs with the same twiddle factor table. */ + float32_t *pTwiddleAReal; /**< points to the real twiddle factor table. */ + float32_t *pTwiddleBReal; /**< points to the imag twiddle factor table. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_rfft_instance_f32; + + /** + * @brief Processing function for the Q15 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q15( + const arm_rfft_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst); + + /** + * @brief Initialization function for the Q15 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of the Q15 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + arm_status arm_rfft_init_q15( + arm_rfft_instance_q15 * S, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Processing function for the Q31 RFFT/RIFFT. + * @param[in] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_q31( + const arm_rfft_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst); + + /** + * @brief Initialization function for the Q31 RFFT/RIFFT. + * @param[in, out] *S points to an instance of the Q31 RFFT/RIFFT structure. + * @param[in, out] *S_CFFT points to an instance of the Q31 CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + arm_status arm_rfft_init_q31( + arm_rfft_instance_q31 * S, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Initialization function for the floating-point RFFT/RIFFT. + * @param[in,out] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in,out] *S_CFFT points to an instance of the floating-point CFFT/CIFFT structure. + * @param[in] fftLenReal length of the FFT. + * @param[in] ifftFlagR flag that selects forward (ifftFlagR=0) or inverse (ifftFlagR=1) transform. + * @param[in] bitReverseFlag flag that enables (bitReverseFlag=1) or disables (bitReverseFlag=0) bit reversal of output. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported value. + */ + + arm_status arm_rfft_init_f32( + arm_rfft_instance_f32 * S, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint32_t fftLenReal, + uint32_t ifftFlagR, + uint32_t bitReverseFlag); + + /** + * @brief Processing function for the floating-point RFFT/RIFFT. + * @param[in] *S points to an instance of the floating-point RFFT/RIFFT structure. + * @param[in] *pSrc points to the input buffer. + * @param[out] *pDst points to the output buffer. + * @return none. + */ + + void arm_rfft_f32( + const arm_rfft_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst); + + /** + * @brief Instance structure for the floating-point DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + float32_t normalize; /**< normalizing factor. */ + float32_t *pTwiddle; /**< points to the twiddle factor table. */ + float32_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_f32 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_f32 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_f32; + + /** + * @brief Initialization function for the floating-point DCT4/IDCT4. + * @param[in,out] *S points to an instance of floating-point DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of floating-point RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of floating-point CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if fftLenReal is not a supported transform length. + */ + + arm_status arm_dct4_init_f32( + arm_dct4_instance_f32 * S, + arm_rfft_instance_f32 * S_RFFT, + arm_cfft_radix4_instance_f32 * S_CFFT, + uint16_t N, + uint16_t Nby2, + float32_t normalize); + + /** + * @brief Processing function for the floating-point DCT4/IDCT4. + * @param[in] *S points to an instance of the floating-point DCT4/IDCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_f32( + const arm_dct4_instance_f32 * S, + float32_t * pState, + float32_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q31 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q31_t normalize; /**< normalizing factor. */ + q31_t *pTwiddle; /**< points to the twiddle factor table. */ + q31_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q31 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q31 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q31; + + /** + * @brief Initialization function for the Q31 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q31 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q31 RFFT/RIFFT structure + * @param[in] *S_CFFT points to an instance of Q31 CFFT/CIFFT structure + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q31( + arm_dct4_instance_q31 * S, + arm_rfft_instance_q31 * S_RFFT, + arm_cfft_radix4_instance_q31 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q31_t normalize); + + /** + * @brief Processing function for the Q31 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q31 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q31( + const arm_dct4_instance_q31 * S, + q31_t * pState, + q31_t * pInlineBuffer); + + /** + * @brief Instance structure for the Q15 DCT4/IDCT4 function. + */ + + typedef struct + { + uint16_t N; /**< length of the DCT4. */ + uint16_t Nby2; /**< half of the length of the DCT4. */ + q15_t normalize; /**< normalizing factor. */ + q15_t *pTwiddle; /**< points to the twiddle factor table. */ + q15_t *pCosFactor; /**< points to the cosFactor table. */ + arm_rfft_instance_q15 *pRfft; /**< points to the real FFT instance. */ + arm_cfft_radix4_instance_q15 *pCfft; /**< points to the complex FFT instance. */ + } arm_dct4_instance_q15; + + /** + * @brief Initialization function for the Q15 DCT4/IDCT4. + * @param[in,out] *S points to an instance of Q15 DCT4/IDCT4 structure. + * @param[in] *S_RFFT points to an instance of Q15 RFFT/RIFFT structure. + * @param[in] *S_CFFT points to an instance of Q15 CFFT/CIFFT structure. + * @param[in] N length of the DCT4. + * @param[in] Nby2 half of the length of the DCT4. + * @param[in] normalize normalizing factor. + * @return arm_status function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_ARGUMENT_ERROR if N is not a supported transform length. + */ + + arm_status arm_dct4_init_q15( + arm_dct4_instance_q15 * S, + arm_rfft_instance_q15 * S_RFFT, + arm_cfft_radix4_instance_q15 * S_CFFT, + uint16_t N, + uint16_t Nby2, + q15_t normalize); + + /** + * @brief Processing function for the Q15 DCT4/IDCT4. + * @param[in] *S points to an instance of the Q15 DCT4 structure. + * @param[in] *pState points to state buffer. + * @param[in,out] *pInlineBuffer points to the in-place input and output buffer. + * @return none. + */ + + void arm_dct4_q15( + const arm_dct4_instance_q15 * S, + q15_t * pState, + q15_t * pInlineBuffer); + + /** + * @brief Floating-point vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector addition. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_add_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q7( + q7_t * pSrcA, + q7_t * pSrcB, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector subtraction. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_sub_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a floating-point vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scale scale factor to be applied + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_f32( + float32_t * pSrc, + float32_t scale, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q7 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q7( + q7_t * pSrc, + q7_t scaleFract, + int8_t shift, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q15 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q15( + q15_t * pSrc, + q15_t scaleFract, + int8_t shift, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Multiplies a Q31 vector by a scalar. + * @param[in] *pSrc points to the input vector + * @param[in] scaleFract fractional portion of the scale value + * @param[in] shift number of bits to shift the result by + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_scale_q31( + q31_t * pSrc, + q31_t scaleFract, + int8_t shift, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Q7 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Floating-point vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Q15 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Q31 vector absolute value. + * @param[in] *pSrc points to the input buffer + * @param[out] *pDst points to the output buffer + * @param[in] blockSize number of samples in each vector + * @return none. + */ + + void arm_abs_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Dot product of floating-point vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t blockSize, + float32_t * result); + + /** + * @brief Dot product of Q7 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q7( + q7_t * pSrcA, + q7_t * pSrcB, + uint32_t blockSize, + q31_t * result); + + /** + * @brief Dot product of Q15 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Dot product of Q31 vectors. + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] blockSize number of samples in each vector + * @param[out] *result output result returned here + * @return none. + */ + + void arm_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t blockSize, + q63_t * result); + + /** + * @brief Shifts the elements of a Q7 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q7( + q7_t * pSrc, + int8_t shiftBits, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q15 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q15( + q15_t * pSrc, + int8_t shiftBits, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Shifts the elements of a Q31 vector a specified number of bits. + * @param[in] *pSrc points to the input vector + * @param[in] shiftBits number of bits to shift. A positive value shifts left; a negative value shifts right. + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_shift_q31( + q31_t * pSrc, + int8_t shiftBits, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_f32( + float32_t * pSrc, + float32_t offset, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q7( + q7_t * pSrc, + q7_t offset, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q15( + q15_t * pSrc, + q15_t offset, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Adds a constant offset to a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[in] offset is the offset to be added + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_offset_q31( + q31_t * pSrc, + q31_t offset, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a floating-point vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q7 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q15 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Negates the elements of a Q31 vector. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] blockSize number of samples in the vector + * @return none. + */ + + void arm_negate_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Copies the elements of a floating-point vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q7 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q7( + q7_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Copies the elements of a Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_copy_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + /** + * @brief Fills a constant value into a floating-point vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_f32( + float32_t value, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q7 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q7( + q7_t value, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q15 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q15( + q15_t value, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Fills a constant value into a Q31 vector. + * @param[in] value input value to be filled + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_fill_q31( + q31_t value, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + +/** + * @brief Convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the location where the output result is written. Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length srcALen+srcBLen-1. + * @return none. + */ + + void arm_conv_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + /** + * @brief Partial convolution of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Partial convolution of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + /** + * @brief Partial convolution of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data + * @param[in] firstIndex is the first output sample to start with. + * @param[in] numPoints is the number of output points to be computed. + * @return Returns either ARM_MATH_SUCCESS if the function completed correctly or ARM_MATH_ARGUMENT_ERROR if the requested subset is not in the range [0 srcALen+srcBLen-2]. + */ + + arm_status arm_conv_partial_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst, + uint32_t firstIndex, + uint32_t numPoints); + + + /** + * @brief Instance structure for the Q15 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + } arm_fir_decimate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR decimator. + */ + + typedef struct + { + uint8_t M; /**< decimation factor. */ + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + + } arm_fir_decimate_instance_f32; + + + + /** + * @brief Processing function for the floating-point FIR decimator. + * @param[in] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_f32( + const arm_fir_decimate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point FIR decimator. + * @param[in,out] *S points to an instance of the floating-point FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_f32( + arm_fir_decimate_instance_f32 * S, + uint16_t numTaps, + uint8_t M, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q15( + const arm_fir_decimate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @brief Initialization function for the Q15 FIR decimator. + * @param[in,out] *S points to an instance of the Q15 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q15( + arm_fir_decimate_instance_q15 * S, + uint16_t numTaps, + uint8_t M, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_q31( + const arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR decimator (fast variant) for Cortex-M3 and Cortex-M4. + * @param[in] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of input samples to process per call. + * @return none + */ + + void arm_fir_decimate_fast_q31( + arm_fir_decimate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 FIR decimator. + * @param[in,out] *S points to an instance of the Q31 FIR decimator structure. + * @param[in] numTaps number of coefficients in the filter. + * @param[in] M decimation factor. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * blockSize is not a multiple of M. + */ + + arm_status arm_fir_decimate_init_q31( + arm_fir_decimate_instance_q31 * S, + uint16_t numTaps, + uint8_t M, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + + /** + * @brief Instance structure for the Q15 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q15_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + q31_t *pState; /**< points to the state variable array. The array is of length blockSize+phaseLength-1. */ + } arm_fir_interpolate_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR interpolator. + */ + + typedef struct + { + uint8_t L; /**< upsample factor. */ + uint16_t phaseLength; /**< length of each polyphase filter component. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length L*phaseLength. */ + float32_t *pState; /**< points to the state variable array. The array is of length phaseLength+numTaps-1. */ + } arm_fir_interpolate_instance_f32; + + + /** + * @brief Processing function for the Q15 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q15( + const arm_fir_interpolate_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 FIR interpolator. + * @param[in,out] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q15( + arm_fir_interpolate_instance_q15 * S, + uint8_t L, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 FIR interpolator. + * @param[in] *S points to an instance of the Q15 FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_q31( + const arm_fir_interpolate_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR interpolator. + * @param[in,out] *S points to an instance of the Q31 FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_q31( + arm_fir_interpolate_instance_q31 * S, + uint8_t L, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the floating-point FIR interpolator. + * @param[in] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_interpolate_f32( + const arm_fir_interpolate_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point FIR interpolator. + * @param[in,out] *S points to an instance of the floating-point FIR interpolator structure. + * @param[in] L upsample factor. + * @param[in] numTaps number of filter coefficients in the filter. + * @param[in] *pCoeffs points to the filter coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] blockSize number of input samples to process per call. + * @return The function returns ARM_MATH_SUCCESS if initialization is successful or ARM_MATH_LENGTH_ERROR if + * the filter length numTaps is not a multiple of the interpolation factor L. + */ + + arm_status arm_fir_interpolate_init_f32( + arm_fir_interpolate_instance_f32 * S, + uint8_t L, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the high precision Q31 Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + q63_t *pState; /**< points to the array of state coefficients. The array is of length 4*numStages. */ + q31_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + uint8_t postShift; /**< additional shift, in bits, applied to each output sample. */ + + } arm_biquad_cas_df1_32x64_ins_q31; + + + /** + * @param[in] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cas_df1_32x64_q31( + const arm_biquad_cas_df1_32x64_ins_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @param[in,out] *S points to an instance of the high precision Q31 Biquad cascade filter structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] postShift shift to be applied to the output. Varies according to the coefficients format + * @return none + */ + + void arm_biquad_cas_df1_32x64_init_q31( + arm_biquad_cas_df1_32x64_ins_q31 * S, + uint8_t numStages, + q31_t * pCoeffs, + q63_t * pState, + uint8_t postShift); + + + + /** + * @brief Instance structure for the floating-point transposed direct form II Biquad cascade filter. + */ + + typedef struct + { + uint8_t numStages; /**< number of 2nd order stages in the filter. Overall order is 2*numStages. */ + float32_t *pState; /**< points to the array of state coefficients. The array is of length 2*numStages. */ + float32_t *pCoeffs; /**< points to the array of coefficients. The array is of length 5*numStages. */ + } arm_biquad_cascade_df2T_instance_f32; + + + /** + * @brief Processing function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in] *S points to an instance of the filter data structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_biquad_cascade_df2T_f32( + const arm_biquad_cascade_df2T_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the floating-point transposed direct form II Biquad cascade filter. + * @param[in,out] *S points to an instance of the filter data structure. + * @param[in] numStages number of 2nd order stages in the filter. + * @param[in] *pCoeffs points to the filter coefficients. + * @param[in] *pState points to the state buffer. + * @return none + */ + + void arm_biquad_cascade_df2T_init_f32( + arm_biquad_cascade_df2T_instance_f32 * S, + uint8_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + + + /** + * @brief Instance structure for the Q15 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point FIR lattice filter. + */ + + typedef struct + { + uint16_t numStages; /**< number of filter stages. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numStages. */ + } arm_fir_lattice_instance_f32; + + /** + * @brief Initialization function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q15( + arm_fir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t * pCoeffs, + q15_t * pState); + + + /** + * @brief Processing function for the Q15 FIR lattice filter. + * @param[in] *S points to an instance of the Q15 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + void arm_fir_lattice_q15( + const arm_fir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_q31( + arm_fir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t * pCoeffs, + q31_t * pState); + + + /** + * @brief Processing function for the Q31 FIR lattice filter. + * @param[in] *S points to an instance of the Q31 FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_q31( + const arm_fir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + +/** + * @brief Initialization function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] numStages number of filter stages. + * @param[in] *pCoeffs points to the coefficient buffer. The array is of length numStages. + * @param[in] *pState points to the state buffer. The array is of length numStages. + * @return none. + */ + + void arm_fir_lattice_init_f32( + arm_fir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t * pCoeffs, + float32_t * pState); + + /** + * @brief Processing function for the floating-point FIR lattice filter. + * @param[in] *S points to an instance of the floating-point FIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_fir_lattice_f32( + const arm_fir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q15_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q15_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q15; + + /** + * @brief Instance structure for the Q31 IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + q31_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + q31_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_q31; + + /** + * @brief Instance structure for the floating-point IIR lattice filter. + */ + typedef struct + { + uint16_t numStages; /**< number of stages in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numStages+blockSize. */ + float32_t *pkCoeffs; /**< points to the reflection coefficient array. The array is of length numStages. */ + float32_t *pvCoeffs; /**< points to the ladder coefficient array. The array is of length numStages+1. */ + } arm_iir_lattice_instance_f32; + + /** + * @brief Processing function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_f32( + const arm_iir_lattice_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point IIR lattice filter. + * @param[in] *S points to an instance of the floating-point IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize-1. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_f32( + arm_iir_lattice_instance_f32 * S, + uint16_t numStages, + float32_t *pkCoeffs, + float32_t *pvCoeffs, + float32_t *pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q31( + const arm_iir_lattice_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q31 IIR lattice filter. + * @param[in] *S points to an instance of the Q31 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to the reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to the ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to the state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_init_q31( + arm_iir_lattice_instance_q31 * S, + uint16_t numStages, + q31_t *pkCoeffs, + q31_t *pvCoeffs, + q31_t *pState, + uint32_t blockSize); + + + /** + * @brief Processing function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the Q15 IIR lattice structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_iir_lattice_q15( + const arm_iir_lattice_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + +/** + * @brief Initialization function for the Q15 IIR lattice filter. + * @param[in] *S points to an instance of the fixed-point Q15 IIR lattice structure. + * @param[in] numStages number of stages in the filter. + * @param[in] *pkCoeffs points to reflection coefficient buffer. The array is of length numStages. + * @param[in] *pvCoeffs points to ladder coefficient buffer. The array is of length numStages+1. + * @param[in] *pState points to state buffer. The array is of length numStages+blockSize. + * @param[in] blockSize number of samples to process per call. + * @return none. + */ + + void arm_iir_lattice_init_q15( + arm_iir_lattice_instance_q15 * S, + uint16_t numStages, + q15_t *pkCoeffs, + q15_t *pvCoeffs, + q15_t *pState, + uint32_t blockSize); + + /** + * @brief Instance structure for the floating-point LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that controls filter coefficient updates. */ + } arm_lms_instance_f32; + + /** + * @brief Processing function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_f32( + const arm_lms_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_init_f32( + arm_lms_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + /** + * @brief Instance structure for the Q15 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + } arm_lms_instance_q15; + + + /** + * @brief Initialization function for the Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to the coefficient buffer. + * @param[in] *pState points to the state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q15( + arm_lms_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Processing function for Q15 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q15( + const arm_lms_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint32_t postShift; /**< bit shift applied to coefficients. */ + + } arm_lms_instance_q31; + + /** + * @brief Processing function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q15 LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_q31( + const arm_lms_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 LMS filter. + * @param[in] *S points to an instance of the Q31 LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_init_q31( + arm_lms_instance_q31 * S, + uint16_t numTaps, + q31_t *pCoeffs, + q31_t *pState, + q31_t mu, + uint32_t blockSize, + uint32_t postShift); + + /** + * @brief Instance structure for the floating-point normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + float32_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + float32_t mu; /**< step size that control filter coefficient updates. */ + float32_t energy; /**< saves previous frame energy. */ + float32_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_f32; + + /** + * @brief Processing function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_f32( + arm_lms_norm_instance_f32 * S, + float32_t * pSrc, + float32_t * pRef, + float32_t * pOut, + float32_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for floating-point normalized LMS filter. + * @param[in] *S points to an instance of the floating-point LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_init_f32( + arm_lms_norm_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + float32_t mu, + uint32_t blockSize); + + + /** + * @brief Instance structure for the Q31 normalized LMS filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + q31_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q31_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q31_t *recipTable; /**< points to the reciprocal initial value table. */ + q31_t energy; /**< saves previous frame energy. */ + q31_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q31; + + /** + * @brief Processing function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q31( + arm_lms_norm_instance_q31 * S, + q31_t * pSrc, + q31_t * pRef, + q31_t * pOut, + q31_t * pErr, + uint32_t blockSize); + + /** + * @brief Initialization function for Q31 normalized LMS filter. + * @param[in] *S points to an instance of the Q31 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q31( + arm_lms_norm_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + q31_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Instance structure for the Q15 normalized LMS filter. + */ + + typedef struct + { + uint16_t numTaps; /**< Number of coefficients in the filter. */ + q15_t *pState; /**< points to the state variable array. The array is of length numTaps+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps. */ + q15_t mu; /**< step size that controls filter coefficient updates. */ + uint8_t postShift; /**< bit shift applied to coefficients. */ + q15_t *recipTable; /**< Points to the reciprocal initial value table. */ + q15_t energy; /**< saves previous frame energy. */ + q15_t x0; /**< saves previous input sample. */ + } arm_lms_norm_instance_q15; + + /** + * @brief Processing function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] *pSrc points to the block of input data. + * @param[in] *pRef points to the block of reference data. + * @param[out] *pOut points to the block of output data. + * @param[out] *pErr points to the block of error data. + * @param[in] blockSize number of samples to process. + * @return none. + */ + + void arm_lms_norm_q15( + arm_lms_norm_instance_q15 * S, + q15_t * pSrc, + q15_t * pRef, + q15_t * pOut, + q15_t * pErr, + uint32_t blockSize); + + + /** + * @brief Initialization function for Q15 normalized LMS filter. + * @param[in] *S points to an instance of the Q15 normalized LMS filter structure. + * @param[in] numTaps number of filter coefficients. + * @param[in] *pCoeffs points to coefficient buffer. + * @param[in] *pState points to state buffer. + * @param[in] mu step size that controls filter coefficient updates. + * @param[in] blockSize number of samples to process. + * @param[in] postShift bit shift applied to coefficients. + * @return none. + */ + + void arm_lms_norm_init_q15( + arm_lms_norm_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + q15_t mu, + uint32_t blockSize, + uint8_t postShift); + + /** + * @brief Correlation of floating-point sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_f32( + float32_t * pSrcA, + uint32_t srcALen, + float32_t * pSrcB, + uint32_t srcBLen, + float32_t * pDst); + + /** + * @brief Correlation of Q15 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Correlation of Q15 sequences (fast version) for Cortex-M3 and Cortex-M4. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q15( + q15_t * pSrcA, + uint32_t srcALen, + q15_t * pSrcB, + uint32_t srcBLen, + q15_t * pDst); + + /** + * @brief Correlation of Q31 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Correlation of Q31 sequences (fast version) for Cortex-M3 and Cortex-M4 + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_fast_q31( + q31_t * pSrcA, + uint32_t srcALen, + q31_t * pSrcB, + uint32_t srcBLen, + q31_t * pDst); + + /** + * @brief Correlation of Q7 sequences. + * @param[in] *pSrcA points to the first input sequence. + * @param[in] srcALen length of the first input sequence. + * @param[in] *pSrcB points to the second input sequence. + * @param[in] srcBLen length of the second input sequence. + * @param[out] *pDst points to the block of output data Length 2 * max(srcALen, srcBLen) - 1. + * @return none. + */ + + void arm_correlate_q7( + q7_t * pSrcA, + uint32_t srcALen, + q7_t * pSrcB, + uint32_t srcBLen, + q7_t * pDst); + + /** + * @brief Instance structure for the floating-point sparse FIR filter. + */ + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + float32_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + float32_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_f32; + + /** + * @brief Instance structure for the Q31 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q31_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q31_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q31; + + /** + * @brief Instance structure for the Q15 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q15_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q15_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q15; + + /** + * @brief Instance structure for the Q7 sparse FIR filter. + */ + + typedef struct + { + uint16_t numTaps; /**< number of coefficients in the filter. */ + uint16_t stateIndex; /**< state buffer index. Points to the oldest sample in the state buffer. */ + q7_t *pState; /**< points to the state buffer array. The array is of length maxDelay+blockSize-1. */ + q7_t *pCoeffs; /**< points to the coefficient array. The array is of length numTaps.*/ + uint16_t maxDelay; /**< maximum offset specified by the pTapDelay array. */ + int32_t *pTapDelay; /**< points to the array of delay values. The array is of length numTaps. */ + } arm_fir_sparse_instance_q7; + + /** + * @brief Processing function for the floating-point sparse FIR filter. + * @param[in] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_f32( + arm_fir_sparse_instance_f32 * S, + float32_t * pSrc, + float32_t * pDst, + float32_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the floating-point sparse FIR filter. + * @param[in,out] *S points to an instance of the floating-point sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_f32( + arm_fir_sparse_instance_f32 * S, + uint16_t numTaps, + float32_t * pCoeffs, + float32_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q31 sparse FIR filter. + * @param[in] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q31( + arm_fir_sparse_instance_q31 * S, + q31_t * pSrc, + q31_t * pDst, + q31_t * pScratchIn, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q31 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q31 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q31( + arm_fir_sparse_instance_q31 * S, + uint16_t numTaps, + q31_t * pCoeffs, + q31_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q15 sparse FIR filter. + * @param[in] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q15( + arm_fir_sparse_instance_q15 * S, + q15_t * pSrc, + q15_t * pDst, + q15_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + + /** + * @brief Initialization function for the Q15 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q15 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q15( + arm_fir_sparse_instance_q15 * S, + uint16_t numTaps, + q15_t * pCoeffs, + q15_t * pState, + int32_t * pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + /** + * @brief Processing function for the Q7 sparse FIR filter. + * @param[in] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] *pSrc points to the block of input data. + * @param[out] *pDst points to the block of output data + * @param[in] *pScratchIn points to a temporary buffer of size blockSize. + * @param[in] *pScratchOut points to a temporary buffer of size blockSize. + * @param[in] blockSize number of input samples to process per call. + * @return none. + */ + + void arm_fir_sparse_q7( + arm_fir_sparse_instance_q7 * S, + q7_t * pSrc, + q7_t * pDst, + q7_t * pScratchIn, + q31_t * pScratchOut, + uint32_t blockSize); + + /** + * @brief Initialization function for the Q7 sparse FIR filter. + * @param[in,out] *S points to an instance of the Q7 sparse FIR structure. + * @param[in] numTaps number of nonzero coefficients in the filter. + * @param[in] *pCoeffs points to the array of filter coefficients. + * @param[in] *pState points to the state buffer. + * @param[in] *pTapDelay points to the array of offset times. + * @param[in] maxDelay maximum offset time supported. + * @param[in] blockSize number of samples that will be processed per block. + * @return none + */ + + void arm_fir_sparse_init_q7( + arm_fir_sparse_instance_q7 * S, + uint16_t numTaps, + q7_t * pCoeffs, + q7_t * pState, + int32_t *pTapDelay, + uint16_t maxDelay, + uint32_t blockSize); + + + /* + * @brief Floating-point sin_cos function. + * @param[in] theta input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cos output. + * @return none. + */ + + void arm_sin_cos_f32( + float32_t theta, + float32_t *pSinVal, + float32_t *pCcosVal); + + /* + * @brief Q31 sin_cos function. + * @param[in] theta scaled input value in degrees + * @param[out] *pSinVal points to the processed sine output. + * @param[out] *pCosVal points to the processed cosine output. + * @return none. + */ + + void arm_sin_cos_q31( + q31_t theta, + q31_t *pSinVal, + q31_t *pCosVal); + + + /** + * @brief Floating-point complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex conjugate. + * @param[in] *pSrc points to the input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_conj_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + + /** + * @brief Floating-point complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude squared + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_squared_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup PID PID Motor Control + * + * A Proportional Integral Derivative (PID) controller is a generic feedback control + * loop mechanism widely used in industrial control systems. + * A PID controller is the most commonly used type of feedback controller. + * + * This set of functions implements (PID) controllers + * for Q15, Q31, and floating-point data types. The functions operate on a single sample + * of data and each call to the function returns a single processed value. + * S points to an instance of the PID control data structure. in + * is the input sample value. The functions return the output value. + * + * \par Algorithm: + *
+   *    y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2]
+   *    A0 = Kp + Ki + Kd
+   *    A1 = (-Kp ) - (2 * Kd )
+   *    A2 = Kd  
+ * + * \par + * where \c Kp is proportional constant, \c Ki is Integral constant and \c Kd is Derivative constant + * + * \par + * \image html PID.gif "Proportional Integral Derivative Controller" + * + * \par + * The PID controller calculates an "error" value as the difference between + * the measured output and the reference input. + * The controller attempts to minimize the error by adjusting the process control inputs. + * The proportional value determines the reaction to the current error, + * the integral value determines the reaction based on the sum of recent errors, + * and the derivative value determines the reaction based on the rate at which the error has been changing. + * + * \par Instance Structure + * The Gains A0, A1, A2 and state variables for a PID controller are stored together in an instance data structure. + * A separate instance structure must be defined for each PID Controller. + * There are separate instance structure declarations for each of the 3 supported data types. + * + * \par Reset Functions + * There is also an associated reset function for each data type which clears the state array. + * + * \par Initialization Functions + * There is also an associated initialization function for each data type. + * The initialization function performs the following operations: + * - Initializes the Gains A0, A1, A2 from Kp,Ki, Kd gains. + * - Zeros out the values in the state buffer. + * + * \par + * Instance structure cannot be placed into a const data section and it is recommended to use the initialization function. + * + * \par Fixed-Point Behavior + * Care must be taken when using the fixed-point versions of the PID Controller functions. + * In particular, the overflow and saturation behavior of the accumulator used in each function must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup PID + * @{ + */ + + /** + * @brief Process function for the floating-point PID Control. + * @param[in,out] *S is an instance of the floating-point PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + */ + + + __STATIC_INLINE float32_t arm_pid_f32( + arm_pid_instance_f32 * S, + float32_t in) + { + float32_t out; + + /* y[n] = y[n-1] + A0 * x[n] + A1 * x[n-1] + A2 * x[n-2] */ + out = (S->A0 * in) + + (S->A1 * S->state[0]) + (S->A2 * S->state[1]) + (S->state[2]); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q31 PID Control. + * @param[in,out] *S points to an instance of the Q31 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 64-bit accumulator. + * The accumulator has a 2.62 format and maintains full precision of the intermediate multiplication results but provides only a single guard bit. + * Thus, if the accumulator result overflows it wraps around rather than clip. + * In order to avoid overflows completely the input signal must be scaled down by 2 bits as there are four additions. + * After all multiply-accumulates are performed, the 2.62 accumulator is truncated to 1.32 format and then saturated to 1.31 format. + */ + + __STATIC_INLINE q31_t arm_pid_q31( + arm_pid_instance_q31 * S, + q31_t in) + { + q63_t acc; + q31_t out; + + /* acc = A0 * x[n] */ + acc = (q63_t) S->A0 * in; + + /* acc += A1 * x[n-1] */ + acc += (q63_t) S->A1 * S->state[0]; + + /* acc += A2 * x[n-2] */ + acc += (q63_t) S->A2 * S->state[1]; + + /* convert output to 1.31 format to add y[n-1] */ + out = (q31_t) (acc >> 31u); + + /* out += y[n-1] */ + out += S->state[2]; + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @brief Process function for the Q15 PID Control. + * @param[in,out] *S points to an instance of the Q15 PID Control structure + * @param[in] in input sample to process + * @return out processed output sample. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using a 64-bit internal accumulator. + * Both Gains and state variables are represented in 1.15 format and multiplications yield a 2.30 result. + * The 2.30 intermediate results are accumulated in a 64-bit accumulator in 34.30 format. + * There is no risk of internal overflow with this approach and the full precision of intermediate multiplications is preserved. + * After all additions have been performed, the accumulator is truncated to 34.15 format by discarding low 15 bits. + * Lastly, the accumulator is saturated to yield a result in 1.15 format. + */ + + __STATIC_INLINE q15_t arm_pid_q15( + arm_pid_instance_q15 * S, + q15_t in) + { + q63_t acc; + q15_t out; + + /* Implementation of PID controller */ + + #ifdef ARM_MATH_CM0 + + /* acc = A0 * x[n] */ + acc = ((q31_t) S->A0 )* in ; + + #else + + /* acc = A0 * x[n] */ + acc = (q31_t) __SMUAD(S->A0, in); + + #endif + + #ifdef ARM_MATH_CM0 + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc += (q31_t) S->A1 * S->state[0] ; + acc += (q31_t) S->A2 * S->state[1] ; + + #else + + /* acc += A1 * x[n-1] + A2 * x[n-2] */ + acc = __SMLALD(S->A1, (q31_t)__SIMD32(S->state), acc); + + #endif + + /* acc += y[n-1] */ + acc += (q31_t) S->state[2] << 15; + + /* saturate the output */ + out = (q15_t) (__SSAT((acc >> 15), 16)); + + /* Update state */ + S->state[1] = S->state[0]; + S->state[0] = in; + S->state[2] = out; + + /* return to application */ + return (out); + + } + + /** + * @} end of PID group + */ + + + /** + * @brief Floating-point matrix inverse. + * @param[in] *src points to the instance of the input floating-point matrix structure. + * @param[out] *dst points to the instance of the output floating-point matrix structure. + * @return The function returns ARM_MATH_SIZE_MISMATCH, if the dimensions do not match. + * If the input matrix is singular (does not have an inverse), then the algorithm terminates and returns error status ARM_MATH_SINGULAR. + */ + + arm_status arm_mat_inverse_f32( + const arm_matrix_instance_f32 * src, + arm_matrix_instance_f32 * dst); + + + + /** + * @ingroup groupController + */ + + + /** + * @defgroup clarke Vector Clarke Transform + * Forward Clarke transform converts the instantaneous stator phases into a two-coordinate time invariant vector. + * Generally the Clarke transform uses three-phase currents Ia, Ib and Ic to calculate currents + * in the two-phase orthogonal stator axis Ialpha and Ibeta. + * When Ialpha is superposed with Ia as shown in the figure below + * \image html clarke.gif Stator current space vector and its components in (a,b). + * and Ia + Ib + Ic = 0, in this condition Ialpha and Ibeta + * can be calculated using only Ia and Ib. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeFormula.gif + * where Ia and Ib are the instantaneous stator phases and + * pIalpha and pIbeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup clarke + * @{ + */ + + /** + * + * @brief Floating-point Clarke transform + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + */ + + __STATIC_INLINE void arm_clarke_f32( + float32_t Ia, + float32_t Ib, + float32_t * pIalpha, + float32_t * pIbeta) + { + /* Calculate pIalpha using the equation, pIalpha = Ia */ + *pIalpha = Ia; + + /* Calculate pIbeta using the equation, pIbeta = (1/sqrt(3)) * Ia + (2/sqrt(3)) * Ib */ + *pIbeta = ((float32_t) 0.57735026919 * Ia + (float32_t) 1.15470053838 * Ib); + + } + + /** + * @brief Clarke transform for Q31 version + * @param[in] Ia input three-phase coordinate a + * @param[in] Ib input three-phase coordinate b + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + __STATIC_INLINE void arm_clarke_q31( + q31_t Ia, + q31_t Ib, + q31_t * pIalpha, + q31_t * pIbeta) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIalpha from Ia by equation pIalpha = Ia */ + *pIalpha = Ia; + + /* Intermediate product is calculated by (1/(sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) Ia * 0x24F34E8B) >> 30); + + /* Intermediate product is calculated by (2/sqrt(3) * Ib) */ + product2 = (q31_t) (((q63_t) Ib * 0x49E69D16) >> 30); + + /* pIbeta is calculated by adding the intermediate products */ + *pIbeta = __QADD(product1, product2); + } + + /** + * @} end of clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q31 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q31( + q7_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_clarke Vector Inverse Clarke Transform + * Inverse Clarke transform converts the two-coordinate time invariant vector into instantaneous stator phases. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html clarkeInvFormula.gif + * where pIa and pIb are the instantaneous stator phases and + * Ialpha and Ibeta are the two coordinates of time invariant vector. + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Clarke transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_clarke + * @{ + */ + + /** + * @brief Floating-point Inverse Clarke transform + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + */ + + + __STATIC_INLINE void arm_inv_clarke_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pIa, + float32_t * pIb) + { + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Calculating pIb from Ialpha and Ibeta by equation pIb = -(1/2) * Ialpha + (sqrt(3)/2) * Ibeta */ + *pIb = -0.5 * Ialpha + (float32_t) 0.8660254039 *Ibeta; + + } + + /** + * @brief Inverse Clarke transform for Q31 version + * @param[in] Ialpha input two-phase orthogonal vector axis alpha + * @param[in] Ibeta input two-phase orthogonal vector axis beta + * @param[out] *pIa points to output three-phase coordinate a + * @param[out] *pIb points to output three-phase coordinate b + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the subtraction, hence there is no risk of overflow. + */ + + __STATIC_INLINE void arm_inv_clarke_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pIa, + q31_t * pIb) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + + /* Calculating pIa from Ialpha by equation pIa = Ialpha */ + *pIa = Ialpha; + + /* Intermediate product is calculated by (1/(2*sqrt(3)) * Ia) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (0x40000000)) >> 31); + + /* Intermediate product is calculated by (1/sqrt(3) * pIb) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (0x6ED9EBA1)) >> 31); + + /* pIb is calculated by subtracting the products */ + *pIb = __QSUB(product2, product1); + + } + + /** + * @} end of inv_clarke group + */ + + /** + * @brief Converts the elements of the Q7 vector to Q15 vector. + * @param[in] *pSrc input pointer + * @param[out] *pDst output pointer + * @param[in] blockSize number of samples to process + * @return none. + */ + void arm_q7_to_q15( + q7_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + + + /** + * @ingroup groupController + */ + + /** + * @defgroup park Vector Park Transform + * + * Forward Park transform converts the input two-coordinate vector to flux and torque components. + * The Park transform can be used to realize the transformation of the Ialpha and the Ibeta currents + * from the stationary to the moving reference frame and control the spatial relationship between + * the stator vector current and rotor flux vector. + * If we consider the d axis aligned with the rotor flux, the diagram below shows the + * current vector and the relationship from the two reference frames: + * \image html park.gif "Stator current space vector and its component in (a,b) and in the d,q rotating reference frame" + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkFormula.gif + * where Ialpha and Ibeta are the stator vector components, + * pId and pIq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup park + * @{ + */ + + /** + * @brief Floating-point Park transform + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * The function implements the forward Park transform. + * + */ + + __STATIC_INLINE void arm_park_f32( + float32_t Ialpha, + float32_t Ibeta, + float32_t * pId, + float32_t * pIq, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pId using the equation, pId = Ialpha * cosVal + Ibeta * sinVal */ + *pId = Ialpha * cosVal + Ibeta * sinVal; + + /* Calculate pIq using the equation, pIq = - Ialpha * sinVal + Ibeta * cosVal */ + *pIq = -Ialpha * sinVal + Ibeta * cosVal; + + } + + /** + * @brief Park transform for Q31 version + * @param[in] Ialpha input two-phase vector coordinate alpha + * @param[in] Ibeta input two-phase vector coordinate beta + * @param[out] *pId points to output rotor reference frame d + * @param[out] *pIq points to output rotor reference frame q + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition and subtraction, hence there is no risk of overflow. + */ + + + __STATIC_INLINE void arm_park_q31( + q31_t Ialpha, + q31_t Ibeta, + q31_t * pId, + q31_t * pIq, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Ialpha * cosVal) */ + product1 = (q31_t) (((q63_t) (Ialpha) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * sinVal) */ + product2 = (q31_t) (((q63_t) (Ibeta) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Ialpha * sinVal) */ + product3 = (q31_t) (((q63_t) (Ialpha) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Ibeta * cosVal) */ + product4 = (q31_t) (((q63_t) (Ibeta) * (cosVal)) >> 31); + + /* Calculate pId by adding the two intermediate products 1 and 2 */ + *pId = __QADD(product1, product2); + + /* Calculate pIq by subtracting the two intermediate products 3 from 4 */ + *pIq = __QSUB(product4, product3); + } + + /** + * @} end of park group + */ + + /** + * @brief Converts the elements of the Q7 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q7_to_float( + q7_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupController + */ + + /** + * @defgroup inv_park Vector Inverse Park transform + * Inverse Park transform converts the input flux and torque components to two-coordinate vector. + * + * The function operates on a single sample of data and each call to the function returns the processed output. + * The library provides separate functions for Q31 and floating-point data types. + * \par Algorithm + * \image html parkInvFormula.gif + * where pIalpha and pIbeta are the stator vector components, + * Id and Iq are rotor vector components and cosVal and sinVal are the + * cosine and sine values of theta (rotor flux position). + * \par Fixed-Point Behavior + * Care must be taken when using the Q31 version of the Park transform. + * In particular, the overflow and saturation behavior of the accumulator used must be considered. + * Refer to the function specific documentation below for usage guidelines. + */ + + /** + * @addtogroup inv_park + * @{ + */ + + /** + * @brief Floating-point Inverse Park transform + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + */ + + __STATIC_INLINE void arm_inv_park_f32( + float32_t Id, + float32_t Iq, + float32_t * pIalpha, + float32_t * pIbeta, + float32_t sinVal, + float32_t cosVal) + { + /* Calculate pIalpha using the equation, pIalpha = Id * cosVal - Iq * sinVal */ + *pIalpha = Id * cosVal - Iq * sinVal; + + /* Calculate pIbeta using the equation, pIbeta = Id * sinVal + Iq * cosVal */ + *pIbeta = Id * sinVal + Iq * cosVal; + + } + + + /** + * @brief Inverse Park transform for Q31 version + * @param[in] Id input coordinate of rotor reference frame d + * @param[in] Iq input coordinate of rotor reference frame q + * @param[out] *pIalpha points to output two-phase orthogonal vector axis alpha + * @param[out] *pIbeta points to output two-phase orthogonal vector axis beta + * @param[in] sinVal sine value of rotation angle theta + * @param[in] cosVal cosine value of rotation angle theta + * @return none. + * + * Scaling and Overflow Behavior: + * \par + * The function is implemented using an internal 32-bit accumulator. + * The accumulator maintains 1.31 format by truncating lower 31 bits of the intermediate multiplication in 2.62 format. + * There is saturation on the addition, hence there is no risk of overflow. + */ + + + __STATIC_INLINE void arm_inv_park_q31( + q31_t Id, + q31_t Iq, + q31_t * pIalpha, + q31_t * pIbeta, + q31_t sinVal, + q31_t cosVal) + { + q31_t product1, product2; /* Temporary variables used to store intermediate results */ + q31_t product3, product4; /* Temporary variables used to store intermediate results */ + + /* Intermediate product is calculated by (Id * cosVal) */ + product1 = (q31_t) (((q63_t) (Id) * (cosVal)) >> 31); + + /* Intermediate product is calculated by (Iq * sinVal) */ + product2 = (q31_t) (((q63_t) (Iq) * (sinVal)) >> 31); + + + /* Intermediate product is calculated by (Id * sinVal) */ + product3 = (q31_t) (((q63_t) (Id) * (sinVal)) >> 31); + + /* Intermediate product is calculated by (Iq * cosVal) */ + product4 = (q31_t) (((q63_t) (Iq) * (cosVal)) >> 31); + + /* Calculate pIalpha by using the two intermediate products 1 and 2 */ + *pIalpha = __QSUB(product1, product2); + + /* Calculate pIbeta by using the two intermediate products 3 and 4 */ + *pIbeta = __QADD(product4, product3); + + } + + /** + * @} end of Inverse park group + */ + + + /** + * @brief Converts the elements of the Q31 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_float( + q31_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup LinearInterpolate Linear Interpolation + * + * Linear interpolation is a method of curve fitting using linear polynomials. + * Linear interpolation works by effectively drawing a straight line between two neighboring samples and returning the appropriate point along that line + * + * \par + * \image html LinearInterp.gif "Linear interpolation" + * + * \par + * A Linear Interpolate function calculates an output value(y), for the input(x) + * using linear interpolation of the input values x0, x1( nearest input values) and the output values y0 and y1(nearest output values) + * + * \par Algorithm: + *
+   *       y = y0 + (x - x0) * ((y1 - y0)/(x1-x0))
+   *       where x0, x1 are nearest values of input x
+   *             y0, y1 are nearest values to output y
+   * 
+ * + * \par + * This set of functions implements Linear interpolation process + * for Q7, Q15, Q31, and floating-point data types. The functions operate on a single + * sample of data and each call to the function returns a single processed value. + * S points to an instance of the Linear Interpolate function data structure. + * x is the input sample value. The functions returns the output value. + * + * \par + * if x is outside of the table boundary, Linear interpolation returns first value of the table + * if x is below input range and returns last value of table if x is above range. + */ + + /** + * @addtogroup LinearInterpolate + * @{ + */ + + /** + * @brief Process function for the floating-point Linear Interpolation Function. + * @param[in,out] *S is an instance of the floating-point Linear Interpolation structure + * @param[in] x input sample to process + * @return y processed output sample. + * + */ + + __STATIC_INLINE float32_t arm_linear_interp_f32( + arm_linear_interp_instance_f32 * S, + float32_t x) + { + + float32_t y; + float32_t x0, x1; /* Nearest input values */ + float32_t y0, y1; /* Nearest output values */ + float32_t xSpacing = S->xSpacing; /* spacing between input values */ + int32_t i; /* Index variable */ + float32_t *pYData = S->pYData; /* pointer to output table */ + + /* Calculation of index */ + i = (x - S->x1) / xSpacing; + + if(i < 0) + { + /* Iniatilize output for below specified range as least output value of table */ + y = pYData[0]; + } + else if(i >= S->nValues) + { + /* Iniatilize output for above specified range as last output value of table */ + y = pYData[S->nValues-1]; + } + else + { + /* Calculation of nearest input values */ + x0 = S->x1 + i * xSpacing; + x1 = S->x1 + (i +1) * xSpacing; + + /* Read of nearest output values */ + y0 = pYData[i]; + y1 = pYData[i + 1]; + + /* Calculation of output */ + y = y0 + (x - x0) * ((y1 - y0)/(x1-x0)); + + } + + /* returns output value */ + return (y); + } + + /** + * + * @brief Process function for the Q31 Linear Interpolation Function. + * @param[in] *pYData pointer to Q31 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + __STATIC_INLINE q31_t arm_linear_interp_q31(q31_t *pYData, + q31_t x, uint32_t nValues) + { + q31_t y; /* output */ + q31_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20); + + if(index >= (nValues - 1)) + { + return(pYData[nValues - 1]); + } + else if(index < 0) + { + return(pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* shift left by 11 to keep fract in 1.31 format */ + fract = (x & 0x000FFFFF) << 11; + + /* Read two nearest output values from the index in 1.31(q31) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 2.30 format */ + y = ((q31_t) ((q63_t) y0 * (0x7FFFFFFF - fract) >> 32)); + + /* Calculation of y0 * (1-fract) + y1 *fract and y is in 2.30 format */ + y += ((q31_t) (((q63_t) y1 * fract) >> 32)); + + /* Convert y to 1.31 format */ + return (y << 1u); + + } + + } + + /** + * + * @brief Process function for the Q15 Linear Interpolation Function. + * @param[in] *pYData pointer to Q15 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + * + */ + + + __STATIC_INLINE q15_t arm_linear_interp_q15(q15_t *pYData, q31_t x, uint32_t nValues) + { + q63_t y; /* output */ + q15_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + if(index >= (nValues - 1)) + { + return(pYData[nValues - 1]); + } + else if(index < 0) + { + return(pYData[0]); + } + else + { + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract) and y is in 13.35 format */ + y = ((q63_t) y0 * (0xFFFFF - fract)); + + /* Calculation of (y0 * (1-fract) + y1 * fract) and y is in 13.35 format */ + y += ((q63_t) y1 * (fract)); + + /* convert y to 1.15 format */ + return (y >> 20); + } + + + } + + /** + * + * @brief Process function for the Q7 Linear Interpolation Function. + * @param[in] *pYData pointer to Q7 Linear Interpolation table + * @param[in] x input sample to process + * @param[in] nValues number of table values + * @return y processed output sample. + * + * \par + * Input sample x is in 12.20 format which contains 12 bits for table index and 20 bits for fractional part. + * This function can support maximum of table size 2^12. + */ + + + __STATIC_INLINE q7_t arm_linear_interp_q7(q7_t *pYData, q31_t x, uint32_t nValues) + { + q31_t y; /* output */ + q7_t y0, y1; /* Nearest output values */ + q31_t fract; /* fractional part */ + int32_t index; /* Index to read nearest output values */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + index = ((x & 0xFFF00000) >> 20u); + + + if(index >= (nValues - 1)) + { + return(pYData[nValues - 1]); + } + else if(index < 0) + { + return(pYData[0]); + } + else + { + + /* 20 bits for the fractional part */ + /* fract is in 12.20 format */ + fract = (x & 0x000FFFFF); + + /* Read two nearest output values from the index and are in 1.7(q7) format */ + y0 = pYData[index]; + y1 = pYData[index + 1u]; + + /* Calculation of y0 * (1-fract ) and y is in 13.27(q27) format */ + y = ((y0 * (0xFFFFF - fract))); + + /* Calculation of y1 * fract + y0 * (1-fract) and y is in 13.27(q27) format */ + y += (y1 * fract); + + /* convert y to 1.7(q7) format */ + return (y >> 20u); + + } + + } + /** + * @} end of LinearInterpolate group + */ + + /** + * @brief Fast approximation to the trigonometric sine function for floating-point data. + * @param[in] x input value in radians. + * @return sin(x). + */ + + float32_t arm_sin_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q31_t arm_sin_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric sine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return sin(x). + */ + + q15_t arm_sin_q15( + q15_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for floating-point data. + * @param[in] x input value in radians. + * @return cos(x). + */ + + float32_t arm_cos_f32( + float32_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q31 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q31_t arm_cos_q31( + q31_t x); + + /** + * @brief Fast approximation to the trigonometric cosine function for Q15 data. + * @param[in] x Scaled input value in radians. + * @return cos(x). + */ + + q15_t arm_cos_q15( + q15_t x); + + + /** + * @ingroup groupFastMath + */ + + + /** + * @defgroup SQRT Square Root + * + * Computes the square root of a number. + * There are separate functions for Q15, Q31, and floating-point data types. + * The square root function is computed using the Newton-Raphson algorithm. + * This is an iterative algorithm of the form: + *
+   *      x1 = x0 - f(x0)/f'(x0)
+   * 
+ * where x1 is the current estimate, + * x0 is the previous estimate and + * f'(x0) is the derivative of f() evaluated at x0. + * For the square root function, the algorithm reduces to: + *
+   *     x0 = in/2                         [initial guess]
+   *     x1 = 1/2 * ( x0 + in / x0)        [each iteration]
+   * 
+ */ + + + /** + * @addtogroup SQRT + * @{ + */ + + /** + * @brief Floating-point square root function. + * @param[in] in input value. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + + __STATIC_INLINE arm_status arm_sqrt_f32( + float32_t in, float32_t *pOut) + { + if(in > 0) + { + +// #if __FPU_USED + #if (__FPU_USED == 1) && defined ( __CC_ARM ) + *pOut = __sqrtf(in); + #elif (__FPU_USED == 1) && defined ( __TMS_740 ) + *pOut = __builtin_sqrtf(in); + #else + *pOut = sqrtf(in); + #endif + + return (ARM_MATH_SUCCESS); + } + else + { + *pOut = 0.0f; + return (ARM_MATH_ARGUMENT_ERROR); + } + + } + + + /** + * @brief Q31 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x00000000 to 0x7FFFFFFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q31( + q31_t in, q31_t *pOut); + + /** + * @brief Q15 square root function. + * @param[in] in input value. The range of the input value is [0 +1) or 0x0000 to 0x7FFF. + * @param[out] *pOut square root of input value. + * @return The function returns ARM_MATH_SUCCESS if input value is positive value or ARM_MATH_ARGUMENT_ERROR if + * in is negative value and returns zero output for negative values. + */ + arm_status arm_sqrt_q15( + q15_t in, q15_t *pOut); + + /** + * @} end of SQRT group + */ + + + + + + + /** + * @brief floating-point Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_f32( + int32_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const int32_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief floating-point Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_f32( + int32_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + int32_t * dst, + int32_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (int32_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + /** + * @brief Q15 Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_q15( + q15_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q15_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q15 Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_q15( + q15_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q15_t * dst, + q15_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q15_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update wOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Q7 Circular write function. + */ + + __STATIC_INLINE void arm_circularWrite_q7( + q7_t * circBuffer, + int32_t L, + uint16_t * writeOffset, + int32_t bufferInc, + const q7_t * src, + int32_t srcInc, + uint32_t blockSize) + { + uint32_t i = 0u; + int32_t wOffset; + + /* Copy the value of Index pointer that points + * to the current location where the input samples to be copied */ + wOffset = *writeOffset; + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the input sample to the circular buffer */ + circBuffer[wOffset] = *src; + + /* Update the input pointer */ + src += srcInc; + + /* Circularly update wOffset. Watch out for positive and negative value */ + wOffset += bufferInc; + if(wOffset >= L) + wOffset -= L; + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *writeOffset = wOffset; + } + + + + /** + * @brief Q7 Circular Read function. + */ + __STATIC_INLINE void arm_circularRead_q7( + q7_t * circBuffer, + int32_t L, + int32_t * readOffset, + int32_t bufferInc, + q7_t * dst, + q7_t * dst_base, + int32_t dst_length, + int32_t dstInc, + uint32_t blockSize) + { + uint32_t i = 0; + int32_t rOffset, dst_end; + + /* Copy the value of Index pointer that points + * to the current location from where the input samples to be read */ + rOffset = *readOffset; + + dst_end = (int32_t) (dst_base + dst_length); + + /* Loop over the blockSize */ + i = blockSize; + + while(i > 0u) + { + /* copy the sample from the circular buffer to the destination buffer */ + *dst = circBuffer[rOffset]; + + /* Update the input pointer */ + dst += dstInc; + + if(dst == (q7_t *) dst_end) + { + dst = dst_base; + } + + /* Circularly update rOffset. Watch out for positive and negative value */ + rOffset += bufferInc; + + if(rOffset >= L) + { + rOffset -= L; + } + + /* Decrement the loop counter */ + i--; + } + + /* Update the index pointer */ + *readOffset = rOffset; + } + + + /** + * @brief Sum of the squares of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q15( + q15_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Sum of the squares of the elements of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_power_q7( + q7_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_mean_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult); + + /** + * @brief Mean value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Mean value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Mean value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + void arm_mean_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Variance of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q31( + q31_t * pSrc, + uint32_t blockSize, + q63_t * pResult); + + /** + * @brief Variance of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_var_q15( + q15_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Root Mean Square of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_rms_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Standard deviation of the elements of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult); + + /** + * @brief Standard deviation of the elements of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output value. + * @return none. + */ + + void arm_std_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult); + + /** + * @brief Floating-point complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_f32( + float32_t * pSrc, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q31( + q31_t * pSrc, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex magnitude + * @param[in] *pSrc points to the complex input vector + * @param[out] *pDst points to the real output vector + * @param[in] numSamples number of complex samples in the input vector + * @return none. + */ + + void arm_cmplx_mag_q15( + q15_t * pSrc, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q15 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q15( + q15_t * pSrcA, + q15_t * pSrcB, + uint32_t numSamples, + q31_t * realResult, + q31_t * imagResult); + + /** + * @brief Q31 complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_q31( + q31_t * pSrcA, + q31_t * pSrcB, + uint32_t numSamples, + q63_t * realResult, + q63_t * imagResult); + + /** + * @brief Floating-point complex dot product + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[in] numSamples number of complex samples in each vector + * @param[out] *realResult real part of the result returned here + * @param[out] *imagResult imaginary part of the result returned here + * @return none. + */ + + void arm_cmplx_dot_prod_f32( + float32_t * pSrcA, + float32_t * pSrcB, + uint32_t numSamples, + float32_t * realResult, + float32_t * imagResult); + + /** + * @brief Q15 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q15( + q15_t * pSrcCmplx, + q15_t * pSrcReal, + q15_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_q31( + q31_t * pSrcCmplx, + q31_t * pSrcReal, + q31_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-real multiplication + * @param[in] *pSrcCmplx points to the complex input vector + * @param[in] *pSrcReal points to the real input vector + * @param[out] *pCmplxDst points to the complex output vector + * @param[in] numSamples number of samples in each vector + * @return none. + */ + + void arm_cmplx_mult_real_f32( + float32_t * pSrcCmplx, + float32_t * pSrcReal, + float32_t * pCmplxDst, + uint32_t numSamples); + + /** + * @brief Minimum value of a Q7 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *result is output pointer + * @param[in] index is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * result, + uint32_t * index); + + /** + * @brief Minimum value of a Q15 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[in] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a Q31 vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + void arm_min_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + + /** + * @brief Minimum value of a floating-point vector. + * @param[in] *pSrc is input pointer + * @param[in] blockSize is the number of samples to process + * @param[out] *pResult is output pointer + * @param[out] *pIndex is the array index of the minimum value in the input buffer. + * @return none. + */ + + void arm_min_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q7 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q7( + q7_t * pSrc, + uint32_t blockSize, + q7_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q15 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q15( + q15_t * pSrc, + uint32_t blockSize, + q15_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a Q31 vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_q31( + q31_t * pSrc, + uint32_t blockSize, + q31_t * pResult, + uint32_t * pIndex); + +/** + * @brief Maximum value of a floating-point vector. + * @param[in] *pSrc points to the input buffer + * @param[in] blockSize length of the input vector + * @param[out] *pResult maximum value returned here + * @param[out] *pIndex index of maximum value returned here + * @return none. + */ + + void arm_max_f32( + float32_t * pSrc, + uint32_t blockSize, + float32_t * pResult, + uint32_t * pIndex); + + /** + * @brief Q15 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q15( + q15_t * pSrcA, + q15_t * pSrcB, + q15_t * pDst, + uint32_t numSamples); + + /** + * @brief Q31 complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_q31( + q31_t * pSrcA, + q31_t * pSrcB, + q31_t * pDst, + uint32_t numSamples); + + /** + * @brief Floating-point complex-by-complex multiplication + * @param[in] *pSrcA points to the first input vector + * @param[in] *pSrcB points to the second input vector + * @param[out] *pDst points to the output vector + * @param[in] numSamples number of complex samples in each vector + * @return none. + */ + + void arm_cmplx_mult_cmplx_f32( + float32_t * pSrcA, + float32_t * pSrcB, + float32_t * pDst, + uint32_t numSamples); + + /** + * @brief Converts the elements of the floating-point vector to Q31 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q31 output vector + * @param[in] blockSize length of the input vector + * @return none. + */ + void arm_float_to_q31( + float32_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q15 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q15 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q15( + float32_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the floating-point vector to Q7 vector. + * @param[in] *pSrc points to the floating-point input vector + * @param[out] *pDst points to the Q7 output vector + * @param[in] blockSize length of the input vector + * @return none + */ + void arm_float_to_q7( + float32_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q31 vector to Q15 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q15( + q31_t * pSrc, + q15_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q31 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q31_to_q7( + q31_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + /** + * @brief Converts the elements of the Q15 vector to floating-point vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_float( + q15_t * pSrc, + float32_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q31 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q31( + q15_t * pSrc, + q31_t * pDst, + uint32_t blockSize); + + + /** + * @brief Converts the elements of the Q15 vector to Q7 vector. + * @param[in] *pSrc is input pointer + * @param[out] *pDst is output pointer + * @param[in] blockSize is the number of samples to process + * @return none. + */ + void arm_q15_to_q7( + q15_t * pSrc, + q7_t * pDst, + uint32_t blockSize); + + + /** + * @ingroup groupInterpolation + */ + + /** + * @defgroup BilinearInterpolate Bilinear Interpolation + * + * Bilinear interpolation is an extension of linear interpolation applied to a two dimensional grid. + * The underlying function f(x, y) is sampled on a regular grid and the interpolation process + * determines values between the grid points. + * Bilinear interpolation is equivalent to two step linear interpolation, first in the x-dimension and then in the y-dimension. + * Bilinear interpolation is often used in image processing to rescale images. + * The CMSIS DSP library provides bilinear interpolation functions for Q7, Q15, Q31, and floating-point data types. + * + * Algorithm + * \par + * The instance structure used by the bilinear interpolation functions describes a two dimensional data table. + * For floating-point, the instance structure is defined as: + *
+   *   typedef struct
+   *   {
+   *     uint16_t numRows;
+   *     uint16_t numCols;
+   *     float32_t *pData;
+   * } arm_bilinear_interp_instance_f32;
+   * 
+ * + * \par + * where numRows specifies the number of rows in the table; + * numCols specifies the number of columns in the table; + * and pData points to an array of size numRows*numCols values. + * The data table pTable is organized in row order and the supplied data values fall on integer indexes. + * That is, table element (x,y) is located at pTable[x + y*numCols] where x and y are integers. + * + * \par + * Let (x, y) specify the desired interpolation point. Then define: + *
+   *     XF = floor(x)
+   *     YF = floor(y)
+   * 
+ * \par + * The interpolated output point is computed as: + *
+   *  f(x, y) = f(XF, YF) * (1-(x-XF)) * (1-(y-YF))
+   *           + f(XF+1, YF) * (x-XF)*(1-(y-YF))
+   *           + f(XF, YF+1) * (1-(x-XF))*(y-YF)
+   *           + f(XF+1, YF+1) * (x-XF)*(y-YF)
+   * 
+ * Note that the coordinates (x, y) contain integer and fractional components. + * The integer components specify which portion of the table to use while the + * fractional components control the interpolation processor. + * + * \par + * if (x,y) are outside of the table boundary, Bilinear interpolation returns zero output. + */ + + /** + * @addtogroup BilinearInterpolate + * @{ + */ + + /** + * + * @brief Floating-point bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate. + * @param[in] Y interpolation coordinate. + * @return out interpolated value. + */ + + + __STATIC_INLINE float32_t arm_bilinear_interp_f32( + const arm_bilinear_interp_instance_f32 * S, + float32_t X, + float32_t Y) + { + float32_t out; + float32_t f00, f01, f10, f11; + float32_t *pData = S->pData; + int32_t xIndex, yIndex, index; + float32_t xdiff, ydiff; + float32_t b1, b2, b3, b4; + + xIndex = (int32_t) X; + yIndex = (int32_t) Y; + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(xIndex < 0 || xIndex > (S->numRows-1) || yIndex < 0 || yIndex > ( S->numCols-1)) + { + return(0); + } + + /* Calculation of index for two nearest points in X-direction */ + index = (xIndex - 1) + (yIndex-1) * S->numCols ; + + + /* Read two nearest points in X-direction */ + f00 = pData[index]; + f01 = pData[index + 1]; + + /* Calculation of index for two nearest points in Y-direction */ + index = (xIndex-1) + (yIndex) * S->numCols; + + + /* Read two nearest points in Y-direction */ + f10 = pData[index]; + f11 = pData[index + 1]; + + /* Calculation of intermediate values */ + b1 = f00; + b2 = f01 - f00; + b3 = f10 - f00; + b4 = f00 - f01 - f10 + f11; + + /* Calculation of fractional part in X */ + xdiff = X - xIndex; + + /* Calculation of fractional part in Y */ + ydiff = Y - yIndex; + + /* Calculation of bi-linear interpolated output */ + out = b1 + b2 * xdiff + b3 * ydiff + b4 * xdiff * ydiff; + + /* return to application */ + return (out); + + } + + /** + * + * @brief Q31 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q31_t arm_bilinear_interp_q31( + arm_bilinear_interp_instance_q31 * S, + q31_t X, + q31_t Y) + { + q31_t out; /* Temporary output */ + q31_t acc = 0; /* output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q31_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q31_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20u); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20u); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) + { + return(0); + } + + /* 20 bits for the fractional part */ + /* shift left xfract by 11 to keep 1.31 format */ + xfract = (X & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + /* 20 bits for the fractional part */ + /* shift left yfract by 11 to keep 1.31 format */ + yfract = (Y & 0x000FFFFF) << 11u; + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 3.29(q29) format */ + out = ((q31_t) (((q63_t) x1 * (0x7FFFFFFF - xfract)) >> 32)); + acc = ((q31_t) (((q63_t) out * (0x7FFFFFFF - yfract)) >> 32)); + + /* x2 * (xfract) * (1-yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) x2 * (0x7FFFFFFF - yfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (xfract) >> 32)); + + /* y1 * (1 - xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y1 * (0x7FFFFFFF - xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* y2 * (xfract) * (yfract) in 3.29(q29) and adding to acc */ + out = ((q31_t) ((q63_t) y2 * (xfract) >> 32)); + acc += ((q31_t) ((q63_t) out * (yfract) >> 32)); + + /* Convert acc to 1.31(q31) format */ + return (acc << 2u); + + } + + /** + * @brief Q15 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q15_t arm_bilinear_interp_q15( + arm_bilinear_interp_instance_q15 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q15_t x1, x2, y1, y2; /* Nearest output values */ + q31_t xfract, yfract; /* X, Y fractional parts */ + int32_t rI, cI; /* Row and column indices */ + q15_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) + { + return(0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 13.51 format */ + + /* x1 is in 1.15(q15), xfract in 12.20 format and out is in 13.35 format */ + /* convert 13.35 to 13.31 by right shifting and out is in 1.31 */ + out = (q31_t) (((q63_t) x1 * (0xFFFFF - xfract)) >> 4u); + acc = ((q63_t) out * (0xFFFFF - yfract)); + + /* x2 * (xfract) * (1-yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) x2 * (0xFFFFF - yfract)) >> 4u); + acc += ((q63_t) out * (xfract)); + + /* y1 * (1 - xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y1 * (0xFFFFF - xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* y2 * (xfract) * (yfract) in 1.51 and adding to acc */ + out = (q31_t) (((q63_t) y2 * (xfract)) >> 4u); + acc += ((q63_t) out * (yfract)); + + /* acc is in 13.51 format and down shift acc by 36 times */ + /* Convert out to 1.15 format */ + return (acc >> 36); + + } + + /** + * @brief Q7 bilinear interpolation. + * @param[in,out] *S points to an instance of the interpolation structure. + * @param[in] X interpolation coordinate in 12.20 format. + * @param[in] Y interpolation coordinate in 12.20 format. + * @return out interpolated value. + */ + + __STATIC_INLINE q7_t arm_bilinear_interp_q7( + arm_bilinear_interp_instance_q7 * S, + q31_t X, + q31_t Y) + { + q63_t acc = 0; /* output */ + q31_t out; /* Temporary output */ + q31_t xfract, yfract; /* X, Y fractional parts */ + q7_t x1, x2, y1, y2; /* Nearest output values */ + int32_t rI, cI; /* Row and column indices */ + q7_t *pYData = S->pData; /* pointer to output table values */ + uint32_t nCols = S->numCols; /* num of rows */ + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + rI = ((X & 0xFFF00000) >> 20); + + /* Input is in 12.20 format */ + /* 12 bits for the table index */ + /* Index value calculation */ + cI = ((Y & 0xFFF00000) >> 20); + + /* Care taken for table outside boundary */ + /* Returns zero output when values are outside table boundary */ + if(rI < 0 || rI > (S->numRows-1) || cI < 0 || cI > ( S->numCols-1)) + { + return(0); + } + + /* 20 bits for the fractional part */ + /* xfract should be in 12.20 format */ + xfract = (X & 0x000FFFFF); + + /* Read two nearest output values from the index */ + x1 = pYData[(rI) + nCols * (cI)]; + x2 = pYData[(rI) + nCols * (cI) + 1u]; + + + /* 20 bits for the fractional part */ + /* yfract should be in 12.20 format */ + yfract = (Y & 0x000FFFFF); + + /* Read two nearest output values from the index */ + y1 = pYData[(rI) + nCols * (cI + 1)]; + y2 = pYData[(rI) + nCols * (cI + 1) + 1u]; + + /* Calculation of x1 * (1-xfract ) * (1-yfract) and acc is in 16.47 format */ + out = ((x1 * (0xFFFFF - xfract))); + acc = (((q63_t) out * (0xFFFFF - yfract))); + + /* x2 * (xfract) * (1-yfract) in 2.22 and adding to acc */ + out = ((x2 * (0xFFFFF - yfract))); + acc += (((q63_t) out * (xfract))); + + /* y1 * (1 - xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y1 * (0xFFFFF - xfract))); + acc += (((q63_t) out * (yfract))); + + /* y2 * (xfract) * (yfract) in 2.22 and adding to acc */ + out = ((y2 * (yfract))); + acc += (((q63_t) out * (xfract))); + + /* acc in 16.47 format and down shift by 40 to convert to 1.7 format */ + return (acc >> 40); + + } + + /** + * @} end of BilinearInterpolate group + */ + + + + + + +#ifdef __cplusplus +} +#endif + + +#endif /* _ARM_MATH_H */ + + +/** + * + * End of file. + */ diff --git a/loader/chip/cmsis/core_cm0plus.h b/loader/chip/cmsis/core_cm0plus.h new file mode 100644 index 0000000..aa20e68 --- /dev/null +++ b/loader/chip/cmsis/core_cm0plus.h @@ -0,0 +1,778 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V3.01 + * @date 22. March 2012 + * + * @note + * Copyright (C) 2009-2012 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. + * + ******************************************************************************/ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +/** \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** \ingroup Cortex-M0+ + @{ + */ + +/* CMSIS CM0P definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (0x01) /*!< [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16) | \ + __CM0PLUS_CMSIS_VERSION_SUB) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x00) /*!< Cortex-M Core */ + + +#if defined ( __CC_ARM ) + #define __ASM __asm /*!< asm keyword for ARM Compiler */ + #define __INLINE __inline /*!< inline keyword for ARM Compiler */ + #define __STATIC_INLINE static __inline + +#elif defined ( __ICCARM__ ) + #define __ASM __asm /*!< asm keyword for IAR Compiler */ + #define __INLINE inline /*!< inline keyword for IAR Compiler. Only available in High optimization mode! */ + #define __STATIC_INLINE static inline + +#elif defined ( __GNUC__ ) + #define __ASM __asm /*!< asm keyword for GNU Compiler */ + #define __INLINE inline /*!< inline keyword for GNU Compiler */ + #define __STATIC_INLINE static inline + +#elif defined ( __TASKING__ ) + #define __ASM __asm /*!< asm keyword for TASKING Compiler */ + #define __INLINE inline /*!< inline keyword for TASKING Compiler */ + #define __STATIC_INLINE static inline + +#endif + +/** __FPU_USED indicates whether an FPU is used or not. This core does not support an FPU at all +*/ +#define __FPU_USED 0 + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000 + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0 + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0 + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2 + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0 + #warning "__Vendor_SysTickConfig not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +/** + \defgroup CMSIS_glob_defs CMSIS Global Defines + + IO Type Qualifiers are used + \li to specify the access to peripheral variables. + \li for automatic generation of peripheral register debug information. +*/ +#ifdef __cplusplus + #define __I volatile /*!< Defines 'read only' permissions */ +#else + #define __I volatile const /*!< Defines 'read only' permissions */ +#endif +#define __O volatile /*!< Defines 'write only' permissions */ +#define __IO volatile /*!< Defines 'read / write' permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:27; /*!< bit: 0..26 Reserved */ +#else + uint32_t _reserved0:16; /*!< bit: 0..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:7; /*!< bit: 20..26 Reserved */ +#endif + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} APSR_Type; + + +/** \brief Union type to access the Interrupt Program Status Register (IPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:23; /*!< bit: 9..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} IPSR_Type; + + +/** \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ +#if (__CORTEX_M != 0x04) + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ +#else + uint32_t _reserved0:7; /*!< bit: 9..15 Reserved */ + uint32_t GE:4; /*!< bit: 16..19 Greater than or Equal flags */ + uint32_t _reserved1:4; /*!< bit: 20..23 Reserved */ +#endif + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t IT:2; /*!< bit: 25..26 saved IT state (read 0) */ + uint32_t Q:1; /*!< bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< bit: 31 Negative condition code flag */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} xPSR_Type; + + +/** \brief Union type to access the Control Registers (CONTROL). + */ +typedef union +{ + struct + { + uint32_t nPRIV:1; /*!< bit: 0 Execution privilege in Thread mode */ + uint32_t SPSEL:1; /*!< bit: 1 Stack to be used */ + uint32_t FPCA:1; /*!< bit: 2 FP extension active flag */ + uint32_t _reserved0:29; /*!< bit: 3..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/*@} end of group CMSIS_CORE */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_NVIC Nested Vectored Interrupt Controller (NVIC) + \brief Type definitions for the NVIC Registers + @{ + */ + +/** \brief Structure type to access the Nested Vectored Interrupt Controller (NVIC). + */ +typedef struct +{ + __IO uint32_t ISER[1]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31]; + __IO uint32_t ICER[1]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31]; + __IO uint32_t ISPR[1]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31]; + __IO uint32_t ICPR[1]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31]; + uint32_t RESERVED4[64]; + __IO uint32_t IP[8]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __I uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IO uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if (__VTOR_PRESENT == 1) + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IO uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IO uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IO uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IO uint32_t SHP[2]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24 /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20 /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16 /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4 /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0 /*!< SCB CPUID: REVISION Position */ +#define SCB_CPUID_REVISION_Msk (0xFUL << SCB_CPUID_REVISION_Pos) /*!< SCB CPUID: REVISION Mask */ + +/* SCB Interrupt Control State Register Definitions */ +#define SCB_ICSR_NMIPENDSET_Pos 31 /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28 /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27 /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26 /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25 /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23 /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22 /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12 /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0 /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL << SCB_ICSR_VECTACTIVE_Pos) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if (__VTOR_PRESENT == 1) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 7 /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0x1FFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16 /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16 /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15 /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2 /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1 /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4 /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2 /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1 /*!< SCB SCR: SLEEPONEXIT Position */ +#define SCB_SCR_SLEEPONEXIT_Msk (1UL << SCB_SCR_SLEEPONEXIT_Pos) /*!< SCB SCR: SLEEPONEXIT Mask */ + +/* SCB Configuration Control Register Definitions */ +#define SCB_CCR_STKALIGN_Pos 9 /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3 /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IO uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IO uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __I uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16 /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2 /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1 /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0 /*!< SysTick CTRL: ENABLE Position */ +#define SysTick_CTRL_ENABLE_Msk (1UL << SysTick_CTRL_ENABLE_Pos) /*!< SysTick CTRL: ENABLE Mask */ + +/* SysTick Reload Register Definitions */ +#define SysTick_LOAD_RELOAD_Pos 0 /*!< SysTick LOAD: RELOAD Position */ +#define SysTick_LOAD_RELOAD_Msk (0xFFFFFFUL << SysTick_LOAD_RELOAD_Pos) /*!< SysTick LOAD: RELOAD Mask */ + +/* SysTick Current Register Definitions */ +#define SysTick_VAL_CURRENT_Pos 0 /*!< SysTick VAL: CURRENT Position */ +#define SysTick_VAL_CURRENT_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick VAL: CURRENT Mask */ + +/* SysTick Calibration Register Definitions */ +#define SysTick_CALIB_NOREF_Pos 31 /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30 /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0 /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL << SysTick_VAL_CURRENT_Pos) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if (__MPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_MPU Memory Protection Unit (MPU) + \brief Type definitions for the Memory Protection Unit (MPU) + @{ + */ + +/** \brief Structure type to access the Memory Protection Unit (MPU). + */ +typedef struct +{ + __I uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IO uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IO uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IO uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IO uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +/* MPU Type Register */ +#define MPU_TYPE_IREGION_Pos 16 /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8 /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0 /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL << MPU_TYPE_SEPARATE_Pos) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register */ +#define MPU_CTRL_PRIVDEFENA_Pos 2 /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1 /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0 /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL << MPU_CTRL_ENABLE_Pos) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register */ +#define MPU_RNR_REGION_Pos 0 /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL << MPU_RNR_REGION_Pos) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register */ +#define MPU_RBAR_ADDR_Pos 8 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4 /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0 /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL << MPU_RBAR_REGION_Pos) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register */ +#define MPU_RASR_ATTRS_Pos 16 /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28 /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24 /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19 /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18 /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17 /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16 /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8 /*!< MPU RASR: Sub-Region Disable Position */ +#define MPU_RASR_SRD_Msk (0xFFUL << MPU_RASR_SRD_Pos) /*!< MPU RASR: Sub-Region Disable Mask */ + +#define MPU_RASR_SIZE_Pos 1 /*!< MPU RASR: Region Size Field Position */ +#define MPU_RASR_SIZE_Msk (0x1FUL << MPU_RASR_SIZE_Pos) /*!< MPU RASR: Region Size Field Mask */ + +#define MPU_RASR_ENABLE_Pos 0 /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL << MPU_RASR_ENABLE_Pos) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) + are only accessible over DAP and not via processor. Therefore + they are not covered by the Cortex-M0 header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Cortex-M0+ Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if (__MPU_PRESENT == 1) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +/* Interrupt Priorities are WORD accessible only under ARMv6M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( (((uint32_t)(IRQn) ) & 0x03) * 8 ) +#define _SHP_IDX(IRQn) ( ((((uint32_t)(IRQn) & 0x0F)-8) >> 2) ) +#define _IP_IDX(IRQn) ( ((uint32_t)(IRQn) >> 2) ) + + +/** \brief Enable External Interrupt + + The function enables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_EnableIRQ(IRQn_Type IRQn) +{ + NVIC->ISER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Disable External Interrupt + + The function disables a device-specific interrupt in the NVIC interrupt controller. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_DisableIRQ(IRQn_Type IRQn) +{ + NVIC->ICER[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Get Pending Interrupt + + The function reads the pending register in the NVIC and returns the pending bit + for the specified interrupt. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + */ +__STATIC_INLINE uint32_t NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + return((uint32_t) ((NVIC->ISPR[0] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); +} + + +/** \brief Set Pending Interrupt + + The function sets the pending bit of an external interrupt. + + \param [in] IRQn Interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ISPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); +} + + +/** \brief Clear Pending Interrupt + + The function clears the pending bit of an external interrupt. + + \param [in] IRQn External interrupt number. Value cannot be negative. + */ +__STATIC_INLINE void NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + NVIC->ICPR[0] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Set Interrupt Priority + + The function sets the priority of an interrupt. + + \note The priority cannot be set for every core interrupt. + + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + */ +__STATIC_INLINE void NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if(IRQn < 0) { + SCB->SHP[_SHP_IDX(IRQn)] = (SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } + else { + NVIC->IP[_IP_IDX(IRQn)] = (NVIC->IP[_IP_IDX(IRQn)] & ~(0xFF << _BIT_SHIFT(IRQn))) | + (((priority << (8 - __NVIC_PRIO_BITS)) & 0xFF) << _BIT_SHIFT(IRQn)); } +} + + +/** \brief Get Interrupt Priority + + The function reads the priority of an interrupt. The interrupt + number can be positive to specify an external (device specific) + interrupt, or negative to specify an internal (core) interrupt. + + + \param [in] IRQn Interrupt number. + \return Interrupt Priority. Value is aligned automatically to the implemented + priority bits of the microcontroller. + */ +__STATIC_INLINE uint32_t NVIC_GetPriority(IRQn_Type IRQn) +{ + + if(IRQn < 0) { + return((uint32_t)((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M0+ system interrupts */ + else { + return((uint32_t)((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief System Reset + + The function initiates a system reset request to reset the MCU. + */ +__STATIC_INLINE void NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FA << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + while(1); /* wait until reset */ +} + +/*@} end of CMSIS_Core_NVICFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if (__Vendor_SysTickConfig == 0) + +/** \brief System Tick Configuration + + The function initializes the System Timer and its interrupt, and starts the System Tick Timer. + Counter is in free running mode to generate periodic interrupts. + + \param [in] ticks Number of ticks between two interrupts. + + \return 0 Function succeeded. + \return 1 Function failed. + + \note When the variable __Vendor_SysTickConfig is set to 1, then the + function SysTick_Config is not included. In this case, the file device.h + must contain a vendor-specific implementation of this function. + + */ +__STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) +{ + if (ticks > SysTick_LOAD_RELOAD_Msk) return (1); /* Reload value impossible */ + + SysTick->LOAD = (ticks & SysTick_LOAD_RELOAD_Msk) - 1; /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1<<__NVIC_PRIO_BITS) - 1); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0; /* Load the SysTick Counter Value */ + SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk; /* Enable SysTick IRQ and SysTick Timer */ + return (0); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/loader/chip/cmsis/core_cmFunc.h b/loader/chip/cmsis/core_cmFunc.h new file mode 100644 index 0000000..902f4f1 --- /dev/null +++ b/loader/chip/cmsis/core_cmFunc.h @@ -0,0 +1,616 @@ +/**************************************************************************//** + * @file core_cmFunc.h + * @brief CMSIS Cortex-M Core Function Access Header File + * @version V3.00 + * @date 19. January 2012 + * + * @note + * Copyright (C) 2009-2012 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. + * + ******************************************************************************/ + +#ifndef __CORE_CMFUNC_H +#define __CORE_CMFUNC_H + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + +/* intrinsic void __enable_irq(); */ +/* intrinsic void __disable_irq(); */ + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__STATIC_INLINE uint32_t __get_CONTROL(void) +{ + register uint32_t __regControl __ASM("control"); + return(__regControl); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + register uint32_t __regControl __ASM("control"); + __regControl = control; +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__STATIC_INLINE uint32_t __get_IPSR(void) +{ + register uint32_t __regIPSR __ASM("ipsr"); + return(__regIPSR); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__STATIC_INLINE uint32_t __get_APSR(void) +{ + register uint32_t __regAPSR __ASM("apsr"); + return(__regAPSR); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__STATIC_INLINE uint32_t __get_xPSR(void) +{ + register uint32_t __regXPSR __ASM("xpsr"); + return(__regXPSR); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + return(__regProcessStackPointer); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + register uint32_t __regProcessStackPointer __ASM("psp"); + __regProcessStackPointer = topOfProcStack; +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + return(__regMainStackPointer); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + register uint32_t __regMainStackPointer __ASM("msp"); + __regMainStackPointer = topOfMainStack; +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + register uint32_t __regPriMask __ASM("primask"); + return(__regPriMask); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + register uint32_t __regPriMask __ASM("primask"); + __regPriMask = (priMask); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + register uint32_t __regBasePri __ASM("basepri"); + return(__regBasePri); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI(uint32_t basePri) +{ + register uint32_t __regBasePri __ASM("basepri"); + __regBasePri = (basePri & 0xff); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + return(__regFaultMask); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + register uint32_t __regFaultMask __ASM("faultmask"); + __regFaultMask = (faultMask & (uint32_t)1); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief Enable IRQ Interrupts + + This function enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i"); +} + + +/** \brief Disable IRQ Interrupts + + This function disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i"); +} + + +/** \brief Get Control Register + + This function returns the content of the Control Register. + + \return Control Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +/** \brief Set Control Register + + This function writes the given value to the Control Register. + + \param [in] control Control Register value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) ); +} + + +/** \brief Get IPSR Register + + This function returns the content of the IPSR Register. + + \return IPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get APSR Register + + This function returns the content of the APSR Register. + + \return APSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get xPSR Register + + This function returns the content of the xPSR Register. + + \return xPSR Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** \brief Get Process Stack Pointer + + This function returns the current value of the Process Stack Pointer (PSP). + + \return PSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, psp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Process Stack Pointer + + This function assigns the given value to the Process Stack Pointer (PSP). + + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0\n" : : "r" (topOfProcStack) ); +} + + +/** \brief Get Main Stack Pointer + + This function returns the current value of the Main Stack Pointer (MSP). + + \return MSP Register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_MSP(void) +{ + register uint32_t result; + + __ASM volatile ("MRS %0, msp\n" : "=r" (result) ); + return(result); +} + + +/** \brief Set Main Stack Pointer + + This function assigns the given value to the Main Stack Pointer (MSP). + + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0\n" : : "r" (topOfMainStack) ); +} + + +/** \brief Get Priority Mask + + This function returns the current state of the priority mask bit from the Priority Mask Register. + + \return Priority Mask value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Priority Mask + + This function assigns the given value to the Priority Mask Register. + + \param [in] priMask Priority Mask + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) ); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Enable FIQ + + This function enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f"); +} + + +/** \brief Disable FIQ + + This function disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f"); +} + + +/** \brief Get Base Priority + + This function returns the current value of the Base Priority register. + + \return Base Priority register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_max" : "=r" (result) ); + return(result); +} + + +/** \brief Set Base Priority + + This function assigns the given value to the Base Priority register. + + \param [in] basePri Base Priority value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_BASEPRI(uint32_t value) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (value) ); +} + + +/** \brief Get Fault Mask + + This function returns the current value of the Fault Mask register. + + \return Fault Mask register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +/** \brief Set Fault Mask + + This function assigns the given value to the Fault Mask register. + + \param [in] faultMask Fault Mask value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) ); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + +#if (__CORTEX_M == 0x04) + +/** \brief Get FPSCR + + This function returns the current value of the Floating Point Status/Control register. + + \return Floating Point Status/Control register value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + + +/** \brief Set FPSCR + + This function assigns the given value to the Floating Point Status/Control register. + + \param [in] fpscr Floating Point Status/Control value to set + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if (__FPU_PRESENT == 1) && (__FPU_USED == 1) + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) ); +#endif +} + +#endif /* (__CORTEX_M == 0x04) */ + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all instrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +#endif /* __CORE_CMFUNC_H */ diff --git a/loader/chip/cmsis/core_cmInstr.h b/loader/chip/cmsis/core_cmInstr.h new file mode 100644 index 0000000..0e6cf3d --- /dev/null +++ b/loader/chip/cmsis/core_cmInstr.h @@ -0,0 +1,618 @@ +/**************************************************************************//** + * @file core_cmInstr.h + * @brief CMSIS Cortex-M Core Instruction Access Header File + * @version V3.00 + * @date 07. February 2012 + * + * @note + * Copyright (C) 2009-2012 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. + * + ******************************************************************************/ + +#ifndef __CORE_CMINSTR_H +#define __CORE_CMINSTR_H + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +#if (__ARMCC_VERSION < 400677) + #error "Please use ARM Compiler Toolchain V4.0.677 or later!" +#endif + + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +#define __WFI __wfi + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +#define __WFE __wfe + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +#define __ISB() __isb(0xF) + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __dsb(0xF) + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __dmb(0xF) + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int32_t __REVSH(int32_t value) +{ + revsh r0, r0 + bx lr +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXB(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXH(value, ptr) __strex(value, ptr) + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#define __STREXW(value, ptr) __strex(value, ptr) + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +#define __CLREX __clrex + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT __ssat + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT __usat + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +#endif /* (__CORTEX_M >= 0x03) */ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +#include + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +#include + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/** \brief No Operation + + No Operation does nothing. This instruction can be used for code alignment purposes. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __NOP(void) +{ + __ASM volatile ("nop"); +} + + +/** \brief Wait For Interrupt + + Wait For Interrupt is a hint instruction that suspends execution + until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFI(void) +{ + __ASM volatile ("wfi"); +} + + +/** \brief Wait For Event + + Wait For Event is a hint instruction that permits the processor to enter + a low-power state until one of a number of events occurs. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __WFE(void) +{ + __ASM volatile ("wfe"); +} + + +/** \brief Send Event + + Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __SEV(void) +{ + __ASM volatile ("sev"); +} + + +/** \brief Instruction Synchronization Barrier + + Instruction Synchronization Barrier flushes the pipeline in the processor, + so that all instructions following the ISB are fetched from cache or + memory, after the instruction has been completed. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __ISB(void) +{ + __ASM volatile ("isb"); +} + + +/** \brief Data Synchronization Barrier + + This function acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DSB(void) +{ + __ASM volatile ("dsb"); +} + + +/** \brief Data Memory Barrier + + This function ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __DMB(void) +{ + __ASM volatile ("dmb"); +} + + +/** \brief Reverse byte order (32 bit) + + This function reverses the byte order in integer value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order (16 bit) + + This function reverses the byte order in two unsigned short values. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Reverse byte order in signed short value + + This function reverses the byte order in a signed short value with sign extension to integer. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE int32_t __REVSH(int32_t value) +{ + uint32_t result; + + __ASM volatile ("revsh %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief Rotate Right in unsigned value (32 bit) + + This function Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + + \param [in] value Value to rotate + \param [in] value Number of Bits to rotate + \return Rotated value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + + __ASM volatile ("ror %0, %0, %1" : "+r" (op1) : "r" (op2) ); + return(op1); +} + + +#if (__CORTEX_M >= 0x03) + +/** \brief Reverse bit order of value + + This function reverses the bit order of the given value. + + \param [in] value Value to reverse + \return Reversed value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + + +/** \brief LDR Exclusive (8 bit) + + This function performs a exclusive LDR command for 8 bit value. + + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint8_t result; + + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (16 bit) + + This function performs a exclusive LDR command for 16 bit values. + + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint16_t result; + + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief LDR Exclusive (32 bit) + + This function performs a exclusive LDR command for 32 bit values. + + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, [%1]" : "=r" (result) : "r" (addr) ); + return(result); +} + + +/** \brief STR Exclusive (8 bit) + + This function performs a exclusive STR command for 8 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (16 bit) + + This function performs a exclusive STR command for 16 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief STR Exclusive (32 bit) + + This function performs a exclusive STR command for 32 bit values. + + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, [%1]" : "=&r" (result) : "r" (addr), "r" (value) ); + return(result); +} + + +/** \brief Remove the exclusive lock + + This function removes the exclusive lock which is created by LDREX. + + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE void __CLREX(void) +{ + __ASM volatile ("clrex"); +} + + +/** \brief Signed Saturate + + This function saturates a signed value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Unsigned Saturate + + This function saturates an unsigned value. + + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** \brief Count leading zeros + + This function counts the number of leading zeros of a data value. + + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint8_t __CLZ(uint32_t value) +{ + uint8_t result; + + __ASM volatile ("clz %0, %1" : "=r" (result) : "r" (value) ); + return(result); +} + +#endif /* (__CORTEX_M >= 0x03) */ + + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + +/* + * The CMSIS functions have been implemented as intrinsics in the compiler. + * Please use "carm -?i" to get an up to date list of all intrinsics, + * Including the CMSIS ones. + */ + +#endif + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + +#endif /* __CORE_CMINSTR_H */ diff --git a/loader/chip/samd20e14.ld b/loader/chip/samd20e14.ld new file mode 100644 index 0000000..3a96cdc --- /dev/null +++ b/loader/chip/samd20e14.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J14 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K +} diff --git a/loader/chip/samd20e15.ld b/loader/chip/samd20e15.ld new file mode 100644 index 0000000..f0546f4 --- /dev/null +++ b/loader/chip/samd20e15.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J15 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K +} diff --git a/loader/chip/samd20e16.ld b/loader/chip/samd20e16.ld new file mode 100644 index 0000000..9ab533c --- /dev/null +++ b/loader/chip/samd20e16.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J16 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} diff --git a/loader/chip/samd20e17.ld b/loader/chip/samd20e17.ld new file mode 100644 index 0000000..6198f14 --- /dev/null +++ b/loader/chip/samd20e17.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J17 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K +} diff --git a/loader/chip/samd20e18.ld b/loader/chip/samd20e18.ld new file mode 100644 index 0000000..6fb1f11 --- /dev/null +++ b/loader/chip/samd20e18.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20E18 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} diff --git a/loader/chip/samd20g14.ld b/loader/chip/samd20g14.ld new file mode 100644 index 0000000..3a96cdc --- /dev/null +++ b/loader/chip/samd20g14.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J14 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K +} diff --git a/loader/chip/samd20g15.ld b/loader/chip/samd20g15.ld new file mode 100644 index 0000000..f0546f4 --- /dev/null +++ b/loader/chip/samd20g15.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J15 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K +} diff --git a/loader/chip/samd20g16.ld b/loader/chip/samd20g16.ld new file mode 100644 index 0000000..9ab533c --- /dev/null +++ b/loader/chip/samd20g16.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J16 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} diff --git a/loader/chip/samd20g17.ld b/loader/chip/samd20g17.ld new file mode 100644 index 0000000..6198f14 --- /dev/null +++ b/loader/chip/samd20g17.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J17 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K +} diff --git a/loader/chip/samd20g18.ld b/loader/chip/samd20g18.ld new file mode 100644 index 0000000..3c18f27 --- /dev/null +++ b/loader/chip/samd20g18.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J18 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} diff --git a/loader/chip/samd20j14.ld b/loader/chip/samd20j14.ld new file mode 100644 index 0000000..3a96cdc --- /dev/null +++ b/loader/chip/samd20j14.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J14 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 2K +} diff --git a/loader/chip/samd20j15.ld b/loader/chip/samd20j15.ld new file mode 100644 index 0000000..f0546f4 --- /dev/null +++ b/loader/chip/samd20j15.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J15 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 4K +} diff --git a/loader/chip/samd20j16.ld b/loader/chip/samd20j16.ld new file mode 100644 index 0000000..9ab533c --- /dev/null +++ b/loader/chip/samd20j16.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J16 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 8K +} diff --git a/loader/chip/samd20j17.ld b/loader/chip/samd20j17.ld new file mode 100644 index 0000000..6198f14 --- /dev/null +++ b/loader/chip/samd20j17.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J17 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 16K +} diff --git a/loader/chip/samd20j18.ld b/loader/chip/samd20j18.ld new file mode 100644 index 0000000..3c18f27 --- /dev/null +++ b/loader/chip/samd20j18.ld @@ -0,0 +1,29 @@ +/* + * Linker script for specifing the memory layout of a target. + * Copyright (C) 2014 + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* SAMD20J18 */ +MEMORY { + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 16K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 32K +} diff --git a/loader/chip/sections.ld b/loader/chip/sections.ld new file mode 100644 index 0000000..b6eef54 --- /dev/null +++ b/loader/chip/sections.ld @@ -0,0 +1,179 @@ +/* Copyright (c) 2011, ARM Limited + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of ARM nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +/* Linker script to place sections and symbol values. Should be used together + * with other linker script that defines memory regions FLASH and RAM. + * It references following symbols, which must be defined in code: + * Reset_Handler : Entry of reset handler + * + * It defines following symbols, which code can use without definition: + * __fixed_start + * __preinit_array_start + * __preinit_array_end + * __init_array_start + * __init_array_end + * __fini_array_start + * __fini_array_end + * __fixed_end + * __etext + * __data_start + * __data_end + * __bss_start + * __bss_start__ + * __bss_end + * __bss_end__ + * __end__ + * end + * __heap_start + * __heap_end + * __stack_end + * __stack_start + */ +ENTRY(Reset_Handler) + +GROUP(libgcc.a libc.a libm.a libnosys.a) + +SECTIONS +{ + .text : + { + . = ALIGN(4); + __fixed_start = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* Verification functions are protected from optimisation and + by being placed in their own section */ + + KEEP(*(.text.verif .text.verif.*)) + + /* Support C constructors, and C destructors in both user code + and the C library. This also provides support for C++ code. */ + + . = ALIGN(4); + KEEP(*(.init)) + . = ALIGN(4); + __preinit_array_start = .; + KEEP (*(.preinit_array)) + __preinit_array_end = .; + + . = ALIGN(4); + __init_array_start = .; + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array)) + __init_array_end = .; + + . = ALIGN(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + __fixed_end = .; + } > FLASH + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + __etext = .; + + .data : AT (__etext) + { + . = ALIGN(4); + __data_start = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + __data_end = .; + } > RAM + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + __bss_start = .; + __bss_start__ = __bss_start; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + __bss_end = .; + __bss_end__ = __bss_end; + } > RAM + + .heap (COPY): + { + __end__ = .; + end = __end__; + __heap_start = __end__; + *(.heap*) + __HeapLimit = .; + __heap_end = __HeapLimit; + } > RAM + + /* .stack_dummy section doesn't contains any symbols. It is only + * used for linker to calculate size of stack sections, and assign + * values to stack symbols later */ + .stack_dummy (COPY): + { + *(.stack*) + } > RAM + + /* Set stack top to end of RAM, and stack limit move down by + * size of stack_dummy section */ + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - SIZEOF(.stack_dummy); + PROVIDE(__stack_start = __StackTop); + PROVIDE(__stack_end = __StackLimit); + + /* Check if data + heap + stack exceeds RAM limit */ + ASSERT(__StackLimit >= __HeapLimit, "region RAM overflowed with stack") +} diff --git a/loader/chip/startup_samd20.c b/loader/chip/startup_samd20.c new file mode 100644 index 0000000..8b65741 --- /dev/null +++ b/loader/chip/startup_samd20.c @@ -0,0 +1,205 @@ +/** + * \file + * + * \brief gcc starttup file for SAMD20 + * + * Copyright (c) 2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "samd20.h" + +/* Initialize segments */ +extern uint32_t __fixed_start; +extern uint32_t __fixed_end; +extern uint32_t __etext; +extern uint32_t __data_start; +extern uint32_t __data_end; +extern uint32_t __bss_start; +extern uint32_t __bss_end; +extern uint32_t __stack_start; +extern uint32_t __stack_end; + +/** \cond DOXYGEN_SHOULD_SKIP_THIS */ +int main(void); +/** \endcond */ + +void __libc_init_array(void); +extern void initialise_monitor_handles(void); + +/* Default empty handler */ +void Dummy_Handler(void); + +/* Cortex-M0+ core handlers */ +void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Peripherals handlers */ +void PM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SYSCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NVMCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EVSYS_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ADC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void AC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Exception Table */ +__attribute__ ((section(".vectors"))) +const DeviceVectors exception_table = { + + /* Configure Initial Stack Pointer, using linker-generated symbols */ + (void*) (&__stack_end), + + (void*) Reset_Handler, + (void*) NMI_Handler, + (void*) HardFault_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) SVC_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) PendSV_Handler, + (void*) SysTick_Handler, + + /* Configurable interrupts */ + (void*) PM_Handler, /* 0 Power Manager */ + (void*) SYSCTRL_Handler, /* 1 System Control */ + (void*) WDT_Handler, /* 2 Watchdog Timer */ + (void*) RTC_Handler, /* 3 Real-Time Counter */ + (void*) EIC_Handler, /* 4 External Interrupt Controller */ + (void*) NVMCTRL_Handler, /* 5 Non-Volatile Memory Controller */ + (void*) EVSYS_Handler, /* 6 Event System Interface */ + (void*) SERCOM0_Handler, /* 7 Serial Communication Interface 0 */ + (void*) SERCOM1_Handler, /* 8 Serial Communication Interface 1 */ + (void*) SERCOM2_Handler, /* 9 Serial Communication Interface 2 */ + (void*) SERCOM3_Handler, /* 10 Serial Communication Interface 3 */ + (void*) SERCOM4_Handler, /* 11 Serial Communication Interface 4 */ + (void*) SERCOM5_Handler, /* 12 Serial Communication Interface 5 */ + (void*) TC0_Handler, /* 13 Basic Timer Counter 0 */ + (void*) TC1_Handler, /* 14 Basic Timer Counter 1 */ + (void*) TC2_Handler, /* 15 Basic Timer Counter 2 */ + (void*) TC3_Handler, /* 16 Basic Timer Counter 3 */ + (void*) TC4_Handler, /* 17 Basic Timer Counter 4 */ + (void*) TC5_Handler, /* 18 Basic Timer Counter 5 */ + (void*) TC6_Handler, /* 19 Basic Timer Counter 6 */ + (void*) TC7_Handler, /* 20 Basic Timer Counter 7 */ + (void*) ADC_Handler, /* 21 Analog Digital Converter */ + (void*) AC_Handler, /* 22 Analog Comparators */ + (void*) DAC_Handler, /* 23 Digital Analog Converter */ + (void*) PTC_Handler /* 24 Peripheral Touch Controller */ +}; + +/** + * \brief This is the code that gets called on processor reset. + * To initialize the device, and call the main() routine. + */ +__attribute__((noreturn)) +void Reset_Handler(void) +{ + uint32_t *pSrc, *pDest; + + /* Initialize the relocate segment */ + pSrc = &__etext; + pDest = &__data_start; + + if (pSrc != pDest) { + for (; pDest < &__data_end;) { + *pDest++ = *pSrc++; + } + } + + /* Clear the zero segment */ + for (pDest = &__bss_start; pDest < &__bss_end;) { + *pDest++ = 0; + } + + /* Initialize the C library */ + __libc_init_array(); + +#ifdef __SEMIHOSTING__ + /* If there's a debugger attached */ + if (DSU->STATUSB.reg & DSU_STATUSB_DBGPRES) { + + /* Initialise handles for semihosting */ + initialise_monitor_handles(); + + /* Set semihosting functions */ + set_semihosting(); + } +#endif /* __SEMIHOSTING__ */ + + /* Branch to main function */ + main(); + + /* Infinite loop */ + while (1); +} + +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Dummy_Handler(void) +{ + + while (1); +} diff --git a/loader/chip/system_samd20.c b/loader/chip/system_samd20.c new file mode 100644 index 0000000..f3386f4 --- /dev/null +++ b/loader/chip/system_samd20.c @@ -0,0 +1,78 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup. + * + * Copyright (c) 2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "samd20.h" + +/** + * Initial system clock frequency. The System RC Oscillator (RCSYS) provides + * the source for the main clock at chip startup. + */ +#define __SYSTEM_CLOCK (1000000) + +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) +{ + // 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/loader/chip/system_samd20.h b/loader/chip/system_samd20.h new file mode 100644 index 0000000..cadcceb --- /dev/null +++ b/loader/chip/system_samd20.h @@ -0,0 +1,62 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup + * + * Copyright (c) 2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SYSTEM_SAMD20_H_INCLUDED_ +#define _SYSTEM_SAMD20_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +void SystemInit(void); +void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_SAMD20_H_INCLUDED */ diff --git a/loader/config.mk b/loader/config.mk new file mode 100644 index 0000000..ee67a9d --- /dev/null +++ b/loader/config.mk @@ -0,0 +1,54 @@ +# Configuration makefile +# Copyright (C) 2014 Richard Meadows +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be +# included in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +# Project Name +# +# This is used to define the name of the build artifact +# +PROJECT_NAME := loader + +# The exact chip being built for. +# +TARGET_CHIP := SAMD20E18 + +# Compiliation Flags +# +# Use this to set the debug level +# +COMPILATION_FLAGS := -g3 -ggdb -O1 + +# Acceptable Warnings +# +ACCEPT_WARN := + +# Linker Flags +# +LINKER_FLAGS := -Wl,--gc-sections + +# The path to a specific blackmagic debugger to use. Optional +# +# You can use `make print-symlinks DEVICE=` to find a +# path to the debugger that will be constant for a given device or +# port. When this field is specified GDB will attempt to connect to +# this debugger on startup. +# +BLACKMAGIC_PATH := diff --git a/loader/inc/adc/adc.h b/loader/inc/adc/adc.h new file mode 100644 index 0000000..92b42b7 --- /dev/null +++ b/loader/inc/adc/adc.h @@ -0,0 +1,1794 @@ +/** + * \file + * + * \brief SAM D20/D21/R21 Peripheral Analog-to-Digital Converter Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef ADC_H_INCLUDED +#define ADC_H_INCLUDED + +/** + * SAM D20/D21/R21 Analog to Digital Converter Driver (ADC) + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the device's Analog to Digital Converter functionality, for + * the conversion of analog voltages into a corresponding digital form. + * The following driver API modes are covered by this manual: + * - Polled APIs + * - Callback APIs + * + * The following peripherals are used by this module: + * + * - ADC (Analog to Digital Converter) + * + * The outline of this documentation is as follows: + * - \ref asfdoc_sam0_adc_prerequisites + * - \ref asfdoc_sam0_adc_module_overview + * - \ref asfdoc_sam0_adc_special_considerations + * - \ref asfdoc_sam0_adc_extra_info + * - \ref asfdoc_sam0_adc_examples + * - \ref asfdoc_sam0_adc_api_overview + * + * + * \section asfdoc_sam0_adc_prerequisites Prerequisites + * + * There are no prerequisites for this module. + * + * + * \section asfdoc_sam0_adc_module_overview Module Overview + * + * This driver provides an interface for the Analog-to-Digital conversion + * functions on the device, to convert analog voltages to a corresponding + * digital value. The ADC has up to 12-bit resolution, and is capable of + * converting up to 500k samples per second (ksps). + * + * The ADC has a compare function for accurate monitoring of user defined + * thresholds with minimum software intervention required. + * The ADC may be configured for 8-, 10- or 12-bit result, reducing the + * conversion time from 2.0μs for 12-bit to 1.4μs for 8-bit result. ADC + * conversion results are provided left or right adjusted which eases + * calculation when the result is represented as a signed integer. + * + * The input selection is flexible, and both single-ended and differential + * measurements can be made. For differential measurements, an optional gain + * stage is available to increase the dynamic range. In addition, several + * internal signal inputs are available. The ADC can provide both signed and + * unsigned results. + * + * The ADC measurements can either be started by application software or an + * incoming event from another peripheral in the device, and both internal and + * external reference voltages can be selected. + * + * \note Internal references will be enabled by the driver, but not disabled. + * Any reference not used by the application should be disabled by the application. + * + * A simplified block diagram of the ADC can be seen in + * \ref asfdoc_sam0_adc_module_block_diagram "the figure below". + * + * \anchor asfdoc_sam0_adc_module_block_diagram + * \dot + * digraph overview { + * splines = false; + * rankdir=LR; + * + * mux1 [label="Positive input", shape=box]; + * mux2 [label="Negative input", shape=box]; + * + * + * mux3 [label="Reference", shape=box]; + * + * adc [label="ADC", shape=polygon, sides=5, orientation=90, distortion=-0.6, style=filled, fillcolor=darkolivegreen1, height=1, width=1]; + * prescaler [label="PRESCALER", shape=box, style=filled, fillcolor=lightblue]; + * + * mux1 -> adc; + * mux2 -> adc; + * mux3 -> adc:sw; + * prescaler -> adc; + * + * postproc [label="Post processing", shape=box]; + * result [label="RESULT", shape=box, style=filled, fillcolor=lightblue]; + * + * adc:e -> postproc:w; + * postproc:e -> result:w; + * + * {rank=same; mux1 mux2} + * {rank=same; prescaler adc} + * + * } + * \enddot + * + * + * \subsection asfdoc_sam0_adc_module_overview_prescaler Sample Clock Prescaler + * The ADC features a prescaler which enables conversion at lower clock rates + * than the input Generic Clock to the ADC module. This feature can be used to + * lower the synchronization time of the digital interface to the ADC module + * via a high speed Generic Clock frequency, while still allowing the ADC + * sampling rate to be reduced. + * + * \subsection asfdoc_sam0_adc_module_overview_resolution ADC Resolution + * The ADC supports full 8-bit, 10-bit or 12-bit resolution. Hardware + * oversampling and decimation can be used to increase the + * effective resolution at the expense of throughput. Using oversampling and + * decimation mode the ADC resolution is increased from 12-bits to an effective + * 13, 14, 15 or 16-bits. In these modes the conversion rate is reduced, as + * a greater number of samples is used to achieve the increased resolution. The + * available resolutions and effective conversion rate is listed in + * \ref asfdoc_sam0_adc_module_conversion_rate "the table below". + * + * \anchor asfdoc_sam0_adc_module_conversion_rate + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Effective ADC conversion speed using oversampling
ResolutionEffective conversion rate
13-bitsConversion rate divided by 4
14-bitsConversion rate divided by 16
15-bitsConversion rate divided by 64
16-bitsConversion rate divided by 256
+ * + * \subsection asfdoc_sam0_adc_module_overview_conversion Conversion Modes + * ADC conversions can be software triggered on demand by the user application, + * if continuous sampling is not required. It is also possible to configure the + * ADC in free-running mode, where new conversions are started as soon as the + * previous conversion is completed, or configure the ADC to scan across a + * number of input pins (see \ref asfdoc_sam0_adc_module_overview_pin_scan). + * + * \subsection asfdoc_sam0_adc_module_overview_diff_mode Differential and Single-Ended Conversion + * The ADC has two conversion modes; differential and single-ended. When + * measuring signals where the positive input pin is always at a higher voltage + * than the negative input pin, the single-ended conversion mode should be used + * in order to achieve a full 12-bit output resolution. + * + * If however the positive input pin voltage may drop below the negative input + * pin the signed differential mode should be used. + * + * \subsection asfdoc_sam0_adc_module_overview_sample_time Sample Time + * The sample time for each ADC conversion is configurable as a number of half + * prescaled ADC clock cycles (depending on the prescaler value), allowing the + * user application to achieve faster or slower sampling depending on the + * source impedance of the ADC input channels. For applications with high + * impedance inputs the sample time can be increased to give the ADC an adequate + * time to sample and convert the input channel. + * + * The resulting sampling time is given by the following equation: + * \f[ + * t_{SAMPLE} = (sample\_length+1) \times \frac{ADC_{CLK}} {2} + * \f] + * + * \subsection asfdoc_sam0_adc_module_overview_averaging Averaging + * The ADC can be configured to trade conversion speed for accuracy by averaging + * multiple samples in hardware. This feature is suitable when operating in + * noisy conditions. + * + * You can specify any number of samples to accumulate (up to 1024) and the + * divide ratio to use (up to divide by 128). To modify these settings the + * ADC_RESOLUTION_CUSTOM needs to be set as the resolution. When this is set + * the number of samples to accumulate and the division ratio can be set by + * the configuration struct members \ref adc_config.accumulate_samples and + * \ref adc_config.divide_result When using this mode the ADC result register + * will be set to be 16-bits wide to accommodate the larger result sizes + * produced by the accumulator. + * + * The effective ADC conversion rate will be reduced by a factor of the number + * of accumulated samples; + * however the effective resolution will be increased according to + * \ref asfdoc_sam0_adc_module_hw_av_resolution "the table below". + * + * \anchor asfdoc_sam0_adc_module_hw_av_resolution + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Effective ADC resolution from various hardware averaging modes
Number of Samples
Final Result
112-bits
213-bits
414-bits
815-bits
1616-bits
3216-bits
6416-bits
12816-bits
25616-bits
51216-bits
102416-bits
+ * + * + * \subsection asfdoc_sam0_adc_module_overview_offset_corr Offset and Gain Correction + * Inherent gain and offset errors affect the absolute accuracy of the ADC. + * + * The offset error is defined as the deviation of the ADC’s actual transfer + * function from ideal straight line at zero input voltage. + * + * The gain error is defined as the deviation of the last output step's + * midpoint from the ideal straight line, after compensating for offset error. + * + * The offset correction value is subtracted from the converted data before the + * result is ready. The gain correction value is multiplied with the offset + * corrected value. + * + * The equation for both offset and gain error compensation is shown below: + * \f[ + * ADC_{RESULT} = (VALUE_{CONV} + CORR_{OFFSET}) \times CORR_{GAIN} + * \f] + * + * When enabled, a given set of offset and gain correction values can be applied + * to the sampled data in hardware, giving a corrected stream of sample data to + * the user application at the cost of an increased sample latency. + * + * In single conversion, a latency of 13 ADC Generic Clock cycles is added for + * the final sample result availability. As the correction time is always less + * than the propagation delay, in free running mode this latency appears only + * during the first conversion. After the first conversion is complete future + * conversion results are available at the defined sampling rate. + * + * \subsection asfdoc_sam0_adc_module_overview_pin_scan Pin Scan + * In pin scan mode, the first ADC conversion will begin from the configured + * positive channel, plus the requested starting offset. When the first + * conversion is completed, the next conversion will start at the next positive + * input channel and so on, until all requested pins to scan have been sampled + * and converted. + * + * Pin scanning gives a simple mechanism to sample a large number of physical + * input channel samples, using a single physical ADC channel. + * + * \subsection asfdoc_sam0_adc_module_overview_window_monitor Window Monitor + * The ADC module window monitor function can be used to automatically compare + * the conversion result against a preconfigured pair of upper and lower + * threshold values. + * + * The threshold values are evaluated differently, depending on whether + * differential or single-ended mode is selected. In differential mode, the + * upper and lower thresholds are evaluated as signed values for the comparison, + * while in single-ended mode the comparisons are made as a set of unsigned + * values. + * + * The significant bits of the lower window monitor threshold and upper window + * monitor threshold values are user-configurable, and follow the overall ADC + * sampling bit precision set when the ADC is configured by the user application. + * For example, only the eight lower bits of the window threshold values will be + * compares to the sampled data whilst the ADC is configured in 8-bit mode. + * In addition, if using differential mode, the 8th bit will be considered as + * the sign bit even if bit 9 is zero. + * + * \subsection asfdoc_sam0_adc_module_overview_events Events + * Event generation and event actions are configurable in the ADC. + * + * The ADC has two actions that can be triggered upon event reception: + * \li Start conversion + * \li Flush pipeline and start conversion + * + * The ADC can generate two events: + * \li Window monitor + * \li Result ready + * + * If the event actions are enabled in the configuration, any incoming event + * will trigger the action. + * + * If the window monitor event is enabled, an event will be generated + * when the configured window condition is detected. + * + * If the result ready event is enabled, an event will be generated when a + * conversion is completed. + * + * \note The connection of events between modules requires the use of the + * \ref asfdoc_sam0_events_group "SAM D20/D21/R21 Event System Driver (EVENTS)" + * to route output event of one module to the the input event of another. + * For more information on event routing, refer to the event driver + * documentation. + * + * + * \section asfdoc_sam0_adc_special_considerations Special Considerations + * + * An integrated analog temperature sensor is available for use with the ADC. + * The bandgap voltage, as well as the scaled IO and core voltages can also be + * measured by the ADC. For internal ADC inputs, the internal source(s) may need + * to be manually enabled by the user application before they can be measured. + * + * + * \section asfdoc_sam0_adc_extra_info Extra Information + * + * For extra information see \ref asfdoc_sam0_adc_extra. This includes: + * - \ref asfdoc_sam0_adc_extra_acronyms + * - \ref asfdoc_sam0_adc_extra_dependencies + * - \ref asfdoc_sam0_adc_extra_errata + * - \ref asfdoc_sam0_adc_extra_history + * + * + * \section asfdoc_sam0_adc_examples Examples + * + * For a list of examples related to this driver, see + * \ref asfdoc_sam0_adc_exqsg. + * + * + * \section asfdoc_sam0_adc_api_overview API Overview + * @{ + */ + +#include "samd20.h" +#include "system/system.h" +#include "system/pinmux.h" +#define Assert assert + +enum adc_status_code { + ADC_STATUS_OK, + ADC_STATUS_BUSY, + ADC_STATUS_ERR_INVALID_ARG, + ADC_STATUS_ERR_OVERFLOW, + ADC_STATUS_ERR_DENIED +}; + +/** Forward definition of the device instance */ +struct adc_module module_inst; + +/** Type of the callback functions */ +typedef void (*adc_callback_t)(void); + +/** + * \brief ADC Callback enum + * + * Callback types for ADC callback driver + * + */ +enum adc_callback { + /** Callback for buffer received */ + ADC_CALLBACK_READ_BUFFER, + /** Callback when window is hit */ + ADC_CALLBACK_WINDOW, + /** Callback for error */ + ADC_CALLBACK_ERROR, +# if !defined(__DOXYGEN__) + /** Number of available callbacks. */ + ADC_CALLBACK_N, +# endif +}; + +/** + * \name Module status flags + * + * ADC status flags, returned by \ref adc_get_status() and cleared by + * \ref adc_clear_status(). + * + * @{ + */ + +/** ADC result ready */ +#define ADC_STATUS_RESULT_READY (1UL << 0) +/** Window monitor match */ +#define ADC_STATUS_WINDOW (1UL << 1) +/** ADC result overwritten before read */ +#define ADC_STATUS_OVERRUN (1UL << 2) + +/** @} */ + +/** + * \brief ADC reference voltage enum + * + * Enum for the possible reference voltages for the ADC. + * + */ +enum adc_reference { + /** 1.0V voltage reference */ + ADC_REFERENCE_INT1V = ADC_REFCTRL_REFSEL_INT1V, + /** 1/1.48 VCC reference */ + ADC_REFERENCE_INTVCC0 = ADC_REFCTRL_REFSEL_INTVCC0, + /** 1/2 VCC (only for internal Vcc > 2.1v) */ + ADC_REFERENCE_INTVCC1 = ADC_REFCTRL_REFSEL_INTVCC1, + /** External reference A */ + ADC_REFERENCE_AREFA = ADC_REFCTRL_REFSEL_AREFA, + /** External reference B */ + ADC_REFERENCE_AREFB = ADC_REFCTRL_REFSEL_AREFB, +}; + +/** + * \brief ADC clock prescaler enum + * + * Enum for the possible clock prescaler values for the ADC. + * + */ +enum adc_clock_prescaler { + /** ADC clock division factor 4 */ + ADC_CLOCK_PRESCALER_DIV4 = ADC_CTRLB_PRESCALER_DIV4, + /** ADC clock division factor 8 */ + ADC_CLOCK_PRESCALER_DIV8 = ADC_CTRLB_PRESCALER_DIV8, + /** ADC clock division factor 16 */ + ADC_CLOCK_PRESCALER_DIV16 = ADC_CTRLB_PRESCALER_DIV16, + /** ADC clock division factor 32 */ + ADC_CLOCK_PRESCALER_DIV32 = ADC_CTRLB_PRESCALER_DIV32, + /** ADC clock division factor 64 */ + ADC_CLOCK_PRESCALER_DIV64 = ADC_CTRLB_PRESCALER_DIV64, + /** ADC clock division factor 128 */ + ADC_CLOCK_PRESCALER_DIV128 = ADC_CTRLB_PRESCALER_DIV128, + /** ADC clock division factor 256 */ + ADC_CLOCK_PRESCALER_DIV256 = ADC_CTRLB_PRESCALER_DIV256, + /** ADC clock division factor 512 */ + ADC_CLOCK_PRESCALER_DIV512 = ADC_CTRLB_PRESCALER_DIV512, +}; + +/** + * \brief ADC resolution enum + * + * Enum for the possible resolution values for the ADC. + * + */ +enum adc_resolution { + /** ADC 12-bit resolution */ + ADC_RESOLUTION_12BIT = ADC_CTRLB_RESSEL_12BIT, + /** ADC 16-bit resolution using oversampling and decimation */ + ADC_RESOLUTION_16BIT = ADC_CTRLB_RESSEL_16BIT, + /** ADC 10-bit resolution */ + ADC_RESOLUTION_10BIT = ADC_CTRLB_RESSEL_10BIT, + /** ADC 8-bit resolution */ + ADC_RESOLUTION_8BIT = ADC_CTRLB_RESSEL_8BIT, + /** ADC 13-bit resolution using oversampling and decimation */ + ADC_RESOLUTION_13BIT, + /** ADC 14-bit resolution using oversampling and decimation */ + ADC_RESOLUTION_14BIT, + /** ADC 15-bit resolution using oversampling and decimation */ + ADC_RESOLUTION_15BIT, + /** ADC 16-bit result register for use with averaging. When using this mode + * the ADC result register will be set to 16-bit wide, and the number of + * samples to accumulate and the division factor is configured by the + * \ref adc_config.accumulate_samples and \ref adc_config.divide_result + * members in the configuration struct + */ + ADC_RESOLUTION_CUSTOM, +}; + +/** + * \brief ADC window monitor mode enum + * + * Enum for the possible window monitor modes for the ADC. + * + */ +enum adc_window_mode { + /** No window mode */ + ADC_WINDOW_MODE_DISABLE = ADC_WINCTRL_WINMODE_DISABLE, + /** RESULT > WINLT */ + ADC_WINDOW_MODE_ABOVE_LOWER = ADC_WINCTRL_WINMODE_MODE1, + /** RESULT < WINUT */ + ADC_WINDOW_MODE_BELOW_UPPER = ADC_WINCTRL_WINMODE_MODE2, + /** WINLT < RESULT < WINUT */ + ADC_WINDOW_MODE_BETWEEN = ADC_WINCTRL_WINMODE_MODE3, + /** !(WINLT < RESULT < WINUT) */ + ADC_WINDOW_MODE_BETWEEN_INVERTED = ADC_WINCTRL_WINMODE_MODE4, +}; + +/** + * \brief ADC gain factor selection enum + * + * Enum for the possible gain factor values for the ADC. + * + */ +enum adc_gain_factor { + /** 1x gain */ + ADC_GAIN_FACTOR_1X = ADC_INPUTCTRL_GAIN_1X, + /** 2x gain */ + ADC_GAIN_FACTOR_2X = ADC_INPUTCTRL_GAIN_2X, + /** 4x gain */ + ADC_GAIN_FACTOR_4X = ADC_INPUTCTRL_GAIN_4X, + /** 8x gain */ + ADC_GAIN_FACTOR_8X = ADC_INPUTCTRL_GAIN_8X, + /** 16x gain */ + ADC_GAIN_FACTOR_16X = ADC_INPUTCTRL_GAIN_16X, + /** 1/2x gain */ + ADC_GAIN_FACTOR_DIV2 = ADC_INPUTCTRL_GAIN_DIV2, +}; + +/** + * \brief ADC event action enum + * + * Enum for the possible actions to take on an incoming event. + * + */ +enum adc_event_action { + /** Event action disabled */ + ADC_EVENT_ACTION_DISABLED = 0, + /** Flush ADC and start conversion */ + ADC_EVENT_ACTION_FLUSH_START_CONV = ADC_EVCTRL_SYNCEI, + /** Start conversion */ + ADC_EVENT_ACTION_START_CONV = ADC_EVCTRL_STARTEI, +}; + +/** + * \brief ADC positive MUX input selection enum + * + * Enum for the possible positive MUX input selections for the ADC. + * + */ +enum adc_positive_input { + /** ADC0 pin */ + ADC_POSITIVE_INPUT_PIN0 = ADC_INPUTCTRL_MUXPOS_PIN0, + /** ADC1 pin */ + ADC_POSITIVE_INPUT_PIN1 = ADC_INPUTCTRL_MUXPOS_PIN1, + /** ADC2 pin */ + ADC_POSITIVE_INPUT_PIN2 = ADC_INPUTCTRL_MUXPOS_PIN2, + /** ADC3 pin */ + ADC_POSITIVE_INPUT_PIN3 = ADC_INPUTCTRL_MUXPOS_PIN3, + /** ADC4 pin */ + ADC_POSITIVE_INPUT_PIN4 = ADC_INPUTCTRL_MUXPOS_PIN4, + /** ADC5 pin */ + ADC_POSITIVE_INPUT_PIN5 = ADC_INPUTCTRL_MUXPOS_PIN5, + /** ADC6 pin */ + ADC_POSITIVE_INPUT_PIN6 = ADC_INPUTCTRL_MUXPOS_PIN6, + /** ADC7 pin */ + ADC_POSITIVE_INPUT_PIN7 = ADC_INPUTCTRL_MUXPOS_PIN7, + /** ADC8 pin */ + ADC_POSITIVE_INPUT_PIN8 = ADC_INPUTCTRL_MUXPOS_PIN8, + /** ADC9 pin */ + ADC_POSITIVE_INPUT_PIN9 = ADC_INPUTCTRL_MUXPOS_PIN9, + /** ADC10 pin */ + ADC_POSITIVE_INPUT_PIN10 = ADC_INPUTCTRL_MUXPOS_PIN10, + /** ADC11 pin */ + ADC_POSITIVE_INPUT_PIN11 = ADC_INPUTCTRL_MUXPOS_PIN11, + /** ADC12 pin */ + ADC_POSITIVE_INPUT_PIN12 = ADC_INPUTCTRL_MUXPOS_PIN12, + /** ADC13 pin */ + ADC_POSITIVE_INPUT_PIN13 = ADC_INPUTCTRL_MUXPOS_PIN13, + /** ADC14 pin */ + ADC_POSITIVE_INPUT_PIN14 = ADC_INPUTCTRL_MUXPOS_PIN14, + /** ADC15 pin */ + ADC_POSITIVE_INPUT_PIN15 = ADC_INPUTCTRL_MUXPOS_PIN15, + /** ADC16 pin */ + ADC_POSITIVE_INPUT_PIN16 = ADC_INPUTCTRL_MUXPOS_PIN16, + /** ADC17 pin */ + ADC_POSITIVE_INPUT_PIN17 = ADC_INPUTCTRL_MUXPOS_PIN17, + /** ADC18 pin */ + ADC_POSITIVE_INPUT_PIN18 = ADC_INPUTCTRL_MUXPOS_PIN18, + /** ADC19 pin */ + ADC_POSITIVE_INPUT_PIN19 = ADC_INPUTCTRL_MUXPOS_PIN19, + /** Temperature reference */ + ADC_POSITIVE_INPUT_TEMP = ADC_INPUTCTRL_MUXPOS_TEMP, + /** Bandgap voltage */ + ADC_POSITIVE_INPUT_BANDGAP = ADC_INPUTCTRL_MUXPOS_BANDGAP, + /** 1/4 scaled core supply */ + ADC_POSITIVE_INPUT_SCALEDCOREVCC = ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC, + /** 1/4 scaled I/O supply */ + ADC_POSITIVE_INPUT_SCALEDIOVCC = ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC, + /** DAC input */ + ADC_POSITIVE_INPUT_DAC = ADC_INPUTCTRL_MUXPOS_DAC, +}; + +/** + * \brief ADC negative MUX input selection enum + * + * Enum for the possible negative MUX input selections for the ADC. + * + */ +enum adc_negative_input { + /** ADC0 pin */ + ADC_NEGATIVE_INPUT_PIN0 = ADC_INPUTCTRL_MUXNEG_PIN0, + /** ADC1 pin */ + ADC_NEGATIVE_INPUT_PIN1 = ADC_INPUTCTRL_MUXNEG_PIN1, + /** ADC2 pin */ + ADC_NEGATIVE_INPUT_PIN2 = ADC_INPUTCTRL_MUXNEG_PIN2, + /** ADC3 pin */ + ADC_NEGATIVE_INPUT_PIN3 = ADC_INPUTCTRL_MUXNEG_PIN3, + /** ADC4 pin */ + ADC_NEGATIVE_INPUT_PIN4 = ADC_INPUTCTRL_MUXNEG_PIN4, + /** ADC5 pin */ + ADC_NEGATIVE_INPUT_PIN5 = ADC_INPUTCTRL_MUXNEG_PIN5, + /** ADC6 pin */ + ADC_NEGATIVE_INPUT_PIN6 = ADC_INPUTCTRL_MUXNEG_PIN6, + /** ADC7 pin */ + ADC_NEGATIVE_INPUT_PIN7 = ADC_INPUTCTRL_MUXNEG_PIN7, + /** Internal ground */ + ADC_NEGATIVE_INPUT_GND = ADC_INPUTCTRL_MUXNEG_GND, + /** I/O ground */ + ADC_NEGATIVE_INPUT_IOGND = ADC_INPUTCTRL_MUXNEG_IOGND, +}; + +/** + * \brief ADC number of accumulated samples enum + * + * Enum for the possible numbers of ADC samples to accumulate. + * This setting is only used when the \ref ADC_RESOLUTION_CUSTOM + * resolution setting is used. + * + */ +enum adc_accumulate_samples { + /** No averaging */ + ADC_ACCUMULATE_DISABLE = ADC_AVGCTRL_SAMPLENUM_1, + /** Average 2 samples */ + ADC_ACCUMULATE_SAMPLES_2 = ADC_AVGCTRL_SAMPLENUM_2, + /** Average 4 samples */ + ADC_ACCUMULATE_SAMPLES_4 = ADC_AVGCTRL_SAMPLENUM_4, + /** Average 8 samples */ + ADC_ACCUMULATE_SAMPLES_8 = ADC_AVGCTRL_SAMPLENUM_8, + /** Average 16 samples */ + ADC_ACCUMULATE_SAMPLES_16 = ADC_AVGCTRL_SAMPLENUM_16, + /** Average 32 samples */ + ADC_ACCUMULATE_SAMPLES_32 = ADC_AVGCTRL_SAMPLENUM_32, + /** Average 64 samples */ + ADC_ACCUMULATE_SAMPLES_64 = ADC_AVGCTRL_SAMPLENUM_64, + /** Average 128 samples */ + ADC_ACCUMULATE_SAMPLES_128 = ADC_AVGCTRL_SAMPLENUM_128, + /** Average 265 samples */ + ADC_ACCUMULATE_SAMPLES_256 = ADC_AVGCTRL_SAMPLENUM_256, + /** Average 512 samples */ + ADC_ACCUMULATE_SAMPLES_512 = ADC_AVGCTRL_SAMPLENUM_512, + /** Average 1024 samples */ + ADC_ACCUMULATE_SAMPLES_1024 = ADC_AVGCTRL_SAMPLENUM_1024, +}; + +/** + * \brief ADC possible dividers for the result register + * + * Enum for the possible division factors to use when accumulating + * multiple samples. To keep the same resolution for the averaged + * result and the actual input value the division factor must + * be equal to the number of samples accumulated. This setting is only + * used when the \ref ADC_RESOLUTION_CUSTOM resolution setting is used. + */ +enum adc_divide_result { + /** Don't divide result register after accumulation */ + ADC_DIVIDE_RESULT_DISABLE = 0, + /** Divide result register by 2 after accumulation */ + ADC_DIVIDE_RESULT_2 = 1, + /** Divide result register by 4 after accumulation */ + ADC_DIVIDE_RESULT_4 = 2, + /** Divide result register by 8 after accumulation */ + ADC_DIVIDE_RESULT_8 = 3, + /** Divide result register by 16 after accumulation */ + ADC_DIVIDE_RESULT_16 = 4, + /** Divide result register by 32 after accumulation */ + ADC_DIVIDE_RESULT_32 = 5, + /** Divide result register by 64 after accumulation */ + ADC_DIVIDE_RESULT_64 = 6, + /** Divide result register by 128 after accumulation */ + ADC_DIVIDE_RESULT_128 = 7, +}; + +/** + * Enum for the possible ADC interrupt flags + */ +enum adc_interrupt_flag { + /** ADC result ready */ + ADC_INTERRUPT_RESULT_READY = ADC_INTFLAG_RESRDY, + /** Window monitor match */ + ADC_INTERRUPT_WINDOW = ADC_INTFLAG_WINMON, + /** ADC result overwritten before read */ + ADC_INTERRUPT_OVERRUN = ADC_INTFLAG_OVERRUN, +}; + +/** + * \brief ADC oversampling and decimation enum + * + * Enum for the possible numbers of bits resolution can be increased by when + * using oversampling and decimation. + * + */ +enum adc_oversampling_and_decimation { + /** Don't use oversampling and decimation mode */ + ADC_OVERSAMPLING_AND_DECIMATION_DISABLE = 0, + /** 1 bit resolution increase */ + ADC_OVERSAMPLING_AND_DECIMATION_1BIT, + /** 2 bits resolution increase */ + ADC_OVERSAMPLING_AND_DECIMATION_2BIT, + /** 3 bits resolution increase */ + ADC_OVERSAMPLING_AND_DECIMATION_3BIT, + /** 4 bits resolution increase */ + ADC_OVERSAMPLING_AND_DECIMATION_4BIT +}; + +/** + * \brief Window monitor configuration structure + * + * Window monitor configuration structure. + */ +struct adc_window_config { + /** Selected window mode */ + enum adc_window_mode window_mode; + /** Lower window value */ + int32_t window_lower_value; + /** Upper window value */ + int32_t window_upper_value; +}; + +/** + * \brief ADC event enable/disable structure. + * + * Event flags for the ADC module. This is used to enable and + * disable events via \ref adc_enable_events() and \ref adc_disable_events(). + */ +struct adc_events { + /** Enable event generation on conversion done */ + bool generate_event_on_conversion_done; + /** Enable event generation on window monitor */ + bool generate_event_on_window_monitor; +}; + +/** + * \brief Gain and offset correction configuration structure + * + * Gain and offset correction configuration structure. + * Part of the \ref adc_config struct and will be initialized by + * \ref adc_get_config_defaults . + */ +struct adc_correction_config { + /** + * Enables correction for gain and offset based on values of gain_correction and + * offset_correction if set to true. + */ + bool correction_enable; + /** + * This value defines how the ADC conversion result is compensated for gain + * error before written to the result register. This is a fractional value, + * 1-bit integer plus an 11-bit fraction, therefore + * 1/2 <= gain_correction < 2. Valid \c gain_correction values ranges from + * \c 0b010000000000 to \c 0b111111111111. + */ + uint16_t gain_correction; + /** + * This value defines how the ADC conversion result is compensated for + * offset error before written to the result register. This is a 12-bit + * value in two’s complement format. + */ + int16_t offset_correction; +}; + +/** + * \brief Pin scan configuration structure + * + * Pin scan configuration structure. Part of the \ref adc_config struct and will + * be initialized by \ref adc_get_config_defaults . + */ +struct adc_pin_scan_config { + /** + * Offset (relative to selected positive input) of the first input pin to be + * used in pin scan mode. + */ + uint8_t offset_start_scan; + /** + * Number of input pins to scan in pin scan mode. A value below 2 will + * disable pin scan mode. + */ + uint8_t inputs_to_scan; +}; + +/** + * \brief ADC configuration structure + * + * Configuration structure for an ADC instance. This structure should be + * initialized by the \ref adc_get_config_defaults() + * function before being modified by the user application. + */ +struct adc_config { + /** GCLK generator used to clock the peripheral */ + enum gclk_generator clock_source; + /** Voltage reference */ + enum adc_reference reference; + /** Clock prescaler */ + enum adc_clock_prescaler clock_prescaler; + /** Result resolution */ + enum adc_resolution resolution; + /** Gain factor */ + enum adc_gain_factor gain_factor; + /** Positive MUX input */ + enum adc_positive_input positive_input; + /** Negative MUX input */ + enum adc_negative_input negative_input; + /** Number of ADC samples to accumulate when using the + * \c ADC_RESOLUTION_CUSTOM mode + */ + enum adc_accumulate_samples accumulate_samples; + /** Division ration when using the ADC_RESOLUTION_CUSTOM mode */ + enum adc_divide_result divide_result; + /** Left adjusted result */ + bool left_adjust; + /** Enables differential mode if true */ + bool differential_mode; + /** Enables free running mode if true */ + bool freerunning; + /** Enables ADC in standby sleep mode if true */ + bool run_in_standby; + /** + * Enables reference buffer offset compensation if true. + * This will increase the accuracy of the gain stage, but decreases the input + * impedance; therefore the startup time of the reference must be increased. + */ + bool reference_compensation_enable; + /** + * This value (0-63) control the ADC sampling time in number of half ADC + * prescaled clock cycles (depends of \c ADC_PRESCALER value), thus + * controlling the ADC input impedance. Sampling time is set according to + * the formula: + * Sample time = (sample_length+1) * (ADCclk / 2) + */ + uint8_t sample_length; + /** Window monitor configuration structure */ + struct adc_window_config window; + /** Gain and offset correction configuration structure */ + struct adc_correction_config correction; + /** Event action to take on incoming event */ + enum adc_event_action event_action; + /** Pin scan configuration structure */ + struct adc_pin_scan_config pin_scan; +}; + +/** + * \brief ADC software device instance structure. + * + * ADC software instance structure, used to retain software state information + * of an associated hardware module instance. + * + * \note The fields of this structure should not be altered by the user + * application; they are reserved for module-internal use only. + */ +struct adc_module { + /** Pointer to ADC hardware module */ + Adc *hw; + /** Keep reference configuration so we know when enable is called */ + enum adc_reference reference; + /** Array to store callback functions */ + adc_callback_t callback[ADC_CALLBACK_N]; + /** Pointer to buffer used for ADC results */ + volatile uint16_t *job_buffer; + /** Remaining number of conversions in current job */ + volatile uint16_t remaining_conversions; + /** Bit mask for callbacks registered */ + uint8_t registered_callback_mask; + /** Bit mask for callbacks enabled */ + uint8_t enabled_callback_mask; + /** Holds the status of the ongoing or last conversion job */ + volatile enum adc_status_code job_status; + /** If software triggering is needed */ + bool software_trigger; +}; + +/** + * Driver initialization and configuration + */ +enum adc_status_code adc_init(Adc *hw, + struct adc_config *config); + +/** + * \brief Initializes an ADC configuration structure to defaults + * + * Initializes a given ADC configuration struct to a set of known default + * values. This function should be called on any new instance of the + * configuration struct before being modified by the user application. + * + * The default configuration is as follows: + * \li GCLK generator 0 (GCLK main) clock source + * \li 1V from internal bandgap reference + * \li Div 4 clock prescaler + * \li 12 bit resolution + * \li Window monitor disabled + * \li No gain + * \li Positive input on ADC PIN 0 + * \li Negative input on ADC PIN 1 + * \li Averaging disabled + * \li Oversampling disabled + * \li Right adjust data + * \li Single-ended mode + * \li Free running disabled + * \li All events (input and generation) disabled + * \li Sleep operation disabled + * \li No reference compensation + * \li No gain/offset correction + * \li No added sampling time + * \li Pin scan mode disabled + * + * \param[out] config Pointer to configuration struct to initialize to + * default values + */ +static inline void adc_get_config_defaults(struct adc_config *const config) +{ + + config->clock_source = GCLK_GENERATOR_0; + config->reference = ADC_REFERENCE_INT1V; + config->clock_prescaler = ADC_CLOCK_PRESCALER_DIV4; + config->resolution = ADC_RESOLUTION_12BIT; + config->window.window_mode = ADC_WINDOW_MODE_DISABLE; + config->window.window_upper_value = 0; + config->window.window_lower_value = 0; + config->gain_factor = ADC_GAIN_FACTOR_1X; +#if SAMR21 + config->positive_input = ADC_POSITIVE_INPUT_PIN6 ; +#else + config->positive_input = ADC_POSITIVE_INPUT_PIN0 ; +#endif + config->negative_input = ADC_NEGATIVE_INPUT_GND ; + config->accumulate_samples = ADC_ACCUMULATE_DISABLE; + config->divide_result = ADC_DIVIDE_RESULT_DISABLE; + config->left_adjust = false; + config->differential_mode = false; + config->freerunning = false; + config->event_action = ADC_EVENT_ACTION_DISABLED; + config->run_in_standby = false; + config->reference_compensation_enable = false; + config->correction.correction_enable = false; + config->correction.gain_correction = ADC_GAINCORR_RESETVALUE; + config->correction.offset_correction = ADC_OFFSETCORR_RESETVALUE; + config->sample_length = 0; + config->pin_scan.offset_start_scan = 0; + config->pin_scan.inputs_to_scan = 0; +} + +/** + * Status Management + */ + +/** + * \brief Retrieves the current module status. + * + * Retrieves the status of the module, giving overall state information. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * + * \return Bitmask of \c ADC_STATUS_* flags + * + * \retval ADC_STATUS_RESULT_READY ADC Result is ready to be read + * \retval ADC_STATUS_WINDOW ADC has detected a value inside the set + * window range + * \retval ADC_STATUS_OVERRUN ADC result has overrun + */ +static inline uint32_t adc_get_status(void) +{ + Adc *const adc_module = module_inst.hw; + + uint32_t int_flags = adc_module->INTFLAG.reg; + + uint32_t status_flags = 0; + + /* Check for ADC Result Ready */ + if (int_flags & ADC_INTFLAG_RESRDY) { + status_flags |= ADC_STATUS_RESULT_READY; + } + + /* Check for ADC Window Match */ + if (int_flags & ADC_INTFLAG_WINMON) { + status_flags |= ADC_STATUS_WINDOW; + } + + /* Check for ADC Overrun */ + if (int_flags & ADC_INTFLAG_OVERRUN) { + status_flags |= ADC_STATUS_OVERRUN; + } + + return status_flags; +} + +/** + * \brief Clears a module status flag. + * + * Clears the given status flag of the module. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] status_flags Bitmask of \c ADC_STATUS_* flags to clear + */ +static inline void adc_clear_status(const uint32_t status_flags) +{ + /* Sanity check arguments */ + + + Adc *const adc_module = module_inst.hw; + + uint32_t int_flags = 0; + + /* Check for ADC Result Ready */ + if (status_flags & ADC_STATUS_RESULT_READY) { + int_flags |= ADC_INTFLAG_RESRDY; + } + + /* Check for ADC Window Match */ + if (status_flags & ADC_STATUS_WINDOW) { + int_flags |= ADC_INTFLAG_WINMON; + } + + /* Check for ADC Overrun */ + if (status_flags & ADC_STATUS_OVERRUN) { + int_flags |= ADC_INTFLAG_OVERRUN; + } + + /* Clear interrupt flag */ + adc_module->INTFLAG.reg = int_flags; +} + + +/** + * Enable, disable and reset ADC module, start conversion and read result + */ +/** + * \brief Determines if the hardware module(s) are currently synchronizing to the bus. + * + * Checks to see if the underlying hardware peripheral module(s) are currently + * synchronizing across multiple clock domains to the hardware bus, This + * function can be used to delay further operations on a module until such time + * that it is ready, to prevent blocking delays for synchronization in the + * user application. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * + * \return Synchronization status of the underlying hardware module(s). + * + * \retval true if the module synchronization is ongoing + * \retval false if the module has completed synchronization + */ +static inline bool adc_is_syncing(void) +{ + Adc *const adc_module = module_inst.hw; + + if (adc_module->STATUS.reg & ADC_STATUS_SYNCBUSY) { + return true; + } + + return false; +} + +/** + * \brief Enables the ADC module + * + * Enables an ADC module that has previously been configured. If any internal reference + * is selected it will be enabled. + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline enum adc_status_code adc_enable(void) +{ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Make sure bandgap is enabled if requested by the config */ + if (module_inst.reference == ADC_REFERENCE_INT1V) { + system_voltage_reference_enable(SYSTEM_VOLTAGE_REFERENCE_BANDGAP); + } + + adc_module->CTRLA.reg |= ADC_CTRLA_ENABLE; + return ADC_STATUS_OK; +} + +/** + * \brief Disables the ADC module + * + * Disables an ADC module that was previously enabled. + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline enum adc_status_code adc_disable(void) +{ + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + adc_module->CTRLA.reg &= ~ADC_CTRLA_ENABLE; + return ADC_STATUS_OK; +} + +/** + * \brief Resets the ADC module + * + * Resets an ADC module, clearing all module state and registers to their + * default values. + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline enum adc_status_code adc_reset(void) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + /* Disable to make sure the pipeline is flushed before reset */ + adc_disable(); + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Software reset the module */ + adc_module->CTRLA.reg |= ADC_CTRLA_SWRST; + return ADC_STATUS_OK; +} + + +/** + * \brief Enables an ADC event input or output. + * + * Enables one or more input or output events to or from the ADC module. See + * \ref adc_events "here" for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in] module_inst Software instance for the ADC peripheral + * \param[in] events Struct containing flags of events to enable + */ +static inline void adc_enable_events(struct adc_events *const events) +{ + /* Sanity check arguments */ + + + + + Adc *const adc_module = module_inst.hw; + + uint32_t event_mask = 0; + + /* Configure Window Monitor event */ + if (events->generate_event_on_window_monitor) { + event_mask |= ADC_EVCTRL_WINMONEO; + } + + /* Configure Result Ready event */ + if (events->generate_event_on_conversion_done) { + event_mask |= ADC_EVCTRL_RESRDYEO; + } + + adc_module->EVCTRL.reg |= event_mask; +} + +/** + * \brief Disables an ADC event input or output. + * + * Disables one or more input or output events to or from the ADC module. See + * \ref adc_events "here" for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in] module_inst Software instance for the ADC peripheral + * \param[in] events Struct containing flags of events to disable + */ +static inline void adc_disable_events(struct adc_events *const events) +{ + /* Sanity check arguments */ + + + + + Adc *const adc_module = module_inst.hw; + + uint32_t event_mask = 0; + + /* Configure Window Monitor event */ + if (events->generate_event_on_window_monitor) { + event_mask |= ADC_EVCTRL_WINMONEO; + } + + /* Configure Result Ready event */ + if (events->generate_event_on_conversion_done) { + event_mask |= ADC_EVCTRL_RESRDYEO; + } + + adc_module->EVCTRL.reg &= ~event_mask; +} + +/** + * \brief Starts an ADC conversion + * + * Starts a new ADC conversion. + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline void adc_start_conversion(void) +{ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + adc_module->SWTRIG.reg |= ADC_SWTRIG_START; +} + +/** + * \brief Reads the ADC result + * + * Reads the result from an ADC conversion that was previously started. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[out] result Pointer to store the result value in + * + * \return Status of the ADC read request. + * \retval ADC_STATUS_OK The result was retrieved successfully + * \retval ADC_STATUS_BUSY A conversion result was not ready + * \retval ADC_STATUS_ERR_OVERFLOW The result register has been overwritten by the + * ADC module before the result was read by the software + */ +static inline enum adc_status_code adc_read(uint16_t *result) +{ + + + + + if (!(adc_get_status() & ADC_STATUS_RESULT_READY)) { + /* Result not ready */ + return ADC_STATUS_BUSY; + } + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Get ADC result */ + *result = adc_module->RESULT.reg; + + /* Reset ready flag */ + adc_clear_status(ADC_STATUS_RESULT_READY); + + if (adc_get_status() & ADC_STATUS_OVERRUN) { + adc_clear_status(ADC_STATUS_OVERRUN); + return ADC_STATUS_ERR_OVERFLOW; + } + + return ADC_STATUS_OK; +} + +/** @} */ + +/** + * \name Runtime changes of ADC module + * @{ + */ + +/** + * \brief Flushes the ADC pipeline + * + * Flushes the pipeline and restart the ADC clock on the next peripheral clock + * edge. All conversions in progress will be lost. When flush is complete, the + * module will resume where it left off. + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline void adc_flush(void) +{ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + adc_module->SWTRIG.reg |= ADC_SWTRIG_FLUSH; +} + +/** + * \brief Sets the ADC window mode + * + * Sets the ADC window mode to a given mode and value range. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] window_mode Window monitor mode to set + * \param[in] window_lower_value Lower window monitor threshold value + * \param[in] window_upper_value Upper window monitor threshold value + */ +static inline void adc_set_window_mode(const enum adc_window_mode window_mode, + const int16_t window_lower_value, + const int16_t window_upper_value) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set window mode */ + adc_module->WINCTRL.reg = window_mode << ADC_WINCTRL_WINMODE_Pos; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set lower window monitor threshold value */ + adc_module->WINLT.reg = window_lower_value << ADC_WINLT_WINLT_Pos; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set upper window monitor threshold value */ + adc_module->WINUT.reg = window_upper_value << ADC_WINUT_WINUT_Pos; +} + + +/** + * \brief Sets ADC gain factor + * + * Sets the ADC gain factor to a specified gain setting. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] gain_factor Gain factor value to set + */ +static inline void adc_set_gain(const enum adc_gain_factor gain_factor) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set new gain factor */ + adc_module->INPUTCTRL.reg = + (adc_module->INPUTCTRL.reg & ~ADC_INPUTCTRL_GAIN_Msk) | + (gain_factor << ADC_INPUTCTRL_GAIN_Pos); +} + +/** + * \brief Sets the ADC pin scan mode + * + * Configures the pin scan mode of the ADC module. In pin scan mode, the first + * conversion will start at the configured positive input + start_offset. When + * a conversion is done, a conversion will start on the next input, until + * \c inputs_to_scan number of conversions are made. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] inputs_to_scan Number of input pins to perform a conversion on + * (must be two or more) + * \param[in] start_offset Offset of first pin to scan (relative to + * configured positive input) + * + * \return Status of the pin scan configuration set request. + * + * \retval ADC_STATUS_OK Pin scan mode has been set successfully + * \retval ADC_STATUS_ERR_INVALID_ARG Number of input pins to scan or offset has + * an invalid value + */ +static inline enum adc_status_code adc_set_pin_scan_mode(uint8_t inputs_to_scan, + const uint8_t start_offset) + +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + if (inputs_to_scan > 0) { + /* + * Number of input sources included is the value written to INPUTSCAN + * plus 1. + */ + inputs_to_scan--; + } + + if (inputs_to_scan > (ADC_INPUTCTRL_INPUTSCAN_Msk >> ADC_INPUTCTRL_INPUTSCAN_Pos) || + start_offset > (ADC_INPUTCTRL_INPUTOFFSET_Msk >> ADC_INPUTCTRL_INPUTOFFSET_Pos)) { + /* Invalid number of input pins */ + return ADC_STATUS_ERR_INVALID_ARG; + } + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set pin scan mode */ + adc_module->INPUTCTRL.reg = + (adc_module->INPUTCTRL.reg & + ~(ADC_INPUTCTRL_INPUTSCAN_Msk | ADC_INPUTCTRL_INPUTOFFSET_Msk)) | + (start_offset << ADC_INPUTCTRL_INPUTOFFSET_Pos) | + (inputs_to_scan << ADC_INPUTCTRL_INPUTSCAN_Pos); + + return ADC_STATUS_OK; +} + +/** + * \brief Disables pin scan mode + * + * Disables pin scan mode. The next conversion will be made on only one pin + * (the configured positive input pin). + * + * \param[in] module_inst Pointer to the ADC software instance struct + */ +static inline void adc_disable_pin_scan_mode(void) +{ + /* Disable pin scan mode */ + adc_set_pin_scan_mode(0, 0); +} + + +/** + * \brief Sets positive ADC input pin + * + * Sets the positive ADC input pin selection. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] positive_input Positive input pin + */ +static inline void adc_set_positive_input(const enum adc_positive_input positive_input) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set positive input pin */ + adc_module->INPUTCTRL.reg = + (adc_module->INPUTCTRL.reg & ~ADC_INPUTCTRL_MUXPOS_Msk) | + (positive_input << ADC_INPUTCTRL_MUXPOS_Pos); +} + + +/** + * \brief Sets negative ADC input pin for differential mode + * + * Sets the negative ADC input pin, when the ADC is configured in differential + * mode. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] negative_input Negative input pin + */ +static inline void adc_set_negative_input(const enum adc_negative_input negative_input) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set negative input pin */ + adc_module->INPUTCTRL.reg = + (adc_module->INPUTCTRL.reg & ~ADC_INPUTCTRL_MUXNEG_Msk) | + (negative_input << ADC_INPUTCTRL_MUXNEG_Pos); +} + +/** + * \brief Enable interrupt + * + * Enable the given interrupt request from the ADC module. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] interrupt Interrupt to enable + */ +static inline void adc_enable_interrupt(enum adc_interrupt_flag interrupt) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + /* Enable interrupt */ + adc_module->INTENSET.reg = interrupt; +} + +/** + * \brief Disable interrupt + * + * Disable the given interrupt request from the ADC module. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] interrupt Interrupt to disable + */ +static inline void adc_disable_interrupt(enum adc_interrupt_flag interrupt) +{ + /* Sanity check arguments */ + + + + Adc *const adc_module = module_inst.hw; + /* Enable interrupt */ + adc_module->INTENCLR.reg = interrupt; +} + +/** + * Enum for the possible types of ADC asynchronous jobs that may be issued to + * the driver. + */ +enum adc_job_type { + /** Asynchronous ADC read into a user provided buffer */ + ADC_JOB_READ_BUFFER, +}; + +/** + * Callback Management + */ +void adc_register_callback(adc_callback_t callback_func, + enum adc_callback callback_type); + +void adc_unregister_callback(enum adc_callback callback_type); + +/** + * \brief Enables callback + * + * Enables the callback function registered by \ref + * adc_register_callback. The callback function will be called from the + * interrupt handler when the conditions for the callback type are met. + * + * \param[in] module Pointer to ADC software instance struct + * \param[in] callback_type Callback type given by an enum + * + * \returns Status of the operation + * \retval STATUS_OK If operation was completed + * \retval STATUS_ERR_INVALID If operation was not completed, + * due to invalid callback_type + * + */ +static inline void adc_enable_callback(enum adc_callback callback_type) +{ + /* Enable callback */ + module_inst.enabled_callback_mask |= (1 << callback_type); + + /* Enable window interrupt if this is a window callback */ + if (callback_type == ADC_CALLBACK_WINDOW) { + adc_enable_interrupt(ADC_INTERRUPT_WINDOW); + } + /* Enable overrun interrupt if error callback is registered */ + if (callback_type == ADC_CALLBACK_ERROR) { + adc_enable_interrupt(ADC_INTERRUPT_OVERRUN); + } +} + +/** + * \brief Disables callback + * + * Disables the callback function registered by the \ref + * adc_register_callback. + * + * \param[in] module Pointer to ADC software instance struct + * \param[in] callback_type Callback type given by an enum + * + * \returns Status of the operation + * \retval STATUS_OK If operation was completed + * \retval STATUS_ERR_INVALID If operation was not completed, + * due to invalid callback_type + * + */ +static inline void adc_disable_callback(enum adc_callback callback_type) +{ + /* Sanity check arguments */ + + + /* Disable callback */ + module_inst.enabled_callback_mask &= ~(1 << callback_type); + + /* Disable window interrupt if this is a window callback */ + if (callback_type == ADC_CALLBACK_WINDOW) { + adc_disable_interrupt(ADC_INTERRUPT_WINDOW); + } + /* Disable overrun interrupt if this is the error callback */ + if (callback_type == ADC_CALLBACK_ERROR) { + adc_disable_interrupt(ADC_INTERRUPT_OVERRUN); + } +} + +/** + * Job Management + */ +enum adc_status_code adc_read_buffer_job(uint16_t *buffer, + uint16_t samples); + +enum adc_status_code adc_get_job_status(enum adc_job_type type); + +void adc_abort_job(enum adc_job_type type); + + + +/** + * \page asfdoc_sam0_adc_extra Extra Information for ADC Driver + * + * \section asfdoc_sam0_adc_extra_acronyms Acronyms + * Below is a table listing the acronyms used in this module, along with their + * intended meanings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
AcronymDescription
ADCAnalog-to-Digital Converter
DACDigital-to-Analog Converter
LSBLeast Significant Bit
MSBMost Significant Bit
DMADirect Memory Access
+ * + * + * \section asfdoc_sam0_adc_extra_dependencies Dependencies + * This driver has the following dependencies: + * + * - \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" + * + * + * \section asfdoc_sam0_adc_extra_errata Errata + * There are no errata related to this driver. + * + * + * \section asfdoc_sam0_adc_extra_history Module History + * An overview of the module history is presented in the table below, with + * details on the enhancements and fixes made to the module since its first + * release. The current version of this corresponds to the newest version in + * the table. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Changelog
Added support for SAMR21.
Added support for SAMD21 and new DMA quick start guide.
Added ADC calibration constant loading from the device signature + * row when the module is initialized.
Initial Release
+ */ + +/** + * \page asfdoc_sam0_adc_exqsg Examples for ADC Driver + * + * This is a list of the available Quick Start guides (QSGs) and example + * applications for \ref asfdoc_sam0_adc_group. QSGs are simple examples with + * step-by-step instructions to configure and use this driver in a selection of + * use cases. Note that QSGs can be compiled as a standalone application or be + * added to the user application. + * + * - \subpage asfdoc_sam0_adc_basic_use_case + * \if ADC_CALLBACK_MODE + * - \subpage asfdoc_sam0_adc_basic_use_case_callback + * \endif + * - \subpage asfdoc_sam0_adc_dma_use_case + * + * \page asfdoc_sam0_adc_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev. + * Date + * Comments + *
D03/2014Added support for SAMR21.
C01/2014Added support for SAMD21.
B06/2013Added additional documentation on the event system. Corrected + * documentation typos.
A06/2013Initial release
+ */ + +#endif /* ADC_H_INCLUDED */ diff --git a/loader/inc/analogue.h b/loader/inc/analogue.h new file mode 100644 index 0000000..7f1800c --- /dev/null +++ b/loader/inc/analogue.h @@ -0,0 +1,36 @@ +/* + * Functions for analogue sensors + * Copyright (C) 2014 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef ANALOGUE_H +#define ANALOGUE_H + + +void start_adc_sequence(void); +uint8_t is_adc_sequence_done(void); + +float get_battery(void); +float get_thermistor(void); +float get_solar(void); + +#endif /* ANALOGUE_H */ diff --git a/loader/inc/flash.h b/loader/inc/flash.h new file mode 100644 index 0000000..94cf407 --- /dev/null +++ b/loader/inc/flash.h @@ -0,0 +1,35 @@ +/* + * Function related to the flash memory + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef FLASH_H +#define FLASH_H + +enum flash_state { + FLASH_GOOD, /* checksum matches */ + FLASH_BAD_CSUM, /* mismatch */ +}; + +enum flash_state check_flash_state(void); + +#endif /* FLASH_H */ diff --git a/loader/inc/hw_config b/loader/inc/hw_config new file mode 120000 index 0000000..11f573d --- /dev/null +++ b/loader/inc/hw_config @@ -0,0 +1 @@ +../../firmware/inc/hw_config \ No newline at end of file diff --git a/loader/inc/hw_config.h b/loader/inc/hw_config.h new file mode 120000 index 0000000..f39f58c --- /dev/null +++ b/loader/inc/hw_config.h @@ -0,0 +1 @@ +../../firmware/inc/hw_config.h \ No newline at end of file diff --git a/loader/inc/init.h b/loader/inc/init.h new file mode 100644 index 0000000..a73f5a2 --- /dev/null +++ b/loader/inc/init.h @@ -0,0 +1,61 @@ +/* + * Board level init functions + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef INIT_H +#define INIT_H + +#include "samd20.h" +#include "hw_config.h" +#include "system/port.h" + +enum init_type { + INIT_NORMAL, + INIT_TESTCASE = 0xCC, +}; + +/** + * Turns the status LED on + */ +static inline void led_on(void) +{ + port_pin_set_output_level(LED0_PIN, 0); /* LED is active low */ +} +/** + * Turns the status LED off + */ +static inline void led_off(void) +{ + port_pin_set_output_level(LED0_PIN, 1); /* LED is active low */ +} +/** + * Toggles the status LED + */ +static inline void led_toggle(void) +{ + port_pin_toggle_output_level(LED0_PIN); +} + +void init(enum init_type init_t); + +#endif /* INIT_H */ diff --git a/loader/inc/loader.h b/loader/inc/loader.h new file mode 100644 index 0000000..56644ec --- /dev/null +++ b/loader/inc/loader.h @@ -0,0 +1,30 @@ +/* + * bootloader functions + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef LOADER_H +#define LOADER_H + +void transfer_to_application(void); + +#endif /* LOADER_H */ diff --git a/loader/inc/memory.h b/loader/inc/memory.h new file mode 100644 index 0000000..9de0fa1 --- /dev/null +++ b/loader/inc/memory.h @@ -0,0 +1,60 @@ +/* + * Provides functions for using the external flash memory + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef MEMORY_H +#define MEMORY_H + +/** + * Memory layout: + * + * 64-byte pages + * 256-byte rows (erase) - 4 pages + */ + +#define TOTAL_PAGES 0x100 +#define TOTAL_ROWS 0x40 + +#define PAGE_MASK 0x7FFC0 +#define ROW_MASK 0x7FF00 + +#define PAGE_SIZE 0x00040 +#define ROW_SIZE 0x00100 + +/** + * Pages assigned to backlog. Currently 256 records + */ +#define BACKLOG_START_PAGE 0x00 +#define BACKLOG_END_PAGE 0xff + + +void mem_chip_erase(void); +void mem_read_memory(uint32_t address, uint8_t* buffer, uint32_t length); +void mem_write_word(uint32_t address, uint32_t word); +void mem_write_page(uint32_t address, uint8_t* buffer, uint16_t length); +void mem_erase_sector(uint32_t address); + +uint8_t mem_power_on(); +void mem_power_off(); + +#endif diff --git a/loader/inc/rtc.h b/loader/inc/rtc.h new file mode 100644 index 0000000..52b1f2f --- /dev/null +++ b/loader/inc/rtc.h @@ -0,0 +1,40 @@ +/* + * Initialised RTC to provide 1Hz event and interrupt + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef RTC_H +#define RTC_H + +/* Counts seconds since last aprs */ +uint32_t get_since_aprs_s(void); +void clear_since_aprs_s(void); + +uint32_t rtc_get_ticks(void); + +/* Initialises RTC to provide 1Hz event and interrupt */ +void rtc_init(void); +/* Sets the hibernate time */ +void rtc_hibernate_time(uint32_t time_s); + + +#endif /* RTC_H */ diff --git a/loader/inc/sercom/i2c.h b/loader/inc/sercom/i2c.h new file mode 100644 index 0000000..c4cde8d --- /dev/null +++ b/loader/inc/sercom/i2c.h @@ -0,0 +1,49 @@ +/* + * A wrapper around the samd20 i2c functions. Single master only + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef I2C_H +#define I2C_H + +#include "sercom/i2c_master.h" + +/** + * I2C Write. + * + * address is the full write address like 0xEE + */ +void i2c_master_write(uint8_t address, uint8_t* data, uint16_t data_length); + +/** + * I2C Read. + * + * address is the full write address like 0xEE + */ +void i2c_master_read(uint8_t address, uint8_t* data, uint16_t data_length); + +/** + * I2C bus master. + */ +void i2c_init(SercomI2cm*const sercom, uint32_t pad0_pinmux, uint32_t pad1_pinmux); + +#endif /* I2C_H */ diff --git a/loader/inc/sercom/i2c_common.h b/loader/inc/sercom/i2c_common.h new file mode 100644 index 0000000..2becddd --- /dev/null +++ b/loader/inc/sercom/i2c_common.h @@ -0,0 +1,553 @@ +/** + * \file + * + * \brief SAM SERCOM I2C Common Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef I2C_COMMON_H_INCLUDED +#define I2C_COMMON_H_INCLUDED + +#include + +/** + * \if (I2C_MASTER_MODE && I2C_SLAVE_MODE) + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Driver (SERCOM I2C) + * \elseif I2C_MASTER_MODE + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Master Mode Driver (SERCOM I2C) + * \elseif I2C_SLAVE_MODE + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Slave Mode Driver (SERCOM I2C) + * \endif + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the device's SERCOM I2C module, for the transfer + * of data via an I2C bus. The following driver API modes are covered + * by this manual: + * + * \if I2C_MASTER_MODE + * - Master Mode Polled APIs + * \endif + * \if I2C_MASTER_CALLBACK_MODE + * - Master Mode Callback APIs + * \endif + * \if I2C_SLAVE_MODE + * - Slave Mode Polled APIs + * \endif + * \if I2C_SLAVE_CALLBACK_MODE + * - Slave Mode Callback APIs + * \endif + * + * The following peripheral is used by this module: + * + * - SERCOM (Serial Communication Interface) + * + * The outline of this documentation is as follows: + * - \ref asfdoc_sam0_sercom_i2c_prerequisites + * - \ref asfdoc_sam0_sercom_i2c_overview + * - \ref asfdoc_sam0_sercom_i2c_special_considerations + * - \ref asfdoc_sam0_sercom_i2c_extra + * - \ref asfdoc_sam0_sercom_i2c_examples + * - \ref asfdoc_sam0_sercom_i2c_api_overview + * + * \section asfdoc_sam0_sercom_i2c_prerequisites Prerequisites + * There are no prerequisites. + * + * \section asfdoc_sam0_sercom_i2c_overview Module Overview + * The outline of this section is as follows: + * - \ref asfdoc_sam0_sercom_i2c_module_features + * - \ref asfdoc_sam0_sercom_i2c_functional_desc + * - \ref asfdoc_sam0_sercom_i2c_bus_topology + * - \ref asfdoc_sam0_sercom_i2c_transactions + * - \ref asfdoc_sam0_sercom_i2c_multi_master + * - \ref asfdoc_sam0_sercom_i2c_bus_states + * - \ref asfdoc_sam0_sercom_i2c_timeout + * - \ref asfdoc_sam0_sercom_i2c_sleep_modes + * + * \subsection asfdoc_sam0_sercom_i2c_module_features Driver Feature Macro Definition + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Driver Feature MacroSupported devices
FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEEDSAM D21/R21
FEATURE_I2C_10_BIT_ADDRESSSAM D21/R21
FEATURE_I2C_SCL_STRETCH_MODESAM D21/R21
FEATURE_I2C_SCL_EXTEND_TIMEOUTSAM D21/R21
+ * \note The specific features are only available in the driver when the + * selected device supports those features. + * + * \subsection asfdoc_sam0_sercom_i2c_functional_desc Functional Description + * The I2C provides a simple two-wire bidirectional bus consisting of a + * wired-AND type serial clock line (SCL) and a wired-AND type serial data line + * (SDA). + * + * The I2C bus provides a simple, but efficient method of interconnecting + * multiple master and slave devices. An arbitration mechanism is provided for + * resolving bus ownership between masters, as only one master device may own + * the bus at any given time. The arbitration mechanism relies on the wired-AND + * connections to avoid bus drivers short-circuiting. + * + * A unique address is assigned to all slave devices connected to the bus. A + * device can contain both master and slave logic, and can emulate multiple + * slave devices by responding to more than one address. + * + * \subsection asfdoc_sam0_sercom_i2c_bus_topology Bus Topology + * The I2C bus topology is illustrated in + * \ref asfdoc_sam0_sercom_i2c_bus_topology_figure "the figure below". The pull-up + * resistors (Rs) will provide a high level on the bus lines when none of the + * I2C devices are driving the bus. These are optional, and can be + * replaced with a constant current source. + * + * \anchor asfdoc_sam0_sercom_i2c_bus_topology_figure + * \image html bus_topology.svg "I2C bus topology" width=100% + * + * \subsection asfdoc_sam0_sercom_i2c_transactions Transactions + * The I2C standard defines three fundamental transaction formats: + * - Master Write + * - The master transmits data packets to the slave after addressing it + * - Master Read + * - The slave transmits data packets to the master after being addressed + * - Combined Read/Write + * - A combined transaction consists of several write and read transactions + * + * A data transfer starts with the master issuing a \b Start condition on the + * bus, followed by the address of the slave together with a bit to indicate + * whether the master wants to read from or write to the slave. + * The addressed slave must respond to this by sending an \b ACK back to the + * master. + * + * After this, data packets are sent from the master or slave, according to the + * read/write bit. Each packet must be acknowledged (ACK) or not + * acknowledged (NACK) by the receiver. + * + * If a slave responds with a NACK, the master must assume that the slave + * cannot receive any more data and cancel the write operation. + * + * The master completes a transaction by issuing a \b Stop condition. + * + * A master can issue multiple \b Start conditions during a transaction; this + * is then called a \b Repeated \b Start condition. + * + * \subsubsection asfdoc_sam0_sercom_i2c_address_packets Address Packets + * The slave address consists of seven bits. The 8th bit in the transfer + * determines the data direction (read or write). An address packet always + * succeeds a \b Start or \b Repeated \b Start condition. The 8th bit is handled + * in the driver, and the user will only have to provide the 7 bit address. + * + * \subsubsection asfdoc_sam0_sercom_i2c_data_packets Data Packets + * Data packets are nine bits long, consisting of one 8-bit data byte, and an + * acknowledgement bit. Data packets follow either an address packet or another + * data packet on the bus. + * + * \subsubsection asfdoc_sam0_sercom_i2c_trans_examples Transaction Examples + * The gray bits in the following examples are sent from master to slave, and + * the white bits are sent from slave to master. + * Example of a read transaction is shown in + * \ref asfdoc_sam0_sercom_i2c_trans_examples_i2c_read "the figure below". Here, the + * master first issues a \b Start condition and gets ownership of the bus. An + * address packet with the direction flag set to read is then sent and + * acknowledged by the slave. Then the slave sends one data packet which is + * acknowledged by the master. The slave sends another packet, which is not + * acknowledged by the master and indicates that the master will terminate the + * transaction. In the end, the transaction is terminated by the master issuing + * a \b Stop condition. + * + * \anchor asfdoc_sam0_sercom_i2c_trans_examples_i2c_read + * \image html i2c_read.svg "I2C Packet Read" width=100% + * + * Example of a write transaction is shown in + * \ref asfdoc_sam0_sercom_i2c_trans_examples_i2c_write "the figure below". Here, the + * master first issues a \b Start condition and gets ownership of the bus. An + * address packet with the dir flag set to write is then sent and acknowledged + * by the slave. Then the master sends two data packets, each acknowledged by + * the slave. In the end, the transaction is terminated by the master issuing + * a \b Stop condition. + * + * \anchor asfdoc_sam0_sercom_i2c_trans_examples_i2c_write + * \image html i2c_write.svg "I2C Packet Write" width=100% + * + * \subsubsection asfdoc_sam0_sercom_i2c_packet_timeout Packet Timeout + * When a master sends an I2C packet, there is no way of + * being sure that a slave will acknowledge the packet. To avoid stalling the + * device forever while waiting for an acknowledge, a user selectable timeout + * is provided in the \ref i2c_master_config struct which + * lets the driver exit a read or write operation after the specified time. + * The function will then return the STATUS_ERR_TIMEOUT flag. + * + * This is also the case for the slave when using the functions postfixed + * \c _wait. + * + * The time before the timeout occurs, will be the same as + * for \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "unknown bus state" timeout. + * + * \subsubsection asfdoc_sam0_sercom_i2c_repeated_start Repeated Start + * To issue a \b Repeated \b Start, the functions postfixed \c _no_stop must be + * used. + * These functions will not send a \b Stop condition when the transfer is done, + * thus the next transfer will start with a \b Repeated \b Start. To end the + * transaction, the functions without the \c _no_stop postfix must be used + * for the last read/write. + * + * \subsection asfdoc_sam0_sercom_i2c_multi_master Multi Master + * In a multi master environment, arbitration of the bus is important, as only + * one master can own the bus at any point. + * + * \subsubsection asfdoc_sam0_sercom_i2c_arbitration Arbitration + * + * \par Clock stretching + * The serial clock line is always driven by a master device. However, all + * devices connected to the bus are allowed stretch the low period of the clock + * to slow down the overall clock frequency or to insert wait states while + * processing data. + * Both master and slave can randomly stretch the clock, which will force the + * other device into a wait-state until the clock line goes high again. + * + * \par Arbitration on the data line + * If two masters start transmitting at the same time, they will both transmit + * until one master detects that the other master is pulling the data line low. + * When this is detected, the master not pulling the line low, will stop the + * transmission and wait until the bus is idle. + * As it is the master trying to contact the slave with the lowest address that + * will get the bus ownership, this will create an arbitration scheme always + * prioritizing the slaves with the lowest address in case of a bus collision. + * + * \subsubsection asfdoc_sam0_sercom_i2c_clock_sync Clock Synchronization + * In situations where more than one master is trying to control the bus clock + * line at the same time, a clock synchronization algorithm based on the same + * principles used for clock stretching is necessary. + * + * + * \subsection asfdoc_sam0_sercom_i2c_bus_states Bus States + * As the I2C bus is limited to one transaction at the time, + * a master that wants to perform a bus transaction must wait until the bus is + * free. + * Because of this, it is necessary for all masters in a multi-master system to + * know the current status of the bus to be able to avoid conflicts and to + * ensure data integrity. + * \li \b IDLE No activity on the bus (between a \b Stop and a new \b Start + * condition) + * \li \b OWNER If the master initiates a transaction successfully + * \li \b BUSY If another master is driving the bus + * \li \b UNKNOWN If the master has recently been enabled or connected to + * the bus. Is forced to \b IDLE after given + * \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "timeout" when + * the master module is enabled. + * + * The bus state diagram can be seen in + * \ref asfdoc_sam0_sercom_i2c_bus_states_figure "the figure below". + * \li S: Start condition + * \li P: Stop condition + * \li Sr: Repeated start condition + * \anchor asfdoc_sam0_sercom_i2c_bus_states_figure + * \image html bus_state_diagram.svg "I2C bus state diagram" width=100% + * + * \subsection asfdoc_sam0_sercom_i2c_timeout Bus Timing + * Inactive bus timeout for the master and SDA hold time is configurable in the + * drivers. + * + * \subsubsection asfdoc_sam0_sercom_i2c_unknown_bus_timeout Unknown Bus State Timeout + * When a master is enabled or connected to the bus, the bus state will be + * unknown until either a given timeout or a stop command has occurred. The + * timeout is configurable in the \ref i2c_master_config struct. + * The timeout time will depend on toolchain and optimization level used, as + * the timeout is a loop incrementing a value until it reaches the specified + * timeout value. + * + * \subsubsection sda_hold SDA Hold Timeout + * When using the I2C in slave mode, it will be important to + * set a SDA hold time which assures that the master will be able to pick up + * the bit sent from the slave. The SDA hold time makes sure that this is the + * case by holding the data line low for a given period after the negative edge + * on the clock. + * + * The SDA hold time is also available for the master driver, but is not a + * necessity. + * + * \subsection asfdoc_sam0_sercom_i2c_sleep_modes Operation in Sleep Modes + * The I2C module can operate in all sleep modes by setting + * the run_in_standby boolean in the \ref i2c_master_config or + * \ref i2c_slave_config struct. + * The operation in slave and master mode is shown in + * \ref asfdoc_sam0_sercom_i2c_sleep_modes_table "the table below". + * + * \anchor asfdoc_sam0_sercom_i2c_sleep_modes_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
I2C standby operations
Run in standbySlaveMaster
falseDisabled, all reception is droppedGCLK disabled when master is idle
trueWake on address match when enabledGCLK enabled while in sleep modes
+ * + * + * \section asfdoc_sam0_sercom_i2c_special_considerations Special Considerations + * + * \if (I2C_MASTER_CALLBACK_MODE || I2C_SLAVE_CALLBACK_MODE) + * \subsection asfdoc_sam0_sercom_i2c_common_interrupt Interrupt-Driven Operation + * While an interrupt-driven operation is in progress, subsequent calls to a + * write or read operation will return the STATUS_BUSY flag, indicating that + * only one operation is allowed at any given time. + * + * To check if another transmission can be initiated, the user can either call + * another transfer operation, or use the + * \ref i2c_master_get_job_status/\ref i2c_slave_get_job_status functions + * depending on mode. + * + * If the user would like to get callback from operations while using the + * interrupt-driven driver, the callback must be registered and then enabled + * using the "register_callback" and "enable_callback" functions. + * \else + * There are no special considerations for this driver for the APIs listed in + * this document. + * \endif + * + * \section asfdoc_sam0_sercom_i2c_extra Extra Information + * For extra information see \ref asfdoc_sam0_sercom_i2c_extra_info_page. + * This includes: + * - \ref asfdoc_sam0_sercom_i2c_acronyms + * - \ref asfdoc_sam0_sercom_i2c_extra_dependencies + * - \ref asfdoc_sam0_sercom_i2c_extra_errata + * - \ref asfdoc_sam0_sercom_i2c_extra_history + * + * \section asfdoc_sam0_sercom_i2c_examples Examples + * + * For a list of examples related to this driver, see + * \ref asfdoc_sam0_sercom_i2c_exqsg. + * + * \section asfdoc_sam0_sercom_i2c_api_overview API Overview + * @{ + */ + +/** + * \name Driver feature definition + * Define SERCOME I2C driver features set according to different device family. + * + * \note The high speed mode and 10-bit address feature are not + * supported by the driver now. + * @{ + */ +#if (SAMD21) || (SAMR21) || defined(__DOXYGEN__) +/** Fast mode plus and high speed support */ +# define FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED +/** 10 bit address support */ +# define FEATURE_I2C_10_BIT_ADDRESS +/** SCL stretch mode support */ +# define FEATURE_I2C_SCL_STRETCH_MODE +/** SCL extend timeout support */ +# define FEATURE_I2C_SCL_EXTEND_TIMEOUT +# define FEATURE_I2C_DMA_SUPPORT +#endif +/*@}*/ + +/** \brief Transfer direction + * + * For master: transfer direction or setting direction bit in address. + * For slave: direction of request from master. + */ +enum i2c_transfer_direction { + I2C_TRANSFER_WRITE = 0, + I2C_TRANSFER_READ = 1, +}; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** + * \page asfdoc_sam0_sercom_i2c_extra_info_page Extra Information for SERCOM I2C Driver + * + * \section asfdoc_sam0_sercom_i2c_acronyms Acronyms + * \ref asfdoc_sam0_sercom_i2c_acronyms_table "Below" is a table listing the acronyms + * used in this module, along with their intended meanings. + * + * \anchor asfdoc_sam0_sercom_i2c_acronyms_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Acronyms
AcronymDescription
SDASerial Data Line
SCLSerial Clock Line
SERCOMSerial Communication Interface
DMADirect Memory Access
+ * + * \section asfdoc_sam0_sercom_i2c_extra_dependencies Dependencies + * The I2C driver has the following dependencies: + * \li \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" + * + * + * \section asfdoc_sam0_sercom_i2c_extra_errata Errata + * There are no errata related to this driver. + * + * \section asfdoc_sam0_sercom_i2c_extra_history Module History + * \ref asfdoc_sam0_sercom_i2c_extra_history_table "Below" is an overview of the + * module history, detailing enhancements and fixes made to the module since + * its first release. The current version of this corresponds to the newest + * version listed in + * \ref asfdoc_sam0_sercom_i2c_extra_history_table "the table below". + * + * \anchor asfdoc_sam0_sercom_i2c_extra_history_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Module History
Changelog
+ * \li Added 10-bit addressing and high speed support in SAM D21. + * \li Seperate structure i2c_packet into i2c_master_packet and i2c_slave packet. + *
+ * \li Added support for SCL stretch and extended timeout hardware features in SAM D21. + * \li Added fast mode plus support in SAM D21. + *
Fixed incorrect logical mask for determining if a bus error has + * occurred in I2C Slave mode. + *
Initial Release
+ */ + +/** + * \page asfdoc_sam0_sercom_i2c_exqsg Examples for SERCOM I2C Driver + * + * This is a list of the available Quick Start guides (QSGs) and example + * applications for \ref asfdoc_sam0_sercom_i2c_group. QSGs are simple examples with + * step-by-step instructions to configure and use this driver in a selection of + * use cases. Note that QSGs can be compiled as a standalone application or be + * added to the user application. + * + * \if I2C_MASTER_MODE + * - \subpage asfdoc_sam0_sercom_i2c_master_basic_use_case "Quick Start Guide for the I2C Master module - Basic Use Case" + * \endif + * \if I2C_MASTER_CALLBACK_MODE + * - \subpage asfdoc_sam0_sercom_i2c_master_callback_use_case "Quick Start Guide for the I2C Master module - Callback Use Case" + * - \subpage asfdoc_sam0_sercom_i2c_master_dma_use_case "Quick Start Guide for the I2C Master module - DMA Use Case" + * \endif + * \if I2C_SLAVE_MODE + * - \subpage asfdoc_sam0_sercom_i2c_slave_basic_use_case "Quick Start Guide for the I2C Slave module - Basic Use Case" + * \endif + * \if I2C_SLAVE_CALLBACK_MODE + * - \subpage asfdoc_sam0_sercom_i2c_slave_callback_use_case "Quick Start Guide for the I2C Slave module - Callback Use Case" + * - \subpage asfdoc_sam0_sercom_i2c_slave_dma_use_case "Quick Start Guide for the I2C Slave module - DMA Use Case" + * \endif + * + * \page asfdoc_sam0_sercom_i2c_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev. + * Date + * Comments + *
E03/2014Added SAM R21 support.
D03/2014Added 10-bit addressing and high speed support in SAM D21.
C01/2014Added the SAM D21 to the application note.
B06/2013Corrected documentation typos. Updated I2C Bus State Diagram.
A06/2013Initial release
+ */ + +#endif /* I2C_COMMON_H_INCLUDED */ diff --git a/loader/inc/sercom/i2c_master.h b/loader/inc/sercom/i2c_master.h new file mode 100644 index 0000000..cdf6df5 --- /dev/null +++ b/loader/inc/sercom/i2c_master.h @@ -0,0 +1,592 @@ +/** + * \file + * + * \brief SAM SERCOM I2C Master Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef I2C_MASTER_H_INCLUDED +#define I2C_MASTER_H_INCLUDED + +#include "samd20.h" +#include "sercom/i2c_common.h" +#include +#include + +#if I2C_MASTER_CALLBACK_MODE == true +# include +#endif + +#ifndef PINMUX_DEFAULT +# define PINMUX_DEFAULT 0 +#endif + +#include +#define Assert assert +/** + * \addtogroup asfdoc_sam0_sercom_i2c_group + * + * @{ + */ + +/** + * \brief I2C master packet for read/write + * + * Structure to be used when transferring I2C master packets. + */ +struct i2c_master_packet { + /** Address to slave device */ + uint16_t address; + /** Length of data array */ + uint16_t data_length; + /** Data array containing all data to be transferred */ + uint8_t *data; + /** Use 10 bit addressing. Set to false if the feature is not supported by the device */ + bool ten_bit_address; + /** Use high speed transfer. Set to false if the feature is not supported by the device */ + bool high_speed; + /** High speed mode master code (0000 1XXX), valid when high_speed is true */ + uint8_t hs_master_code; +}; + +/** \brief Interrupt flags + * + * Flags used when reading or setting interrupt flags. + */ +enum i2c_master_interrupt_flag { + /** Interrupt flag used for write */ + I2C_MASTER_INTERRUPT_WRITE = 0, + /** Interrupt flag used for read */ + I2C_MASTER_INTERRUPT_READ = 1, +}; + +/** + * \brief Values for hold time after start bit. + * + * Values for the possible I2C master mode SDA internal hold times after start + * bit has been sent. + */ +enum i2c_master_start_hold_time { + /** Internal SDA hold time disabled */ + I2C_MASTER_START_HOLD_TIME_DISABLED = SERCOM_I2CM_CTRLA_SDAHOLD(0), + /** Internal SDA hold time 50ns-100ns */ + I2C_MASTER_START_HOLD_TIME_50NS_100NS = SERCOM_I2CM_CTRLA_SDAHOLD(1), + /** Internal SDA hold time 300ns-600ns */ + I2C_MASTER_START_HOLD_TIME_300NS_600NS = SERCOM_I2CM_CTRLA_SDAHOLD(2), + /** Internal SDA hold time 400ns-800ns */ + I2C_MASTER_START_HOLD_TIME_400NS_800NS = SERCOM_I2CM_CTRLA_SDAHOLD(3), +}; + +/** + * \ brief Values for inactive bus time-out. + * + * If the inactive bus time-out is enabled and the bus is inactive for + * longer than the time-out setting, the bus state logic will be set to idle. + */ +enum i2c_master_inactive_timeout { + /** Inactive bus time-out disabled */ + I2C_MASTER_INACTIVE_TIMEOUT_DISABLED = SERCOM_I2CM_CTRLA_INACTOUT(0), + /** Inactive bus time-out 5-6 SCL cycle time-out (50-60us) */ + I2C_MASTER_INACTIVE_TIMEOUT_55US = SERCOM_I2CM_CTRLA_INACTOUT(1), + /** Inactive bus time-out 10-11 SCL cycle time-out (100-110us) */ + I2C_MASTER_INACTIVE_TIMEOUT_105US = SERCOM_I2CM_CTRLA_INACTOUT(2), + /** Inactive bus time-out 20-21 SCL cycle time-out (200-210us) */ + I2C_MASTER_INACTIVE_TIMEOUT_205US = SERCOM_I2CM_CTRLA_INACTOUT(3), +}; + +/** + * \brief I2C frequencies + * + * Values for I2C speeds supported by the module. The driver + * will also support setting any other value, in which case set + * the value in the \ref i2c_master_config at desired value divided by 1000. + * + * Example: If 10kHz operation is required, give baud_rate in the configuration + * structure the value 10. + */ +enum i2c_master_baud_rate { + /** Baud rate at 100kHz (Standard-mode) */ + I2C_MASTER_BAUD_RATE_100KHZ = 100, + /** Baud rate at 400kHz (Fast-mode) */ + I2C_MASTER_BAUD_RATE_400KHZ = 400, +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + /** Baud rate at 1MHz (Fast-mode Plus) */ + I2C_MASTER_BAUD_RATE_1000KHZ = 1000, + /** Baud rate at 3.4MHz (High-speed mode) */ + I2C_MASTER_BAUD_RATE_3400KHZ = 3400, +#endif +}; + +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED +/** + * \brief Enum for the transfer speed + * + * Enum for the transfer speed. + */ +enum i2c_master_transfer_speed { + /** Standard-mode (Sm) up to 100 kHz and Fast-mode (Fm) up to 400 kHz */ + I2C_MASTER_SPEED_STANDARD_AND_FAST = SERCOM_I2CM_CTRLA_SPEED(0), + /** Fast-mode Plus (Fm+) up to 1 MHz */ + I2C_MASTER_SPEED_FAST_MODE_PLUS = SERCOM_I2CM_CTRLA_SPEED(1), + /** High-speed mode (Hs-mode) up to 3.4 MHz */ + I2C_MASTER_SPEED_HIGH_SPEED = SERCOM_I2CM_CTRLA_SPEED(2), +}; +#endif + +#if I2C_MASTER_CALLBACK_MODE == true +/** + * \brief Callback types + * + * The available callback types for the I2C master module. + */ +enum i2c_master_callback { + /** Callback for packet write complete */ + I2C_MASTER_CALLBACK_WRITE_COMPLETE = 0, + /** Callback for packet read complete */ + I2C_MASTER_CALLBACK_READ_COMPLETE = 1, + /** Callback for error */ + I2C_MASTER_CALLBACK_ERROR = 2, +# if !defined(__DOXYGEN__) + /** Total number of callbacks */ + _I2C_MASTER_CALLBACK_N = 3, +# endif +}; + +# if !defined(__DOXYGEN__) +/* Prototype for software module. */ +struct i2c_master_module; + +typedef void (*i2c_master_callback_t)( + struct i2c_master_module *const module); +# endif +#endif + +/** + * \brief SERCOM I2C Master driver software device instance structure. + * + * SERCOM I2C Master driver software instance structure, used to + * retain software state information of an associated hardware module instance. + * + * \note The fields of this structure should not be altered by the user + * application; they are reserved for module-internal use only. + */ +struct i2c_master_module { +#if !defined(__DOXYGEN__) + /** Hardware instance initialized for the struct */ + Sercom *hw; + /** Module lock */ + volatile bool locked; + /** Unknown bus state timeout */ + uint16_t unknown_bus_state_timeout; + /** Buffer write timeout value */ + uint16_t buffer_timeout; + /** If true, stop condition will be sent after a read/write */ + bool send_stop; +# if I2C_MASTER_CALLBACK_MODE == true + /** Pointers to callback functions */ + volatile i2c_master_callback_t callbacks[_I2C_MASTER_CALLBACK_N]; + /** Mask for registered callbacks */ + volatile uint8_t registered_callback; + /** Mask for enabled callbacks */ + volatile uint8_t enabled_callback; + /** The total number of bytes to transfer */ + volatile uint16_t buffer_length; + /** + * Counter used for bytes left to send in write and to count number of + * obtained bytes in read + */ + volatile uint16_t buffer_remaining; + /** Data buffer for packet write and read */ + volatile uint8_t *buffer; + /** Save direction of async request. 1 = read, 0 = write */ + volatile enum i2c_transfer_direction transfer_direction; + /** Status for status read back in error callback */ + volatile enum status_code status; +# endif +#endif +}; + +/** + * \brief Configuration structure for the I2C Master device + * + * This is the configuration structure for the I2C Master device. It + * is used as an argument for \ref i2c_master_init to provide the desired + * configurations for the module. The structure should be initialized using the + * \ref i2c_master_get_config_defaults . + */ +struct i2c_master_config { + /** Baud rate (in KHZ) for I2C operations in + * standard-mode, Fast-mode and Fast-mode Plus Transfers, + * \ref i2c_master_baud_rate */ + uint32_t baud_rate; +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + /** Baud rate (in KHz) for I2C operations in + * High-speed mode, \ref i2c_master_baud_rate */ + uint32_t baud_rate_high_speed; + /** Transfer speed mode */ + enum i2c_master_transfer_speed transfer_speed; +#endif + /** GCLK generator to use as clock source */ + enum gclk_generator generator_source; + /** Bus hold time after start signal on data line */ + enum i2c_master_start_hold_time start_hold_time; + /** Unknown bus state \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "timeout" */ + uint16_t unknown_bus_state_timeout; + /** Timeout for packet write to wait for slave */ + uint16_t buffer_timeout; + /** Set to keep module active in sleep modes */ + bool run_in_standby; + /** PAD0 (SDA) pinmux */ + uint32_t pinmux_pad0; + /** PAD1 (SCL) pinmux */ + uint32_t pinmux_pad1; + /** Set to enable SCL low time-out */ + bool scl_low_timeout; + /** Inactive bus time out */ + enum i2c_master_inactive_timeout inactive_timeout; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + /** Set to enable SCL stretch only after ACK bit (required for high speed) */ + bool scl_stretch_only_after_ack_bit; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + /** Set to enable slave SCL low extend time-out */ + bool slave_scl_low_extend_timeout; + /** Set to enable maser SCL low extend time-out */ + bool master_scl_low_extend_timeout; +#endif +}; + +/** + * \name Lock/Unlock + * @{ + */ + +/** + * \brief Attempt to get lock on driver instance + * + * This function checks the instance's lock, which indicates whether or not it + * is currently in use, and sets the lock if it was not already set. + * + * The purpose of this is to enable exclusive access to driver instances, so + * that, e.g., transactions by different services will not interfere with each + * other. + * + * \param[in,out] module Pointer to the driver instance to lock. + * + * \retval STATUS_OK if the module was locked. + * \retval STATUS_BUSY if the module was already locked. + */ +static inline enum status_code i2c_master_lock( + struct i2c_master_module *const module) +{ + enum status_code status; + + system_interrupt_enter_critical_section(); + + if (module->locked) { + status = STATUS_BUSY; + } else { + module->locked = true; + status = STATUS_OK; + } + + system_interrupt_leave_critical_section(); + + return status; +} + +/** + * \brief Unlock driver instance + * + * This function clears the instance lock, indicating that it is available for + * use. + * + * \param[in,out] module Pointer to the driver instance to lock. + * + * \retval STATUS_OK if the module was locked. + * \retval STATUS_BUSY if the module was already locked. + */ +static inline void i2c_master_unlock(struct i2c_master_module *const module) +{ + module->locked = false; +} + +/** @} */ + +/** + * \name Configuration and Initialization + * @{ + */ + +/** + * \brief Returns the synchronization status of the module + * + * Returns the synchronization status of the module. + * + * \param[in] module Pointer to software module structure + * + * \return Status of the synchronization. + * \retval true Module is busy synchronizing + * \retval false Module is not synchronizing + */ +static inline bool i2c_master_is_syncing ( + const struct i2c_master_module *const module) +{ + /* Sanity check. */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_hw = &(module->hw->I2CM); + +#if defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1) + return (i2c_hw->STATUS.reg & SERCOM_I2CM_STATUS_SYNCBUSY); +#elif defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2) + return (i2c_hw->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK); +#else +# error Unknown SERCOM SYNCBUSY scheme! +#endif +} + +#if !defined(__DOXYGEN__) +/** + * \internal + * Wait for hardware module to sync + * + * \param[in] module Pointer to software module structure + */ +static void _i2c_master_wait_for_sync( + const struct i2c_master_module *const module) +{ + /* Sanity check. */ + Assert(module); + + while (i2c_master_is_syncing(module)) { + /* Wait for I2C module to sync. */ + } +} +#endif + +/** + * \brief Gets the I2C master default configurations + * + * Use to initialize the configuration structure to known default values. + * + * The default configuration is as follows: + * - Baudrate 100kHz + * - GCLK generator 0 + * - Do not run in standby + * - Start bit hold time 300ns-600ns + * - Buffer timeout = 65535 + * - Unknown bus status timeout = 65535 + * - Do not run in standby + * - PINMUX_DEFAULT for SERCOM pads + * + * Those default configuration only availale if the device supports it: + * - High speed baudrate 3.4MHz + * - Standard-mode and Fast-mode transfer speed + * - SCL stretch disabled + * - slave SCL low extend time-out disabled + * - maser SCL low extend time-out disabled + * + * \param[out] config Pointer to configuration structure to be initiated + */ +static inline void i2c_master_get_config_defaults( + struct i2c_master_config *const config) +{ + /*Sanity check argument. */ + Assert(config); + config->baud_rate = I2C_MASTER_BAUD_RATE_100KHZ; +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + config->baud_rate_high_speed = I2C_MASTER_BAUD_RATE_3400KHZ; + config->transfer_speed = I2C_MASTER_SPEED_STANDARD_AND_FAST; +#endif + config->generator_source = GCLK_GENERATOR_0; + config->run_in_standby = false; + config->start_hold_time = I2C_MASTER_START_HOLD_TIME_300NS_600NS; + config->buffer_timeout = 65535; + config->unknown_bus_state_timeout = 65535; + config->pinmux_pad0 = PINMUX_DEFAULT; + config->pinmux_pad1 = PINMUX_DEFAULT; + config->scl_low_timeout = false; + config->inactive_timeout = I2C_MASTER_INACTIVE_TIMEOUT_DISABLED; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + config->scl_stretch_only_after_ack_bit = false; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + config->slave_scl_low_extend_timeout = false; + config->master_scl_low_extend_timeout = false; +#endif +} + +enum status_code i2c_master_init( + struct i2c_master_module *const module, + Sercom *const hw, + const struct i2c_master_config *const config); + +/** + * \brief Enables the I2C module + * + * Enables the requested I2C module and set the bus state to IDLE + * after the specified \ref asfdoc_sam0_sercom_i2c_timeout "timeout" period if no + * stop bit is detected. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_master_enable( + const struct i2c_master_module *const module) +{ + /* Sanity check of arguments. */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Timeout counter used to force bus state. */ + uint32_t timeout_counter = 0; + + /* Wait for module to sync. */ + _i2c_master_wait_for_sync(module); + + /* Enable module. */ + i2c_module->CTRLA.reg |= SERCOM_I2CM_CTRLA_ENABLE; + +#if I2C_MASTER_CALLBACK_MODE == true + /* Enable module interrupts */ + system_interrupt_enable(_sercom_get_interrupt_vector(module->hw)); +#endif + /* Start timeout if bus state is unknown. */ + while (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(1))) { + timeout_counter++; + if(timeout_counter >= (module->unknown_bus_state_timeout)) { + /* Timeout, force bus state to idle. */ + i2c_module->STATUS.reg = SERCOM_I2CM_STATUS_BUSSTATE(1); + /* Workaround #1 */ + return; + } + } +} + +/** + * \brief Disable the I2C module + * + * Disables the requested I2C module. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_master_disable( + const struct i2c_master_module *const module) +{ + /* Sanity check of arguments. */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Wait for module to sync. */ + _i2c_master_wait_for_sync(module); + + /* Disable module. */ + i2c_module->CTRLA.reg &= ~SERCOM_I2CM_CTRLA_ENABLE; + +#if I2C_MASTER_CALLBACK_MODE == true + /* Disable module interrupts */ + system_interrupt_disable(_sercom_get_interrupt_vector(module->hw)); +#endif +} + +void i2c_master_reset(struct i2c_master_module *const module); + +/** @} */ + +/** +* \name Read and Write +* @{ +*/ + +enum status_code i2c_master_read_packet_wait( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet); + +enum status_code i2c_master_read_packet_wait_no_stop( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet); + +enum status_code i2c_master_write_packet_wait( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet); + +enum status_code i2c_master_write_packet_wait_no_stop( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet); + +void i2c_master_send_stop(struct i2c_master_module *const module); + +/** @} */ + +#ifdef FEATURE_I2C_DMA_SUPPORT +/** +* \name SERCOM I2C master with DMA interfaces +* @{ +*/ + +/** + * \brief Set I2C for DMA transfer with slave address and transfer size. + * + * This function will set the slave address, transfer size and enable the auto transfer + * mode for DMA. + * + * \param[in,out] module Pointer to the driver instance to lock. + * \param[in] addr I2C slave address + * \param[in] length I2C transfer length with DMA. + * \param[in] direction I2C transfer direction + * + */ +static inline void i2c_master_dma_set_transfer(struct i2c_master_module *const module, + uint16_t addr, uint8_t length, enum i2c_transfer_direction direction) +{ + module->hw->I2CM.ADDR.reg = + SERCOM_I2CM_ADDR_ADDR(addr<<1) | + SERCOM_I2CM_ADDR_LENEN | + SERCOM_I2CM_ADDR_LEN(length) | + direction; +} + +#endif + +#endif /* I2C_MASTER_H_INCLUDED */ diff --git a/loader/inc/sercom/old/i2c_common.h b/loader/inc/sercom/old/i2c_common.h new file mode 100644 index 0000000..9966c42 --- /dev/null +++ b/loader/inc/sercom/old/i2c_common.h @@ -0,0 +1,557 @@ +/** + * \file + * + * \brief SAM SERCOM I2C Common Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef I2C_COMMON_H_INCLUDED +#define I2C_COMMON_H_INCLUDED + +#include "sercom/sercom.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \if (I2C_MASTER_MODE && I2C_SLAVE_MODE) + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Driver (SERCOM I2C) + * \elseif I2C_MASTER_MODE + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Master Mode Driver (SERCOM I2C) + * \elseif I2C_SLAVE_MODE + * \defgroup asfdoc_sam0_sercom_i2c_group SAM D20/D21/R21 I2C Slave Mode Driver (SERCOM I2C) + * \endif + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the device's SERCOM I2C module, for the transfer + * of data via an I2C bus. The following driver API modes are covered + * by this manual: + * + * \if I2C_MASTER_MODE + * - Master Mode Polled APIs + * \endif + * \if I2C_MASTER_CALLBACK_MODE + * - Master Mode Callback APIs + * \endif + * \if I2C_SLAVE_MODE + * - Slave Mode Polled APIs + * \endif + * \if I2C_SLAVE_CALLBACK_MODE + * - Slave Mode Callback APIs + * \endif + * + * The following peripheral is used by this module: + * + * - SERCOM (Serial Communication Interface) + * + * The outline of this documentation is as follows: + * - \ref asfdoc_sam0_sercom_i2c_prerequisites + * - \ref asfdoc_sam0_sercom_i2c_overview + * - \ref asfdoc_sam0_sercom_i2c_special_considerations + * - \ref asfdoc_sam0_sercom_i2c_extra + * - \ref asfdoc_sam0_sercom_i2c_examples + * - \ref asfdoc_sam0_sercom_i2c_api_overview + * + * \section asfdoc_sam0_sercom_i2c_prerequisites Prerequisites + * There are no prerequisites. + * + * \section asfdoc_sam0_sercom_i2c_overview Module Overview + * The outline of this section is as follows: + * - \ref asfdoc_sam0_sercom_i2c_module_features + * - \ref asfdoc_sam0_sercom_i2c_functional_desc + * - \ref asfdoc_sam0_sercom_i2c_bus_topology + * - \ref asfdoc_sam0_sercom_i2c_transactions + * - \ref asfdoc_sam0_sercom_i2c_multi_master + * - \ref asfdoc_sam0_sercom_i2c_bus_states + * - \ref asfdoc_sam0_sercom_i2c_timeout + * - \ref asfdoc_sam0_sercom_i2c_sleep_modes + * + * \subsection asfdoc_sam0_sercom_i2c_module_features Driver Feature Macro Definition + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Driver Feature MacroSupported devices
FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEEDSAM D21/R21
FEATURE_I2C_10_BIT_ADDRESSSAM D21/R21
FEATURE_I2C_SCL_STRETCH_MODESAM D21/R21
FEATURE_I2C_SCL_EXTEND_TIMEOUTSAM D21/R21
+ * \note The specific features are only available in the driver when the + * selected device supports those features. + * + * \subsection asfdoc_sam0_sercom_i2c_functional_desc Functional Description + * The I2C provides a simple two-wire bidirectional bus consisting of a + * wired-AND type serial clock line (SCL) and a wired-AND type serial data line + * (SDA). + * + * The I2C bus provides a simple, but efficient method of interconnecting + * multiple master and slave devices. An arbitration mechanism is provided for + * resolving bus ownership between masters, as only one master device may own + * the bus at any given time. The arbitration mechanism relies on the wired-AND + * connections to avoid bus drivers short-circuiting. + * + * A unique address is assigned to all slave devices connected to the bus. A + * device can contain both master and slave logic, and can emulate multiple + * slave devices by responding to more than one address. + * + * \subsection asfdoc_sam0_sercom_i2c_bus_topology Bus Topology + * The I2C bus topology is illustrated in + * \ref asfdoc_sam0_sercom_i2c_bus_topology_figure "the figure below". The pull-up + * resistors (Rs) will provide a high level on the bus lines when none of the + * I2C devices are driving the bus. These are optional, and can be + * replaced with a constant current source. + * + * \anchor asfdoc_sam0_sercom_i2c_bus_topology_figure + * \image html bus_topology.svg "I2C bus topology" width=100% + * + * \subsection asfdoc_sam0_sercom_i2c_transactions Transactions + * The I2C standard defines three fundamental transaction formats: + * - Master Write + * - The master transmits data packets to the slave after addressing it + * - Master Read + * - The slave transmits data packets to the master after being addressed + * - Combined Read/Write + * - A combined transaction consists of several write and read transactions + * + * A data transfer starts with the master issuing a \b Start condition on the + * bus, followed by the address of the slave together with a bit to indicate + * whether the master wants to read from or write to the slave. + * The addressed slave must respond to this by sending an \b ACK back to the + * master. + * + * After this, data packets are sent from the master or slave, according to the + * read/write bit. Each packet must be acknowledged (ACK) or not + * acknowledged (NACK) by the receiver. + * + * If a slave responds with a NACK, the master must assume that the slave + * cannot receive any more data and cancel the write operation. + * + * The master completes a transaction by issuing a \b Stop condition. + * + * A master can issue multiple \b Start conditions during a transaction; this + * is then called a \b Repeated \b Start condition. + * + * \subsubsection asfdoc_sam0_sercom_i2c_address_packets Address Packets + * The slave address consists of seven bits. The 8th bit in the transfer + * determines the data direction (read or write). An address packet always + * succeeds a \b Start or \b Repeated \b Start condition. The 8th bit is handled + * in the driver, and the user will only have to provide the 7 bit address. + * + * \subsubsection asfdoc_sam0_sercom_i2c_data_packets Data Packets + * Data packets are nine bits long, consisting of one 8-bit data byte, and an + * acknowledgement bit. Data packets follow either an address packet or another + * data packet on the bus. + * + * \subsubsection asfdoc_sam0_sercom_i2c_trans_examples Transaction Examples + * The gray bits in the following examples are sent from master to slave, and + * the white bits are sent from slave to master. + * Example of a read transaction is shown in + * \ref asfdoc_sam0_sercom_i2c_trans_examples_i2c_read "the figure below". Here, the + * master first issues a \b Start condition and gets ownership of the bus. An + * address packet with the direction flag set to read is then sent and + * acknowledged by the slave. Then the slave sends one data packet which is + * acknowledged by the master. The slave sends another packet, which is not + * acknowledged by the master and indicates that the master will terminate the + * transaction. In the end, the transaction is terminated by the master issuing + * a \b Stop condition. + * + * \anchor asfdoc_sam0_sercom_i2c_trans_examples_i2c_read + * \image html i2c_read.svg "I2C Packet Read" width=100% + * + * Example of a write transaction is shown in + * \ref asfdoc_sam0_sercom_i2c_trans_examples_i2c_write "the figure below". Here, the + * master first issues a \b Start condition and gets ownership of the bus. An + * address packet with the dir flag set to write is then sent and acknowledged + * by the slave. Then the master sends two data packets, each acknowledged by + * the slave. In the end, the transaction is terminated by the master issuing + * a \b Stop condition. + * + * \anchor asfdoc_sam0_sercom_i2c_trans_examples_i2c_write + * \image html i2c_write.svg "I2C Packet Write" width=100% + * + * \subsubsection asfdoc_sam0_sercom_i2c_packet_timeout Packet Timeout + * When a master sends an I2C packet, there is no way of + * being sure that a slave will acknowledge the packet. To avoid stalling the + * device forever while waiting for an acknowledge, a user selectable timeout + * is provided in the \ref i2c_master_config struct which + * lets the driver exit a read or write operation after the specified time. + * The function will then return the STATUS_ERR_TIMEOUT flag. + * + * This is also the case for the slave when using the functions postfixed + * \c _wait. + * + * The time before the timeout occurs, will be the same as + * for \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "unknown bus state" timeout. + * + * \subsubsection asfdoc_sam0_sercom_i2c_repeated_start Repeated Start + * To issue a \b Repeated \b Start, the functions postfixed \c _no_stop must be + * used. + * These functions will not send a \b Stop condition when the transfer is done, + * thus the next transfer will start with a \b Repeated \b Start. To end the + * transaction, the functions without the \c _no_stop postfix must be used + * for the last read/write. + * + * \subsection asfdoc_sam0_sercom_i2c_multi_master Multi Master + * In a multi master environment, arbitration of the bus is important, as only + * one master can own the bus at any point. + * + * \subsubsection asfdoc_sam0_sercom_i2c_arbitration Arbitration + * + * \par Clock stretching + * The serial clock line is always driven by a master device. However, all + * devices connected to the bus are allowed stretch the low period of the clock + * to slow down the overall clock frequency or to insert wait states while + * processing data. + * Both master and slave can randomly stretch the clock, which will force the + * other device into a wait-state until the clock line goes high again. + * + * \par Arbitration on the data line + * If two masters start transmitting at the same time, they will both transmit + * until one master detects that the other master is pulling the data line low. + * When this is detected, the master not pulling the line low, will stop the + * transmission and wait until the bus is idle. + * As it is the master trying to contact the slave with the lowest address that + * will get the bus ownership, this will create an arbitration scheme always + * prioritizing the slaves with the lowest address in case of a bus collision. + * + * \subsubsection asfdoc_sam0_sercom_i2c_clock_sync Clock Synchronization + * In situations where more than one master is trying to control the bus clock + * line at the same time, a clock synchronization algorithm based on the same + * principles used for clock stretching is necessary. + * + * + * \subsection asfdoc_sam0_sercom_i2c_bus_states Bus States + * As the I2C bus is limited to one transaction at the time, + * a master that wants to perform a bus transaction must wait until the bus is + * free. + * Because of this, it is necessary for all masters in a multi-master system to + * know the current status of the bus to be able to avoid conflicts and to + * ensure data integrity. + * \li \b IDLE No activity on the bus (between a \b Stop and a new \b Start + * condition) + * \li \b OWNER If the master initiates a transaction successfully + * \li \b BUSY If another master is driving the bus + * \li \b UNKNOWN If the master has recently been enabled or connected to + * the bus. Is forced to \b IDLE after given + * \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "timeout" when + * the master module is enabled. + * + * The bus state diagram can be seen in + * \ref asfdoc_sam0_sercom_i2c_bus_states_figure "the figure below". + * \li S: Start condition + * \li P: Stop condition + * \li Sr: Repeated start condition + * \anchor asfdoc_sam0_sercom_i2c_bus_states_figure + * \image html bus_state_diagram.svg "I2C bus state diagram" width=100% + * + * \subsection asfdoc_sam0_sercom_i2c_timeout Bus Timing + * Inactive bus timeout for the master and SDA hold time is configurable in the + * drivers. + * + * \subsubsection asfdoc_sam0_sercom_i2c_unknown_bus_timeout Unknown Bus State Timeout + * When a master is enabled or connected to the bus, the bus state will be + * unknown until either a given timeout or a stop command has occurred. The + * timeout is configurable in the \ref i2c_master_config struct. + * The timeout time will depend on toolchain and optimization level used, as + * the timeout is a loop incrementing a value until it reaches the specified + * timeout value. + * + * \subsubsection sda_hold SDA Hold Timeout + * When using the I2C in slave mode, it will be important to + * set a SDA hold time which assures that the master will be able to pick up + * the bit sent from the slave. The SDA hold time makes sure that this is the + * case by holding the data line low for a given period after the negative edge + * on the clock. + * + * The SDA hold time is also available for the master driver, but is not a + * necessity. + * + * \subsection asfdoc_sam0_sercom_i2c_sleep_modes Operation in Sleep Modes + * The I2C module can operate in all sleep modes by setting + * the run_in_standby boolean in the \ref i2c_master_config or + * \ref i2c_slave_config struct. + * The operation in slave and master mode is shown in + * \ref asfdoc_sam0_sercom_i2c_sleep_modes_table "the table below". + * + * \anchor asfdoc_sam0_sercom_i2c_sleep_modes_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
I2C standby operations
Run in standbySlaveMaster
falseDisabled, all reception is droppedGCLK disabled when master is idle
trueWake on address match when enabledGCLK enabled while in sleep modes
+ * + * + * \section asfdoc_sam0_sercom_i2c_special_considerations Special Considerations + * + * \if (I2C_MASTER_CALLBACK_MODE || I2C_SLAVE_CALLBACK_MODE) + * \subsection asfdoc_sam0_sercom_i2c_common_interrupt Interrupt-Driven Operation + * While an interrupt-driven operation is in progress, subsequent calls to a + * write or read operation will return the STATUS_BUSY flag, indicating that + * only one operation is allowed at any given time. + * + * To check if another transmission can be initiated, the user can either call + * another transfer operation, or use the + * \ref i2c_master_get_job_status/\ref i2c_slave_get_job_status functions + * depending on mode. + * + * If the user would like to get callback from operations while using the + * interrupt-driven driver, the callback must be registered and then enabled + * using the "register_callback" and "enable_callback" functions. + * \else + * There are no special considerations for this driver for the APIs listed in + * this document. + * \endif + * + * \section asfdoc_sam0_sercom_i2c_extra Extra Information + * For extra information see \ref asfdoc_sam0_sercom_i2c_extra_info_page. + * This includes: + * - \ref asfdoc_sam0_sercom_i2c_acronyms + * - \ref asfdoc_sam0_sercom_i2c_extra_dependencies + * - \ref asfdoc_sam0_sercom_i2c_extra_errata + * - \ref asfdoc_sam0_sercom_i2c_extra_history + * + * \section asfdoc_sam0_sercom_i2c_examples Examples + * + * For a list of examples related to this driver, see + * \ref asfdoc_sam0_sercom_i2c_exqsg. + * + * \section asfdoc_sam0_sercom_i2c_api_overview API Overview + * @{ + */ + +/** + * \name Driver feature definition + * Define SERCOME I2C driver features set according to different device family. + * + * \note The high speed mode and 10-bit address feature are not + * supported by the driver now. + * @{ + */ +#if (SAMD21) || (SAMR21) || defined(__DOXYGEN__) +/** Fast mode plus and high speed support */ +# define FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED +/** 10 bit address support */ +# define FEATURE_I2C_10_BIT_ADDRESS +/** SCL stretch mode support */ +# define FEATURE_I2C_SCL_STRETCH_MODE +/** SCL extend timeout support */ +# define FEATURE_I2C_SCL_EXTEND_TIMEOUT +# define FEATURE_I2C_DMA_SUPPORT +#endif +/*@}*/ + +/** \brief Transfer direction + * + * For master: transfer direction or setting direction bit in address. + * For slave: direction of request from master. + */ + enum i2c_transfer_direction { + I2C_TRANSFER_WRITE = 0, + I2C_TRANSFER_READ = 1, + }; + +/** @} */ + +#ifdef __cplusplus +} +#endif + +/** + * \page asfdoc_sam0_sercom_i2c_extra_info_page Extra Information for SERCOM I2C Driver + * + * \section asfdoc_sam0_sercom_i2c_acronyms Acronyms + * \ref asfdoc_sam0_sercom_i2c_acronyms_table "Below" is a table listing the acronyms + * used in this module, along with their intended meanings. + * + * \anchor asfdoc_sam0_sercom_i2c_acronyms_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Acronyms
AcronymDescription
SDASerial Data Line
SCLSerial Clock Line
SERCOMSerial Communication Interface
DMADirect Memory Access
+ * + * \section asfdoc_sam0_sercom_i2c_extra_dependencies Dependencies + * The I2C driver has the following dependencies: + * \li \ref asfdoc_sam0_system_pinmux_group "System Pin Multiplexer Driver" + * + * + * \section asfdoc_sam0_sercom_i2c_extra_errata Errata + * There are no errata related to this driver. + * + * \section asfdoc_sam0_sercom_i2c_extra_history Module History + * \ref asfdoc_sam0_sercom_i2c_extra_history_table "Below" is an overview of the + * module history, detailing enhancements and fixes made to the module since + * its first release. The current version of this corresponds to the newest + * version listed in + * \ref asfdoc_sam0_sercom_i2c_extra_history_table "the table below". + * + * \anchor asfdoc_sam0_sercom_i2c_extra_history_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Module History
Changelog
+ * \li Added 10-bit addressing and high speed support in SAM D21. + * \li Seperate structure i2c_packet into i2c_master_packet and i2c_slave packet. + *
+ * \li Added support for SCL stretch and extended timeout hardware features in SAM D21. + * \li Added fast mode plus support in SAM D21. + *
Fixed incorrect logical mask for determining if a bus error has + * occurred in I2C Slave mode. + *
Initial Release
+ */ + +/** + * \page asfdoc_sam0_sercom_i2c_exqsg Examples for SERCOM I2C Driver + * + * This is a list of the available Quick Start guides (QSGs) and example + * applications for \ref asfdoc_sam0_sercom_i2c_group. QSGs are simple examples with + * step-by-step instructions to configure and use this driver in a selection of + * use cases. Note that QSGs can be compiled as a standalone application or be + * added to the user application. + * + * \if I2C_MASTER_MODE + * - \subpage asfdoc_sam0_sercom_i2c_master_basic_use_case "Quick Start Guide for the I2C Master module - Basic Use Case" + * \endif + * \if I2C_MASTER_CALLBACK_MODE + * - \subpage asfdoc_sam0_sercom_i2c_master_callback_use_case "Quick Start Guide for the I2C Master module - Callback Use Case" + * - \subpage asfdoc_sam0_sercom_i2c_master_dma_use_case "Quick Start Guide for the I2C Master module - DMA Use Case" + * \endif + * \if I2C_SLAVE_MODE + * - \subpage asfdoc_sam0_sercom_i2c_slave_basic_use_case "Quick Start Guide for the I2C Slave module - Basic Use Case" + * \endif + * \if I2C_SLAVE_CALLBACK_MODE + * - \subpage asfdoc_sam0_sercom_i2c_slave_callback_use_case "Quick Start Guide for the I2C Slave module - Callback Use Case" + * - \subpage asfdoc_sam0_sercom_i2c_slave_dma_use_case "Quick Start Guide for the I2C Slave module - DMA Use Case" + * \endif + * + * \page asfdoc_sam0_sercom_i2c_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev. + * Date + * Comments + *
E03/2014Added SAM R21 support.
D03/2014Added 10-bit addressing and high speed support in SAM D21.
C01/2014Added the SAM D21 to the application note.
B06/2013Corrected documentation typos. Updated I2C Bus State Diagram.
A06/2013Initial release
+ */ + +#endif /* I2C_COMMON_H_INCLUDED */ diff --git a/loader/inc/sercom/old/i2c_master.h b/loader/inc/sercom/old/i2c_master.h new file mode 100644 index 0000000..b53ba8f --- /dev/null +++ b/loader/inc/sercom/old/i2c_master.h @@ -0,0 +1,593 @@ +/** + * \file + * + * \brief SAM SERCOM I2C Master Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef I2C_MASTER_H_INCLUDED +#define I2C_MASTER_H_INCLUDED + +#include "sercom/i2c_common.h" +#include "sercom/sercom.h" +#include "system/pinmux.h" +#include "system/gclk.h" + +#if I2C_MASTER_CALLBACK_MODE == true +# include +#endif + +#ifndef PINMUX_DEFAULT +# define PINMUX_DEFAULT 0 +#endif + +enum i2c_status_code { + I2C_STATUS_OK, + I2C_STATUS_BUSY, + I2C_STATUS_ERR_BAUDRATE_UNAVAILABLE, + I2C_STATUS_ERR_DENIED, + I2C_STATUS_ERR_PACKET_COLLISION, + I2C_STATUS_ERR_BAD_ADDRESS, + I2C_STATUS_ERR_TIMEOUT, + I2C_STATUS_ERR_OVERFLOW, +}; + +/** + * \addtogroup asfdoc_sam0_sercom_i2c_group + * + */ + +/** + * \brief I2C master packet for read/write + * + * Structure to be used when transferring I2C master packets. + */ +struct i2c_master_packet { + /** Address to slave device */ + uint16_t address; + /** Length of data array */ + uint16_t data_length; + /** Data array containing all data to be transferred */ + uint8_t *data; + /** Use 10 bit addressing. Set to false if the feature is not supported by the device */ + bool ten_bit_address; + /** Use high speed transfer. Set to false if the feature is not supported by the device */ + bool high_speed; + /** High speed mode master code (0000 1XXX), valid when high_speed is true */ + uint8_t hs_master_code; +}; + +/** \brief Interrupt flags + * + * Flags used when reading or setting interrupt flags. + */ +enum i2c_master_interrupt_flag { + /** Interrupt flag used for write */ + I2C_MASTER_INTERRUPT_WRITE = 0, + /** Interrupt flag used for read */ + I2C_MASTER_INTERRUPT_READ = 1, +}; + +/** + * \brief Values for hold time after start bit. + * + * Values for the possible I2C master mode SDA internal hold times after start + * bit has been sent. + */ +enum i2c_master_start_hold_time { + /** Internal SDA hold time disabled */ + I2C_MASTER_START_HOLD_TIME_DISABLED = SERCOM_I2CM_CTRLA_SDAHOLD(0), + /** Internal SDA hold time 50ns-100ns */ + I2C_MASTER_START_HOLD_TIME_50NS_100NS = SERCOM_I2CM_CTRLA_SDAHOLD(1), + /** Internal SDA hold time 300ns-600ns */ + I2C_MASTER_START_HOLD_TIME_300NS_600NS = SERCOM_I2CM_CTRLA_SDAHOLD(2), + /** Internal SDA hold time 400ns-800ns */ + I2C_MASTER_START_HOLD_TIME_400NS_800NS = SERCOM_I2CM_CTRLA_SDAHOLD(3), +}; + +/** + * \ brief Values for inactive bus time-out. + * + * If the inactive bus time-out is enabled and the bus is inactive for + * longer than the time-out setting, the bus state logic will be set to idle. + */ +enum i2c_master_inactive_timeout { + /** Inactive bus time-out disabled */ + I2C_MASTER_INACTIVE_TIMEOUT_DISABLED = SERCOM_I2CM_CTRLA_INACTOUT(0), + /** Inactive bus time-out 5-6 SCL cycle time-out (50-60us) */ + I2C_MASTER_INACTIVE_TIMEOUT_55US = SERCOM_I2CM_CTRLA_INACTOUT(1), + /** Inactive bus time-out 10-11 SCL cycle time-out (100-110us) */ + I2C_MASTER_INACTIVE_TIMEOUT_105US = SERCOM_I2CM_CTRLA_INACTOUT(2), + /** Inactive bus time-out 20-21 SCL cycle time-out (200-210us) */ + I2C_MASTER_INACTIVE_TIMEOUT_205US = SERCOM_I2CM_CTRLA_INACTOUT(3), +}; + +/** + * \brief I2C frequencies + * + * Values for I2C speeds supported by the module. The driver + * will also support setting any other value, in which case set + * the value in the \ref i2c_master_config at desired value divided by 1000. + * + * Example: If 10kHz operation is required, give baud_rate in the configuration + * structure the value 10. + */ +enum i2c_master_baud_rate { + /** Baud rate at 100kHz (Standard-mode) */ + I2C_MASTER_BAUD_RATE_100KHZ = 100, + /** Baud rate at 400kHz (Fast-mode) */ + I2C_MASTER_BAUD_RATE_400KHZ = 400, +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + /** Baud rate at 1MHz (Fast-mode Plus) */ + I2C_MASTER_BAUD_RATE_1000KHZ = 1000, + /** Baud rate at 3.4MHz (High-speed mode) */ + I2C_MASTER_BAUD_RATE_3400KHZ = 3400, +#endif +}; + +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED +/** + * \brief Enum for the transfer speed + * + * Enum for the transfer speed. + */ +enum i2c_master_transfer_speed { + /** Standard-mode (Sm) up to 100 kHz and Fast-mode (Fm) up to 400 kHz */ + I2C_MASTER_SPEED_STANDARD_AND_FAST = SERCOM_I2CM_CTRLA_SPEED(0), + /** Fast-mode Plus (Fm+) up to 1 MHz */ + I2C_MASTER_SPEED_FAST_MODE_PLUS = SERCOM_I2CM_CTRLA_SPEED(1), + /** High-speed mode (Hs-mode) up to 3.4 MHz */ + I2C_MASTER_SPEED_HIGH_SPEED = SERCOM_I2CM_CTRLA_SPEED(2), +}; +#endif + +#if I2C_MASTER_CALLBACK_MODE == true +/** + * \brief Callback types + * + * The available callback types for the I2C master module. + */ +enum i2c_master_callback { + /** Callback for packet write complete */ + I2C_MASTER_CALLBACK_WRITE_COMPLETE = 0, + /** Callback for packet read complete */ + I2C_MASTER_CALLBACK_READ_COMPLETE = 1, + /** Callback for error */ + I2C_MASTER_CALLBACK_ERROR = 2, +# if !defined(__DOXYGEN__) + /** Total number of callbacks */ + _I2C_MASTER_CALLBACK_N = 3, +# endif +}; + +# if !defined(__DOXYGEN__) +/* Prototype for software module. */ +struct i2c_master_module; + +typedef void (*i2c_master_callback_t)( + struct i2c_master_module *const module); +# endif +#endif + +/** + * \brief SERCOM I2C Master driver software device instance structure. + * + * SERCOM I2C Master driver software instance structure, used to + * retain software state information of an associated hardware module instance. + * + * \note The fields of this structure should not be altered by the user + * application; they are reserved for module-internal use only. + */ +struct i2c_master_module { +#if !defined(__DOXYGEN__) + /** Hardware instance initialized for the struct */ + Sercom *hw; + /** Module lock */ + volatile bool locked; + /** Unknown bus state timeout */ + uint16_t unknown_bus_state_timeout; + /** Buffer write timeout value */ + uint16_t buffer_timeout; + /** If true, stop condition will be sent after a read/write */ + bool send_stop; +# if I2C_MASTER_CALLBACK_MODE == true + /** Pointers to callback functions */ + volatile i2c_master_callback_t callbacks[_I2C_MASTER_CALLBACK_N]; + /** Mask for registered callbacks */ + volatile uint8_t registered_callback; + /** Mask for enabled callbacks */ + volatile uint8_t enabled_callback; + /** The total number of bytes to transfer */ + volatile uint16_t buffer_length; + /** + * Counter used for bytes left to send in write and to count number of + * obtained bytes in read + */ + volatile uint16_t buffer_remaining; + /** Data buffer for packet write and read */ + volatile uint8_t *buffer; + /** Save direction of async request. 1 = read, 0 = write */ + volatile enum i2c_transfer_direction transfer_direction; + /** Status for status read back in error callback */ + volatile enum i2c_status_code status; +# endif +#endif +}; + +extern struct i2c_master_module module_instance; +extern struct i2c_master_module *const module; + +/** + * \brief Configuration structure for the I2C Master device + * + * This is the configuration structure for the I2C Master device. It + * is used as an argument for \ref i2c_master_init to provide the desired + * configurations for the module. The structure should be initialized using the + * \ref i2c_master_get_config_defaults . + */ +struct i2c_master_config { + /** Baud rate (in KHZ) for I2C operations in + * standard-mode, Fast-mode and Fast-mode Plus Transfers, + * \ref i2c_master_baud_rate */ + uint32_t baud_rate; +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + /** Baud rate (in KHz) for I2C operations in + * High-speed mode, \ref i2c_master_baud_rate */ + uint32_t baud_rate_high_speed; + /** Transfer speed mode */ + enum i2c_master_transfer_speed transfer_speed; +#endif + /** GCLK generator to use as clock source */ + enum gclk_generator generator_source; + /** Bus hold time after start signal on data line */ + enum i2c_master_start_hold_time start_hold_time; + /** Unknown bus state \ref asfdoc_sam0_sercom_i2c_unknown_bus_timeout "timeout" */ + uint16_t unknown_bus_state_timeout; + /** Timeout for packet write to wait for slave */ + uint16_t buffer_timeout; + /** Set to keep module active in sleep modes */ + bool run_in_standby; + /** PAD0 (SDA) pinmux */ + uint32_t pinmux_pad0; + /** PAD1 (SCL) pinmux */ + uint32_t pinmux_pad1; + /** Set to enable SCL low time-out */ + bool scl_low_timeout; + /** Inactive bus time out */ + enum i2c_master_inactive_timeout inactive_timeout; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + /** Set to enable SCL stretch only after ACK bit (required for high speed) */ + bool scl_stretch_only_after_ack_bit; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + /** Set to enable slave SCL low extend time-out */ + bool slave_scl_low_extend_timeout; + /** Set to enable maser SCL low extend time-out */ + bool master_scl_low_extend_timeout; +#endif +}; + +/** + * \name Lock/Unlock + */ + +/** + * \brief Attempt to get lock on driver instance + * + * This function checks the instance's lock, which indicates whether or not it + * is currently in use, and sets the lock if it was not already set. + * + * The purpose of this is to enable exclusive access to driver instances, so + * that, e.g., transactions by different services will not interfere with each + * other. + * + * \param[in,out] module Pointer to the driver instance to lock. + * + * \retval I2C_STATUS_OK if the module was locked. + * \retval I2C_STATUS_BUSY if the module was already locked. + */ +static inline enum i2c_status_code i2c_master_lock(void) +{ + enum i2c_status_code status; + + system_interrupt_enter_critical_section(); + + if (module->locked) { + status = I2C_STATUS_BUSY; + } else { + module->locked = true; + status = I2C_STATUS_OK; + } + + system_interrupt_leave_critical_section(); + + return status; +} + +/** + * \brief Unlock driver instance + * + * This function clears the instance lock, indicating that it is available for + * use. + * + * \param[in,out] module Pointer to the driver instance to lock. + * + * \retval I2C_STATUS_OK if the module was locked. + * \retval I2C_STATUS_BUSY if the module was already locked. + */ +static inline void i2c_master_unlock(void) +{ + module->locked = false; +} + + +/** + * \name Configuration and Initialization + */ + +/** + * \brief Returns the synchronization status of the module + * + * Returns the synchronization status of the module. + * + * \param[in] module Pointer to software module structure + * + * \return Status of the synchronization. + * \retval true Module is busy synchronizing + * \retval false Module is not synchronizing + */ +static inline bool i2c_master_is_syncing ( + void) +{ + /* Sanity check. */ + assert(module); + assert(module->hw); + + SercomI2cm *const i2c_hw = &(module->hw->I2CM); + +#if defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1) + return (i2c_hw->STATUS.reg & SERCOM_I2CM_STATUS_SYNCBUSY); +#elif defined(FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2) + return (i2c_hw->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK); +#else +# error Unknown SERCOM SYNCBUSY scheme! +#endif +} + +#if !defined(__DOXYGEN__) +/** + * \internal + * Wait for hardware module to sync + * + * \param[in] module Pointer to software module structure + */ +static void _i2c_master_wait_for_sync( + void) +{ + /* Sanity check. */ + assert(module); + + while (i2c_master_is_syncing()) { + /* Wait for I2C module to sync. */ + } +} +#endif + +/** + * \brief Gets the I2C master default configurations + * + * Use to initialize the configuration structure to known default values. + * + * The default configuration is as follows: + * - Baudrate 100kHz + * - GCLK generator 0 + * - Do not run in standby + * - Start bit hold time 300ns-600ns + * - Buffer timeout = 65535 + * - Unknown bus status timeout = 65535 + * - Do not run in standby + * - PINMUX_DEFAULT for SERCOM pads + * + * Those default configuration only availale if the device supports it: + * - High speed baudrate 3.4MHz + * - Standard-mode and Fast-mode transfer speed + * - SCL stretch disabled + * - slave SCL low extend time-out disabled + * - maser SCL low extend time-out disabled + * + * \param[out] config Pointer to configuration structure to be initiated + */ +static inline void i2c_master_get_config_defaults( + struct i2c_master_config *const config) +{ + /*Sanity check argument. */ + assert(config); + config->baud_rate = I2C_MASTER_BAUD_RATE_100KHZ; +#ifdef FEATURE_I2C_FAST_MODE_PLUS_AND_HIGH_SPEED + config->baud_rate_high_speed = I2C_MASTER_BAUD_RATE_3400KHZ; + config->transfer_speed = I2C_MASTER_SPEED_STANDARD_AND_FAST; +#endif + config->generator_source = GCLK_GENERATOR_0; + config->run_in_standby = false; + config->start_hold_time = I2C_MASTER_START_HOLD_TIME_300NS_600NS; + config->buffer_timeout = 65535; + config->unknown_bus_state_timeout = 65535; + config->pinmux_pad0 = PINMUX_DEFAULT; + config->pinmux_pad1 = PINMUX_DEFAULT; + config->scl_low_timeout = false; + config->inactive_timeout = I2C_MASTER_INACTIVE_TIMEOUT_DISABLED; +#ifdef FEATURE_I2C_SCL_STRETCH_MODE + config->scl_stretch_only_after_ack_bit = false; +#endif +#ifdef FEATURE_I2C_SCL_EXTEND_TIMEOUT + config->slave_scl_low_extend_timeout = false; + config->master_scl_low_extend_timeout = false; +#endif +} + +enum i2c_status_code i2c_master_init( + + SercomI2cm *const hw, + const struct i2c_master_config *const config); + +/** + * \brief Enables the I2C module + * + * Enables the requested I2C module and set the bus state to IDLE + * after the specified \ref asfdoc_sam0_sercom_i2c_timeout "timeout" period if no + * stop bit is detected. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_master_enable(void + ) +{ + /* Sanity check of arguments. */ + assert(module); + assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Timeout counter used to force bus state. */ + uint32_t timeout_counter = 0; + + /* Wait for module to sync. */ + _i2c_master_wait_for_sync(); + + /* Enable module. */ + i2c_module->CTRLA.reg |= SERCOM_I2CM_CTRLA_ENABLE; + +#if I2C_MASTER_CALLBACK_MODE == true + /* Enable module interrupts */ + system_interrupt_enable(_sercom_get_interrupt_vector(module->hw)); +#endif + /* Start timeout if bus state is unknown. */ + while (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(1))) { + timeout_counter++; + if(timeout_counter >= (module->unknown_bus_state_timeout)) { + /* Timeout, force bus state to idle. */ + i2c_module->STATUS.reg = SERCOM_I2CM_STATUS_BUSSTATE(1); + /* Workaround #1 */ + return; + } + } +} + +/** + * \brief Disable the I2C module + * + * Disables the requested I2C module. + * + * \param[in] module Pointer to the software module struct + */ +static inline void i2c_master_disable( + ) +{ + /* Sanity check of arguments. */ + assert(module); + assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Wait for module to sync. */ + _i2c_master_wait_for_sync(); + + /* Disable module. */ + i2c_module->CTRLA.reg &= ~SERCOM_I2CM_CTRLA_ENABLE; + +#if I2C_MASTER_CALLBACK_MODE == true + /* Disable module interrupts */ + system_interrupt_disable(_sercom_get_interrupt_vector(module->hw)); +#endif +} + +void i2c_master_reset(); + +/** + * \name Read and Write + */ + +enum i2c_status_code i2c_master_read_packet_wait( + + struct i2c_master_packet *const packet); + +enum i2c_status_code i2c_master_read_packet_wait_no_stop( + + struct i2c_master_packet *const packet); + +enum i2c_status_code i2c_master_write_packet_wait( + + struct i2c_master_packet *const packet); + +enum i2c_status_code i2c_master_write_packet_wait_no_stop( + + struct i2c_master_packet *const packet); + +void i2c_master_send_stop(); + + +#ifdef FEATURE_I2C_DMA_SUPPORT +/** + * \name SERCOM I2C master with DMA interfaces + */ + +/** + * \brief Set I2C for DMA transfer with slave address and transfer size. + * + * This function will set the slave address, transfer size and enable the auto transfer + * mode for DMA. + * + * \param[in,out] module Pointer to the driver instance to lock. + * \param[in] addr I2C slave address + * \param[in] length I2C transfer length with DMA. + * \param[in] direction I2C transfer direction + * + */ +static inline void i2c_master_dma_set_transfer( + uint16_t addr, uint8_t length, enum i2c_transfer_direction direction) +{ + module->hw->I2CM.ADDR.reg = + SERCOM_I2CM_ADDR_ADDR(addr<<1) | + SERCOM_I2CM_ADDR_LENEN | + SERCOM_I2CM_ADDR_LEN(length) | + direction; +} + +#endif +#endif /* I2C_MASTER_H_INCLUDED */ diff --git a/loader/inc/sercom/sercom.h b/loader/inc/sercom/sercom.h new file mode 100644 index 0000000..393a5d5 --- /dev/null +++ b/loader/inc/sercom/sercom.h @@ -0,0 +1,127 @@ +/** + * SAM D20/D21/R21 Serial Peripheral Interface Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef SERCOM_H_INCLUDED +#define SERCOM_H_INCLUDED + +#include "system/system.h" +#include "system/clock.h" +#include "sercom/sercom_pinout.h" + +#if (SERCOM0_GCLK_ID_SLOW == SERCOM1_GCLK_ID_SLOW && \ + SERCOM0_GCLK_ID_SLOW == SERCOM2_GCLK_ID_SLOW && \ + SERCOM0_GCLK_ID_SLOW == SERCOM3_GCLK_ID_SLOW) +# define SERCOM_GCLK_ID SERCOM0_GCLK_ID_SLOW +#else +# error "SERCOM modules must share the same slow GCLK channel ID." +#endif + +#if (0x1ff >= REV_SERCOM) +# define FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_1 +#elif (0x2ff >= REV_SERCOM) +# define FEATURE_SERCOM_SYNCBUSY_SCHEME_VERSION_2 +#else +# error "Unknown SYNCBUSY scheme for this SERCOM revision" +#endif + +/** + * Status Codes + */ +enum sercom_status_t { + SERCOM_STATUS_OK = 1, + SERCOM_STATUS_BAUDRATE_UNAVAILABLE, + SERCOM_STATUS_TIMEOUT, + SERCOM_STATUS_PACKET_COLLISION, + SERCOM_STATUS_BUSY, + SERCOM_STATUS_DENIED, + SERCOM_STATUS_BAD_FORMAT, + SERCOM_STATUS_BAD_DATA, + SERCOM_STATUS_OVERFLOW, + SERCOM_STATUS_IO, + SERCOM_STATUS_INVALID_ARG, + SERCOM_STATUS_ABORTED, + SERCOM_STATUS_UNSUPPORTED_DEV +}; + +/** + * Select sercom asynchronous operation mode + */ +enum sercom_asynchronous_operation_mode { + SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC = 0, + SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL, +}; + +/** + * Select number of samples per bit + */ +enum sercom_asynchronous_sample_num { + SERCOM_ASYNC_SAMPLE_NUM_3 = 3, + SERCOM_ASYNC_SAMPLE_NUM_8 = 8, + SERCOM_ASYNC_SAMPLE_NUM_16 = 16, +}; + +/** + * Type used for registering interrupt handlers + */ +typedef void (*sercom_handler_t)(Sercom* const sercom_instance, + uint8_t instance_index); + +uint8_t _sercom_get_sercom_inst_index(Sercom *const sercom_instance); + +void _sercom_set_handler(Sercom* const sercom_instance, + const sercom_handler_t interrupt_handler); + +void _sercom_set_gclk_generator(const enum gclk_generator generator_source); + +enum sercom_status_t _sercom_get_sync_baud_val(const uint32_t baudrate, + const uint32_t external_clock, + uint16_t *const baudval); + +enum sercom_status_t _sercom_get_async_baud_val(const uint32_t baudrate, + const uint32_t peripheral_clock, + uint16_t *const baudval, + enum sercom_asynchronous_operation_mode mode, + enum sercom_asynchronous_sample_num sample_num); + +uint32_t _sercom_get_default_pad(Sercom *const sercom_module, + const uint8_t pad); + +#endif /* SERCOM_H_INCLUDED */ diff --git a/loader/inc/sercom/sercom_pinout.h b/loader/inc/sercom/sercom_pinout.h new file mode 100644 index 0000000..43ab6c3 --- /dev/null +++ b/loader/inc/sercom/sercom_pinout.h @@ -0,0 +1,82 @@ +/** + * SAM D20/D21/R21 SERCOM Module Pinout Definitions + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SERCOM_PINOUT_H_INCLUDED +#define SERCOM_PINOUT_H_INCLUDED + +#include "sercom/sercom.h" + +/* SERCOM0 */ +#define SERCOM0_PAD0_DEFAULT PINMUX_PA04D_SERCOM0_PAD0 +#define SERCOM0_PAD1_DEFAULT PINMUX_PA05D_SERCOM0_PAD1 +#define SERCOM0_PAD2_DEFAULT PINMUX_PA06D_SERCOM0_PAD2 +#define SERCOM0_PAD3_DEFAULT PINMUX_PA07D_SERCOM0_PAD3 + +/* SERCOM1 */ +#define SERCOM1_PAD0_DEFAULT PINMUX_PA00D_SERCOM1_PAD0 +#define SERCOM1_PAD1_DEFAULT PINMUX_PA01D_SERCOM1_PAD1 +#define SERCOM1_PAD2_DEFAULT PINMUX_PA30D_SERCOM1_PAD2 +#define SERCOM1_PAD3_DEFAULT PINMUX_PA31D_SERCOM1_PAD3 + +/* SERCOM2 */ +#define SERCOM2_PAD0_DEFAULT PINMUX_PA08D_SERCOM2_PAD0 +#define SERCOM2_PAD1_DEFAULT PINMUX_PA09D_SERCOM2_PAD1 +#define SERCOM2_PAD2_DEFAULT PINMUX_PA10D_SERCOM2_PAD2 +#define SERCOM2_PAD3_DEFAULT PINMUX_PA11D_SERCOM2_PAD3 + +/* SERCOM3 */ +#define SERCOM3_PAD0_DEFAULT PINMUX_PA16D_SERCOM3_PAD0 +#define SERCOM3_PAD1_DEFAULT PINMUX_PA17D_SERCOM3_PAD1 +#define SERCOM3_PAD2_DEFAULT PINMUX_PA18D_SERCOM3_PAD2 +#define SERCOM3_PAD3_DEFAULT PINMUX_PA19D_SERCOM3_PAD3 + +/* SERCOM4 */ +#define SERCOM4_PAD0_DEFAULT PINMUX_PA12D_SERCOM4_PAD0 +#define SERCOM4_PAD1_DEFAULT PINMUX_PA13D_SERCOM4_PAD1 +#define SERCOM4_PAD2_DEFAULT PINMUX_PA14D_SERCOM4_PAD2 +#define SERCOM4_PAD3_DEFAULT PINMUX_PA15D_SERCOM4_PAD3 + +/* SERCOM5 */ +#define SERCOM5_PAD0_DEFAULT PINMUX_PA22D_SERCOM5_PAD0 +#define SERCOM5_PAD1_DEFAULT PINMUX_PA23D_SERCOM5_PAD1 +#define SERCOM5_PAD2_DEFAULT PINMUX_PA24D_SERCOM5_PAD2 +#define SERCOM5_PAD3_DEFAULT PINMUX_PA25D_SERCOM5_PAD3 + +#endif /* SERCOM_PINOUT_H_INCLUDED */ diff --git a/loader/inc/sercom/spi.h b/loader/inc/sercom/spi.h new file mode 100644 index 0000000..f3d626d --- /dev/null +++ b/loader/inc/sercom/spi.h @@ -0,0 +1,1133 @@ +/** + * SAM D20/D21/R21 Serial Peripheral Interface Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef SPI_H_INCLUDED +#define SPI_H_INCLUDED + +/** + * SAM D20/D21/R21 Serial Peripheral Interface Driver (SERCOM SPI) + * + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the SERCOM module in its SPI + * mode to transfer SPI data frames. + * + * The following peripherals are used by this module: + * + * - SERCOM (Serial Communication Interface) + * + * Module Overview + * + * The Serial Peripheral Interface (SPI) is a high-speed synchronous + * data transfer interface using three or four pins. It allows fast + * communication between a master device and one or more peripheral + * devices. + * + * A device connected to the bus must act as a master or a slave. The + * master initiates and controls all data transactions. + * + * The SPI master initiates a communication cycle by pulling low the + * Slave Select (SS) pin of the desired slave. The Slave Select pin is + * active low. Master and slave prepare data to be sent in their + * respective shift registers, and the master generates the required + * clock pulses on the SCK line to interchange data. Data is always + * shifted from master to slave on the Master Out - Slave In (MOSI) + * line, and from slave to master on the Master In - Slave Out (MISO) + * line. After each data transfer, the master can synchronize to the + * slave by pulling the SS line high. + * + * \subsection asfdoc_sam0_sercom_spi_bus SPI Bus Connection + * In \ref asfdoc_sam0_spi_connection_example "the figure below", the + * connection between one master and one slave is shown. + * + * \anchor asfdoc_sam0_spi_connection_example + * \dot + * digraph spi_slaves_par { + * subgraph cluster_spi_master { + * shift_reg [label="Shift register", shape=box]; + * mosi_m [label="MOSI", shape=none]; + * miso_m [label="MISO", shape=none]; + * sck_m [label="SCK", shape=none]; + * ss_m [label="GPIO pin", shape=none]; + * {rank=same; mosi_m miso_m sck_m ss_m} + * label="SPI Master"; + * } + * subgraph cluster_spi_slave { + * mosi_s [label="MOSI", shape=none]; + * miso_s [label="MISO", shape=none]; + * sck_s [label="SCK", shape=none]; + * ss_s [label="SS", shape=none]; + * shift_reg_s [label="Shift register", shape=box]; + * {rank=same; mosi_s miso_s sck_s ss_s} + * label="SPI Slave"; + * rankdir=LR; + * } + * shift_reg:e -> mosi_m:w [label=""]; + * mosi_m:e -> mosi_s:w [label=""]; + * mosi_s:e -> shift_reg_s:w [label=""]; + * miso_s:w -> miso_m:e [label=""]; + * sck_m -> sck_s; + * ss_m -> ss_s; + * shift_reg_s:se -> miso_s:e [label=""]; + * miso_m:w -> shift_reg:sw [label=""]; + * rankdir=LR; + * } + * \enddot + * + * The different lines are as follows: + * + * MOSI Master Input Slave Output. The line where the data is shifted + * out from the master and in to the slave. + * + * MISO Master Output Slave Input. The line where the data is shifted + * out from the slave and in to the master. + * + * SCK Serial Clock. Generated by the master device. + * + * SS Slave Select. To initiate a transaction, the master must pull + * this line low. + * + * If the bus consists of several SPI slaves, they can be connected in + * parallel and the SPI master can use general I/O pins to control + * separate SS lines to each slave on the bus. + * + * It is also possible to connect all slaves in series. In this + * configuration, a common SS is provided to \c N slaves, enabling + * them simultaneously. The MISO from the \c N-1 slaves is connected + * to the MOSI on the next slave. The \c Nth slave connects its MISO + * back to the master. For a complete transaction, the master must + * shift \c N+1 characters. + * + * SPI Character Size + * + * The SPI character size is configurable to 8 or 9 bits. + * + * Master Mode + * + * When configured as a master, the SS pin will be configured as an output. + * + * Data Transfer + * + * Writing a character will start the SPI clock generator, and the + * character is transferred to the shift register when the shift + * register is empty. Once this is done, a new character can be + * written. As each character is shifted out from the master, a + * character is shifted in from the slave. If the receiver is enabled, + * the data is moved to the receive buffer at the completion of the + * frame and can be read. + * + * Slave Mode + * + * When configured as a slave, the SPI interface will remain inactive + * with MISO tri-stated as long as the SS pin is driven high. + * + * Data Transfer + * + * The data register can be updated at any time. As the SPI slave + * shift register is clocked by SCK, a minimum of three SCK cycles are + * needed from the time new data is written, until the character is + * ready to be shifted out. If the shift register has not been loaded + * with data, the current contents will be transmitted. + * + * If constant transmission of data is needed in SPI slave mode, the + * system clock should be faster than SCK. If the receiver is + * enabled, the received character can be read from the. When SS line + * is driven high, the slave will not receive any additional data. + * + * Address Recognition + * + * When the SPI slave is configured with address recognition, the + * first character in a transaction is checked for an address + * match. If there is a match, the MISO output is enabled and the + * transaction is processed. If the address does not match, the + * complete transaction is ignored. + * + * If the device is asleep, it can be woken up by an address match in + * order to process the transaction. + * + * \note In master mode, an address packet is written by the + * \ref spi_select_slave function if the address_enabled configuration is + * set in the \ref spi_slave_inst_config struct. + * + * Data Modes + * + * There are four combinations of SCK phase and polarity with respect + * to serial data. \ref asfdoc_sam0_spi_mode_table "The table below" + * shows the clock polarity (CPOL) and clock phase (CPHA) in the + * different modes. Leading edge is the first clock edge in a + * clock cycle and trailing edge is the last clock edge in a + * clock cycle. + * + * \anchor asfdoc_sam0_spi_mode_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SPI Data Modes
ModeCPOLCPHALeading EdgeTrailing Edge
0 0 0 Rising, Sample Falling, Setup
1 0 1 Rising, Setup Falling, Sample
2 1 0 Falling, Sample Rising, Setup
3 1 1 Falling, Setup Rising, Sample
+ * + * + * SERCOM Pads + * + * The SERCOM pads are automatically configured as seen in + * \ref asfdoc_sam0_spi_sercom_pad_table "the table below". If the receiver + * is disabled, the data input (MISO for master, MOSI for slave) can be used + * for other purposes. + * + * In master mode, the SS pin(s) must be configured using the \ref spi_slave_inst + * struct. + * + * \anchor asfdoc_sam0_spi_sercom_pad_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SERCOM SPI Pad Usages
Pin Master SPI Slave SPI
MOSI Output Input
MISO Input Output
SCK Output Input
SS User defined output enable Input
+ * + * Operation in Sleep Modes + * + * The SPI module can operate in all sleep modes by setting the + * run_in_standby option. The operation in slave and master mode is + * shown in the table below. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
run_in_standby Slave Master
false Disabled, all reception is dropped GCLK disabled when master is idle, wake on transmit complete
true Wake on reception GCLK is enabled while in sleep modes, wake on all interrupts
+ * + * Clock Generation + * + * In SPI master mode, the clock (SCK) is generated internally using the + * SERCOM baud rate generator. In SPI slave mode, the clock is provided by + * an external master on the SCK pin. This clock is used to directly clock + * the SPI shift register. + * + * Pin MUX Settings + * + * The pin MUX settings must be configured properly, as not all settings + * can be used in different modes of operation. + * + */ + +#include "sercom/sercom.h" +#include "system/pinmux.h" +#include "system/port.h" +#include + +#define CONF_SPI_MASTER_ENABLE true +#define CONF_SPI_SLAVE_ENABLE false +#define CONF_SPI_TIMEOUT 10000 + +#define SPI_WAIT_FOR_SYNC(hw) while(hw->STATUS.reg & SERCOM_SPI_STATUS_SYNCBUSY) + +/** + * Define SERCOM SPI features set according to different device family. + */ +# if (SAMD21) || (SAMR21) +/** SPI slave select low detection */ +# define FEATURE_SPI_SLAVE_SELECT_LOW_DETECT +/** Slave select can be controlled by hardware */ +# define FEATURE_SPI_HARDWARE_SLAVE_SELECT +/** SPI with error detect feature */ +# define FEATURE_SPI_ERROR_INTERRUPT +/** SPI sync scheme version 2 */ +# define FEATURE_SPI_SYNC_SCHEME_VERSION_2 +# endif + +# ifndef PINMUX_DEFAULT +/** Default pin mux */ +# define PINMUX_DEFAULT 0 +# endif + +# ifndef PINMUX_UNUSED +/** Unused PIN mux */ +# define PINMUX_UNUSED 0xFFFFFFFF +# endif + +# ifndef SPI_TIMEOUT +/** SPI timeout value */ +# define SPI_TIMEOUT 10000 +# endif + +/** + * Interrupt flags for the SPI module. + */ +enum spi_interrupt_flag { + /** + * This flag is set when the contents of the data register has been moved + * to the shift register and the data register is ready for new data + */ + SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY = SERCOM_SPI_INTFLAG_DRE, + /** + * This flag is set when the contents of the shift register has been + * shifted out + */ + SPI_INTERRUPT_FLAG_TX_COMPLETE = SERCOM_SPI_INTFLAG_TXC, + /** This flag is set when data has been shifted into the data register */ + SPI_INTERRUPT_FLAG_RX_COMPLETE = SERCOM_SPI_INTFLAG_RXC, +# ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT + /** This flag is set when slave select low */ + SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW = SERCOM_SPI_INTFLAG_SSL, +# endif +# ifdef FEATURE_SPI_ERROR_INTERRUPT + /** This flag is set when combined error happen */ + SPI_INTERRUPT_FLAG_COMBINED_ERROR = SERCOM_SPI_INTFLAG_ERROR, +# endif +}; + +/** + * SPI transfer mode. + */ +enum spi_transfer_mode { + /** Mode 0. Leading edge: rising, sample. Trailing edge: falling, setup */ + SPI_TRANSFER_MODE_0 = 0, + /** Mode 1. Leading edge: rising, setup. Trailing edge: falling, sample */ + SPI_TRANSFER_MODE_1 = SERCOM_SPI_CTRLA_CPHA, + /** Mode 2. Leading edge: falling, sample. Trailing edge: rising, setup */ + SPI_TRANSFER_MODE_2 = SERCOM_SPI_CTRLA_CPOL, + /** Mode 3. Leading edge: falling, setup. Trailing edge: rising, sample */ + SPI_TRANSFER_MODE_3 = SERCOM_SPI_CTRLA_CPHA | SERCOM_SPI_CTRLA_CPOL, +}; + +/** + * Frame format for slave mode. + */ +enum spi_frame_format { + /** SPI frame */ + SPI_FRAME_FORMAT_SPI_FRAME = SERCOM_SPI_CTRLA_FORM(0), + /** SPI frame with address */ + SPI_FRAME_FORMAT_SPI_FRAME_ADDR = SERCOM_SPI_CTRLA_FORM(2), +}; + +/** + * SPI signal mux settings + * + * Set the functionality of the SERCOM pins. + * As not all settings can be used in different modes of operation, proper + * settings must be chosen according to the rest of the configuration. + * + * See \ref asfdoc_sam0_sercom_spi_mux_settings for a description of the + * various MUX setting options. + */ +enum spi_signal_mux_setting { + /** SPI MUX setting A */ + SPI_SIGNAL_MUX_SETTING_A = + (0x0 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x0 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting B */ + SPI_SIGNAL_MUX_SETTING_B = + (0x0 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x1 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting C */ + SPI_SIGNAL_MUX_SETTING_C = + (0x0 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x2 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting D */ + SPI_SIGNAL_MUX_SETTING_D = + (0x0 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x3 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting E */ + SPI_SIGNAL_MUX_SETTING_E = + (0x1 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x0 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting F */ + SPI_SIGNAL_MUX_SETTING_F = + (0x1 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x1 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting G */ + SPI_SIGNAL_MUX_SETTING_G = + (0x1 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x2 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting H */ + SPI_SIGNAL_MUX_SETTING_H = + (0x1 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x3 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting I */ + SPI_SIGNAL_MUX_SETTING_I = + (0x2 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x0 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting J */ + SPI_SIGNAL_MUX_SETTING_J = + (0x2 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x1 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting K */ + SPI_SIGNAL_MUX_SETTING_K = + (0x2 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x2 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting L */ + SPI_SIGNAL_MUX_SETTING_L = + (0x2 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x3 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting M */ + SPI_SIGNAL_MUX_SETTING_M = + (0x3 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x0 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting N */ + SPI_SIGNAL_MUX_SETTING_N = + (0x3 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x1 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting O */ + SPI_SIGNAL_MUX_SETTING_O = + (0x3 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x2 << SERCOM_SPI_CTRLA_DIPO_Pos), + /** SPI MUX setting P */ + SPI_SIGNAL_MUX_SETTING_P = + (0x3 << SERCOM_SPI_CTRLA_DOPO_Pos) | + (0x3 << SERCOM_SPI_CTRLA_DIPO_Pos), +}; + +/** + * For slave mode when using the SPI frame with address format. + * + */ +enum spi_addr_mode { + /** + * \c address_mask in the \ref spi_config struct is used as a mask to the register. + */ + SPI_ADDR_MODE_MASK = SERCOM_SPI_CTRLB_AMODE(0), + /** + * The slave responds to the two unique addresses in \c address and + * \c address_mask in the \ref spi_config struct. + */ + SPI_ADDR_MODE_UNIQUE = SERCOM_SPI_CTRLB_AMODE(1), + /** + * The slave responds to the range of addresses between and including \c address + * and \c address_mask in in the \ref spi_config struct. + */ + SPI_ADDR_MODE_RANGE = SERCOM_SPI_CTRLB_AMODE(2), +}; + +/** + * \brief SPI modes enum + * + * SPI mode selection. + */ +enum spi_mode { + /** Master mode */ + SPI_MODE_MASTER = 1, + /** Slave mode */ + SPI_MODE_SLAVE = 0, +}; + +/** + * \brief SPI data order enum + * + * SPI data order. + * + */ +enum spi_data_order { + /** The LSB of the data is transmitted first */ + SPI_DATA_ORDER_LSB = SERCOM_SPI_CTRLA_DORD, + /** The MSB of the data is transmitted first */ + SPI_DATA_ORDER_MSB = 0, +}; + +/** + * \brief SPI character size enum + * + * SPI character size. + * + */ +enum spi_character_size { + /** 8 bit character */ + SPI_CHARACTER_SIZE_8BIT = SERCOM_SPI_CTRLB_CHSIZE(0), + /** 9 bit character */ + SPI_CHARACTER_SIZE_9BIT = SERCOM_SPI_CTRLB_CHSIZE(1), +}; + +/** + * \brief SPI peripheral slave instance structure + * + * SPI peripheral slave software instance structure, used to configure the + * correct SPI transfer mode settings for an attached slave. See + * \ref spi_select_slave. + */ +struct spi_slave_inst { + /** Pin to use as Slave Select */ + uint8_t ss_pin; + /** Address recognition enabled in slave device */ + bool address_enabled; + /** Address of slave device */ + uint8_t address; +}; + +/** + * \brief SPI peripheral slave configuration structure + * + * SPI Peripheral slave configuration structure + */ +struct spi_slave_inst_config { + /** Pin to use as Slave Select */ + uint8_t ss_pin; + /** Enable address */ + bool address_enabled; + /** Address of slave */ + uint8_t address; +}; + +/** + * \brief Initializes an SPI peripheral slave device configuration structure to default values + * + * This function will initialize a given SPI slave device configuration + * structure to a set of known default values. This function should be called + * on any new instance of the configuration structures before being modified by + * the user application. + * + * The default configuration is as follows: + * \li Slave Select on GPIO pin 10 + * \li Addressing not enabled + * + * \param[out] config Configuration structure to initialize to default values + */ +static inline void spi_slave_inst_get_config_defaults( + struct spi_slave_inst_config *const config) +{ + + + config->ss_pin = 10; + config->address_enabled = false; + config->address = 0; +} + +/** + * This function will initialize the software SPI peripheral slave, based on + * the values of the config struct. The slave can then be selected and + * optionally addressed by the \ref spi_select_slave function. + * + * \param[out] slave Pointer to the software slave instance struct + * \param[in] config Pointer to the config struct + * + */ +static inline void spi_attach_slave(struct spi_slave_inst *const slave) +// struct spi_slave_inst_config *const config) +{ + +// + +// slave->ss_pin = config->ss_pin; +// slave->address_enabled = config->address_enabled; +// slave->address = config->address; + + /* Set config on Slave Select pin */ + port_pin_set_config(slave->ss_pin, + PORT_PIN_DIR_OUTPUT, + PORT_PIN_PULL_UP, + false); + /* Set high */ + port_pin_set_output_level(slave->ss_pin, true); +} + +enum sercom_status_t spi_init(SercomSpi *const hw, + enum spi_mode mode, + enum spi_data_order data_order, + enum spi_transfer_mode transfer_mode, + enum spi_signal_mux_setting mux_setting, + enum spi_character_size character_size, + bool run_in_standby, + bool receiver_enable, + uint32_t master_baudrate, + enum spi_frame_format slave_frame_format, + enum spi_addr_mode slave_address_mode, + uint8_t slave_address, + uint8_t salve_address_mask, + bool savle_preload_enable, +# ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT + bool select_slave_low_detect_enable, +# endif +# ifdef FEATURE_SPI_HARDWARE_SLAVE_SELECT + bool master_slave_select_enable, +# endif + enum gclk_generator generator_source, + uint32_t pinmux_pad0, + uint32_t pinmux_pad1, + uint32_t pinmux_pad2, + uint32_t pinmux_pad3); +enum sercom_status_t spi_init_default(SercomSpi *const hw); + + +/** + * This function will enable the SERCOM SPI module. + * + * \param[in,out] module Pointer to the software instance struct + */ +static inline void spi_enable(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + +// system_interrupt_enable(_sercom_get_interrupt_vector(module->hw)); + + SPI_WAIT_FOR_SYNC(hw); + + /* Enable SPI */ + hw->CTRLA.reg |= SERCOM_SPI_CTRLA_ENABLE; +} + +/** + * This function will disable the SERCOM SPI module. + * + * \param[in,out] module Pointer to the software instance struct + */ +static inline void spi_disable(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + // system_interrupt_disable(_sercom_get_interrupt_vector(module->hw)); + + SPI_WAIT_FOR_SYNC(hw); + + /* Disable SPI */ + hw->CTRLA.reg &= ~SERCOM_SPI_CTRLA_ENABLE; +} + +void spi_reset(SercomSpi* const hw); + +enum sercom_status_t spi_set_baudrate(SercomSpi* const hw, + uint32_t baudrate); + +/** + * This function will check if the SPI master module has shifted out last data, + * or if the slave select pin has been drawn high by the master for the SPI + * slave module. + * + * \param[in] module Pointer to the software instance struct + * + * \return Indication of whether any writes are ongoing + * \retval true If the SPI master module has shifted out data, or slave select + * has been drawn high for SPI slave + * \retval false If the SPI master module has not shifted out data + */ +static inline bool spi_is_write_complete(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + /* Check interrupt flag */ + return (hw->INTFLAG.reg & SERCOM_SPI_INTFLAG_TXC); +} + +/** + * This function will check if the SPI module is ready to write data. + * + * \param[in] module Pointer to the software instance struct + * + * \return Indication of whether the module is ready to read data or not + * \retval true If the SPI module is ready to write data + * \retval false If the SPI module is not ready to write data + */ +static inline bool spi_is_ready_to_write(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + /* Check interrupt flag */ + return (hw->INTFLAG.reg & SERCOM_SPI_INTFLAG_DRE); +} + +/** + * This function will check if the SPI module is ready to read data. + * + * \param[in] module Pointer to the software instance struct + * + * \return Indication of whether the module is ready to read data or not + * \retval true If the SPI module is ready to read data + * \retval false If the SPI module is not ready to read data + */ +static inline bool spi_is_ready_to_read(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + /* Check interrupt flag */ + return (hw->INTFLAG.reg & SERCOM_SPI_INTFLAG_RXC); +} + + +/** + * This function will send a single SPI character via SPI and ignore any data + * shifted in by the connected device. To both send and receive data, use the + * \ref spi_transceive_wait function or use the \ref spi_read function after + * writing a character. The \ref spi_is_ready_to_write function + * should be called before calling this function. + * + * Note that this function does not handle the SS (Slave Select) + * pin(s) in master mode; this must be handled from the user application. + * + * \note In slave mode, the data will not be transferred before a master + * initiates a transaction. + * + * \param[in] module Pointer to the software instance struct + * \param[in] tx_data Data to transmit + * + * \return Status of the procedure + * \retval STATUS_OK If the data was written + * \retval STATUS_BUSY If the last write was not completed + */ +static inline enum sercom_status_t spi_write(SercomSpi* const hw, + uint16_t tx_data) +{ + /* Sanity check arguments */ + + + /* Check if the data register has been copied to the shift register */ + if (!spi_is_ready_to_write(hw)) { + /* Data register has not been copied to the shift register, return */ + return SERCOM_STATUS_BUSY; + } + + /* Write the character to the DATA register */ + hw->DATA.reg = tx_data & SERCOM_SPI_DATA_MASK; + + return SERCOM_STATUS_OK; +} + +enum sercom_status_t spi_write_buffer_wait(SercomSpi* const hw, + const uint8_t *tx_data, + uint16_t length); + +/** + * This function will return the last SPI character shifted into the receive + * register by the \ref spi_write function + * + * \note The \ref spi_is_ready_to_read function should be called before calling + * this function. + * + * \note Receiver must be enabled in the configuration + * + * \param[in] module Pointer to the software instance struct + * \param[out] rx_data Pointer to store the received data + * + * \returns Status of the read operation. + * \retval STATUS_OK If data was read + * \retval STATUS_ERR_IO If no data is available + * \retval STATUS_ERR_OVERFLOW If the data is overflown + */ +static inline enum sercom_status_t spi_read(SercomSpi* const hw, + uint16_t *rx_data) +{ + /* Sanity check arguments */ + + + /* Check if data is ready to be read */ + if (!spi_is_ready_to_read(hw)) { + /* No data has been received, return */ + return SERCOM_STATUS_IO; + } + + /* Return value */ + enum sercom_status_t retval = SERCOM_STATUS_OK; + + /* Check if data is overflown */ + if (hw->STATUS.reg & SERCOM_SPI_STATUS_BUFOVF) { + retval = SERCOM_STATUS_OVERFLOW; + /* Clear overflow flag */ + hw->STATUS.reg |= SERCOM_SPI_STATUS_BUFOVF; + } + + /* Read the character from the DATA register */ + if (hw->CTRLB.bit.CHSIZE) { /* If 9-bit */ + *rx_data = (hw->DATA.reg & SERCOM_SPI_DATA_MASK); + } else { + *rx_data = (uint8_t)hw->DATA.reg; + } + + return retval; +} + +enum sercom_status_t spi_read_buffer_wait(SercomSpi* const hw, + uint8_t *rx_data, + uint16_t length, + uint16_t dummy); + +enum sercom_status_t spi_transceive_wait(SercomSpi* const hw, + uint16_t tx_data, + uint16_t *rx_data); + +enum sercom_status_t spi_transceive_buffer_wait(SercomSpi* const hw, + uint8_t *tx_data, + uint8_t *rx_data, + uint16_t length); + +enum sercom_status_t spi_select_slave(SercomSpi* const hw, + uint8_t ss_pin, + bool address_enabled, + uint8_t address, + const bool select); + +/** + * Mux Settings + * + * The following lists the possible internal SERCOM module pad function + * assignments, for the four SERCOM pads in both SPI Master, and SPI Slave + * modes. Note that this is in addition to the physical GPIO pin MUX of the + * device, and can be used in conjunction to optimize the serial data pin-out. + * + * \section asfdoc_sam0_sercom_spi_mux_settings_master Master Mode Settings + * The following table describes the SERCOM pin functionalities for the various + * MUX settings, whilst in SPI Master mode. + * + * \note If MISO is unlisted, the SPI receiver must not be enabled for the + * given MUX setting. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Mux/PadPAD 0PAD 1PAD 2PAD 3
AMOSISCK--
BMOSISCK--
CMOSISCKMISO-
DMOSISCK-MISO
EMISO-MOSISCK
F-MISOMOSISCK
G--MOSISCK
H--MOSISCK
I (1)MISOSCK-MOSI
J (1)-SCK-MOSI
K (1)-SCKMISOMOSI
L (1)-SCK-MOSI
M (1)MOSI--SCK
N (1)MOSIMISO-SCK
O (1)MOSI-MISOSCK
P (1)MOSI--SCK
+ * + * (1) Not available in all silicon revisions. + * + * \section asfdoc_sam0_sercom_spi_mux_settings_slave Slave Mode Settings + * The following table describes the SERCOM pin functionalities for the various + * MUX settings, whilst in SPI Slave mode. + * + * \note If MISO is unlisted, the SPI receiver must not be enabled for the + * given MUX setting. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Mux/PadPAD 0PAD 1PAD 2PAD 3
AMISOSCK/SS-
BMISOSCK/SS-
CMISOSCK/SS-
DMISOSCK/SSMOSI
EMOSI/SSMISOSCK
F-/SSMISOSCK
G-/SSMISOSCK
H-/SSMISOSCK
I (1)MOSISCK/SSMISO
J (1)-SCK/SSMISO
K (1)-SCK/SSMISO
L (1)-SCK/SSMISO
M (1)MISO/SS-SCK
N (1)MISO/SS-SCK
O (1)MISO/SSMOSISCK
P (1)MISO/SS-SCK
+ * + */ + +#endif /* SPI_H_INCLUDED */ diff --git a/loader/inc/sercom/usart.h b/loader/inc/sercom/usart.h new file mode 100644 index 0000000..1ce6f48 --- /dev/null +++ b/loader/inc/sercom/usart.h @@ -0,0 +1,568 @@ +/** + * SAM D20/D21/R21 SERCOM USART Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef USART_H_INCLUDED +#define USART_H_INCLUDED + +/** + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the SERCOM module in its USART mode to transfer or receive + * USART data frames. + * + * The following peripherals are used by this module: + * + * - SERCOM (Serial Communication Interface) + * + * Prerequisites + * + * To use the USART you need to have a GCLK generator enabled and running + * that can be used as the SERCOM clock source. This can either be configured + * in conf_clocks.h or by using the system clock driver. + * + * Module Overview + * + * This driver will use one (or more) SERCOM interfaces on the system + * and configure it to run as a USART interface in either synchronous + * or asynchronous mode. + * + * Frame Format + * + * Communication is based on frames, where the frame format can be customized + * to accommodate a wide range of standards. A frame consists of a start bit, + * a number of data bits, an optional parity bit for error detection as well + * as a configurable length stop bit(s) - see + * \ref asfdoc_sam0_sercom_usart_frame_diagram "the figure below". + * \ref asfdoc_sam0_sercom_usart_frame_params "The table below" shows the + * available parameters you can change in a frame. + * + * \anchor asfdoc_sam0_sercom_usart_frame_params + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
USART Frame Parameters
ParameterOptions
Start bit1
Data bits5, 6, 7, 8, 9
Parity bitNone, Even, Odd
Stop bits1, 2
+ * + * Synchronous mode + * + * In synchronous mode a dedicated clock line is provided; either by the USART + * itself if in master mode, or by an external master if in slave mode. + * Maximum transmission speed is the same as the GCLK clocking the USART + * peripheral when in slave mode, and the GCLK divided by two if in + * master mode. In synchronous mode the interface needs three lines to + * communicate: + * - TX (Transmit pin) + * - RX (Receive pin) + * - XCK (Clock pin) + * + * Data sampling + + * In synchronous mode the data is sampled on either the rising or falling edge + * of the clock signal. This is configured by setting the clock polarity in the + * configuration struct. + * + * Asynchronous mode + * + * In asynchronous mode no dedicated clock line is used, and the + * communication is based on matching the clock speed on the + * transmitter and receiver. The clock is generated from the internal + * SERCOM baudrate generator, and the frames are synchronized by using + * the frame start bits. Maximum transmission speed is limited to the + * SERCOM GCLK divided by 16. + * In asynchronous mode the interface only needs two lines to communicate: + * - TX (Transmit pin) + * - RX (Receive pin) + * + * Transmitter/receiver clock matching + * + * For successful transmit and receive using the asynchronous mode the + * receiver and transmitter clocks needs to be closely matched. When + * receiving a frame that does not match the selected baud rate + * closely enough the receiver will be unable to synchronize the + * frame(s), and garbage transmissions will result. + * + * Parity + * + * Parity can be enabled to detect if a transmission was in + * error. This is done by counting the number of "1" bits in the + * frame. When using Even parity the parity bit will be set if the + * total number of "1"s in the frame are an even number. If using Odd + * parity the parity bit will be set if the total number of "1"s are + * Odd. + * + * When receiving a character the receiver will count the number of + * "1"s in the frame and give an error if the received frame and + * parity bit disagree. + * + * GPIO configuration + * + * The SERCOM module has four internal pads; the RX pin can be placed + * freely on any one of the four pads, and the TX and XCK pins have + * two predefined positions that can be selected as a pair. The pads + * can then be routed to an external GPIO pin using the normal pin + * multiplexing scheme on the SAM D20/D21/R21. + * + * Special Considerations + * + * Never execute large portions of code in the callbacks. These + * are run from the interrupt routine, and thus having long callbacks will + * keep the processor in the interrupt handler for an equally long time. + * A common way to handle this is to use global flags signaling the + * main application that an interrupt event has happened, and only do the + * minimal needed processing in the callback. + */ + +#include "sercom/sercom.h" +#include "system/pinmux.h" +#include "samd20.h" + +#define USART_WAIT_FOR_SYNC(hw) \ + while(hw->STATUS.reg & SERCOM_USART_STATUS_SYNCBUSY) + +/** + * Define SERCOM USART features set according to different device family. + */ +#if (SAMD21) || (SAMR21) +/** Usart sync scheme version 2. */ +# define FEATURE_USART_SYNC_SCHEME_V2 +/** Usart over sampling. */ +# define FEATURE_USART_OVER_SAMPLE +/** Usart hardware control flow. */ +# define FEATURE_USART_HARDWARE_FLOW_CONTROL +/** IrDA mode. */ +# define FEATURE_USART_IRDA +/** LIN slave mode. */ +# define FEATURE_USART_LIN_SLAVE +/** Usart collision detection. */ +# define FEATURE_USART_COLLISION_DECTION +/** Usart start frame detection. */ +# define FEATURE_USART_START_FRAME_DECTION +/** Usart start buffer overflow notification. */ +# define FEATURE_USART_IMMEDIATE_BUFFER_OVERFLOW_NOTIFICATION +#endif + +#ifndef PINMUX_DEFAULT +/** Default pin mux. */ +# define PINMUX_DEFAULT 0 +#endif + +#ifndef PINMUX_UNUSED +/** Unused PIN mux. */ +# define PINMUX_UNUSED 0xFFFFFFFF +#endif + +#ifndef USART_TIMEOUT +/** USART timeout value. */ +# define USART_TIMEOUT 0xFFFF +#endif + +/** + * Callbacks for the Asynchronous USART driver + */ +enum usart_callback { + /** Callback for buffer transmitted */ + USART_CALLBACK_BUFFER_TRANSMITTED, + /** Callback for buffer received */ + USART_CALLBACK_BUFFER_RECEIVED, + /** Callback for error */ + USART_CALLBACK_ERROR, +#ifdef FEATURE_USART_LIN_SLAVE + /** Callback for break character is received. */ + USART_CALLBACK_BREAK_RECEIVED, +#endif +#ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL + /** Callback for a change is detected on the CTS pin. */ + USART_CALLBACK_CTS_INPUT_CHANGE, +#endif +#ifdef FEATURE_USART_START_FRAME_DECTION + /** Callback for a start condition is detected on the RxD line. */ + USART_CALLBACK_START_RECEIVED, +#endif +# if !defined(__DOXYGEN__) + /** Number of available callbacks. */ + USART_CALLBACK_N, +# endif +}; + +/** + * The data order decides which of MSB or LSB is shifted out first when data is + * transferred + */ +enum usart_dataorder { + /** The MSB will be shifted out first during transmission, + * and shifted in first during reception */ + USART_DATAORDER_MSB = 0, + /** The LSB will be shifted out first during transmission, + * and shifted in first during reception */ + USART_DATAORDER_LSB = SERCOM_USART_CTRLA_DORD, +}; + +/** + * Select USART transfer mode + */ +enum usart_transfer_mode { + /** Transfer of data is done synchronously */ + USART_TRANSFER_SYNCHRONOUSLY = (SERCOM_USART_CTRLA_CMODE), + /** Transfer of data is done asynchronously */ + USART_TRANSFER_ASYNCHRONOUSLY = 0 +}; + +/* + * Select parity USART parity mode + */ +enum usart_parity { + /** For odd parity checking, the parity bit will be set if number of + * ones being transferred is even */ + USART_PARITY_ODD = SERCOM_USART_CTRLB_PMODE, + + /** For even parity checking, the parity bit will be set if number of + * ones being received is odd */ + USART_PARITY_EVEN = 0, + + /** No parity checking will be executed, and there will be no parity bit + * in the received frame */ + USART_PARITY_NONE = 0xFF, +}; + +/** + * Set the functionality of the SERCOM pins. + * + * See \ref asfdoc_sam0_sercom_usart_mux_settings for a description of the + * various MUX setting options. + */ +enum usart_signal_mux_settings { +#ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL + /** MUX setting RX_0_TX_0_XCK_1 */ + USART_RX_0_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(0)), + /** MUX setting RX_0_TX_2_XCK_3 */ + USART_RX_0_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(1)), + /** MUX setting USART_RX_0_TX_0_RTS_2_CTS_3 */ + USART_RX_0_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO(2)), + /** MUX setting RX_1_TX_0_XCK_1 */ + USART_RX_1_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(0)), + /** MUX setting RX_1_TX_2_XCK_3 */ + USART_RX_1_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(1)), + /** MUX setting USART_RX_1_TX_0_RTS_2_CTS_3 */ + USART_RX_1_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO(2)), + /** MUX setting RX_2_TX_0_XCK_1 */ + USART_RX_2_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(0)), + /** MUX setting RX_2_TX_2_XCK_3 */ + USART_RX_2_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(1)), + /** MUX setting USART_RX_2_TX_0_RTS_2_CTS_3 */ + USART_RX_2_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO(2)), + /** MUX setting RX_3_TX_0_XCK_1 */ + USART_RX_3_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(0)), + /** MUX setting RX_3_TX_2_XCK_3 */ + USART_RX_3_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(1)), + /** MUX setting USART_RX_3_TX_0_RTS_2_CTS_3 */ + USART_RX_3_TX_0_RTS_2_CTS_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO(2)), +#else + /** MUX setting RX_0_TX_0_XCK_1 */ + USART_RX_0_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(0)), + /** MUX setting RX_0_TX_2_XCK_3 */ + USART_RX_0_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(0) | SERCOM_USART_CTRLA_TXPO), + /** MUX setting RX_1_TX_0_XCK_1 */ + USART_RX_1_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(1)), + /** MUX setting RX_1_TX_2_XCK_3 */ + USART_RX_1_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(1) | SERCOM_USART_CTRLA_TXPO), + /** MUX setting RX_2_TX_0_XCK_1 */ + USART_RX_2_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(2)), + /** MUX setting RX_2_TX_2_XCK_3 */ + USART_RX_2_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(2) | SERCOM_USART_CTRLA_TXPO), + /** MUX setting RX_3_TX_0_XCK_1 */ + USART_RX_3_TX_0_XCK_1 = (SERCOM_USART_CTRLA_RXPO(3)), + /** MUX setting RX_3_TX_2_XCK_3 */ + USART_RX_3_TX_2_XCK_3 = (SERCOM_USART_CTRLA_RXPO(3) | SERCOM_USART_CTRLA_TXPO), +#endif +}; + +/** + * Number of stop bits for a frame. + */ +enum usart_stopbits { + /** Each transferred frame contains 1 stop bit */ + USART_STOPBITS_1 = 0, + /** Each transferred frame contains 2 stop bits */ + USART_STOPBITS_2 = SERCOM_USART_CTRLB_SBMODE, +}; + +/** + * Number of bits for the character sent in a frame. + */ +enum usart_character_size { + /** The char being sent in a frame is 5 bits long */ + USART_CHARACTER_SIZE_5BIT = SERCOM_USART_CTRLB_CHSIZE(5), + /** The char being sent in a frame is 6 bits long */ + USART_CHARACTER_SIZE_6BIT = SERCOM_USART_CTRLB_CHSIZE(6), + /** The char being sent in a frame is 7 bits long */ + USART_CHARACTER_SIZE_7BIT = SERCOM_USART_CTRLB_CHSIZE(7), + /** The char being sent in a frame is 8 bits long */ + USART_CHARACTER_SIZE_8BIT = SERCOM_USART_CTRLB_CHSIZE(0), + /** The char being sent in a frame is 9 bits long */ + USART_CHARACTER_SIZE_9BIT = SERCOM_USART_CTRLB_CHSIZE(1), +}; + +#ifdef FEATURE_USART_OVER_SAMPLE +/** + * The value of sample rate and baud rate generation mode. + */ +enum usart_sample_rate { + /** 16x over-sampling using arithmetic baud rate generation */ + USART_SAMPLE_RATE_16X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(0), + /** 16x over-sampling using fractional baud rate generation */ + USART_SAMPLE_RATE_16X_FRACTIONAL = SERCOM_USART_CTRLA_SAMPR(1), + /** 8x over-sampling using arithmetic baud rate generation */ + USART_SAMPLE_RATE_8X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(2), + /** 8x over-sampling using fractional baud rate generation */ + USART_SAMPLE_RATE_8X_FRACTIONAL = SERCOM_USART_CTRLA_SAMPR(3), + /** 3x over-sampling using arithmetic baud rate generation */ + USART_SAMPLE_RATE_3X_ARITHMETIC = SERCOM_USART_CTRLA_SAMPR(4), +}; + +/** + * The value of sample number used for majority voting + */ +enum usart_sample_adjustment { + /** The first, middle and last sample number used for majority voting is 7-8-9 */ + USART_SAMPLE_ADJUSTMENT_7_8_9 = SERCOM_USART_CTRLA_SAMPA(0), + /** The first, middle and last sample number used for majority voting is 9-10-11 */ + USART_SAMPLE_ADJUSTMENT_9_10_11 = SERCOM_USART_CTRLA_SAMPA(1), + /** The first, middle and last sample number used for majority voting is 11-12-13 */ + USART_SAMPLE_ADJUSTMENT_11_12_13 = SERCOM_USART_CTRLA_SAMPA(2), + /** The first, middle and last sample number used for majority voting is 13-14-15 */ + USART_SAMPLE_ADJUSTMENT_13_14_15 = SERCOM_USART_CTRLA_SAMPA(3), +}; +#endif + +/** + * Select Receiver or Transmitter + */ +enum usart_transceiver_type { + /** The parameter is for the Receiver */ + USART_TRANSCEIVER_RX, + /** The parameter is for the Transmitter */ + USART_TRANSCEIVER_TX, +}; + +/** + * Enables the USART module + * + * \param[in] module Pointer to USART software instance struct + */ +static inline void usart_enable(SercomUsart* const hw) +{ + /* Sanity check arguments */ + + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Enable USART module */ + hw->CTRLA.reg |= SERCOM_USART_CTRLA_ENABLE; +} + +/** + * Disables the USART module + * + * \param[in] module Pointer to USART software instance struct + */ +static inline void usart_disable(SercomUsart* const hw) +{ + /* Sanity check arguments */ + + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Disable USART module */ + hw->CTRLA.reg &= ~SERCOM_USART_CTRLA_ENABLE; +} + +/** + * Disables and resets the USART module. + * + * \param[in] module Pointer to the USART software instance struct + */ +static inline void usart_reset(SercomUsart* const hw) +{ + /* Sanity check arguments */ + + + usart_disable(hw); + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Reset module */ + hw->CTRLA.reg = SERCOM_USART_CTRLA_SWRST; +} + +/** + * Enable the given transceiver. Either RX or TX. + * + * \param[in] module Pointer to USART software instance struct + * \param[in] transceiver_type Transceiver type. + */ +static inline void usart_enable_transceiver(SercomUsart* const hw, + enum usart_transceiver_type transceiver_type) +{ + /* Sanity check arguments */ + + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + switch (transceiver_type) { + case USART_TRANSCEIVER_RX: + /* Enable RX */ + hw->CTRLB.reg |= SERCOM_USART_CTRLB_RXEN; + break; + + case USART_TRANSCEIVER_TX: + /* Enable TX */ + hw->CTRLB.reg |= SERCOM_USART_CTRLB_TXEN; + break; + } +} + +/** + * Disable the given transceiver (RX or TX). + * + * \param[in] module Pointer to USART software instance struct + * \param[in] transceiver_type Transceiver type. + */ +static inline void usart_disable_transceiver(SercomUsart* const hw, + enum usart_transceiver_type transceiver_type) +{ + /* Sanity check arguments */ + + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + switch (transceiver_type) { + case USART_TRANSCEIVER_RX: + /* Disable RX */ + hw->CTRLB.reg &= ~SERCOM_USART_CTRLB_RXEN; + break; + + case USART_TRANSCEIVER_TX: + /* Disable TX */ + hw->CTRLB.reg &= ~SERCOM_USART_CTRLB_TXEN; + break; + } +} + +enum sercom_status_t usart_init(SercomUsart* const hw, + enum usart_dataorder data_order, + enum usart_transfer_mode transfer_mode, + enum usart_parity parity, + enum usart_stopbits stopbits, + enum usart_character_size character_size, + enum usart_signal_mux_settings mux_setting, +#ifdef FEATURE_USART_OVER_SAMPLE + enum usart_sample_rate sample_rate, + enum usart_sample_adjustment sample_adjustment, +#endif + bool immediate_buffer_overflow_notification, + bool encoding_format_enable, + uint8_t receive_pulse_length, + bool lin_slave_enable, + bool start_frame_detection_enable, + bool collision_detection_enable, + uint32_t baudrate, + bool receiver_enable, + bool transmitter_enable, + bool clock_polarity_inverted, + bool use_external_clock, + uint32_t ext_clock_freq, + bool run_in_standby, + enum gclk_generator generator_source, + uint32_t pinmux_pad0, + uint32_t pinmux_pad1, + uint32_t pinmux_pad2, + uint32_t pinmux_pad3); + +enum sercom_status_t usart_write_wait(SercomUsart* const hw, + const uint16_t tx_data); + +enum sercom_status_t usart_read_wait(SercomUsart* const hw, + uint16_t *const rx_data); + +enum sercom_status_t usart_write_buffer_wait(SercomUsart* const hw, + const uint8_t *tx_data, + uint16_t length); + +enum sercom_status_t usart_read_buffer_wait(SercomUsart* const hw, + uint8_t *rx_data, + uint16_t length); + +/** + * -------------------------------- Interrupts ------------------------------- + */ + +/** + * Rx Callback type for usart + */ +typedef void (*usart_rx_callback_t)(SercomUsart* const sercom_instance, + uint16_t data); + +void usart_register_rx_callback(SercomUsart* const hw, + usart_rx_callback_t callback, + uint32_t priority); + +#endif /* USART_H_INCLUDED */ diff --git a/loader/inc/system/clock.h b/loader/inc/system/clock.h new file mode 100644 index 0000000..92994fc --- /dev/null +++ b/loader/inc/system/clock.h @@ -0,0 +1,854 @@ +/** + * SAM D20/D21/R21 Clock Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef SYSTEM_CLOCK_H_INCLUDED +#define SYSTEM_CLOCK_H_INCLUDED + +/** + * SAM D20/D21/R21 System Clock Management Driver (SYSTEM CLOCK) + * + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the device's clocking related + * functions. This includes the various clock sources, bus clocks and + * generic clocks within the device, with functions to manage the + * enabling, disabling, source selection and prescaling of clocks to + * various internal peripherals. + * + * The following peripherals are used by this module: + * + * - GCLK (Generic Clock Management) + * - PM (Power Management) + * - SYSCTRL (Clock Source Control) + * + * Module Overview + * + * The SAM D20/D21/R21 devices contain a sophisticated clocking + * system, which is designed to give the maximum flexibility to the + * user application. This system allows a system designer to tune the + * performance and power consumption of the device in a dynamic + * manner, to achieve the best trade-off between the two for a + * particular application. + * + * This driver provides a set of functions for the configuration and + * management of the various clock related functionality within the + * device. + * + * Clock Sources + * + * The SAM D20/D21/R21 devices have a number of master clock source + * modules, each of which being capable of producing a stabilized + * output frequency which can then be fed into the various peripherals + * and modules within the device. + * + * Possible clock source modules include internal R/C oscillators, + * internal DFLL modules, as well as external crystal oscillators + * and/or clock inputs. + * + * CPU / Bus Clocks + * + * The CPU and AHB/APBx buses are clocked by the same physical clock + * source (referred in this module as the Main Clock), however the + * APBx buses may have additional prescaler division ratios set to + * give each peripheral bus a different clock speed. + * + * Clock Masking + * + * To save power, the input clock to one or more peripherals on the AHB and APBx + * buses can be masked away - when masked, no clock is passed into the module. + * Disabling of clocks of unused modules will prevent all access to the masked + * module, but will reduce the overall device power consumption. + * + * Generic Clocks + * + * Within the SAM D20/D21/R21 devices are a number of Generic Clocks; + * these are used to provide clocks to the various peripheral clock + * domains in the device in a standardized manner. One or more master + * source clocks can be selected as the input clock to a Generic Clock + * Generator, which can prescale down the input frequency to a slower + * rate for use in a peripheral. + * + * Additionally, a number of individually selectable Generic Clock + * Channels are provided, which multiplex and gate the various + * generator outputs for one or more peripherals within the + * device. This setup allows for a single common generator to feed one + * or more channels, which can then be enabled or disabled + * individually as required. + * + * Generic Clock Generators + * + * Each Generic Clock generator within the device can source its input clock + * from one of the provided Source Clocks, and prescale the output for one or + * more Generic Clock Channels in a one-to-many relationship. The generators + * thus allow for several clocks to be generated of different frequencies, + * power usages and accuracies, which can be turned on and off individually to + * disable the clocks to multiple peripherals as a group. + * + * Generic Clock Channels + * + * To connect a Generic Clock Generator to a peripheral within the + * device, a Generic Clock Channel is used. Each peripheral or + * peripheral group has an associated Generic Clock Channel, which serves as the + * clock input for the peripheral(s). To supply a clock to the peripheral + * module(s), the associated channel must be connected to a running Generic + * Clock Generator and the channel enabled. + * + */ + + +#include "samd20.h" +#include "system/gclk.h" + +/** + * Define system clock features set according to different device family. + */ +#if (SAMD21) || (SAMR21) +/** Digital Phase Locked Loop (DPLL) feature support */ +# define FEATURE_SYSTEM_CLOCK_DPLL +#endif + +/** + * Clock status type + */ +enum clock_status_t { + CLOCK_STATUS_OK = 0, + CLOCK_STATUS_INVALID_ARG, + +}; + +/** + * Available external 32KHz oscillator start-up times, as a number of external + * clock cycles. + */ +enum system_xosc32k_startup { + /** Wait 0 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_0, + /** Wait 32 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_32, + /** Wait 2048 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_2048, + /** Wait 4096 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_4096, + /** Wait 16384 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_16384, + /** Wait 32768 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_32768, + /** Wait 65536 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_65536, + /** Wait 131072 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC32K_STARTUP_131072, +}; + +/** + * Available external oscillator start-up times, as a number of external clock + * cycles. + */ +enum system_xosc_startup { + /** Wait 1 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_1, + /** Wait 2 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_2, + /** Wait 4 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_4, + /** Wait 8 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_8, + /** Wait 16 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_16, + /** Wait 32 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_32, + /** Wait 64 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_64, + /** Wait 128 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_128, + /** Wait 256 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_256, + /** Wait 512 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_512, + /** Wait 1024 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_1024, + /** Wait 2048 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_2048, + /** Wait 4096 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_4096, + /** Wait 8192 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_8192, + /** Wait 16384 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_16384, + /** Wait 32768 clock cycles until the clock source is considered stable */ + SYSTEM_XOSC_STARTUP_32768, +}; + +/** +* Available internal 32KHz oscillator start-up times, as a number of internal +* OSC32K clock cycles. +*/ +enum system_osc32k_startup { + /** Wait 3 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_3, + /** Wait 4 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_4, + /** Wait 6 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_6, + /** Wait 10 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_10, + /** Wait 18 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_18, + /** Wait 34 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_34, + /** Wait 66 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_66, + /** Wait 130 clock cycles until the clock source is considered stable */ + SYSTEM_OSC32K_STARTUP_130, +}; + +/** + * Available prescalers for the internal 8MHz (nominal) system clock. + */ +enum system_osc8m_div { + /** Do not divide the 8MHz RC oscillator output */ + SYSTEM_OSC8M_DIV_1, + /** Divide the 8MHz RC oscillator output by 2 */ + SYSTEM_OSC8M_DIV_2, + /** Divide the 8MHz RC oscillator output by 4 */ + SYSTEM_OSC8M_DIV_4, + /** Divide the 8MHz RC oscillator output by 8 */ + SYSTEM_OSC8M_DIV_8, +}; + +/** + * Internal 8Mhz RC oscillator frequency range setting + */ +enum system_osc8m_frequency_range { + /** Frequency range 4 Mhz to 6 Mhz */ + SYSTEM_OSC8M_FREQUENCY_RANGE_4_TO_6, + /** Frequency range 6 Mhz to 8 Mhz */ + SYSTEM_OSC8M_FREQUENCY_RANGE_6_TO_8, + /** Frequency range 8 Mhz to 11 Mhz */ + SYSTEM_OSC8M_FREQUENCY_RANGE_8_TO_11, + /** Frequency range 11 Mhz to 15 Mhz */ + SYSTEM_OSC8M_FREQUENCY_RANGE_11_TO_15, +}; + +/** + * Available division ratios for the CPU and APB/AHB bus clocks. + */ +enum system_main_clock_div { + /** Divide Main clock by 1 */ + SYSTEM_MAIN_CLOCK_DIV_1, + /** Divide Main clock by 2 */ + SYSTEM_MAIN_CLOCK_DIV_2, + /** Divide Main clock by 4 */ + SYSTEM_MAIN_CLOCK_DIV_4, + /** Divide Main clock by 8 */ + SYSTEM_MAIN_CLOCK_DIV_8, + /** Divide Main clock by 16 */ + SYSTEM_MAIN_CLOCK_DIV_16, + /** Divide Main clock by 32 */ + SYSTEM_MAIN_CLOCK_DIV_32, + /** Divide Main clock by 64 */ + SYSTEM_MAIN_CLOCK_DIV_64, + /** Divide Main clock by 128 */ + SYSTEM_MAIN_CLOCK_DIV_128, +}; + +/** + * Available external clock source types. + */ +enum system_clock_external { + /** The external clock source is a crystal oscillator */ + SYSTEM_CLOCK_EXTERNAL_CRYSTAL, + /** The connected clock source is an external logic level clock signal */ + SYSTEM_CLOCK_EXTERNAL_CLOCK, +}; + +/** + * Available operating modes of the DFLL clock source module, + */ +enum system_clock_dfll_loop_mode { + /** The DFLL is operating in open loop mode with no feedback */ + SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN, + /** The DFLL is operating in closed loop mode with frequency feedback from + * a low frequency reference clock + */ + SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED = SYSCTRL_DFLLCTRL_MODE, + /** The DFLL is operating in USB recovery mode with frequency feedback + * from USB SOF + */ +}; + +/** + * DFLL lock behavior modes on device wake-up from sleep. + */ +enum system_clock_dfll_wakeup_lock { + /** Keep DFLL lock when the device wakes from sleep */ + SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP, + /** Lose DFLL lock when the devices wakes from sleep */ + SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_LOSE = SYSCTRL_DFLLCTRL_LLAW, +}; + +/** + * DFLL fine tracking behavior modes after a lock has been acquired. + */ +enum system_clock_dfll_stable_tracking { + /** Keep tracking after the DFLL has gotten a fine lock */ + SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK, + /** Stop tracking after the DFLL has gotten a fine lock */ + SYSTEM_CLOCK_DFLL_STABLE_TRACKING_FIX_AFTER_LOCK = SYSCTRL_DFLLCTRL_STABLE, +}; + +/** + * DFLL chill-cycle behavior modes of the DFLL module. A chill cycle is a period + * of time when the DFLL output frequency is not measured by the unit, to allow + * the output to stabilize after a change in the input clock source. + */ +enum system_clock_dfll_chill_cycle { + /** Enable a chill cycle, where the DFLL output frequency is not measured */ + SYSTEM_CLOCK_DFLL_CHILL_CYCLE_ENABLE, + /** Disable a chill cycle, where the DFLL output frequency is not measured */ + SYSTEM_CLOCK_DFLL_CHILL_CYCLE_DISABLE = SYSCTRL_DFLLCTRL_CCDIS, +}; + +/** + * DFLL QuickLock settings for the DFLL module, to allow for a faster lock of + * the DFLL output frequency at the expense of accuracy. + */ +enum system_clock_dfll_quick_lock { + /** Enable the QuickLock feature for looser lock requirements on the DFLL */ + SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE, + /** Disable the QuickLock feature for strict lock requirements on the DFLL */ + SYSTEM_CLOCK_DFLL_QUICK_LOCK_DISABLE = SYSCTRL_DFLLCTRL_QLDIS, +}; + +/** + * Clock sources available to the GCLK generators + */ +enum system_clock_source { + /** Internal 8MHz RC oscillator */ + SYSTEM_CLOCK_SOURCE_OSC8M = GCLK_SOURCE_OSC8M, + /** Internal 32kHz RC oscillator */ + SYSTEM_CLOCK_SOURCE_OSC32K = GCLK_SOURCE_OSC32K, + /** External oscillator */ + SYSTEM_CLOCK_SOURCE_XOSC = GCLK_SOURCE_XOSC , + /** External 32kHz oscillator */ + SYSTEM_CLOCK_SOURCE_XOSC32K = GCLK_SOURCE_XOSC32K, + /** Digital Frequency Locked Loop (DFLL) */ + SYSTEM_CLOCK_SOURCE_DFLL = GCLK_SOURCE_DFLL48M, + /** Internal Ultra Low Power 32kHz oscillator */ + SYSTEM_CLOCK_SOURCE_ULP32K = GCLK_SOURCE_OSCULP32K, + /** Generator input pad */ + SYSTEM_CLOCK_SOURCE_GCLKIN = GCLK_SOURCE_GCLKIN, + /** Generic clock generator 1 output */ + SYSTEM_CLOCK_SOURCE_GCLKGEN1 = GCLK_SOURCE_GCLKGEN1, +#ifdef FEATURE_SYSTEM_CLOCK_DPLL + /** Digital Phase Locked Loop (DPLL). */ + SYSTEM_CLOCK_SOURCE_DPLL = GCLK_SOURCE_FDPLL, +#endif +}; + +/** + * Available bus clock domains on the APB bus. + */ +enum system_clock_apb_bus { + /** Peripheral bus A on the APB bus. */ + SYSTEM_CLOCK_APB_APBA, + /** Peripheral bus B on the APB bus. */ + SYSTEM_CLOCK_APB_APBB, + /** Peripheral bus C on the APB bus. */ + SYSTEM_CLOCK_APB_APBC, +}; + +/** + * Possible NVM flash wait state settings + */ +enum system_wait_states { + /** Wait state maximum frequencies at 1.8V */ + SYSTEM_WAIT_STATE_1_8V_14MHZ = 0, + SYSTEM_WAIT_STATE_1_8V_28MHZ = 1, + SYSTEM_WAIT_STATE_1_8V_42MHZ = 2, + SYSTEM_WAIT_STATE_1_8V_48MHZ = 3, + /** Wait state maximum frequencies at 3.3V */ + SYSTEM_WAIT_STATE_3_3V_24MHZ = 0, + SYSTEM_WAIT_STATE_3_3V_48MHZ = 1, +}; + +void system_clock_source_osc8m_set_config(enum system_osc8m_div prescaler, + bool run_in_standby, + bool on_demand); +void system_clock_source_osc8m_set_config_default(void); + +void system_clock_source_osc32k_set_config(enum system_osc32k_startup startup_time, + bool enable_1khz_output, + bool enable_32khz_output, + bool run_in_standby, + bool on_demand, + bool write_once); +void system_clock_source_osc32k_set_config_default(void); + +void system_clock_source_xosc_set_config(enum system_clock_external external_clock, + enum system_xosc_startup startup_time, + bool auto_gain_control, + uint32_t frequency, + bool run_in_standby, + bool on_demand); +void system_clock_source_xosc_set_config_default(void); + +void system_clock_source_xosc32k_set_config(enum system_clock_external external_clock, + enum system_xosc32k_startup startup_time, + bool auto_gain_control, + bool enable_1khz_output, + bool enable_32khz_output, + bool run_in_standby, + bool on_demand, + bool write_once); +void system_clock_source_xosc32k_set_config_default(void); + +void system_clock_source_dfll_set_config( + enum system_clock_dfll_loop_mode loop_mode, + bool on_demand, + enum system_clock_dfll_quick_lock quick_lock, + enum system_clock_dfll_chill_cycle chill_cycle, + enum system_clock_dfll_wakeup_lock wakeup_lock, + enum system_clock_dfll_stable_tracking stable_tracking, + uint8_t coarse_value, + uint16_t fine_value, + uint8_t coarse_max_step, + uint16_t fine_max_step, + uint16_t multiply_factor); +void system_clock_source_dfll_set_config_default(void); + +enum clock_status_t system_clock_source_write_calibration( + const enum system_clock_source system_clock_source, + const uint16_t calibration_value, + const uint8_t freq_range); + +enum clock_status_t system_clock_source_enable( + const enum system_clock_source system_clock_source); + +enum clock_status_t system_clock_source_disable( + const enum system_clock_source clk_source); + +bool system_clock_source_is_ready( + const enum system_clock_source clk_source); + +uint32_t system_clock_source_get_hz( + const enum system_clock_source clk_source); + +/** + * Enable or disable the main clock failure detection. + * + * This mechanism allows switching automatically the main clock to the safe + * RCSYS clock, when the main clock source is considered off. + * + * This may happen for instance when an external crystal is selected as the + * clock source of the main clock and the crystal dies. The mechanism is to + * detect, during a RCSYS period, at least one rising edge of the main clock. + * If no rising edge is seen the clock is considered failed. + * As soon as the detector is enabled, the clock failure detector + * CFD) will monitor the divided main clock. When a clock failure is detected, + * the main clock automatically switches to the RCSYS clock and the CFD + * interrupt is generated if enabled. + * + * \note The failure detect must be disabled if the system clock is the same or + * slower than 32kHz as it will believe the system clock has failed with + * a too-slow clock. + * + * \param[in] enable Boolean \c true to enable, \c false to disable detection + */ +static inline void system_main_clock_set_failure_detect(const bool enable) +{ + if (enable) { +// PM->CTRL.reg |= PM_CTRL_CFDEN; + } else { +// PM->CTRL.reg &= ~PM_CTRL_CFDEN; + } +} + +/** + * Sets the clock divider used on the main clock to provide the CPU clock. + * + * \param[in] divider CPU clock divider to set + */ +static inline void system_cpu_clock_set_divider( + const enum system_main_clock_div divider) +{ + + PM->CPUSEL.reg = (uint32_t)divider; +} + +/** + * Retrieves the operating frequency of the CPU core, obtained from the main + * generic clock and the set CPU bus divider. + * + * \return Current CPU frequency in Hz. + */ +static inline uint32_t system_cpu_clock_get_hz(void) +{ + return (system_gclk_gen_get_hz(GCLK_GENERATOR_0) >> PM->CPUSEL.reg); +} + +/** + * Set APBx clock divider. + * + * Set the clock divider used on the main clock to provide the clock for the + * given APBx bus. + * + * \param[in] divider APBx bus divider to set + * \param[in] bus APBx bus to set divider for + * + * \returns Status of the clock division change operation. + * + * \retval STATUS_ERR_INVALID_ARG Invalid bus ID was given + * \retval STATUS_OK The APBx clock was set successfully + */ +static inline enum clock_status_t system_apb_clock_set_divider( + const enum system_clock_apb_bus bus, + const enum system_main_clock_div divider) +{ + switch (bus) { + case SYSTEM_CLOCK_APB_APBA: + PM->APBASEL.reg = (uint32_t)divider; + break; + case SYSTEM_CLOCK_APB_APBB: + PM->APBBSEL.reg = (uint32_t)divider; + break; + case SYSTEM_CLOCK_APB_APBC: + PM->APBCSEL.reg = (uint32_t)divider; + break; + default: + + return CLOCK_STATUS_INVALID_ARG; + } + + return CLOCK_STATUS_OK; +} + +/** + * Retrieves the operating frequency of an APBx bus, obtained from the main + * generic clock and the set APBx bus divider. + * + * \return Current APBx bus frequency in Hz. + */ +static inline uint32_t system_apb_clock_get_hz( + const enum system_clock_apb_bus bus) +{ + uint16_t bus_divider = 0; + + switch (bus) { + case SYSTEM_CLOCK_APB_APBA: + bus_divider = PM->APBASEL.reg; + break; + case SYSTEM_CLOCK_APB_APBB: + bus_divider = PM->APBBSEL.reg; + break; + case SYSTEM_CLOCK_APB_APBC: + bus_divider = PM->APBCSEL.reg; + break; + default: + + return 0; + } + + return (system_gclk_gen_get_hz(GCLK_GENERATOR_0) >> bus_divider); +} + + +/** + * Set bits in the clock mask for the AHB bus. + * + * This function will set bits in the clock mask for the AHB bus. + * Any bits set to 1 will enable that clock, 0 bits in the mask + * will be ignored + * + * \param[in] ahb_mask AHB clock mask to enable + */ +static inline void system_ahb_clock_set_mask(const uint32_t ahb_mask) +{ + PM->AHBMASK.reg |= ahb_mask; +} + +/** + * Clear bits in the clock mask for the AHB bus. + * + * This function will clear bits in the clock mask for the AHB bus. + * Any bits set to 1 will disable that clock, 0 bits in the mask + * will be ignored. + * + * \param[in] ahb_mask AHB clock mask to disable + */ +static inline void system_ahb_clock_clear_mask(const uint32_t ahb_mask) +{ + PM->AHBMASK.reg &= ~ahb_mask; +} + +/** + * Set bits in the clock mask for an APBx bus. + * + * This function will set bits in the clock mask for an APBx bus. + * Any bits set to 1 will enable the corresponding module clock, zero bits in + * the mask will be ignored. + * + * \param[in] mask APBx clock mask, a \c SYSTEM_CLOCK_APB_APBx constant from + * the device header files + * \param[in] bus Bus to set clock mask bits for, a mask of \c PM_APBxMASK_* + * constants from the device header files + * + * \returns Status indicating the result of the clock mask change operation. + * + * \retval STATUS_ERR_INVALID_ARG Invalid bus given + * \retval STATUS_OK The clock mask was set successfully + */ +static inline enum clock_status_t system_apb_clock_set_mask( + const enum system_clock_apb_bus bus, + const uint32_t mask) +{ + switch (bus) { + case SYSTEM_CLOCK_APB_APBA: + PM->APBAMASK.reg |= mask; + break; + + case SYSTEM_CLOCK_APB_APBB: + PM->APBBMASK.reg |= mask; + break; + + case SYSTEM_CLOCK_APB_APBC: + PM->APBCMASK.reg |= mask; + break; + + default: + + return CLOCK_STATUS_INVALID_ARG; + + } + + return CLOCK_STATUS_OK; +} + +/** + * Clear bits in the clock mask for an APBx bus. + * + * This function will clear bits in the clock mask for an APBx bus. + * Any bits set to 1 will disable the corresponding module clock, zero bits in + * the mask will be ignored. + * + * \param[in] mask APBx clock mask, a \c SYSTEM_CLOCK_APB_APBx constant from + * the device header files + * \param[in] bus Bus to clear clock mask bits for + * + * \returns Status indicating the result of the clock mask change operation. + * + * \retval STATUS_ERR_INVALID_ARG Invalid bus ID was given. + * \retval STATUS_OK The clock mask was changed successfully. + */ +static inline enum clock_status_t system_apb_clock_clear_mask( + const enum system_clock_apb_bus bus, + const uint32_t mask) +{ + switch (bus) { + case SYSTEM_CLOCK_APB_APBA: + PM->APBAMASK.reg &= ~mask; + break; + + case SYSTEM_CLOCK_APB_APBB: + PM->APBBMASK.reg &= ~mask; + break; + + case SYSTEM_CLOCK_APB_APBC: + PM->APBCMASK.reg &= ~mask; + break; + + default: + + return CLOCK_STATUS_INVALID_ARG; + } + + return CLOCK_STATUS_OK; +} + +#ifdef FEATURE_SYSTEM_CLOCK_DPLL +/** + * Reference clock source of the DPLL module + */ +enum system_clock_source_dpll_reference_clock { + /** Select CLK_DPLL_REF0 as clock reference */ + SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_REF0, + /** Select CLK_DPLL_REF1 as clock reference */ + SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_REF1, + /** Select GCLK_DPLL as clock reference */ + SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_GCLK, +}; + +/** + * Lock time-out value of the DPLL module + */ +enum system_clock_source_dpll_lock_time { + /** Set no time-out as default */ + SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT, + /** Set time-out if no lock within 8 ms */ + SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_8MS = 0x04, + /** Set time-out if no lock within 9 ms */ + SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_9MS, + /** Set time-out if no lock within 10 ms */ + SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_10MS, + /** Set time-out if no lock within 11 ms */ + SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_11MS, +}; + +/** + * Filter type of the DPLL module + */ +enum system_clock_source_dpll_filter { + /** Default filter mode */ + SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT, + /** Low bandwidth filter */ + SYSTEM_CLOCK_SOURCE_DPLL_FILTER_LOW_BANDWIDTH_FILTER, + /** High bandwidth filter */ + SYSTEM_CLOCK_SOURCE_DPLL_FILTER_HIGH_BANDWIDTH_FILTER, + /** High damping filter */ + SYSTEM_CLOCK_SOURCE_DPLL_FILTER_HIGH_DAMPING_FILTER, +}; + +/** + * Configuration structure for DPLL + * + * DPLL oscillator configuration structure. + */ +struct system_clock_source_dpll_config { + /** Run On Demand. If this is set the DPLL won't run + * until requested by a peripheral */ + bool on_demand; + /** Keep the DPLL enabled in standby sleep mode */ + bool run_in_standby; + /** Bypass lock signal */ + bool lock_bypass; + /** Wake up fast. If this is set DPLL output clock is enabled after + * the startup time */ + bool wake_up_fast; + /** Enable low power mode */ + bool low_power_enable; + + /** Output frequency of the clock */ + uint32_t output_frequency; + /** Reference frequency of the clock */ + uint32_t reference_frequency; + /** Devider of reference clock */ + uint16_t reference_divider; + + /** Filter type of the DPLL module */ + enum system_clock_source_dpll_filter filter; + /** Lock time-out value of the DPLL module */ + enum system_clock_source_dpll_lock_time lock_time; + /** Reference clock source of the DPLL module */ + enum system_clock_source_dpll_reference_clock reference_clock; +}; + +/** + * \brief Retrieve the default configuration for DPLL + * + * Fills a configuration structure with the default configuration for a + * DPLL oscillator module: + * - Run only when requested by peripheral (on demand) + * - Don't run in STANDBY sleep mode + * - Lock bypass disabled + * - Fast wake up disabled + * - Low power mode disabled + * - Output frequency is 48MHz + * - Reference clock frequency is 32768Hz + * - Not divide reference clock + * - Select REF0 as reference clock + * - Set lock time to default mode + * - Use default filter + * + * \param[out] config Configuration structure to fill with default values + */ +static inline void system_clock_source_dpll_get_config_defaults( + struct system_clock_source_dpll_config *const config) +{ + config->on_demand = true; + config->run_in_standby = false; + config->lock_bypass = false; + config->wake_up_fast = false; + config->low_power_enable = false; + + config->output_frequency = 48000000; + config->reference_frequency = 32768; + config->reference_divider = 1; + config->reference_clock = SYSTEM_CLOCK_SOURCE_DPLL_REFERENCE_CLOCK_REF0; + + config->lock_time = SYSTEM_CLOCK_SOURCE_DPLL_LOCK_TIME_DEFAULT; + config->filter = SYSTEM_CLOCK_SOURCE_DPLL_FILTER_DEFAULT; +}; + +void system_clock_source_dpll_set_config( + struct system_clock_source_dpll_config *const config); + +#endif + +void system_clock_init(void); + +/** + * Set flash controller wait states + * + * Will set the number of wait states that are used by the onboard + * flash memory. The number of wait states depend on both device + * supply voltage and CPU speed. The required number of wait states + * can be found in the electrical characteristics of the device. + * + * \param[in] wait_states Number of wait states to use for internal flash + */ +static inline void system_flash_set_waitstates(const enum system_wait_states wait_states) +{ + NVMCTRL->CTRLB.bit.RWS = wait_states; +} + +/** + * - This driver implements workaround for errata 10558 + * + * "Several reset values of SYSCTRL.INTFLAG are wrong (BOD and DFLL)" + * When system_init is called it will reset these interrupts flags before they are used. + * + * - This driver implements experimental workaround for errata 9905 + * + * "The DFLL clock must be requested before being configured otherwise a + * write access to a DFLL register can freeze the device." + * This driver will enable and configure the DFLL before the ONDEMAND bit is set. + * + */ + +#endif /* SYSTEM_CLOCK_H_INCLUDED */ diff --git a/loader/inc/system/clock_config_check.h b/loader/inc/system/clock_config_check.h new file mode 100644 index 0000000..155aa91 --- /dev/null +++ b/loader/inc/system/clock_config_check.h @@ -0,0 +1,373 @@ +/** + * SAM D20 Clock Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef CLOCK_CONFIG_CHECK_H +#define CLOCK_CONFIG_CHECK_H + +#if !defined(CONF_CLOCK_FLASH_WAIT_STATES) +# error CONF_CLOCK_FLASH_WAIT_STATES not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_CPU_DIVIDER) +# error CONF_CLOCK_CPU_DIVIDER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_APBA_DIVIDER) +# error CONF_CLOCK_APBA_DIVIDER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_APBB_DIVIDER) +# error CONF_CLOCK_APBB_DIVIDER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC8M_PRESCALER) +# error CONF_CLOCK_OSC8M_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC8M_ON_DEMAND) +# error CONF_CLOCK_OSC8M_ON_DEMAND not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC8M_RUN_IN_STANDBY) +# error CONF_CLOCK_OSC8M_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_ENABLE) +# error CONF_CLOCK_XOSC_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL) +# error CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY) +# error CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_STARTUP_TIME) +# error CONF_CLOCK_XOSC_STARTUP_TIME not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL) +# error CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_ON_DEMAND) +# error CONF_CLOCK_XOSC_ON_DEMAND not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC_RUN_IN_STANDBY) +# error CONF_CLOCK_XOSC_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_ENABLE) +# error CONF_CLOCK_XOSC32K_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL) +# error CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_STARTUP_TIME) +# error CONF_CLOCK_XOSC32K_STARTUP_TIME not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL) +# error CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT) +# error CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT) +# error CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_ON_DEMAND) +# error CONF_CLOCK_XOSC32K_ON_DEMAND not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_XOSC32K_RUN_IN_STANDBY) +# error CONF_CLOCK_XOSC32K_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_ENABLE) +# error CONF_CLOCK_OSC32K_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_STARTUP_TIME) +# error CONF_CLOCK_OSC32K_STARTUP_TIME not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT) +# error CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT) +# error CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_ON_DEMAND) +# error CONF_CLOCK_OSC32K_ON_DEMAND not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_OSC32K_RUN_IN_STANDBY) +# error CONF_CLOCK_OSC32K_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_ENABLE) +# error CONF_CLOCK_DFLL_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_LOOP_MODE) +# error CONF_CLOCK_DFLL_LOOP_MODE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_ON_DEMAND) +# error CONF_CLOCK_DFLL_ON_DEMAND not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_COARSE_VALUE) +# error CONF_CLOCK_DFLL_COARSE_VALUE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_FINE_VALUE) +# error CONF_CLOCK_DFLL_FINE_VALUE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR) +# error CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_MULTIPLY_FACTOR) +# error CONF_CLOCK_DFLL_MULTIPLY_FACTOR not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_QUICK_LOCK) +# error CONF_CLOCK_DFLL_QUICK_LOCK not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK) +# error CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP) +# error CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE) +# error CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE) +# error CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE) +# error CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_CONFIGURE_GCLK) +# error CONF_CLOCK_CONFIGURE_GCLK not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_0_ENABLE) +# error CONF_CLOCK_GCLK_0_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_0_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_0_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_0_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_0_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_0_PRESCALER) +# error CONF_CLOCK_GCLK_0_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_0_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_0_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_1_ENABLE) +# error CONF_CLOCK_GCLK_1_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_1_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_1_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_1_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_1_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_1_PRESCALER) +# error CONF_CLOCK_GCLK_1_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_1_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_1_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_2_ENABLE) +# error CONF_CLOCK_GCLK_2_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_2_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_2_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_2_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_2_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_2_PRESCALER) +# error CONF_CLOCK_GCLK_2_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_2_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_2_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_3_ENABLE) +# error CONF_CLOCK_GCLK_3_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_3_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_3_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_3_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_3_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_3_PRESCALER) +# error CONF_CLOCK_GCLK_3_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_3_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_3_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_4_ENABLE) +# error CONF_CLOCK_GCLK_4_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_4_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_4_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_4_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_4_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_4_PRESCALER) +# error CONF_CLOCK_GCLK_4_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_4_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_4_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_5_ENABLE) +# error CONF_CLOCK_GCLK_5_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_5_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_5_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_5_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_5_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_5_PRESCALER) +# error CONF_CLOCK_GCLK_5_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_5_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_5_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_6_ENABLE) +# error CONF_CLOCK_GCLK_6_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_6_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_6_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_6_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_6_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_6_PRESCALER) +# error CONF_CLOCK_GCLK_6_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_6_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_6_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_7_ENABLE) +# error CONF_CLOCK_GCLK_7_ENABLE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_7_RUN_IN_STANDBY) +# error CONF_CLOCK_GCLK_7_RUN_IN_STANDBY not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_7_CLOCK_SOURCE) +# error CONF_CLOCK_GCLK_7_CLOCK_SOURCE not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_7_PRESCALER) +# error CONF_CLOCK_GCLK_7_PRESCALER not defined in conf_clock.h +#endif + +#if !defined(CONF_CLOCK_GCLK_7_OUTPUT_ENABLE) +# error CONF_CLOCK_GCLK_7_OUTPUT_ENABLE not defined in conf_clock.h +#endif + +#endif /* CLOCK_CONFIG_CHECK_H */ diff --git a/loader/inc/system/conf_clocks.h b/loader/inc/system/conf_clocks.h new file mode 100644 index 0000000..9c4e2bd --- /dev/null +++ b/loader/inc/system/conf_clocks.h @@ -0,0 +1,164 @@ +/** + * SAM D20 Clock configuration + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include + +#ifndef CONF_CLOCKS_H_INCLUDED +#define CONF_CLOCKS_H_INCLUDED + +/* System clock bus configuration */ +# define CONF_CLOCK_FLASH_WAIT_STATES 0 +# define CONF_CLOCK_CPU_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 +# define CONF_CLOCK_APBA_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 +# define CONF_CLOCK_APBB_DIVIDER SYSTEM_MAIN_CLOCK_DIV_1 + +/* SYSTEM_CLOCK_SOURCE_OSC8M configuration - Internal 8MHz oscillator */ +# define CONF_CLOCK_OSC8M_PRESCALER SYSTEM_OSC8M_DIV_1 +# define CONF_CLOCK_OSC8M_ON_DEMAND true +# define CONF_CLOCK_OSC8M_RUN_IN_STANDBY false + +/* SYSTEM_CLOCK_SOURCE_XOSC configuration - External clock/oscillator */ +# define CONF_CLOCK_XOSC_ENABLE false +# define CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL +# define CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY 12000000UL +# define CONF_CLOCK_XOSC_STARTUP_TIME SYSTEM_XOSC_STARTUP_32768 +# define CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL true +# define CONF_CLOCK_XOSC_ON_DEMAND true +# define CONF_CLOCK_XOSC_RUN_IN_STANDBY false + +/* SYSTEM_CLOCK_SOURCE_XOSC32K configuration - External 32KHz crystal/clock oscillator */ +# define CONF_CLOCK_XOSC32K_ENABLE false +# define CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL SYSTEM_CLOCK_EXTERNAL_CRYSTAL +# define CONF_CLOCK_XOSC32K_STARTUP_TIME SYSTEM_XOSC32K_STARTUP_65536 +# define CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL false +# define CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT false +# define CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT true +# define CONF_CLOCK_XOSC32K_ON_DEMAND true +# define CONF_CLOCK_XOSC32K_RUN_IN_STANDBY false + +/* SYSTEM_CLOCK_SOURCE_OSC32K configuration - Internal 32KHz oscillator */ +# define CONF_CLOCK_OSC32K_ENABLE false +# define CONF_CLOCK_OSC32K_STARTUP_TIME SYSTEM_OSC32K_STARTUP_130 +# define CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT true +# define CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT true +# define CONF_CLOCK_OSC32K_ON_DEMAND true +# define CONF_CLOCK_OSC32K_RUN_IN_STANDBY false + +/* SYSTEM_CLOCK_SOURCE_DFLL configuration - Digital Frequency Locked Loop */ +# define CONF_CLOCK_DFLL_ENABLE false +# define CONF_CLOCK_DFLL_LOOP_MODE SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN +# define CONF_CLOCK_DFLL_ON_DEMAND false + +/* DFLL open loop mode configuration */ +# define CONF_CLOCK_DFLL_COARSE_VALUE (0x1f / 4) +# define CONF_CLOCK_DFLL_FINE_VALUE (0xff / 4) + +/* DFLL closed loop mode configuration */ +# define CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR GCLK_GENERATOR_1 +# define CONF_CLOCK_DFLL_MULTIPLY_FACTOR 6 +# define CONF_CLOCK_DFLL_QUICK_LOCK true +# define CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK true +# define CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP true +# define CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE true +# define CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE (0x1f / 4) +# define CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE (0xff / 4) + + +/* Set this to true to configure the GCLK when running clocks_init. If set to + * false, none of the GCLK generators will be configured in clocks_init(). */ +# define CONF_CLOCK_CONFIGURE_GCLK true + +/* Configure GCLK generator 0 (Main Clock) */ +# define CONF_CLOCK_GCLK_0_ENABLE true +# define CONF_CLOCK_GCLK_0_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_0_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_0_PRESCALER 1 +# define CONF_CLOCK_GCLK_0_OUTPUT_ENABLE false + +/* Configure GCLK generator 1 */ +# define CONF_CLOCK_GCLK_1_ENABLE false +# define CONF_CLOCK_GCLK_1_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_1_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_1_PRESCALER 1 +# define CONF_CLOCK_GCLK_1_OUTPUT_ENABLE false + +/* Configure GCLK generator 2 (RTC) */ +# define CONF_CLOCK_GCLK_2_ENABLE false +# define CONF_CLOCK_GCLK_2_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_2_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC32K +# define CONF_CLOCK_GCLK_2_PRESCALER 32 +# define CONF_CLOCK_GCLK_2_OUTPUT_ENABLE false + +/* Configure GCLK generator 3 */ +# define CONF_CLOCK_GCLK_3_ENABLE false +# define CONF_CLOCK_GCLK_3_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_3_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_3_PRESCALER 1 +# define CONF_CLOCK_GCLK_3_OUTPUT_ENABLE false + +/* Configure GCLK generator 4 */ +# define CONF_CLOCK_GCLK_4_ENABLE false +# define CONF_CLOCK_GCLK_4_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_4_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_4_PRESCALER 1 +# define CONF_CLOCK_GCLK_4_OUTPUT_ENABLE false + +/* Configure GCLK generator 5 */ +# define CONF_CLOCK_GCLK_5_ENABLE false +# define CONF_CLOCK_GCLK_5_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_5_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_5_PRESCALER 1 +# define CONF_CLOCK_GCLK_5_OUTPUT_ENABLE false + +/* Configure GCLK generator 6 */ +# define CONF_CLOCK_GCLK_6_ENABLE false +# define CONF_CLOCK_GCLK_6_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_6_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_6_PRESCALER 1 +# define CONF_CLOCK_GCLK_6_OUTPUT_ENABLE false + +/* Configure GCLK generator 7 */ +# define CONF_CLOCK_GCLK_7_ENABLE false +# define CONF_CLOCK_GCLK_7_RUN_IN_STANDBY false +# define CONF_CLOCK_GCLK_7_CLOCK_SOURCE SYSTEM_CLOCK_SOURCE_OSC8M +# define CONF_CLOCK_GCLK_7_PRESCALER 1 +# define CONF_CLOCK_GCLK_7_OUTPUT_ENABLE false + +#endif /* CONF_CLOCKS_H_INCLUDED */ diff --git a/loader/inc/system/events.h b/loader/inc/system/events.h new file mode 100644 index 0000000..4161cfa --- /dev/null +++ b/loader/inc/system/events.h @@ -0,0 +1,335 @@ +/** + * SAM D20/D21/R21 Event System Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef EVENTS_H_INCLUDED +#define EVENTS_H_INCLUDED + +#include "samd20.h" +#include "system/system.h" + +/** + * Event System Driver (EVENTS) + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the device's peripheral event resources and users within + * the device, including enabling and disabling of peripheral source selection + * and synchronization of clock domains between various modules. The following API + * modes is covered by this manual: + * - Polled API + * + * The following peripherals are used by this module: + * + * - EVSYS (Event System Management) + * + * Module Overview + * + * Peripherals within the SAM D20/D21/R21 devices are capable of generating two types of + * actions in response to given stimulus: set a register flag for later + * intervention by the CPU (using interrupt or polling methods), or generate + * event signals which can be internally routed directly to other + * peripherals within the device. The use of events allows for direct actions + * to be performed in one peripheral in response to a stimulus in another + * without CPU intervention. This can lower the overall power consumption of the + * system if the CPU is able to remain in sleep modes for longer periods (SleepWalking™), and + * lowers the latency of the system response. + * + * The event system is comprised of a number of freely configurable Event + * resources, plus a number of fixed Event Users. Each Event resource can be + * configured to select the input peripheral that will generate the events + * signal, as well as the synchronization path and edge detection mode. + * The fixed-function Event Users, connected to peripherals within the device, + * can then subscribe to an Event resource in a one-to-many relationship in order + * to receive events as they are generated. An overview of the event system + * chain is shown in + * + * There are many different events that can be routed in the device, which can + * then trigger many different actions. For example, an Analog Comparator module + * could be configured to generate an event when the input signal rises above + * the compare threshold, which then triggers a Timer Counter module to capture + * the current count value for later use. + * + * Event Channels + * + * The Event module in each device consists of several channels, which can be + * freely linked to an event generator (i.e. a peripheral within the device + * that is capable of generating events). Each channel can be individually + * configured to select the generator peripheral, signal path and edge detection + * applied to the input event signal, before being passed to any event user(s). + * + * Event channels can support multiple users within the device in a standardized + * manner; when an Event User is linked to an Event Channel, the channel will + * automatically handshake with all attached users to ensure that all modules + * correctly receive and acknowledge the event. + * + * Event Users + * + * Event Users are able to subscribe to an Event Channel, once it has been + * configured. Each Event User consists of a fixed connection to one of the + * peripherals within the device (for example, an ADC module or Timer module) + * and is capable of being connected to a single Event Channel. + * + * Edge Detection + * + * For asynchronous events, edge detection on the event input is not possible, + * and the event signal must be passed directly between the event generator and + * event user. For synchronous and re-synchronous events, the input signal from + * the event generator must pass through an edge detection unit, so that only + * the rising, falling or both edges of the event signal triggers an action in + * the event user. + * + * Path Selection + * + * The event system in the SAM D20/D21/R21 devices supports three signal path types from + * the event generator to event users: asynchronous, synchronous and + * re-synchronous events. + * + * Asynchronous Paths + * + * Asynchronous event paths allow for an asynchronous connection between the + * event generator and event user(s), when the source and destination + * peripherals share the same "Generic Clock" + * channel. In this mode the event is propagated between the source and + * destination directly to reduce the event latency, thus no edge detection is + * possible. + * + * Synchronous Paths + * + * The Synchronous event path should be used when edge detection or interrupts + * from the event channel are required, and the source event generator and the + * event channel shares the same Generic Clock channel. + * + * Re-synchronous Paths + * + * Re-synchronous event paths are a special form of synchronous events, where + * when edge detection or interrupts from the event channel are required, but + * the event generator and the event channel use different Generic Clock + * channels. The re-synchronous path allows the Event System to synchronize the + * incoming event signal from the Event Generator to the clock of the Event + * System module to avoid missed events, at the cost of a higher latency due to + * the re-synchronization process. + * + * + * Configuring Events + * + * For SAM D20/D21/R21 devices, several steps are required to properly configure an + * event chain, so that hardware peripherals can respond to events generated by + * each other, listed below. + * + * Source Peripheral + * -# The source peripheral (that will generate events) must be configured and + * enabled. + * -# The source peripheral (that will generate events) must have an output + * event enabled. + * + * Event System + * -# An event system channel must be allocated and configured with the + * correct source peripheral selected as the channel's event generator. + * -# The event system user must be configured and enabled, and attached to + # event channel previously allocated. + * + * Destination Peripheral + * -# The destination peripheral (that will receive events) must be configured + * and enabled. + * -# The destination peripheral (that will receive events) must have an input + * event enabled. + * + */ + + +enum status_code { + STATUS_OK, + STATUS_BUSY, + STATUS_ERR_INVALID_ARG, + STATUS_ERR_OVERFLOW, + STATUS_ERR_DENIED, + STATUS_ERR_BAUDRATE_UNAVAILABLE, + STATUS_ERR_PACKET_COLLISION, + STATUS_ERR_BAD_ADDRESS, +STATUS_ERR_TIMEOUT +}; + + +/** + * Edge detect enum + * + * Event channel edge detect setting + * + */ +enum events_edge_detect { + /** No event output */ + EVENTS_EDGE_DETECT_NONE, + /** Event on rising edge */ + EVENTS_EDGE_DETECT_RISING, + /** Event on falling edge */ + EVENTS_EDGE_DETECT_FALLING, + /** Event on both edges */ + EVENTS_EDGE_DETECT_BOTH, +}; + +/** + * Path selection enum + * + * Event channel path selection + * + */ +enum events_path_selection { + /** Select the synchronous path for this event channel */ + EVENTS_PATH_SYNCHRONOUS, + /** Select the resynchronizer path for this event channel */ + EVENTS_PATH_RESYNCHRONIZED, + /** Select the asynchronous path for this event channel */ + EVENTS_PATH_ASYNCHRONOUS, +}; + +/** Definition for no generator selection */ +#define EVSYS_ID_GEN_NONE 0 +/** Definition for no user selection */ +#define EVSYS_ID_USER_NONE 0 + + + +void system_events_init(void); + +/** + * Allocate an event channel and set configuration + * + * Allocates an event channel from the event channel pool and sets + * the channel configuration. + * + * \param[out] resource Pointer to a \ref events_resource struct instance + * \param[in] config Pointer to a \ref events_config struct + * + * \return Status of the configuration procedure + * \retval STATUS_OK Allocation and configuration went successful + * \retval STATUS_ERR_NOT_FOUND No free event channel found + * + */ +enum status_code events_allocate(uint8_t channel, + enum events_edge_detect edge_detect, /** edge detection mode */ + enum events_path_selection path, /** events channel path */ + uint8_t generator, /** event generator for the channel */ + uint8_t clock_source); /** clock source for the event channel */ + +/** + * Attach user to the event channel + * + * Attach a user peripheral to the event channel to receive events. + * + * \param[in] resource Pointer to an \ref events_resource struct instance + * \param[in] user_id A number identifying the user peripheral found in the device header file. + * + * \return Status of the user attach procedure + * \retval STATUS_OK No errors detected when attaching the event user + */ +enum status_code events_attach_user(uint8_t channel, uint8_t user_id); + +/** + * Check if a channel is busy + * + * Check if a channel is busy, a channels stays busy until all users connected to the channel + * has handled an event + * + * \param[in] resource Pointer to a \ref events_resource struct instance + * + * \return Status of the channels busy state + * \retval true One or more users connected to the channel has not handled the last event + * \retval false All users are ready handle new events + */ +bool events_is_busy(uint8_t channel); + +/** + * Trigger software event + * + * Trigger an event by software + * + * \param[in] resource Pointer to an \ref events_resource struct + * + * \return Status of the event software procedure + * \retval STATUS_OK No error was detected when software tigger signal was issued + * \retval STATUS_ERR_UNSUPPORTED_DEV If the channel path is asynchronous and/or the + * edge detection is not set to RISING + */ +enum status_code events_trigger(uint8_t channel); + +/** + * Check if all users connected to the channel is ready + * + * Check if all users connected to the channel is ready to handle incomming events + * + * \param[in] resource Pointer to an \ref events_resource struct + * + * \return The ready status of users connected to an event channel + * \retval true All users connect to event channel is ready handle incomming events + * \retval false One or more users connect to event channel is not ready to handle incomming events + */ +bool events_is_users_ready(uint8_t channel); + +/** + * Check if event is detected on event channel + * + * Check if an event has been detected on the channel + * + * \note This function will clear the event detected interrupt flag + * + * \param[in] resource Pointer to an \ref events_resource struct + * + * \return Status of the event detection interrupt flag + * \retval true Event has been detected + * \retval false Event has not been detected + */ +bool events_is_detected(uint8_t channel); + +/** + * Check if there has been an overrun situation on this channel + * + * Check if there has been an overrun situation on this channel + * + * \note This function will clear the event overrun detected interrupt flag + * + * \param[in] resource Pointer to an \ref events_resource struct + * + * \return Status of the event overrun interrupt flag + * \retval true Event overrun has been detected + * \retval false Event overrun has not been detected + */ +bool events_is_overrun(uint8_t channel); + + +#endif /* EVENTS_H_INCLUDED */ diff --git a/loader/inc/system/extint.h b/loader/inc/system/extint.h new file mode 100644 index 0000000..9d8efea --- /dev/null +++ b/loader/inc/system/extint.h @@ -0,0 +1,437 @@ +/** + * SAM D20/D21/R21 External Interrupt Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef EXTINT_H_INCLUDED +#define EXTINT_H_INCLUDED + +/** + * SAM D20/D21/R21 External Interrupt Driver (EXTINT) + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of external interrupts generated by the physical device pins, + * including edge detection. + * + * Module Overview + * + * The External Interrupt (EXTINT) module provides a method of asynchronously + * detecting rising edge, falling edge or specific level detection on individual + * I/O pins of a device. This detection can then be used to trigger a software + * interrupt or event, or polled for later use if required. External interrupts + * can also optionally be used to automatically wake up the device from sleep + * mode, allowing the device to conserve power while still being able to react + * to an external stimulus in a timely manner. + * + * Logical Channels + * + * The External Interrupt module contains a number of logical channels, each of + * which is capable of being individually configured for a given pin routing, + * detection mode and filtering/wake up characteristics. + * + * Each individual logical external interrupt channel may be routed to a single + * physical device I/O pin in order to detect a particular edge or level of the + * incoming signal. + * + * NMI Channels + * + * One or more Non Maskable Interrupt (NMI) channels are provided within each + * physical External Interrupt Controller module, allowing a single physical pin + * of the device to fire a single NMI interrupt in response to a particular + * edge or level stimulus. A NMI cannot, as the name suggests, be disabled in + * firmware and will take precedence over any in-progress interrupt sources. + * + * NMIs can be used to implement critical device features such as forced + * software reset or other functionality where the action should be executed in + * preference to all other running code with a minimum amount of latency. + * + * Input Filtering and Detection + * + * To reduce the possibility of noise or other transient signals causing + * unwanted device wake-ups, interrupts and/or events via an external interrupt + * channel, a hardware signal filter can be enabled on individual channels. This + * filter provides a Majority-of-Three voter filter on the incoming signal, so + * that the input state is considered to be the majority vote of three + * subsequent samples of the pin input buffer. + * + * Events and Interrupts + * + * Channel detection states may be polled inside the application for synchronous + * detection, or events and interrupts may be used for asynchronous behavior. + * Each channel can be configured to give an asynchronous hardware event (which + * may in turn trigger actions in other hardware modules) or an asynchronous + * software interrupt. + * + * Special Considerations + * + * Not all devices support disabling of the NMI channel(s) detection mode - see + * your device datasheet. + * + */ + +#include "samd20.h" +#include "system/pinmux.h" + +/** + * Configuration option, setting the EIC clock source which can be used for + * EIC edge detection or filtering. + */ +#define EXTINT_CLOCK_SOURCE GCLK_GENERATOR_0 + +/** + * External interrupt edge detection configuration enum. + * + * Enum for the possible signal edge detection modes of the External + * Interrupt Controller module. + */ +enum extint_detect { + /** No edge detection. Not allowed as a NMI detection mode on some + * devices. */ + EXTINT_DETECT_NONE = 0, + /** Detect rising signal edges. */ + EXTINT_DETECT_RISING = 1, + /** Detect falling signal edges. */ + EXTINT_DETECT_FALLING = 2, + /** Detect both signal edges. */ + EXTINT_DETECT_BOTH = 3, + /** Detect high signal levels. */ + EXTINT_DETECT_HIGH = 4, + /** Detect low signal levels. */ + EXTINT_DETECT_LOW = 5, +}; + +/** + * External interrupt internal pull configuration enum. + * + * Enum for the possible pin internal pull configurations. + * + * \note Disabling the internal pull resistor is not recommended if the driver + * is used in interrupt (callback) mode, due the possibility of floating + * inputs generating continuous interrupts. + */ +enum extint_pull { + /** Internal pull-up resistor is enabled on the pin. */ + EXTINT_PULL_UP = SYSTEM_PINMUX_PIN_PULL_UP, + /** Internal pull-down resistor is enabled on the pin. */ + EXTINT_PULL_DOWN = SYSTEM_PINMUX_PIN_PULL_DOWN, + /** Internal pull resistor is disconnected from the pin. */ + EXTINT_PULL_NONE = SYSTEM_PINMUX_PIN_PULL_NONE, +}; + +/** + * External Interrupt Controller channel configuration structure. + * + * Configuration structure for the edge detection mode of an external + * interrupt channel. + */ +struct extint_chan_conf { + /** GPIO pin the NMI should be connected to. */ + uint32_t gpio_pin; + /** MUX position the GPIO pin should be configured to. */ + uint32_t gpio_pin_mux; + /** Internal pull to enable on the input pin. */ + enum extint_pull gpio_pin_pull; + /** Wake up the device if the channel interrupt fires during sleep mode. */ + bool wake_if_sleeping; + /** Filter the raw input signal to prevent noise from triggering an + * interrupt accidentally, using a 3 sample majority filter. */ + bool filter_input_signal; + /** Edge detection mode to use. */ + enum extint_detect detection_criteria; +}; + +/** + * External Interrupt event enable/disable structure. + * + * Event flags for the \ref extint_enable_events() and + * \ref extint_disable_events(). + */ +struct extint_events { + /** If \c true, an event will be generated when an external interrupt + * channel detection state changes. */ + bool generate_event_on_detect[32 * EIC_INST_NUM]; +}; + +/** + * \brief External Interrupt Controller NMI configuration structure. + * + * Configuration structure for the edge detection mode of an external + * interrupt NMI channel. + */ +struct extint_nmi_conf { + /** GPIO pin the NMI should be connected to. */ + uint32_t gpio_pin; + /** MUX position the GPIO pin should be configured to. */ + uint32_t gpio_pin_mux; + /** Internal pull to enable on the input pin. */ + enum extint_pull gpio_pin_pull; + /** Filter the raw input signal to prevent noise from triggering an + * interrupt accidentally, using a 3 sample majority filter. */ + bool filter_input_signal; + /** Edge detection mode to use. Not all devices support all possible + * detection modes for NMIs. + */ + enum extint_detect detection_criteria; +}; + + + + +void system_extint_init(void); +void extint_enable(void); +void extint_disable(void); + +/** + * Retrieves the base EIC module address from a given channel number. + * + * Retrieves the base address of a EIC hardware module associated with the + * given external interrupt channel. + * + * \param[in] channel External interrupt channel index to convert. + * + * \return Base address of the associated EIC module. + */ +static inline Eic * _extint_get_eic_from_channel( + const uint8_t channel) +{ + uint8_t eic_index = (channel / 32); + + if (eic_index < EIC_INST_NUM) { + /* Array of available EICs. */ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + return eics[eic_index]; + } else { + return NULL; + } +} + +/** + * Retrieves the base EIC module address from a given NMI channel number. + * + * Retrieves the base address of a EIC hardware module associated with the + * given non-maskable external interrupt channel. + * + * \param[in] nmi_channel Non-Maskable interrupt channel index to convert. + * + * \return Base address of the associated EIC module. + */ +static inline Eic * _extint_get_eic_from_nmi( + const uint8_t nmi_channel) +{ + uint8_t eic_index = nmi_channel; + + if (eic_index < EIC_INST_NUM) { + /* Array of available EICs. */ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + return eics[eic_index]; + } else { + return NULL; + } +} + +/** + * Determines if the hardware module(s) are currently synchronizing to the bus. + * + * Checks to see if the underlying hardware peripheral module(s) are currently + * synchronizing across multiple clock domains to the hardware bus, This + * function can be used to delay further operations on a module until such time + * that it is ready, to prevent blocking delays for synchronization in the + * user application. + * + * \return Synchronization status of the underlying hardware module(s). + * + * \retval true If the module has completed synchronization + * \retval false If the module synchronization is ongoing + */ +static inline bool extint_is_syncing(void) +{ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + if (eics[i]->STATUS.reg & EIC_STATUS_SYNCBUSY) { + return true; + } + } + + return false; +} + +void extint_enable_events( + struct extint_events *const events); + +void extint_disable_events( + struct extint_events *const events); + +/** + * Initializes an External Interrupt channel configuration structure to defaults. + * + * Initializes a given External Interrupt channel configuration structure to a + * set of known default values. This function should be called on all new + * instances of these configuration structures before being modified by the + * user application. + * + * The default configuration is as follows: + * \li Wake the device if an edge detection occurs whilst in sleep + * \li Input filtering disabled + * \li Internal pull-up enabled + * \li Detect falling edges of a signal + * + * \param[out] config Configuration structure to initialize to default values + */ +static inline void extint_chan_get_config_defaults( + struct extint_chan_conf *const config) +{ + /* Default configuration values */ + config->gpio_pin = 0; + config->gpio_pin_mux = 0; + config->gpio_pin_pull = EXTINT_PULL_UP; + config->wake_if_sleeping = true; + config->filter_input_signal = false; + config->detection_criteria = EXTINT_DETECT_FALLING; +} + +void extint_chan_set_config( + const uint8_t channel, + const struct extint_chan_conf *const config); + +/** + * Initializes an External Interrupt NMI channel configuration structure to defaults. + * + * Initializes a given External Interrupt NMI channel configuration structure + * to a set of known default values. This function should be called on all new + * instances of these configuration structures before being modified by the + * user application. + * + * The default configuration is as follows: + * \li Input filtering disabled + * \li Detect falling edges of a signal + * + * \param[out] config Configuration structure to initialize to default values + */ +static inline void extint_nmi_get_config_defaults( + struct extint_nmi_conf *const config) +{ + /* Default configuration values */ + config->gpio_pin = 0; + config->gpio_pin_mux = 0; + config->gpio_pin_pull = EXTINT_PULL_UP; + config->filter_input_signal = false; + config->detection_criteria = EXTINT_DETECT_FALLING; +} + +void extint_nmi_set_config( + const uint8_t nmi_channel, + const struct extint_nmi_conf *const config); + +/** + * Retrieves the edge detection state of a configured channel. + * + * Reads the current state of a configured channel, and determines + * if the detection criteria of the channel has been met. + * + * \param[in] channel External Interrupt channel index to check. + * + * \return Status of the requested channel's edge detection state. + * \retval true If the channel's edge/level detection criteria was met + * \retval false If the channel has not detected its configured criteria + */ +static inline bool extint_chan_is_detected( + const uint8_t channel) +{ + Eic *const eic_module = _extint_get_eic_from_channel(channel); + uint32_t eic_mask = (1UL << (channel % 32)); + + return (eic_module->INTFLAG.reg & eic_mask); +} + +/** + * Clears the edge detection state of a configured channel. + * + * Clears the current state of a configured channel, readying it for + * the next level or edge detection. + * + * \param[in] channel External Interrupt channel index to check. + */ +static inline void extint_chan_clear_detected( + const uint8_t channel) +{ + Eic *const eic_module = _extint_get_eic_from_channel(channel); + uint32_t eic_mask = (1UL << (channel % 32)); + + eic_module->INTFLAG.reg = eic_mask; +} + +/** + * Retrieves the edge detection state of a configured NMI channel. + * + * Reads the current state of a configured NMI channel, and determines + * if the detection criteria of the NMI channel has been met. + * + * \param[in] nmi_channel External Interrupt NMI channel index to check. + * + * \return Status of the requested NMI channel's edge detection state. + * \retval true If the NMI channel's edge/level detection criteria was met + * \retval false If the NMI channel has not detected its configured criteria + */ +static inline bool extint_nmi_is_detected( + const uint8_t nmi_channel) +{ + Eic *const eic_module = _extint_get_eic_from_nmi(nmi_channel); + + return (eic_module->NMIFLAG.reg & EIC_NMIFLAG_NMI); +} + +/** + * Clears the edge detection state of a configured NMI channel. + * + * Clears the current state of a configured NMI channel, readying it for + * the next level or edge detection. + * + * \param[in] nmi_channel External Interrupt NMI channel index to check. + */ +static inline void extint_nmi_clear_detected( + const uint8_t nmi_channel) +{ + Eic *const eic_module = _extint_get_eic_from_nmi(nmi_channel); + + eic_module->NMIFLAG.reg = EIC_NMIFLAG_NMI; +} + +#endif /* EXTINT_H_INCLUDED */ diff --git a/loader/inc/system/gclk.h b/loader/inc/system/gclk.h new file mode 100644 index 0000000..b75f717 --- /dev/null +++ b/loader/inc/system/gclk.h @@ -0,0 +1,145 @@ +/** + * SAM D20/D21/R21 Generic Clock Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SYSTEM_CLOCK_GCLK_H_INCLUDED +#define SYSTEM_CLOCK_GCLK_H_INCLUDED + +#include +#include "samd20.h" + +/** + * List of Available GCLK generators. This enum is used in the peripheral + * device drivers to select the GCLK generator to be used for its operation. + * + * The number of GCLK generators available is device dependent. + */ +enum gclk_generator { + /** GCLK generator channel 0. */ + GCLK_GENERATOR_0, +#if (GCLK_GEN_NUM_MSB > 0) + /** GCLK generator channel 1. */ + GCLK_GENERATOR_1, +#endif +#if (GCLK_GEN_NUM_MSB > 1) + /** GCLK generator channel 2. */ + GCLK_GENERATOR_2, +#endif +#if (GCLK_GEN_NUM_MSB > 2) + /** GCLK generator channel 3. */ + GCLK_GENERATOR_3, +#endif +#if (GCLK_GEN_NUM_MSB > 3) + /** GCLK generator channel 4. */ + GCLK_GENERATOR_4, +#endif +#if (GCLK_GEN_NUM_MSB > 4) + /** GCLK generator channel 5. */ + GCLK_GENERATOR_5, +#endif +#if (GCLK_GEN_NUM_MSB > 5) + /** GCLK generator channel 6. */ + GCLK_GENERATOR_6, +#endif +#if (GCLK_GEN_NUM_MSB > 6) + /** GCLK generator channel 7. */ + GCLK_GENERATOR_7, +#endif +#if (GCLK_GEN_NUM_MSB > 7) + /** GCLK generator channel 8. */ + GCLK_GENERATOR_8, +#endif +#if (GCLK_GEN_NUM_MSB > 8) + /** GCLK generator channel 9. */ + GCLK_GENERATOR_9, +#endif +#if (GCLK_GEN_NUM_MSB > 9) + /** GCLK generator channel 10. */ + GCLK_GENERATOR_10, +#endif +#if (GCLK_GEN_NUM_MSB > 10) + /** GCLK generator channel 11. */ + GCLK_GENERATOR_11, +#endif +#if (GCLK_GEN_NUM_MSB > 11) + /** GCLK generator channel 12. */ + GCLK_GENERATOR_12, +#endif +#if (GCLK_GEN_NUM_MSB > 12) + /** GCLK generator channel 13. */ + GCLK_GENERATOR_13, +#endif +#if (GCLK_GEN_NUM_MSB > 13) + /** GCLK generator channel 14. */ + GCLK_GENERATOR_14, +#endif +#if (GCLK_GEN_NUM_MSB > 14) + /** GCLK generator channel 15. */ + GCLK_GENERATOR_15, +#endif +#if (GCLK_GEN_NUM_MSB > 15) + /** GCLK generator channel 16. */ + GCLK_GENERATOR_16, +#endif +}; + +/* Generators */ +void system_gclk_init (void); +void system_gclk_gen_set_config (const uint8_t generator, + const uint8_t source_clock, + const bool high_when_disabled, + const uint32_t division_factor, + const bool run_in_standby, + const bool output_enable); +void system_gclk_gen_enable (const uint8_t generator); +void system_gclk_gen_disable (const uint8_t generator); +bool system_gclk_gen_is_enabled (const uint8_t generator); +uint32_t system_gclk_gen_get_hz (const uint8_t generator); + +/* Channels */ +void system_gclk_chan_set_config(const uint8_t channel, + enum gclk_generator source_generator); +void system_gclk_chan_enable (const uint8_t channel); +void system_gclk_chan_disable (const uint8_t channel); +bool system_gclk_chan_is_enabled(const uint8_t channel); +void system_gclk_chan_lock (const uint8_t channel); +bool system_gclk_chan_is_locked (const uint8_t channel); +uint32_t system_gclk_chan_get_hz(const uint8_t channel); + +#endif diff --git a/loader/inc/system/interrupt.h b/loader/inc/system/interrupt.h new file mode 100644 index 0000000..fb387c9 --- /dev/null +++ b/loader/inc/system/interrupt.h @@ -0,0 +1,75 @@ +/** + * Global interrupt management for SAM D20, SAM3 and SAM4 (NVIC based) + * + * Copyright (c) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef SYSTEM_INTERRUPT_H +#define SYSTEM_INTERRUPT_H + +#include "samd20.h" + +/** + * Registers an interupt with the NVIC + */ +#define irq_register_handler(int_num, int_prio) \ + do { \ + NVIC_ClearPendingIRQ((IRQn_Type)int_num); \ + NVIC_SetPriority( (IRQn_Type)int_num, int_prio); \ + NVIC_EnableIRQ( (IRQn_Type)int_num); \ + } while (0) + +/** + * Safe global IRQ enable / disable + */ +#define cpu_irq_enable() \ + do { \ + __DMB(); \ + __enable_irq(); \ + } while (0) +#define cpu_irq_disable() \ + do { \ + __disable_irq(); \ + __DMB(); \ + } while (0) +#define cpu_irq_is_enabled() (__get_PRIMASK() == 0) + +void cpu_irq_enter_critical(void); +void cpu_irq_leave_critical(void); + +#endif /* SYSTEM_INTERRUPT_H */ diff --git a/loader/inc/system/pinmux.h b/loader/inc/system/pinmux.h new file mode 100644 index 0000000..1a736f4 --- /dev/null +++ b/loader/inc/system/pinmux.h @@ -0,0 +1,221 @@ +/** + * SAM D20/D21/R21 Pin Multiplexer Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef PINMUX_H_INCLUDED +#define PINMUX_H_INCLUDED + + +#include +#include +#include "samd20.h" + +/* + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the device's physical I/O Pins, + * to alter the direction and input/drive characteristics as well as + * to configure the pin peripheral multiplexer selection. + * + * The following peripherals are used by this module: + * + * - PORT (Port I/O Management) + * + * Module Overview + * + * The SAM D20/D21/R21 devices contain a number of General Purpose I/O + * pins, used to interface the user application logic and internal + * hardware peripherals to an external system. The Pin Multiplexer + * (PINMUX) driver provides a method of configuring the individual pin + * peripheral multiplexers to select alternate pin functions. + * + * Physical and Logical GPIO Pins + * + * SAM D20/D21/R21 devices use two naming conventions for the I/O pins + * in the device; one physical, and one logical. Each physical pin on + * a device package is assigned both a physical port and pin + * identifier (e.g. "PORTA.0") as well as a monotonically incrementing + * logical GPIO number (e.g. "GPIO0"). While the former is used to map + * physical pins to their physical internal device module + * counterparts, for simplicity the design of this driver uses the + * logical GPIO numbers instead. + * + * Peripheral Multiplexing + * + * SAM D20/D21/R21 devices contain a peripheral MUX, which is + * individually controllable for each I/O pin of the device. The + * peripheral MUX allows you to select the function of a physical + * package pin - whether it will be controlled as a user controllable + * GPIO pin, or whether it will be connected internally to one of + * several peripheral modules (such as an I2C module). When + * a pin is configured in GPIO mode, other peripherals connected to + * the same pin will be disabled. + * + * Special Pad Characteristics + * + * There are several special modes that can be selected on one or more + * I/O pins of the device, which alter the input and output + * characteristics of the pad: + * + * Drive Strength + * + * The Drive Strength configures the strength of the output driver on + * the pad. Normally, there is a fixed current limit that each I/O pin + * can safely drive, however some I/O pads offer a higher drive mode + * which increases this limit for that I/O pin at the expense of an + * increased power. + * + * Slew Rate + * + * The Slew Rate configures the slew rate of the output driver, + * limiting the rate at which the pad output voltage can change with + * time. + * + * Input Sample Mode + * + * The Input Sample Mode configures the input sampler buffer of the + * pad. By default, the input buffer is only sampled "on-demand", + * i.e. when the user application attempts to read from the input + * buffer. This mode is the most power efficient, but increases the + * latency of the input sample by two clock cycles of the port + * clock. To reduce latency, the input sampler can instead be + * configured to always sample the input buffer on each port clock + * cycle, at the expense of an increased power consumption. + * + * Special Considerations + * + * The SAM D20/D21/R21 port pin input sampling mode is set in groups + * of four physical pins; setting the sampling mode of any pin in a + * sub-group of eight I/O pins will configure the sampling mode of the + * entire sub-group. + * + * High Drive Strength output driver mode is not available on all device pins - + * refer to your device specific datasheet. + */ + +/** Peripheral multiplexer index to select GPIO mode for a pin. */ +#define SYSTEM_PINMUX_GPIO (1 << 7) + +/** + * Enum for the possible pin direction settings of the port pin configuration + * structure, to indicate the direction the pin should use. + */ +enum system_pinmux_pin_dir { + /** The pin's input buffer should be enabled, so that the pin state can + * be read. */ + SYSTEM_PINMUX_PIN_DIR_INPUT, + + /** The pin's output buffer should be enabled, so that the pin state can + * be set (but not read back). */ + SYSTEM_PINMUX_PIN_DIR_OUTPUT, + + /** The pin's output and input buffers should both be enabled, so that the + * pin state can be set and read back. */ + SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK, +}; + +/** + * Enum for the possible pin pull settings of the port pin + * configuration structure, to indicate the type of logic level pull + * the pin should use. + */ +enum system_pinmux_pin_pull { + /** No logical pull should be applied to the pin. */ + SYSTEM_PINMUX_PIN_PULL_NONE, + + /** Pin should be pulled up when idle. */ + SYSTEM_PINMUX_PIN_PULL_UP, + + /** Pin should be pulled down when idle. */ + SYSTEM_PINMUX_PIN_PULL_DOWN, +}; + +/** + * Enum for the possible input sampling modes for the port pin + * configuration structure, to indicate the type of sampling a port + * pin should use. + */ +enum system_pinmux_pin_sample { + /** Pin input buffer should continuously sample the pin state. */ + SYSTEM_PINMUX_PIN_SAMPLE_CONTINUOUS, + + /** Pin input buffer should be enabled when the IN register is read. */ + SYSTEM_PINMUX_PIN_SAMPLE_ONDEMAND, +}; + +void system_pinmux_pin_set_config(const uint8_t gpio_pin, + const uint8_t mux_position, + const enum system_pinmux_pin_dir direction, + const enum system_pinmux_pin_pull input_pull, + bool powersave); +void system_pinmux_group_set_config(PortGroup *const port, + const uint32_t mask, + const uint8_t mux_position, + const enum system_pinmux_pin_dir direction, + const enum system_pinmux_pin_pull input_pull, + bool powersave); + +/** + * Retrieves the PORT module group instance associated with a given + * logical GPIO pin number. + * + * \param[in] gpio_pin Index of the GPIO pin to convert. + * + * \return Base address of the associated PORT module. + */ +static inline PortGroup* system_pinmux_get_group_from_gpio_pin( + const uint8_t gpio_pin) +{ + uint8_t port_index = (gpio_pin / 128); + uint8_t group_index = (gpio_pin / 32); + + /* Array of available ports. */ + Port *const ports[PORT_INST_NUM] = PORT_INSTS; + + if (port_index < PORT_INST_NUM) { + return &(ports[port_index]->Group[group_index]); + } else { + return NULL; + } +} + +void system_pinmux_group_set_input_sample_mode(PortGroup *const port, + const uint32_t mask, + const enum system_pinmux_pin_sample mode); + +#endif diff --git a/loader/inc/system/port.h b/loader/inc/system/port.h new file mode 100644 index 0000000..489bf1f --- /dev/null +++ b/loader/inc/system/port.h @@ -0,0 +1,307 @@ +/** + * SAM D20/D21/R21 GPIO Port Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef PORT_H_INCLUDED +#define PORT_H_INCLUDED + +/** + * Port Driver (PORT) + * + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the device's General Purpose + * Input/Output (GPIO) pin functionality, for manual pin state reading + * and writing. + * + * The following peripherals are used by this module: + * + * - PORT (GPIO Management) + * + * Module Overview + * + * The device GPIO (PORT) module provides an interface between the + * user application logic and external hardware peripherals, when + * general pin state manipulation is required. This driver provides an + * easy-to-use interface to the physical pin input samplers and output + * drivers, so that pins can be read from or written to for general + * purpose external hardware control. + * + * Physical and Logical GPIO Pins + * + * SAM D20/D21/R21 devices use two naming conventions for the I/O pins + * in the device; one physical, and one logical. Each physical pin on + * a device package is assigned both a physical port and pin + * identifier (e.g. "PORTA.0") as well as a monotonically incrementing + * logical GPIO number (e.g. "GPIO0"). While the former is used to map + * physical pins to their physical internal device module + * counterparts, for simplicity the design of this driver uses the + * logical GPIO numbers instead. + * + * Special Considerations + * + * The SAM D20/D21/R21 port pin input sampler can be disabled when the pin is configured + * in pure output mode to save power; reading the pin state of a pin configured + * in output-only mode will read the logical output state that was last set. + * + */ + +#include "system/pinmux.h" + +/** Convenience definition for GPIO module group A on the device (if + * available). */ +#if (PORT_GROUPS > 0) +# define PORTA PORT->Group[0] +#endif +#if (PORT_GROUPS > 1) +/** Convenience definition for GPIO module group B on the device (if + * available). */ +# define PORTB PORT->Group[1] +#endif +#if (PORT_GROUPS > 2) +/** Convenience definition for GPIO module group C on the device (if + * available). */ +# define PORTC PORT->Group[2] +#endif +#if (PORT_GROUPS > 3) +/** Convenience definition for GPIO module group D on the device (if + * available). */ +# define PORTD PORT->Group[3] +#endif + +/** + * Enum for the possible pin direction settings of the port pin configuration + * structure, to indicate the direction the pin should use. + */ +enum port_pin_dir { + /** The pin's input buffer should be enabled, so that the pin state can + * be read. */ + PORT_PIN_DIR_INPUT = SYSTEM_PINMUX_PIN_DIR_INPUT, + /** The pin's output buffer should be enabled, so that the pin state can + * be set. */ + PORT_PIN_DIR_OUTPUT = SYSTEM_PINMUX_PIN_DIR_OUTPUT, + /** The pin's output and input buffers should be enabled, so that the pin + * state can be set and read back. */ + PORT_PIN_DIR_OUTPUT_WTH_READBACK = SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK, +}; + +/** + * Enum for the possible pin pull settings of the port pin configuration + * structure, to indicate the type of logic level pull the pin should use. + */ +enum port_pin_pull { + /** No logical pull should be applied to the pin. */ + PORT_PIN_PULL_NONE = SYSTEM_PINMUX_PIN_PULL_NONE, + /** Pin should be pulled up when idle. */ + PORT_PIN_PULL_UP = SYSTEM_PINMUX_PIN_PULL_UP, + /** Pin should be pulled down when idle. */ + PORT_PIN_PULL_DOWN = SYSTEM_PINMUX_PIN_PULL_DOWN, +}; + + +/** + * Retrieves the PORT module group instance from a given GPIO pin number. + * + * Retrieves the PORT module group instance associated with a given + * logical GPIO pin number. + * + * \param[in] gpio_pin Index of the GPIO pin to convert. + * + * \return Base address of the associated PORT module. + */ +static inline PortGroup* port_get_group_from_gpio_pin(const uint8_t gpio_pin) +{ + return system_pinmux_get_group_from_gpio_pin(gpio_pin); +} + +/** + * Retrieves the state of a group of port pins that are configured as inputs. + * + * Reads the current logic level of a port module's pins and returns + * the current levels as a bitmask. + * + * \param[in] port Base of the PORT module to read from. + * \param[in] mask Mask of the port pin(s) to read. + * + * \return Status of the port pin(s) input buffers. + */ +static inline uint32_t port_group_get_input_level(const PortGroup *const port, + const uint32_t mask) +{ + /* Sanity check arguments */ + + + return (port->IN.reg & mask); +} + +/** + * Retrieves the state of a group of port pins that are configured as outputs. + * + * Reads the current logical output level of a port module's pins and + * returns the current levels as a bitmask. + * + * \param[in] port Base of the PORT module to read from. + * \param[in] mask Mask of the port pin(s) to read. + * + * \return Status of the port pin(s) output buffers. + */ +static inline uint32_t port_group_get_output_level(const PortGroup *const port, + const uint32_t mask) +{ + /* Sanity check arguments */ + + + return (port->OUT.reg & mask); +} + +/** + * Sets the state of a group of port pins that are configured as outputs. + * + * \param[out] port Base of the PORT module to write to. + * \param[in] mask Mask of the port pin(s) to change. + * \param[in] level_mask Mask of the port level(s) to set. + */ +static inline void port_group_set_output_level(PortGroup *const port, + const uint32_t mask, + const uint32_t level_mask) +{ + /* Sanity check arguments */ + + + port->OUTSET.reg = (mask & level_mask); + port->OUTCLR.reg = (mask & ~level_mask); +} + +/** + * Toggles the state of a group of port pins that are configured as an outputs. + * + * \param[out] port Base of the PORT module to write to. + * \param[in] mask Mask of the port pin(s) to toggle. + */ +static inline void port_group_toggle_output_level(PortGroup *const port, + const uint32_t mask) +{ + /* Sanity check arguments */ + + + port->OUTTGL.reg = mask; +} + +void port_pin_set_config(const uint8_t gpio_pin, + enum port_pin_dir direction, + enum port_pin_pull input_pull, + bool powersave); +void port_pin_set_config_default(const uint8_t gpio_pin); + + +void port_group_set_config(PortGroup *const port, + const uint32_t mask, + enum port_pin_dir direction, + enum port_pin_pull input_pull, + bool powersave); +void port_group_set_config_default(PortGroup *const port, + const uint32_t mask); + + +/** + * Reads the current logic level of a port pin and returns the current + * level as a boolean value. + * + * \param[in] gpio_pin Index of the GPIO pin to read. + * + * \return Status of the port pin's input buffer. + */ +static inline bool port_pin_get_input_level(const uint8_t gpio_pin) +{ + PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin); + uint32_t pin_mask = (1UL << (gpio_pin % 32)); + + return (port_base->IN.reg & pin_mask); +} + +/** + * Reads the current logical output level of a port pin and returns the current + * level as a boolean value. + * + * \param[in] gpio_pin Index of the GPIO pin to read. + * + * \return Status of the port pin's output buffer. + */ +static inline bool port_pin_get_output_level(const uint8_t gpio_pin) +{ + PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin); + uint32_t pin_mask = (1UL << (gpio_pin % 32)); + + return (port_base->OUT.reg & pin_mask); +} + +/** + * Sets the current output level of a port pin to a given logic level. + * + * \param[in] gpio_pin Index of the GPIO pin to write to. + * \param[in] level Logical level to set the given pin to. + */ +static inline void port_pin_set_output_level(const uint8_t gpio_pin, + const bool level) +{ + PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin); + uint32_t pin_mask = (1UL << (gpio_pin % 32)); + + /* Set the pin to high or low atomically based on the requested level */ + if (level) { + port_base->OUTSET.reg = pin_mask; + } else { + port_base->OUTCLR.reg = pin_mask; + } +} + +/** + * Toggles the current output level of a port pin. + * + * \param[in] gpio_pin Index of the GPIO pin to toggle. + */ +static inline void port_pin_toggle_output_level(const uint8_t gpio_pin) +{ + PortGroup *const port_base = port_get_group_from_gpio_pin(gpio_pin); + uint32_t pin_mask = (1UL << (gpio_pin % 32)); + + /* Toggle pin output level */ + port_base->OUTTGL.reg = pin_mask; +} + +#endif diff --git a/loader/inc/system/rtc_count.h b/loader/inc/system/rtc_count.h new file mode 100644 index 0000000..61073e3 --- /dev/null +++ b/loader/inc/system/rtc_count.h @@ -0,0 +1,732 @@ +/** + * \file + * + * \brief SAM D20/D21/R21 RTC Driver (Count Mode) + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef RTC_COUNT_H_INCLUDED +#define RTC_COUNT_H_INCLUDED + +/** + * \defgroup asfdoc_sam0_rtc_count_group SAM D20/D21/R21 RTC Count Driver (RTC COUNT) + * + * This driver for SAM D20/D21/R21 devices provides an interface for the configuration + * and management of the device's Real Time Clock functionality in Count + * operating mode, for the configuration and retrieval of the current RTC + * counter value. The following driver API modes are covered by this + * manual: + * + * - Polled APIs + * \if RTC_COUNT_CALLBACK_MODE + * - Callback APIs + * \endif + * + * The following peripherals are used by this module: + * + * - RTC (Real Time Clock) + * + * The outline of this documentation is as follows: + * - \ref asfdoc_sam0_rtc_count_prerequisites + * - \ref asfdoc_sam0_rtc_count_module_overview + * - \ref asfdoc_sam0_rtc_count_special_considerations + * - \ref asfdoc_sam0_rtc_count_extra_info + * - \ref asfdoc_sam0_rtc_count_examples + * - \ref asfdoc_sam0_rtc_count_api_overview + * + * + * \section asfdoc_sam0_rtc_count_prerequisites Prerequisites + * + * There are no prerequisites for this module. + * + * + * \section asfdoc_sam0_rtc_count_module_overview Module Overview + * + * The RTC module in the SAM D20/D21/R21 devices is a 32-bit counter, with a 10-bit + * programmable prescaler. Typically, the RTC clock is run continuously, + * including in the device's low-power sleep modes, to track the current time + * and date information. The RTC can be used as a source to wake up the system + * at a scheduled time or periodically using the alarm functions. + * + * In this driver, the RTC is operated in Count mode. This allows for an + * easy integration of an asynchronous counter into a user application, which is + * capable of operating while the device is in sleep mode. + * + * Whilst operating in Count mode, the RTC features: + * - 16-bit counter mode + * - Selectable counter period + * - Up to 6 configurable compare values + * - 32-bit counter mode + * - Clear counter value on match + * - Up to 4 configurable compare values + * + * + * \section asfdoc_sam0_rtc_count_module_overview_compares Compare and Overflow + * The RTC can be used with up to 4/6 compare values (depending on selected + * operation mode). These compare values will trigger on match with the current + * RTC counter value, and can be set up to trigger an interrupt, event, or both. + * The RTC can also be configured to clear the counter value on compare match + * in 32-bit mode, resetting the count value back to zero. + * + * If the RTC is operated without the Clear on Match option enabled, or in + * 16-bit mode, the RTC counter value will instead be cleared on overflow once + * the maximum count value has been reached: + * + * \f[ COUNT_{MAX} = 2^{32}-1 \f] for 32-bit counter mode, and + * \f[ COUNT_{MAX} = 2^{16}-1 \f] for 16-bit counter mode. + * + * When running in 16-bit mode, the overflow value is selectable with a period + * value. The counter overflow will then occur when the counter value reaches + * the specified period value. + * + * \subsection asfdoc_sam0_rtc_count_module_overview_periodic Periodic Events + * The RTC can generate events at periodic intervals, allowing for direct + * peripheral actions without CPU intervention. The periodic events can be + * generated on the upper 8 bits of the RTC prescaler, and will be generated on + * the rising edge transition of the specified bit. The resulting periodic + * frequency can be calculated by the following formula: + * + * \f[ f_{PERIODIC}=\frac{f_{ASY}}{2^{n+3}} \f] + * + * Where \f$f_{ASY}\f$ refers to the \e asynchronous clock set up in the RTC + * module configuration. The \b n parameter is the event source generator index + * of the RTC module. If the asynchronous clock is operated at the recommended + * frequency of 1 KHz, the formula results in the values shown in + * \ref asfdoc_sam0_rtc_count_module_rtc_hz "the table below". + * + * \anchor asfdoc_sam0_rtc_count_module_rtc_hz + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
RTC event frequencies for each prescaler bit using a 1KHz clock
n Periodic event
7 1 Hz
6 2 Hz
5 4 Hz
4 8 Hz
3 16 Hz
2 32 Hz
1 64 Hz
0 128 Hz
+ * + * \note The connection of events between modules requires the use of the + * \ref asfdoc_sam0_events_group "SAM D20/D21/R21 Event System Driver (EVENTS)" + * to route output event of one module to the the input event of another. + * For more information on event routing, refer to the event driver + * documentation. + * + * \subsection asfdoc_sam0_rtc_count_module_overview_correction Digital Frequency Correction + * The RTC module contains Digital Frequency Correction logic to compensate for + * inaccurate source clock frequencies which would otherwise result in skewed + * time measurements. The correction scheme requires that at least two bits + * in the RTC module prescaler are reserved by the correction logic. As a + * result of this implementation, frequency correction is only available when + * the RTC is running from a 1 Hz reference clock. + * + * The correction procedure is implemented by subtracting or adding a single + * cycle from the RTC prescaler every 1024 RTC GCLK cycles. The adjustment is + * applied the specified number of time (max 127) over 976 of these periods. The + * corresponding correction in PPM will be given by: + * + * \f[ Correction(PPM) = \frac{VALUE}{999424}10^6 \f] + * + * The RTC clock will tick faster if provided with a positive correction value, + * and slower when given a negative correction value. + * + * + * \section asfdoc_sam0_rtc_count_special_considerations Special Considerations + * + * \subsection asfdoc_sam0_rtc_count_special_considerations_clock Clock Setup + * The RTC is typically clocked by a specialized GCLK generator that has a + * smaller prescaler than the others. By default the RTC clock is on, selected + * to use the internal 32 KHz RC-oscillator with a prescaler of 32, giving a + * resulting clock frequency of 1 KHz to the RTC. When the internal RTC + * prescaler is set to 1024, this yields an end-frequency of 1 Hz. + * + * The implementer also has the option to set other end-frequencies. + * \ref asfdoc_sam0_rtc_count_rtc_out_freq "The table below" lists the + * available RTC frequencies for each possible GCLK and RTC input prescaler + * options. + * + * \anchor asfdoc_sam0_rtc_count_rtc_out_freq + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
RTC output frequencies from allowable input clocks
End-frequencyGCLK prescalerRTC Prescaler
32 KHz11
1 KHz321
1 Hz321024
+ * + * The overall RTC module clocking scheme is shown in + * \ref asfdoc_sam0_rtc_count_rtc_clock_fig "the figure below". + * + * \anchor asfdoc_sam0_rtc_count_rtc_clock_fig + * \dot + * digraph clocking_scheme { + * rankdir=LR; + * GCLK [shape="record", label=" GCLK | RTC_GCLK", + * bgcolor="lightgray", style="filled"]; + * RTCPRE [shape="record" label=" RTC | RTC PRESCALER"]; + * RTC [shape="record", label=" RTC | RTC CLOCK"]; + * + * GCLK:f1 -> RTCPRE:f1; + * RTCPRE:f1 -> RTC:f1; + * } + * \enddot + * + * + * \section asfdoc_sam0_rtc_count_extra_info Extra Information + * + * For extra information see \ref asfdoc_sam0_rtc_count_extra. This includes: + * - \ref asfdoc_sam0_rtc_count_extra_acronyms + * - \ref asfdoc_sam0_rtc_count_extra_dependencies + * - \ref asfdoc_sam0_rtc_count_extra_errata + * - \ref asfdoc_sam0_rtc_count_extra_history + * + * + * \section asfdoc_sam0_rtc_count_examples Examples + * + * For a list of examples related to this driver, see + * \ref asfdoc_sam0_rtc_count_exqsg. + * + * + * \section asfdoc_sam0_rtc_count_api_overview API Overview + * @{ + */ + +#include "samd20.h" +#include + +/** + * \brief Available operation modes for the RTC. + * + * RTC Count operating modes, to select the counting width and associated module + * operation. + */ +enum rtc_count_mode { + /** RTC Count module operates in 16-bit mode. */ + RTC_COUNT_MODE_16BIT = 0, + /** RTC Count module operates in 32-bit mode. */ + RTC_COUNT_MODE_32BIT = 1, +}; + +/** + * \brief Available compare channels. + * + * \note Not all compare channels are available in all devices and modes. + */ +enum rtc_count_compare { + /** Compare channel 0. */ + RTC_COUNT_COMPARE_0 = 0, +#if (RTC_NUM_OF_COMP16 > 1) || defined(__DOXYGEN__) + /** Compare channel 1. */ + RTC_COUNT_COMPARE_1 = 1, +#endif +#if (RTC_NUM_OF_COMP16 > 2) || defined(__DOXYGEN__) + /** Compare channel 2. */ + RTC_COUNT_COMPARE_2 = 2, +#endif +#if (RTC_NUM_OF_COMP16 > 3) || defined(__DOXYGEN__) + /** Compare channel 3. */ + RTC_COUNT_COMPARE_3 = 3, +#endif +#if (RTC_NUM_OF_COMP16 > 4) || defined(__DOXYGEN__) + /** Compare channel 4. */ + RTC_COUNT_COMPARE_4 = 4, +#endif +#if (RTC_NUM_OF_COMP16 > 5) || defined(__DOXYGEN__) + /** Compare channel 5. */ + RTC_COUNT_COMPARE_5 = 5, +#endif +}; + +/** + * \brief RTC input clock prescaler settings + * + * The available input clock prescaler values for the RTC count module. + */ +enum rtc_count_prescaler { + /** RTC input clock frequency is prescaled by a factor of 1. */ + RTC_COUNT_PRESCALER_DIV_1 = RTC_MODE0_CTRL_PRESCALER_DIV1, + /** RTC input clock frequency is prescaled by a factor of 2. */ + RTC_COUNT_PRESCALER_DIV_2 = RTC_MODE0_CTRL_PRESCALER_DIV2, + /** RTC input clock frequency is prescaled by a factor of 4. */ + RTC_COUNT_PRESCALER_DIV_4 = RTC_MODE0_CTRL_PRESCALER_DIV4, + /** RTC input clock frequency is prescaled by a factor of 8. */ + RTC_COUNT_PRESCALER_DIV_8 = RTC_MODE0_CTRL_PRESCALER_DIV8, + /** RTC input clock frequency is prescaled by a factor of 16. */ + RTC_COUNT_PRESCALER_DIV_16 = RTC_MODE0_CTRL_PRESCALER_DIV16, + /** RTC input clock frequency is prescaled by a factor of 32. */ + RTC_COUNT_PRESCALER_DIV_32 = RTC_MODE0_CTRL_PRESCALER_DIV32, + /** RTC input clock frequency is prescaled by a factor of 64. */ + RTC_COUNT_PRESCALER_DIV_64 = RTC_MODE0_CTRL_PRESCALER_DIV64, + /** RTC input clock frequency is prescaled by a factor of 128. */ + RTC_COUNT_PRESCALER_DIV_128 = RTC_MODE0_CTRL_PRESCALER_DIV128, + /** RTC input clock frequency is prescaled by a factor of 256. */ + RTC_COUNT_PRESCALER_DIV_256 = RTC_MODE0_CTRL_PRESCALER_DIV256, + /** RTC input clock frequency is prescaled by a factor of 512. */ + RTC_COUNT_PRESCALER_DIV_512 = RTC_MODE0_CTRL_PRESCALER_DIV512, + /** RTC input clock frequency is prescaled by a factor of 1024. */ + RTC_COUNT_PRESCALER_DIV_1024 = RTC_MODE0_CTRL_PRESCALER_DIV1024, +}; + +/** + * \brief RTC Count event enable/disable structure. + * + * Event flags for the \ref rtc_count_enable_events() and + * \ref rtc_count_disable_events(). + */ +struct rtc_count_events { + /** Generate an output event on each overflow of the RTC count. */ + bool generate_event_on_overflow; + /** Generate an output event on a compare channel match against the RTC + * count. */ + bool generate_event_on_compare[RTC_NUM_OF_COMP16]; + /** Generate an output event periodically at a binary division of the RTC + * counter frequency (see + * \ref asfdoc_sam0_rtc_count_module_overview_periodic). + */ + bool generate_event_on_periodic[8]; +}; + +/** + * \brief RTC Count configuration structure + * + * Configuration structure for the RTC instance. This structure should + * be initialized using the \ref rtc_count_get_config_defaults() before any + * user configurations are set. + */ +struct rtc_count_config { + /** Input clock prescaler for the RTC module. */ + enum rtc_count_prescaler prescaler; + /** Select the operation mode of the RTC.*/ + enum rtc_count_mode mode; + /** If true, clears the counter value on compare match. Only available + * whilst running in 32-bit mode. */ + bool clear_on_match; + /** Continuously update the counter value so no synchronization is + * needed for reading. */ + bool continuously_update; + /** Array of Compare values. Not all Compare values are available in 32-bit + * mode. */ + uint32_t compare_values[RTC_NUM_OF_COMP16]; +}; + + +/** + * \brief Determines if the hardware module(s) are currently synchronizing to the bus. + * + * Checks to see if the underlying hardware peripheral module(s) are currently + * synchronizing across multiple clock domains to the hardware bus, This + * function can be used to delay further operations on a module until such time + * that it is ready, to prevent blocking delays for synchronization in the + * user application. + * + * \param[in] module RTC hardware module + * + * \return Synchronization status of the underlying hardware module(s). + * + * \retval true if the module has completed synchronization + * \retval false if the module synchronization is ongoing + */ +static inline bool rtc_count_is_syncing(void) +{ + if (RTC->MODE0.STATUS.reg & RTC_STATUS_SYNCBUSY) { + return true; + } + + return false; +} + +/** + * \brief Gets the RTC default configurations. + * + * Initializes the configuration structure to default values. This + * function should be called at the start of any RTC initialization. + * + * The default configuration is as follows: + * - Input clock divided by a factor of 1024. + * - RTC in 32 bit mode. + * - Clear on compare match off. + * - Continuously sync count register off. + * - No event source on. + * - All compare values equal 0. + * + * \param[out] config Configuration structure to be initialized to default + * values. + */ +static inline void rtc_count_get_config_defaults( + struct rtc_count_config *const config) +{ + /* Set default into configuration structure */ + config->prescaler = RTC_COUNT_PRESCALER_DIV_1024; + config->mode = RTC_COUNT_MODE_32BIT; + config->clear_on_match = false; + config->continuously_update = false; + for (uint8_t i = 0; i < RTC_NUM_OF_COMP16; i++) { + config->compare_values[i] = 0; + } +} + +void rtc_count_reset(void); + +/** + * \brief Enables the RTC module. + * + * Enables the RTC module once it has been configured, ready for use. Most + * module configuration parameters cannot be altered while the module is enabled. + * + * \param[in,out] module RTC hardware module + */ +static inline void rtc_count_enable(void) +{ + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Enable RTC module. */ + RTC->MODE0.CTRL.reg |= RTC_MODE0_CTRL_ENABLE; +} + +/** + * \brief Disables the RTC module. + * + * Disables the RTC module. + * + * \param[in,out] module RTC hardware module + */ +static inline void rtc_count_disable(void) +{ + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Disable RTC module. */ + RTC->MODE0.CTRL.reg &= ~RTC_MODE0_CTRL_ENABLE; +} + +enum status_code rtc_count_init( + const struct rtc_count_config *const config); + +enum status_code rtc_count_frequency_correction( + const int8_t value); + +enum status_code rtc_count_set_count( + const uint32_t count_value); + +uint32_t rtc_count_get_count(void); + +enum status_code rtc_count_set_compare( + const uint32_t comp_value, + const enum rtc_count_compare comp_index); + +enum status_code rtc_count_get_compare( + uint32_t *const comp_value, + const enum rtc_count_compare comp_index); + +enum status_code rtc_count_set_period( + uint16_t period_value); + +enum status_code rtc_count_get_period( + uint16_t *const period_value); + + +/** + * \brief Check if an RTC overflow has occurred. + * + * Checks the overflow flag in the RTC. The flag is set when there + * is an overflow in the clock. + * + * \param[in,out] module RTC hardware module + * + * \return Overflow state of the RTC module. + * + * \retval true If the RTC count value has overflowed + * \retval false If the RTC count value has not overflowed + */ + +static inline bool rtc_count_is_overflow(void) +{ + /* Return status of flag */ + return (RTC->MODE0.INTFLAG.reg & RTC_MODE0_INTFLAG_OVF); +} + +/** + * \brief Clears the RTC overflow flag. + * + * Clears the RTC module counter overflow flag, so that new overflow conditions + * can be detected. + * + * \param[in,out] module RTC hardware module + */ +static inline void rtc_count_clear_overflow(void) +{ + /* Clear OVF flag */ + RTC->MODE0.INTFLAG.reg = RTC_MODE0_INTFLAG_OVF; +} + +bool rtc_count_is_compare_match( + const enum rtc_count_compare comp_index); + +enum status_code rtc_count_clear_compare_match( + const enum rtc_count_compare comp_index); + + +/** + * \brief Enables a RTC event output. + * + * Enables one or more output events from the RTC module. See + * \ref rtc_count_events for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in,out] module RTC hardware module + * \param[in] events Struct containing flags of events to enable + */ +static inline void rtc_count_enable_events( + struct rtc_count_events *const events) +{ + uint32_t event_mask = 0; + + /* Check if the user has requested an overflow event. */ + if (events->generate_event_on_overflow) { + event_mask |= RTC_MODE0_EVCTRL_OVFEO; + } + + /* Check if the user has requested any compare events. */ + for (uint8_t i = 0; i < RTC_NUM_OF_COMP16; i++) { + if (events->generate_event_on_compare[i]) { + event_mask |= RTC_MODE0_EVCTRL_CMPEO(1 << i); + } + } + + /* Check if the user has requested any periodic events. */ + for (uint8_t i = 0; i < 8; i++) { + if (events->generate_event_on_periodic[i]) { + event_mask |= RTC_MODE0_EVCTRL_PEREO(1 << i); + } + } + + /* Enable given event(s). */ + RTC->MODE0.EVCTRL.reg |= event_mask; +} + +/** + * \brief Disables a RTC event output. + * + * Disabled one or more output events from the RTC module. See + * \ref rtc_count_events for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in,out] module RTC hardware module + * \param[in] events Struct containing flags of events to disable + */ +static inline void rtc_count_disable_events( + struct rtc_count_events *const events) +{ + uint32_t event_mask = 0; + + /* Check if the user has requested an overflow event. */ + if (events->generate_event_on_overflow) { + event_mask |= RTC_MODE0_EVCTRL_OVFEO; + } + + /* Check if the user has requested any compare events. */ + for (uint8_t i = 0; i < RTC_NUM_OF_COMP16; i++) { + if (events->generate_event_on_compare[i]) { + event_mask |= RTC_MODE0_EVCTRL_CMPEO(1 << i); + } + } + + /* Check if the user has requested any periodic events. */ + for (uint8_t i = 0; i < 8; i++) { + if (events->generate_event_on_periodic[i]) { + event_mask |= RTC_MODE0_EVCTRL_PEREO(1 << i); + } + } + + /* Disable given event(s). */ + RTC->MODE0.EVCTRL.reg &= ~event_mask; +} + + +/** + * \page asfdoc_sam0_rtc_count_extra Extra Information for RTC COUNT Driver + * + * \section asfdoc_sam0_rtc_count_extra_acronyms Acronyms + * Below is a table listing the acronyms used in this module, along with their + * intended meanings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Acronym + * Description + *
RTCReal Time Counter
PPMPart Per Million
RCResistor/Capacitor
+ * + * + * \section asfdoc_sam0_rtc_count_extra_dependencies Dependencies + * This driver has the following dependencies: + * + * - None + * + * + * \section asfdoc_sam0_rtc_count_extra_errata Errata + * There are no errata related to this driver. + * + * + * \section asfdoc_sam0_rtc_count_extra_history Module History + * An overview of the module history is presented in the table below, with + * details on the enhancements and fixes made to the module since its first + * release. The current version of this corresponds to the newest version in + * the table. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Changelog
+ * Added support for SAMD21 and added driver instance parameter to all + * API function calls, except get_config_defaults. + *
Updated initialization function to also enable the digital interface + * clock to the module if it is disabled.
Initial Release
+ */ + +/** + * \page asfdoc_sam0_rtc_count_exqsg Examples for RTC (COUNT) Driver + * + * This is a list of the available Quick Start guides (QSGs) and example + * applications for \ref asfdoc_sam0_rtc_count_group. QSGs are simple + * examples with step-by-step instructions to configure and use this driver in a + * selection of use cases. Note that QSGs can be compiled as a standalone + * application or be added to the user application. + * + * - \subpage asfdoc_sam0_rtc_count_basic_use_case + * \if RTC_COUNT_CALLBACK_MODE + * - \subpage asfdoc_sam0_rtc_count_callback_use_case + * \endif + * + * \page asfdoc_sam0_rtc_count_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
Doc. Rev. + * Date + * Comments + *
D03/2014Added support for SAMR21.
C01/2014Added support for SAMD21.
B06/2013Added additional documentation on the event system. Corrected + * documentation typos.
A06/2013Initial release
+ */ + +#endif /* RTC_COUNT_H_INCLUDED */ diff --git a/loader/inc/system/system.h b/loader/inc/system/system.h new file mode 100644 index 0000000..1e556b2 --- /dev/null +++ b/loader/inc/system/system.h @@ -0,0 +1,358 @@ +/** + * \file + * + * \brief SAM D20/D21/R21 System related functionality + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef SYSTEM_H_INCLUDED +#define SYSTEM_H_INCLUDED + +#include "system/clock.h" +#include "system/gclk.h" +#include "system/pinmux.h" + +/** + * SAM D20/D21/R21 System Driver (SYSTEM) + * + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the device's system relation + * functionality, necessary for the basic device operation. This is + * not limited to a single peripheral, but extends across multiple + * hardware peripherals, + * + * The following peripherals are used by this module: + * + * - SYSCTRL (System Control) + * - PM (Power Manager) + * + * Module Overview + * + * The System driver provides a collection of interfaces between the + * user application logic, and the core device functionality (such as + * clocks, reset cause determination, etc.) that is required for all + * applications. + * + * Voltage References + * + * The various analog modules within the SAM D20/D21/R21 devices (such + * as AC, ADC and DAC) require a voltage reference to be configured to + * act as a reference point for comparisons and conversions. + * + * The SAM D20/D21/R21 devices contain multiple references, including + * an internal temperature sensor, and a fixed band-gap voltage + * source. When enabled, the associated voltage reference can be + * selected within the desired peripheral where applicable. + * + * System Reset Cause + * + * In some application there may be a need to execute a different + * program flow based on how the device was reset. For example, if the + * cause of reset was the Watchdog timer (WDT), this might indicate an + * error in the application and a form of error handling or error + * logging might be needed. + * + * For this reason, an API is provided to retrieve the cause of the + * last system reset, so that appropriate action can be taken. + * + * Sleep Modes + * + * The SAM D20/D21/R21 devices have several sleep modes, where the sleep mode controls + * which clock systems on the device will remain enabled or disabled when the + * device enters a low power sleep mode. + + * \ref asfdoc_sam0_system_module_sleep_mode_table "The table below" lists the + * clock settings of the different sleep modes. + * + * \anchor asfdoc_sam0_system_module_sleep_mode_table + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
SAM D20/D21/R21 Device Sleep Modes
Sleep modeCPU clockAHB clockAPB clocksClock sourcesSystem clock32KHzReg modeRAM mode
IDLE 0StopRunRunRunRunRunNormalNormal
IDLE 1StopStopRunRunRunRunNormalNormal
IDLE 2StopStopStopRunRunRunNormalNormal
STANDBYStopStopStopStopStopStopLow PowerSource/Drain biasing
+ * + * To enter device sleep, one of the available sleep modes must be set, and the + * function to enter sleep called. The device will automatically wake up in + * response to an interrupt being generated or other device event. + * + * Some peripheral clocks will remain enabled during sleep, depending on their + * configuration; if desired, modules can remain clocked during sleep to allow + * them to continue to operate while other parts of the system are powered down + * to save power. + * + */ + +/** + * List of available voltage references (VREF) that may be used within + * the device. + */ +enum system_voltage_reference { + /** Temperature sensor voltage reference. */ + SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE, + /** Bandgap voltage reference. */ + SYSTEM_VOLTAGE_REFERENCE_BANDGAP, +}; + +/** + * List of available sleep modes in the device. A table of clocks + * available in different sleep modes can be found in \ref + * asfdoc_sam0_system_module_overview_sleep_mode. + */ +enum system_sleepmode { + /** IDLE 0 sleep mode. */ + SYSTEM_SLEEPMODE_IDLE_0, + /** IDLE 1 sleep mode. */ + SYSTEM_SLEEPMODE_IDLE_1, + /** IDLE 2 sleep mode. */ + SYSTEM_SLEEPMODE_IDLE_2, + /** Standby sleep mode. */ + SYSTEM_SLEEPMODE_STANDBY, +}; + +/** + * List of possible reset causes of the system. + */ +enum system_reset_cause { + /** The system was last reset by a software reset. */ + SYSTEM_RESET_CAUSE_SOFTWARE = PM_RCAUSE_SYST, + /** The system was last reset by the watchdog timer. */ + SYSTEM_RESET_CAUSE_WDT = PM_RCAUSE_WDT, + /** The system was last reset because the external reset line was pulled low. */ + SYSTEM_RESET_CAUSE_EXTERNAL_RESET = PM_RCAUSE_EXT, + /** The system was last reset by the BOD33. */ + SYSTEM_RESET_CAUSE_BOD33 = PM_RCAUSE_BOD33, + /** The system was last reset by the BOD12. */ + SYSTEM_RESET_CAUSE_BOD12 = PM_RCAUSE_BOD12, + /** The system was last reset by the POR (Power on reset). */ + SYSTEM_RESET_CAUSE_POR = PM_RCAUSE_POR, +}; + +/** + * Retrieves the signature of the current device. + * + * \return Device ID signature as a 32-bit integer. + */ +static inline uint32_t system_get_device_id(void) +{ + return DSU->DID.reg; +} + +/** + * Enables the selected voltage reference source, making the voltage reference + * available on a pin as well as an input source to the analog peripherals. + * + * \param[in] vref Voltage reference to enable + */ +static inline void system_voltage_reference_enable( + const enum system_voltage_reference vref) +{ + switch (vref) { + case SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE: + SYSCTRL->VREF.reg |= SYSCTRL_VREF_TSEN; + break; + + case SYSTEM_VOLTAGE_REFERENCE_BANDGAP: + SYSCTRL->VREF.reg |= SYSCTRL_VREF_BGOUTEN; + break; + + default: + + return; + } +} + +/** + * Disables the selected voltage reference source. + * + * \param[in] vref Voltage reference to disable + */ +static inline void system_voltage_reference_disable( + const enum system_voltage_reference vref) +{ + switch (vref) { + case SYSTEM_VOLTAGE_REFERENCE_TEMPSENSE: + SYSCTRL->VREF.reg &= ~SYSCTRL_VREF_TSEN; + break; + + case SYSTEM_VOLTAGE_REFERENCE_BANDGAP: + SYSCTRL->VREF.reg &= ~SYSCTRL_VREF_BGOUTEN; + break; + + default: + + return; + } +} + +/** + * Set the sleep mode of the device + * + * Sets the sleep mode of the device; the configured sleep mode will be entered + * upon the next call of the \ref system_sleep() function. + * + * For an overview of which systems are disabled in sleep for the different + * sleep modes, see \ref asfdoc_sam0_system_module_overview_sleep_mode. + * + * \param[in] sleep_mode Sleep mode to configure for the next sleep operation + * + * \retval STATUS_OK Operation completed successfully + * \retval STATUS_ERR_INVALID_ARG The requested sleep mode was invalid or not + * available + */ +static inline void system_set_sleepmode( + const enum system_sleepmode sleep_mode) +{ + switch (sleep_mode) { + case SYSTEM_SLEEPMODE_IDLE_0: + case SYSTEM_SLEEPMODE_IDLE_1: + case SYSTEM_SLEEPMODE_IDLE_2: + SCB->SCR &= ~SCB_SCR_SLEEPDEEP_Msk; + PM->SLEEP.reg = sleep_mode; + break; + + case SYSTEM_SLEEPMODE_STANDBY: + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; + break; + + default: + break; +// return STATUS_ERR_INVALID_ARG; + } +} + +/** + * Executes a device DSB (Data Synchronization Barrier) instruction to ensure + * all ongoing memory accesses have completed, then a WFI (Wait For Interrupt) + * instruction to place the device into the sleep mode specified by + * \ref system_set_sleepmode until woken by an interrupt. + */ +static inline void system_sleep(void) +{ + __DSB(); + __WFI(); +} + +/** + * Check if debugger is connected to the onboard debug system (DAP) + * + * \return A bool identifying if a debugger is present + * + * \retval true Debugger is connected to the system + * \retval false Debugger is not connected to the system + * + */ +static inline bool system_is_debugger_present(void) +{ + return DSU->STATUSB.reg & DSU_STATUSB_DBGPRES; +} + +/** + * Resets the MCU and all associated peripherals and registers, except + * RTC, all 32kHz sources, WDT (if ALWAYSON is set) and GCLK (if + * WRTLOCK is set). + * + */ +static inline void system_reset(void) +{ + NVIC_SystemReset(); +} + +/** + * Retrieves the cause of the last system reset. + * + * \return An enum value indicating the cause of the last system reset. + */ +static inline enum system_reset_cause system_get_reset_cause(void) +{ + return (enum system_reset_cause)PM->RCAUSE.reg; +} + +#endif /* SYSTEM_H_INCLUDED */ diff --git a/loader/inc/system/wdt.h b/loader/inc/system/wdt.h new file mode 100644 index 0000000..e0e3a3a --- /dev/null +++ b/loader/inc/system/wdt.h @@ -0,0 +1,221 @@ +/** + * SAM D20/D21/R21 Watchdog Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#ifndef WDT_H_INCLUDED +#define WDT_H_INCLUDED + +/** + * SAM D20/D21/R21 Watchdog Driver (WDT) + * + * This driver for SAM D20/D21/R21 devices provides an interface for + * the configuration and management of the device's Watchdog Timer + * module, including the enabling, disabling and kicking within the + * device. The following driver API modes are covered by this manual: + * + * - Polled APIs + * + * The following peripherals are used by this module: + * + * - WDT (Watchdog Timer) + * + * Module Overview + * + * The Watchdog module (WDT) is designed to give an added level of + * safety in critical systems, to ensure a system reset is triggered + * in the case of a deadlock or other software malfunction that + * prevents normal device operation. + * + * At a basic level, the Watchdog is a system timer with a fixed + * period; once enabled, it will continue to count ticks of its + * asynchronous clock until it is periodically reset, or the timeout + * period is reached. In the event of a Watchdog timeout, the module + * will trigger a system reset identical to a pulse of the device's + * reset pin, resetting all peripherals to their power-on default + * states and restarting the application software from the reset + * vector. + * + * In many systems, there is an obvious upper bound to the amount of + * time each iteration of the main application loop can be expected to + * run, before a malfunction can be assumed (either due to a deadlock + * waiting on hardware or software, or due to other means). When the + * Watchdog is configured with a timeout period equal to this upper + * bound, a malfunction in the system will force a full system reset + * to allow for a graceful recovery. + * + * Locked Mode + * + * The Watchdog configuration can be set in the device fuses and + * locked in hardware, so that no software changes can be made to the + * Watchdog configuration. Additionally, the Watchdog can be locked on + * in software if it is not already locked, so that the module + * configuration cannot be modified until a power on reset of the + * device. + * + * The locked configuration can be used to ensure that faulty software + * does not cause the Watchdog configuration to be changed, preserving + * the level of safety given by the module. + * + * Window Mode + * + * Just as there is a reasonable upper bound to the time the main + * program loop should take for each iteration, there is also in many + * applications a lower bound, i.e. a minimum time for which each loop + * iteration should run for under normal circumstances. To guard + * against a system failure resetting the Watchdog in a tight loop (or + * a failure in the system application causing the main loop to run + * faster than expected) a "Window" mode can be enabled to disallow + * resetting of the Watchdog counter before a certain period of time. + * If the Watchdog is not reset after the window opens but not before + * the Watchdog expires, the system will reset. + * + * Early Warning + * + * In some cases it is desirable to receive an early warning that the + * Watchdog is about to expire, so that some system action (such as + * saving any system configuration data for failure analysis purposes) + * can be performed before the system reset occurs. The Early Warning + * feature of the Watchdog module allows such a notification to be + * requested; after the configured early warning time (but before the + * expiry of the Watchdog counter) the Early Warning flag will become + * set, so that the user application can take an appropriate action. + * + * \note It is important to note that the purpose of the Early Warning feature + * is not to allow the user application to reset the Watchdog; doing + * so will defeat the safety the module gives to the user application. + * Instead, this feature should be used purely to perform any tasks that + * need to be undertaken before the system reset occurs. + * + * Special Considerations + * + * On some devices the Watchdog configuration can be fused to be always on in + * a particular configuration; if this mode is enabled the Watchdog is not + * software configurable and can have its count reset and early warning state + * checked/cleared only. + * + */ + +#include "system/clock.h" +#include "system/gclk.h" + +/** + * Enum for the possible period settings of the Watchdog timer module, for + * values requiring a period as a number of Watchdog timer clock ticks. + */ +enum wdt_period { + /** No Watchdog period. This value can only be used when setting the + * Window and Early Warning periods; its use as the Watchdog Reset + * Period is invalid. */ + WDT_PERIOD_NONE = 0, + /** Watchdog period of 8 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_8CLK = 1, + /** Watchdog period of 16 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_16CLK = 2, + /** Watchdog period of 32 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_32CLK = 3, + /** Watchdog period of 64 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_64CLK = 4, + /** Watchdog period of 128 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_128CLK = 5, + /** Watchdog period of 256 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_256CLK = 6, + /** Watchdog period of 512 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_512CLK = 7, + /** Watchdog period of 1024 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_1024CLK = 8, + /** Watchdog period of 2048 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_2048CLK = 9, + /** Watchdog period of 4096 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_4096CLK = 10, + /** Watchdog period of 8192 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_8192CLK = 11, + /** Watchdog period of 16384 clocks of the Watchdog Timer Generic Clock. */ + WDT_PERIOD_16384CLK = 12, +}; + +void wdt_set_config(bool always_on, + bool enable, + enum gclk_generator clock_source, + enum wdt_period timeout_period, + enum wdt_period window_period, + enum wdt_period early_warning_period); +void wdt_set_config_default(void); + +/** + * Determines if the Watchdog timer is currently enabled and locked, so that + * it cannot be disabled or otherwise reconfigured. + * + * \return Current Watchdog lock state. + */ +static inline bool wdt_is_locked(void) +{ + Wdt *const WDT_module = WDT; + + return (WDT_module->CTRL.reg & WDT_CTRL_ALWAYSON); +} + +/** + * Clears the Watchdog timer Early Warning period elapsed flag, so that a new + * early warning period can be detected. + */ +static inline void wdt_clear_early_warning(void) +{ + Wdt *const WDT_module = WDT; + + WDT_module->INTFLAG.reg = WDT_INTFLAG_EW; +} + +/** + * Determines if the Watchdog timer Early Warning period has elapsed. + * + * \note If no early warning period was configured, the value returned by this + * function is invalid. + * + * \return Current Watchdog Early Warning state. + */ +static inline bool wdt_is_early_warning(void) +{ + Wdt *const WDT_module = WDT; + + return (WDT_module->INTFLAG.reg & WDT_INTFLAG_EW); +} + +void wdt_reset_count(void); + +#endif /* WDT_H_INCLUDED */ diff --git a/loader/inc/util/mrecursion.h b/loader/inc/util/mrecursion.h new file mode 100644 index 0000000..d6db053 --- /dev/null +++ b/loader/inc/util/mrecursion.h @@ -0,0 +1,581 @@ +/** + * Preprocessor macro recursion utils. + * + * Copyright (C) 2013-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _MRECURSION_H_ +#define _MRECURSION_H_ + +#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 +#define DEC_(n) DEC_##n + +/** Maximal number of repetitions supported by MRECURSION. */ +#define MRECURSION_LIMIT 256 + +/** \brief Macro recursion. + * + * This macro represents a horizontal repetition construct. + * + * \param[in] count The number of repetitious calls to macro. Valid values + * range from 0 to MRECURSION_LIMIT. + * \param[in] macro A binary operation of the form macro(data, n). This macro + * is expanded by MRECURSION with the current repetition number + * and the auxiliary data argument. + * \param[in] data A recursive threshold, building on this to decline by times + * defined with param count. + * + * \return macro(data-count+1,0) macro(data-count+2,1)...macro(data,count-1) + */ +#define TPASTE2(a, b) a##b +#define MRECURSION(count, macro, data) TPASTE2(MRECURSION, count) (macro, data) + +#define MRECURSION0( macro, data) +#define MRECURSION1( macro, data) MRECURSION0( macro, DEC_(data)) macro(data, 0) +#define MRECURSION2( macro, data) MRECURSION1( macro, DEC_(data)) macro(data, 1) +#define MRECURSION3( macro, data) MRECURSION2( macro, DEC_(data)) macro(data, 2) +#define MRECURSION4( macro, data) MRECURSION3( macro, DEC_(data)) macro(data, 3) +#define MRECURSION5( macro, data) MRECURSION4( macro, DEC_(data)) macro(data, 4) +#define MRECURSION6( macro, data) MRECURSION5( macro, DEC_(data)) macro(data, 5) +#define MRECURSION7( macro, data) MRECURSION6( macro, DEC_(data)) macro(data, 6) +#define MRECURSION8( macro, data) MRECURSION7( macro, DEC_(data)) macro(data, 7) +#define MRECURSION9( macro, data) MRECURSION8( macro, DEC_(data)) macro(data, 8) +#define MRECURSION10( macro, data) MRECURSION9( macro, DEC_(data)) macro(data, 9) +#define MRECURSION11( macro, data) MRECURSION10( macro, DEC_(data)) macro(data, 10) +#define MRECURSION12( macro, data) MRECURSION11( macro, DEC_(data)) macro(data, 11) +#define MRECURSION13( macro, data) MRECURSION12( macro, DEC_(data)) macro(data, 12) +#define MRECURSION14( macro, data) MRECURSION13( macro, DEC_(data)) macro(data, 13) +#define MRECURSION15( macro, data) MRECURSION14( macro, DEC_(data)) macro(data, 14) +#define MRECURSION16( macro, data) MRECURSION15( macro, DEC_(data)) macro(data, 15) +#define MRECURSION17( macro, data) MRECURSION16( macro, DEC_(data)) macro(data, 16) +#define MRECURSION18( macro, data) MRECURSION17( macro, DEC_(data)) macro(data, 17) +#define MRECURSION19( macro, data) MRECURSION18( macro, DEC_(data)) macro(data, 18) +#define MRECURSION20( macro, data) MRECURSION19( macro, DEC_(data)) macro(data, 19) +#define MRECURSION21( macro, data) MRECURSION20( macro, DEC_(data)) macro(data, 20) +#define MRECURSION22( macro, data) MRECURSION21( macro, DEC_(data)) macro(data, 21) +#define MRECURSION23( macro, data) MRECURSION22( macro, DEC_(data)) macro(data, 22) +#define MRECURSION24( macro, data) MRECURSION23( macro, DEC_(data)) macro(data, 23) +#define MRECURSION25( macro, data) MRECURSION24( macro, DEC_(data)) macro(data, 24) +#define MRECURSION26( macro, data) MRECURSION25( macro, DEC_(data)) macro(data, 25) +#define MRECURSION27( macro, data) MRECURSION26( macro, DEC_(data)) macro(data, 26) +#define MRECURSION28( macro, data) MRECURSION27( macro, DEC_(data)) macro(data, 27) +#define MRECURSION29( macro, data) MRECURSION28( macro, DEC_(data)) macro(data, 28) +#define MRECURSION30( macro, data) MRECURSION29( macro, DEC_(data)) macro(data, 29) +#define MRECURSION31( macro, data) MRECURSION30( macro, DEC_(data)) macro(data, 30) +#define MRECURSION32( macro, data) MRECURSION31( macro, DEC_(data)) macro(data, 31) +#define MRECURSION33( macro, data) MRECURSION32( macro, DEC_(data)) macro(data, 32) +#define MRECURSION34( macro, data) MRECURSION33( macro, DEC_(data)) macro(data, 33) +#define MRECURSION35( macro, data) MRECURSION34( macro, DEC_(data)) macro(data, 34) +#define MRECURSION36( macro, data) MRECURSION35( macro, DEC_(data)) macro(data, 35) +#define MRECURSION37( macro, data) MRECURSION36( macro, DEC_(data)) macro(data, 36) +#define MRECURSION38( macro, data) MRECURSION37( macro, DEC_(data)) macro(data, 37) +#define MRECURSION39( macro, data) MRECURSION38( macro, DEC_(data)) macro(data, 38) +#define MRECURSION40( macro, data) MRECURSION39( macro, DEC_(data)) macro(data, 39) +#define MRECURSION41( macro, data) MRECURSION40( macro, DEC_(data)) macro(data, 40) +#define MRECURSION42( macro, data) MRECURSION41( macro, DEC_(data)) macro(data, 41) +#define MRECURSION43( macro, data) MRECURSION42( macro, DEC_(data)) macro(data, 42) +#define MRECURSION44( macro, data) MRECURSION43( macro, DEC_(data)) macro(data, 43) +#define MRECURSION45( macro, data) MRECURSION44( macro, DEC_(data)) macro(data, 44) +#define MRECURSION46( macro, data) MRECURSION45( macro, DEC_(data)) macro(data, 45) +#define MRECURSION47( macro, data) MRECURSION46( macro, DEC_(data)) macro(data, 46) +#define MRECURSION48( macro, data) MRECURSION47( macro, DEC_(data)) macro(data, 47) +#define MRECURSION49( macro, data) MRECURSION48( macro, DEC_(data)) macro(data, 48) +#define MRECURSION50( macro, data) MRECURSION49( macro, DEC_(data)) macro(data, 49) +#define MRECURSION51( macro, data) MRECURSION50( macro, DEC_(data)) macro(data, 50) +#define MRECURSION52( macro, data) MRECURSION51( macro, DEC_(data)) macro(data, 51) +#define MRECURSION53( macro, data) MRECURSION52( macro, DEC_(data)) macro(data, 52) +#define MRECURSION54( macro, data) MRECURSION53( macro, DEC_(data)) macro(data, 53) +#define MRECURSION55( macro, data) MRECURSION54( macro, DEC_(data)) macro(data, 54) +#define MRECURSION56( macro, data) MRECURSION55( macro, DEC_(data)) macro(data, 55) +#define MRECURSION57( macro, data) MRECURSION56( macro, DEC_(data)) macro(data, 56) +#define MRECURSION58( macro, data) MRECURSION57( macro, DEC_(data)) macro(data, 57) +#define MRECURSION59( macro, data) MRECURSION58( macro, DEC_(data)) macro(data, 58) +#define MRECURSION60( macro, data) MRECURSION59( macro, DEC_(data)) macro(data, 59) +#define MRECURSION61( macro, data) MRECURSION60( macro, DEC_(data)) macro(data, 60) +#define MRECURSION62( macro, data) MRECURSION61( macro, DEC_(data)) macro(data, 61) +#define MRECURSION63( macro, data) MRECURSION62( macro, DEC_(data)) macro(data, 62) +#define MRECURSION64( macro, data) MRECURSION63( macro, DEC_(data)) macro(data, 63) +#define MRECURSION65( macro, data) MRECURSION64( macro, DEC_(data)) macro(data, 64) +#define MRECURSION66( macro, data) MRECURSION65( macro, DEC_(data)) macro(data, 65) +#define MRECURSION67( macro, data) MRECURSION66( macro, DEC_(data)) macro(data, 66) +#define MRECURSION68( macro, data) MRECURSION67( macro, DEC_(data)) macro(data, 67) +#define MRECURSION69( macro, data) MRECURSION68( macro, DEC_(data)) macro(data, 68) +#define MRECURSION70( macro, data) MRECURSION69( macro, DEC_(data)) macro(data, 69) +#define MRECURSION71( macro, data) MRECURSION70( macro, DEC_(data)) macro(data, 70) +#define MRECURSION72( macro, data) MRECURSION71( macro, DEC_(data)) macro(data, 71) +#define MRECURSION73( macro, data) MRECURSION72( macro, DEC_(data)) macro(data, 72) +#define MRECURSION74( macro, data) MRECURSION73( macro, DEC_(data)) macro(data, 73) +#define MRECURSION75( macro, data) MRECURSION74( macro, DEC_(data)) macro(data, 74) +#define MRECURSION76( macro, data) MRECURSION75( macro, DEC_(data)) macro(data, 75) +#define MRECURSION77( macro, data) MRECURSION76( macro, DEC_(data)) macro(data, 76) +#define MRECURSION78( macro, data) MRECURSION77( macro, DEC_(data)) macro(data, 77) +#define MRECURSION79( macro, data) MRECURSION78( macro, DEC_(data)) macro(data, 78) +#define MRECURSION80( macro, data) MRECURSION79( macro, DEC_(data)) macro(data, 79) +#define MRECURSION81( macro, data) MRECURSION80( macro, DEC_(data)) macro(data, 80) +#define MRECURSION82( macro, data) MRECURSION81( macro, DEC_(data)) macro(data, 81) +#define MRECURSION83( macro, data) MRECURSION82( macro, DEC_(data)) macro(data, 82) +#define MRECURSION84( macro, data) MRECURSION83( macro, DEC_(data)) macro(data, 83) +#define MRECURSION85( macro, data) MRECURSION84( macro, DEC_(data)) macro(data, 84) +#define MRECURSION86( macro, data) MRECURSION85( macro, DEC_(data)) macro(data, 85) +#define MRECURSION87( macro, data) MRECURSION86( macro, DEC_(data)) macro(data, 86) +#define MRECURSION88( macro, data) MRECURSION87( macro, DEC_(data)) macro(data, 87) +#define MRECURSION89( macro, data) MRECURSION88( macro, DEC_(data)) macro(data, 88) +#define MRECURSION90( macro, data) MRECURSION89( macro, DEC_(data)) macro(data, 89) +#define MRECURSION91( macro, data) MRECURSION90( macro, DEC_(data)) macro(data, 90) +#define MRECURSION92( macro, data) MRECURSION91( macro, DEC_(data)) macro(data, 91) +#define MRECURSION93( macro, data) MRECURSION92( macro, DEC_(data)) macro(data, 92) +#define MRECURSION94( macro, data) MRECURSION93( macro, DEC_(data)) macro(data, 93) +#define MRECURSION95( macro, data) MRECURSION94( macro, DEC_(data)) macro(data, 94) +#define MRECURSION96( macro, data) MRECURSION95( macro, DEC_(data)) macro(data, 95) +#define MRECURSION97( macro, data) MRECURSION96( macro, DEC_(data)) macro(data, 96) +#define MRECURSION98( macro, data) MRECURSION97( macro, DEC_(data)) macro(data, 97) +#define MRECURSION99( macro, data) MRECURSION98( macro, DEC_(data)) macro(data, 98) +#define MRECURSION100(macro, data) MRECURSION99( macro, DEC_(data)) macro(data, 99) +#define MRECURSION101(macro, data) MRECURSION100( macro, DEC_(data)) macro(data, 100) +#define MRECURSION102(macro, data) MRECURSION101( macro, DEC_(data)) macro(data, 101) +#define MRECURSION103(macro, data) MRECURSION102( macro, DEC_(data)) macro(data, 102) +#define MRECURSION104(macro, data) MRECURSION103( macro, DEC_(data)) macro(data, 103) +#define MRECURSION105(macro, data) MRECURSION104( macro, DEC_(data)) macro(data, 104) +#define MRECURSION106(macro, data) MRECURSION105( macro, DEC_(data)) macro(data, 105) +#define MRECURSION107(macro, data) MRECURSION106( macro, DEC_(data)) macro(data, 106) +#define MRECURSION108(macro, data) MRECURSION107( macro, DEC_(data)) macro(data, 107) +#define MRECURSION109(macro, data) MRECURSION108( macro, DEC_(data)) macro(data, 108) +#define MRECURSION110(macro, data) MRECURSION109( macro, DEC_(data)) macro(data, 109) +#define MRECURSION111(macro, data) MRECURSION110( macro, DEC_(data)) macro(data, 110) +#define MRECURSION112(macro, data) MRECURSION111( macro, DEC_(data)) macro(data, 111) +#define MRECURSION113(macro, data) MRECURSION112( macro, DEC_(data)) macro(data, 112) +#define MRECURSION114(macro, data) MRECURSION113( macro, DEC_(data)) macro(data, 113) +#define MRECURSION115(macro, data) MRECURSION114( macro, DEC_(data)) macro(data, 114) +#define MRECURSION116(macro, data) MRECURSION115( macro, DEC_(data)) macro(data, 115) +#define MRECURSION117(macro, data) MRECURSION116( macro, DEC_(data)) macro(data, 116) +#define MRECURSION118(macro, data) MRECURSION117( macro, DEC_(data)) macro(data, 117) +#define MRECURSION119(macro, data) MRECURSION118( macro, DEC_(data)) macro(data, 118) +#define MRECURSION120(macro, data) MRECURSION119( macro, DEC_(data)) macro(data, 119) +#define MRECURSION121(macro, data) MRECURSION120( macro, DEC_(data)) macro(data, 120) +#define MRECURSION122(macro, data) MRECURSION121( macro, DEC_(data)) macro(data, 121) +#define MRECURSION123(macro, data) MRECURSION122( macro, DEC_(data)) macro(data, 122) +#define MRECURSION124(macro, data) MRECURSION123( macro, DEC_(data)) macro(data, 123) +#define MRECURSION125(macro, data) MRECURSION124( macro, DEC_(data)) macro(data, 124) +#define MRECURSION126(macro, data) MRECURSION125( macro, DEC_(data)) macro(data, 125) +#define MRECURSION127(macro, data) MRECURSION126( macro, DEC_(data)) macro(data, 126) +#define MRECURSION128(macro, data) MRECURSION127( macro, DEC_(data)) macro(data, 127) +#define MRECURSION129(macro, data) MRECURSION128( macro, DEC_(data)) macro(data, 128) +#define MRECURSION130(macro, data) MRECURSION129( macro, DEC_(data)) macro(data, 129) +#define MRECURSION131(macro, data) MRECURSION130( macro, DEC_(data)) macro(data, 130) +#define MRECURSION132(macro, data) MRECURSION131( macro, DEC_(data)) macro(data, 131) +#define MRECURSION133(macro, data) MRECURSION132( macro, DEC_(data)) macro(data, 132) +#define MRECURSION134(macro, data) MRECURSION133( macro, DEC_(data)) macro(data, 133) +#define MRECURSION135(macro, data) MRECURSION134( macro, DEC_(data)) macro(data, 134) +#define MRECURSION136(macro, data) MRECURSION135( macro, DEC_(data)) macro(data, 135) +#define MRECURSION137(macro, data) MRECURSION136( macro, DEC_(data)) macro(data, 136) +#define MRECURSION138(macro, data) MRECURSION137( macro, DEC_(data)) macro(data, 137) +#define MRECURSION139(macro, data) MRECURSION138( macro, DEC_(data)) macro(data, 138) +#define MRECURSION140(macro, data) MRECURSION139( macro, DEC_(data)) macro(data, 139) +#define MRECURSION141(macro, data) MRECURSION140( macro, DEC_(data)) macro(data, 140) +#define MRECURSION142(macro, data) MRECURSION141( macro, DEC_(data)) macro(data, 141) +#define MRECURSION143(macro, data) MRECURSION142( macro, DEC_(data)) macro(data, 142) +#define MRECURSION144(macro, data) MRECURSION143( macro, DEC_(data)) macro(data, 143) +#define MRECURSION145(macro, data) MRECURSION144( macro, DEC_(data)) macro(data, 144) +#define MRECURSION146(macro, data) MRECURSION145( macro, DEC_(data)) macro(data, 145) +#define MRECURSION147(macro, data) MRECURSION146( macro, DEC_(data)) macro(data, 146) +#define MRECURSION148(macro, data) MRECURSION147( macro, DEC_(data)) macro(data, 147) +#define MRECURSION149(macro, data) MRECURSION148( macro, DEC_(data)) macro(data, 148) +#define MRECURSION150(macro, data) MRECURSION149( macro, DEC_(data)) macro(data, 149) +#define MRECURSION151(macro, data) MRECURSION150( macro, DEC_(data)) macro(data, 150) +#define MRECURSION152(macro, data) MRECURSION151( macro, DEC_(data)) macro(data, 151) +#define MRECURSION153(macro, data) MRECURSION152( macro, DEC_(data)) macro(data, 152) +#define MRECURSION154(macro, data) MRECURSION153( macro, DEC_(data)) macro(data, 153) +#define MRECURSION155(macro, data) MRECURSION154( macro, DEC_(data)) macro(data, 154) +#define MRECURSION156(macro, data) MRECURSION155( macro, DEC_(data)) macro(data, 155) +#define MRECURSION157(macro, data) MRECURSION156( macro, DEC_(data)) macro(data, 156) +#define MRECURSION158(macro, data) MRECURSION157( macro, DEC_(data)) macro(data, 157) +#define MRECURSION159(macro, data) MRECURSION158( macro, DEC_(data)) macro(data, 158) +#define MRECURSION160(macro, data) MRECURSION159( macro, DEC_(data)) macro(data, 159) +#define MRECURSION161(macro, data) MRECURSION160( macro, DEC_(data)) macro(data, 160) +#define MRECURSION162(macro, data) MRECURSION161( macro, DEC_(data)) macro(data, 161) +#define MRECURSION163(macro, data) MRECURSION162( macro, DEC_(data)) macro(data, 162) +#define MRECURSION164(macro, data) MRECURSION163( macro, DEC_(data)) macro(data, 163) +#define MRECURSION165(macro, data) MRECURSION164( macro, DEC_(data)) macro(data, 164) +#define MRECURSION166(macro, data) MRECURSION165( macro, DEC_(data)) macro(data, 165) +#define MRECURSION167(macro, data) MRECURSION166( macro, DEC_(data)) macro(data, 166) +#define MRECURSION168(macro, data) MRECURSION167( macro, DEC_(data)) macro(data, 167) +#define MRECURSION169(macro, data) MRECURSION168( macro, DEC_(data)) macro(data, 168) +#define MRECURSION170(macro, data) MRECURSION169( macro, DEC_(data)) macro(data, 169) +#define MRECURSION171(macro, data) MRECURSION170( macro, DEC_(data)) macro(data, 170) +#define MRECURSION172(macro, data) MRECURSION171( macro, DEC_(data)) macro(data, 171) +#define MRECURSION173(macro, data) MRECURSION172( macro, DEC_(data)) macro(data, 172) +#define MRECURSION174(macro, data) MRECURSION173( macro, DEC_(data)) macro(data, 173) +#define MRECURSION175(macro, data) MRECURSION174( macro, DEC_(data)) macro(data, 174) +#define MRECURSION176(macro, data) MRECURSION175( macro, DEC_(data)) macro(data, 175) +#define MRECURSION177(macro, data) MRECURSION176( macro, DEC_(data)) macro(data, 176) +#define MRECURSION178(macro, data) MRECURSION177( macro, DEC_(data)) macro(data, 177) +#define MRECURSION179(macro, data) MRECURSION178( macro, DEC_(data)) macro(data, 178) +#define MRECURSION180(macro, data) MRECURSION179( macro, DEC_(data)) macro(data, 179) +#define MRECURSION181(macro, data) MRECURSION180( macro, DEC_(data)) macro(data, 180) +#define MRECURSION182(macro, data) MRECURSION181( macro, DEC_(data)) macro(data, 181) +#define MRECURSION183(macro, data) MRECURSION182( macro, DEC_(data)) macro(data, 182) +#define MRECURSION184(macro, data) MRECURSION183( macro, DEC_(data)) macro(data, 183) +#define MRECURSION185(macro, data) MRECURSION184( macro, DEC_(data)) macro(data, 184) +#define MRECURSION186(macro, data) MRECURSION185( macro, DEC_(data)) macro(data, 185) +#define MRECURSION187(macro, data) MRECURSION186( macro, DEC_(data)) macro(data, 186) +#define MRECURSION188(macro, data) MRECURSION187( macro, DEC_(data)) macro(data, 187) +#define MRECURSION189(macro, data) MRECURSION188( macro, DEC_(data)) macro(data, 188) +#define MRECURSION190(macro, data) MRECURSION189( macro, DEC_(data)) macro(data, 189) +#define MRECURSION191(macro, data) MRECURSION190( macro, DEC_(data)) macro(data, 190) +#define MRECURSION192(macro, data) MRECURSION191( macro, DEC_(data)) macro(data, 191) +#define MRECURSION193(macro, data) MRECURSION192( macro, DEC_(data)) macro(data, 192) +#define MRECURSION194(macro, data) MRECURSION193( macro, DEC_(data)) macro(data, 193) +#define MRECURSION195(macro, data) MRECURSION194( macro, DEC_(data)) macro(data, 194) +#define MRECURSION196(macro, data) MRECURSION195( macro, DEC_(data)) macro(data, 195) +#define MRECURSION197(macro, data) MRECURSION196( macro, DEC_(data)) macro(data, 196) +#define MRECURSION198(macro, data) MRECURSION197( macro, DEC_(data)) macro(data, 197) +#define MRECURSION199(macro, data) MRECURSION198( macro, DEC_(data)) macro(data, 198) +#define MRECURSION200(macro, data) MRECURSION199( macro, DEC_(data)) macro(data, 199) +#define MRECURSION201(macro, data) MRECURSION200( macro, DEC_(data)) macro(data, 200) +#define MRECURSION202(macro, data) MRECURSION201( macro, DEC_(data)) macro(data, 201) +#define MRECURSION203(macro, data) MRECURSION202( macro, DEC_(data)) macro(data, 202) +#define MRECURSION204(macro, data) MRECURSION203( macro, DEC_(data)) macro(data, 203) +#define MRECURSION205(macro, data) MRECURSION204( macro, DEC_(data)) macro(data, 204) +#define MRECURSION206(macro, data) MRECURSION205( macro, DEC_(data)) macro(data, 205) +#define MRECURSION207(macro, data) MRECURSION206( macro, DEC_(data)) macro(data, 206) +#define MRECURSION208(macro, data) MRECURSION207( macro, DEC_(data)) macro(data, 207) +#define MRECURSION209(macro, data) MRECURSION208( macro, DEC_(data)) macro(data, 208) +#define MRECURSION210(macro, data) MRECURSION209( macro, DEC_(data)) macro(data, 209) +#define MRECURSION211(macro, data) MRECURSION210( macro, DEC_(data)) macro(data, 210) +#define MRECURSION212(macro, data) MRECURSION211( macro, DEC_(data)) macro(data, 211) +#define MRECURSION213(macro, data) MRECURSION212( macro, DEC_(data)) macro(data, 212) +#define MRECURSION214(macro, data) MRECURSION213( macro, DEC_(data)) macro(data, 213) +#define MRECURSION215(macro, data) MRECURSION214( macro, DEC_(data)) macro(data, 214) +#define MRECURSION216(macro, data) MRECURSION215( macro, DEC_(data)) macro(data, 215) +#define MRECURSION217(macro, data) MRECURSION216( macro, DEC_(data)) macro(data, 216) +#define MRECURSION218(macro, data) MRECURSION217( macro, DEC_(data)) macro(data, 217) +#define MRECURSION219(macro, data) MRECURSION218( macro, DEC_(data)) macro(data, 218) +#define MRECURSION220(macro, data) MRECURSION219( macro, DEC_(data)) macro(data, 219) +#define MRECURSION221(macro, data) MRECURSION220( macro, DEC_(data)) macro(data, 220) +#define MRECURSION222(macro, data) MRECURSION221( macro, DEC_(data)) macro(data, 221) +#define MRECURSION223(macro, data) MRECURSION222( macro, DEC_(data)) macro(data, 222) +#define MRECURSION224(macro, data) MRECURSION223( macro, DEC_(data)) macro(data, 223) +#define MRECURSION225(macro, data) MRECURSION224( macro, DEC_(data)) macro(data, 224) +#define MRECURSION226(macro, data) MRECURSION225( macro, DEC_(data)) macro(data, 225) +#define MRECURSION227(macro, data) MRECURSION226( macro, DEC_(data)) macro(data, 226) +#define MRECURSION228(macro, data) MRECURSION227( macro, DEC_(data)) macro(data, 227) +#define MRECURSION229(macro, data) MRECURSION228( macro, DEC_(data)) macro(data, 228) +#define MRECURSION230(macro, data) MRECURSION229( macro, DEC_(data)) macro(data, 229) +#define MRECURSION231(macro, data) MRECURSION230( macro, DEC_(data)) macro(data, 230) +#define MRECURSION232(macro, data) MRECURSION231( macro, DEC_(data)) macro(data, 231) +#define MRECURSION233(macro, data) MRECURSION232( macro, DEC_(data)) macro(data, 232) +#define MRECURSION234(macro, data) MRECURSION233( macro, DEC_(data)) macro(data, 233) +#define MRECURSION235(macro, data) MRECURSION234( macro, DEC_(data)) macro(data, 234) +#define MRECURSION236(macro, data) MRECURSION235( macro, DEC_(data)) macro(data, 235) +#define MRECURSION237(macro, data) MRECURSION236( macro, DEC_(data)) macro(data, 236) +#define MRECURSION238(macro, data) MRECURSION237( macro, DEC_(data)) macro(data, 237) +#define MRECURSION239(macro, data) MRECURSION238( macro, DEC_(data)) macro(data, 238) +#define MRECURSION240(macro, data) MRECURSION239( macro, DEC_(data)) macro(data, 239) +#define MRECURSION241(macro, data) MRECURSION240( macro, DEC_(data)) macro(data, 240) +#define MRECURSION242(macro, data) MRECURSION241( macro, DEC_(data)) macro(data, 241) +#define MRECURSION243(macro, data) MRECURSION242( macro, DEC_(data)) macro(data, 242) +#define MRECURSION244(macro, data) MRECURSION243( macro, DEC_(data)) macro(data, 243) +#define MRECURSION245(macro, data) MRECURSION244( macro, DEC_(data)) macro(data, 244) +#define MRECURSION246(macro, data) MRECURSION245( macro, DEC_(data)) macro(data, 245) +#define MRECURSION247(macro, data) MRECURSION246( macro, DEC_(data)) macro(data, 246) +#define MRECURSION248(macro, data) MRECURSION247( macro, DEC_(data)) macro(data, 247) +#define MRECURSION249(macro, data) MRECURSION248( macro, DEC_(data)) macro(data, 248) +#define MRECURSION250(macro, data) MRECURSION249( macro, DEC_(data)) macro(data, 249) +#define MRECURSION251(macro, data) MRECURSION250( macro, DEC_(data)) macro(data, 250) +#define MRECURSION252(macro, data) MRECURSION251( macro, DEC_(data)) macro(data, 251) +#define MRECURSION253(macro, data) MRECURSION252( macro, DEC_(data)) macro(data, 252) +#define MRECURSION254(macro, data) MRECURSION253( macro, DEC_(data)) macro(data, 253) +#define MRECURSION255(macro, data) MRECURSION254( macro, DEC_(data)) macro(data, 254) +#define MRECURSION256(macro, data) MRECURSION255( macro, DEC_(data)) macro(data, 255) + +#endif /* _MRECURSION_H_ */ diff --git a/loader/inc/watchdog.h b/loader/inc/watchdog.h new file mode 100644 index 0000000..04bf4b4 --- /dev/null +++ b/loader/inc/watchdog.h @@ -0,0 +1,56 @@ +/* + * Functions related to the watchdog. + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef WATCHDOG_H +#define WATCHDOG_H + +#include "samd20.h" + +/** + * These are random constants to prevent run-away code from + * accidentially hitting them. + */ +typedef enum { + IDLE_NONE, + IDLE_LOADER = 0x15476064, +} idle_wait_t; + +/** + * Define how many iterations these loops are permitted before a reset + * is triggered. Values defined to be well above values encountered in + * normal operation. + */ +#define MAXIDLE_WHILE_LOADER 1800 + +struct idle_counter { + uint32_t while_loader; +}; + +void awake_do_watchdog(void); +void kick_the_watchdog(void); +void idle(idle_wait_t idle_t); +void external_watchdog_safe(void); +void watchdog_init(void); + +#endif /* WATCHDOG_H */ diff --git a/loader/inc/xosc.h b/loader/inc/xosc.h new file mode 100644 index 0000000..052c8ba --- /dev/null +++ b/loader/inc/xosc.h @@ -0,0 +1,64 @@ +/* + * Functions for controlling and calibrating against the external oscillator + * Copyright (C) 2014 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef XOSC_H +#define XOSC_H + +#include "samd20.h" + +enum xosc_measurement_t { + XOSC_MEASURE_TIMEPULSE, + XOSC_MEASURE_LFTIMER, +}; + +typedef void (*measurement_result_t)(uint32_t result); + + +/** HF Clock */ +void hf_clock_init(void); +void hf_clock_enable(void); +void hf_clock_disable(void); + +/** LF Clock */ +void lf_clock_startup(void); + +/** GCLK0 */ +void gclk0_to_hf_clock(void); +void gclk0_to_lf_clock(void); + +/** GCLK1 */ +void gclk1_init(void); + +/** GLCK2 */ +void gclk2_init(void); + +/** Measurement */ +void measure_xosc(enum xosc_measurement_t measurement_t, measurement_result_t callback, uint8_t oneshot); +void measure_xosc_disable(enum xosc_measurement_t measurement_t); + +/** LF Timer */ +void lf_tick_start(void); +void lf_tick_stop(void); + +#endif /* XOSC_H */ diff --git a/loader/samd20/component/ac.h b/loader/samd20/component/ac.h new file mode 100644 index 0000000..ebf6337 --- /dev/null +++ b/loader/samd20/component/ac.h @@ -0,0 +1,559 @@ +/** + * \file + * + * \brief Component description for AC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_AC_COMPONENT_ +#define _SAMD20_AC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR AC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_AC Analog Comparators */ +/*@{*/ + +#define AC_U2205 +#define REV_AC 0x111 + +/* -------- AC_CTRLA : (AC Offset: 0x00) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :4; /*!< bit: 3.. 6 Reserved */ + uint8_t LPMUX:1; /*!< bit: 7 Low-Power Mux */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_CTRLA_OFFSET 0x00 /**< \brief (AC_CTRLA offset) Control A */ +#define AC_CTRLA_RESETVALUE 0x00 /**< \brief (AC_CTRLA reset_value) Control A */ + +#define AC_CTRLA_SWRST_Pos 0 /**< \brief (AC_CTRLA) Software Reset */ +#define AC_CTRLA_SWRST (0x1u << AC_CTRLA_SWRST_Pos) +#define AC_CTRLA_ENABLE_Pos 1 /**< \brief (AC_CTRLA) Enable */ +#define AC_CTRLA_ENABLE (0x1u << AC_CTRLA_ENABLE_Pos) +#define AC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (AC_CTRLA) Run in Standby */ +#define AC_CTRLA_RUNSTDBY_Msk (0x1u << AC_CTRLA_RUNSTDBY_Pos) +#define AC_CTRLA_RUNSTDBY(value) ((AC_CTRLA_RUNSTDBY_Msk & ((value) << AC_CTRLA_RUNSTDBY_Pos))) +#define AC_CTRLA_LPMUX_Pos 7 /**< \brief (AC_CTRLA) Low-Power Mux */ +#define AC_CTRLA_LPMUX (0x1u << AC_CTRLA_LPMUX_Pos) +#define AC_CTRLA_MASK 0x87u /**< \brief (AC_CTRLA) MASK Register */ + +/* -------- AC_CTRLB : (AC Offset: 0x01) ( /W 8) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t START0:1; /*!< bit: 0 Comparator 0 Start Comparison */ + uint8_t START1:1; /*!< bit: 1 Comparator 1 Start Comparison */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t START:2; /*!< bit: 0.. 1 Comparator x Start Comparison */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_CTRLB_OFFSET 0x01 /**< \brief (AC_CTRLB offset) Control B */ +#define AC_CTRLB_RESETVALUE 0x00 /**< \brief (AC_CTRLB reset_value) Control B */ + +#define AC_CTRLB_START0_Pos 0 /**< \brief (AC_CTRLB) Comparator 0 Start Comparison */ +#define AC_CTRLB_START0 (1 << AC_CTRLB_START0_Pos) +#define AC_CTRLB_START1_Pos 1 /**< \brief (AC_CTRLB) Comparator 1 Start Comparison */ +#define AC_CTRLB_START1 (1 << AC_CTRLB_START1_Pos) +#define AC_CTRLB_START_Pos 0 /**< \brief (AC_CTRLB) Comparator x Start Comparison */ +#define AC_CTRLB_START_Msk (0x3u << AC_CTRLB_START_Pos) +#define AC_CTRLB_START(value) ((AC_CTRLB_START_Msk & ((value) << AC_CTRLB_START_Pos))) +#define AC_CTRLB_MASK 0x03u /**< \brief (AC_CTRLB) MASK Register */ + +/* -------- AC_EVCTRL : (AC Offset: 0x02) (R/W 16) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t COMPEO0:1; /*!< bit: 0 Comparator 0 Event Output Enable */ + uint16_t COMPEO1:1; /*!< bit: 1 Comparator 1 Event Output Enable */ + uint16_t :2; /*!< bit: 2.. 3 Reserved */ + uint16_t WINEO0:1; /*!< bit: 4 Window 0 Event Output Enable */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t COMPEI0:1; /*!< bit: 8 Comparator 0 Event Input */ + uint16_t COMPEI1:1; /*!< bit: 9 Comparator 1 Event Input */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t COMPEO:2; /*!< bit: 0.. 1 Comparator x Event Output Enable */ + uint16_t :2; /*!< bit: 2.. 3 Reserved */ + uint16_t WINEO:1; /*!< bit: 4 Window x Event Output Enable */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t COMPEI:2; /*!< bit: 8.. 9 Comparator x Event Input */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} AC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_EVCTRL_OFFSET 0x02 /**< \brief (AC_EVCTRL offset) Event Control */ +#define AC_EVCTRL_RESETVALUE 0x0000 /**< \brief (AC_EVCTRL reset_value) Event Control */ + +#define AC_EVCTRL_COMPEO0_Pos 0 /**< \brief (AC_EVCTRL) Comparator 0 Event Output Enable */ +#define AC_EVCTRL_COMPEO0 (1 << AC_EVCTRL_COMPEO0_Pos) +#define AC_EVCTRL_COMPEO1_Pos 1 /**< \brief (AC_EVCTRL) Comparator 1 Event Output Enable */ +#define AC_EVCTRL_COMPEO1 (1 << AC_EVCTRL_COMPEO1_Pos) +#define AC_EVCTRL_COMPEO_Pos 0 /**< \brief (AC_EVCTRL) Comparator x Event Output Enable */ +#define AC_EVCTRL_COMPEO_Msk (0x3u << AC_EVCTRL_COMPEO_Pos) +#define AC_EVCTRL_COMPEO(value) ((AC_EVCTRL_COMPEO_Msk & ((value) << AC_EVCTRL_COMPEO_Pos))) +#define AC_EVCTRL_WINEO0_Pos 4 /**< \brief (AC_EVCTRL) Window 0 Event Output Enable */ +#define AC_EVCTRL_WINEO0 (1 << AC_EVCTRL_WINEO0_Pos) +#define AC_EVCTRL_WINEO_Pos 4 /**< \brief (AC_EVCTRL) Window x Event Output Enable */ +#define AC_EVCTRL_WINEO_Msk (0x1u << AC_EVCTRL_WINEO_Pos) +#define AC_EVCTRL_WINEO(value) ((AC_EVCTRL_WINEO_Msk & ((value) << AC_EVCTRL_WINEO_Pos))) +#define AC_EVCTRL_COMPEI0_Pos 8 /**< \brief (AC_EVCTRL) Comparator 0 Event Input */ +#define AC_EVCTRL_COMPEI0 (1 << AC_EVCTRL_COMPEI0_Pos) +#define AC_EVCTRL_COMPEI1_Pos 9 /**< \brief (AC_EVCTRL) Comparator 1 Event Input */ +#define AC_EVCTRL_COMPEI1 (1 << AC_EVCTRL_COMPEI1_Pos) +#define AC_EVCTRL_COMPEI_Pos 8 /**< \brief (AC_EVCTRL) Comparator x Event Input */ +#define AC_EVCTRL_COMPEI_Msk (0x3u << AC_EVCTRL_COMPEI_Pos) +#define AC_EVCTRL_COMPEI(value) ((AC_EVCTRL_COMPEI_Msk & ((value) << AC_EVCTRL_COMPEI_Pos))) +#define AC_EVCTRL_MASK 0x0313u /**< \brief (AC_EVCTRL) MASK Register */ + +/* -------- AC_INTENCLR : (AC Offset: 0x04) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COMP0:1; /*!< bit: 0 Comparator 0 Interrupt Enable */ + uint8_t COMP1:1; /*!< bit: 1 Comparator 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN0:1; /*!< bit: 4 Window 0 Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN:1; /*!< bit: 4 Window x Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTENCLR_OFFSET 0x04 /**< \brief (AC_INTENCLR offset) Interrupt Enable Clear */ +#define AC_INTENCLR_RESETVALUE 0x00 /**< \brief (AC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define AC_INTENCLR_COMP0_Pos 0 /**< \brief (AC_INTENCLR) Comparator 0 Interrupt Enable */ +#define AC_INTENCLR_COMP0 (1 << AC_INTENCLR_COMP0_Pos) +#define AC_INTENCLR_COMP1_Pos 1 /**< \brief (AC_INTENCLR) Comparator 1 Interrupt Enable */ +#define AC_INTENCLR_COMP1 (1 << AC_INTENCLR_COMP1_Pos) +#define AC_INTENCLR_COMP_Pos 0 /**< \brief (AC_INTENCLR) Comparator x Interrupt Enable */ +#define AC_INTENCLR_COMP_Msk (0x3u << AC_INTENCLR_COMP_Pos) +#define AC_INTENCLR_COMP(value) ((AC_INTENCLR_COMP_Msk & ((value) << AC_INTENCLR_COMP_Pos))) +#define AC_INTENCLR_WIN0_Pos 4 /**< \brief (AC_INTENCLR) Window 0 Interrupt Enable */ +#define AC_INTENCLR_WIN0 (1 << AC_INTENCLR_WIN0_Pos) +#define AC_INTENCLR_WIN_Pos 4 /**< \brief (AC_INTENCLR) Window x Interrupt Enable */ +#define AC_INTENCLR_WIN_Msk (0x1u << AC_INTENCLR_WIN_Pos) +#define AC_INTENCLR_WIN(value) ((AC_INTENCLR_WIN_Msk & ((value) << AC_INTENCLR_WIN_Pos))) +#define AC_INTENCLR_MASK 0x13u /**< \brief (AC_INTENCLR) MASK Register */ + +/* -------- AC_INTENSET : (AC Offset: 0x05) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COMP0:1; /*!< bit: 0 Comparator 0 Interrupt Enable */ + uint8_t COMP1:1; /*!< bit: 1 Comparator 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN0:1; /*!< bit: 4 Window 0 Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN:1; /*!< bit: 4 Window x Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTENSET_OFFSET 0x05 /**< \brief (AC_INTENSET offset) Interrupt Enable Set */ +#define AC_INTENSET_RESETVALUE 0x00 /**< \brief (AC_INTENSET reset_value) Interrupt Enable Set */ + +#define AC_INTENSET_COMP0_Pos 0 /**< \brief (AC_INTENSET) Comparator 0 Interrupt Enable */ +#define AC_INTENSET_COMP0 (1 << AC_INTENSET_COMP0_Pos) +#define AC_INTENSET_COMP1_Pos 1 /**< \brief (AC_INTENSET) Comparator 1 Interrupt Enable */ +#define AC_INTENSET_COMP1 (1 << AC_INTENSET_COMP1_Pos) +#define AC_INTENSET_COMP_Pos 0 /**< \brief (AC_INTENSET) Comparator x Interrupt Enable */ +#define AC_INTENSET_COMP_Msk (0x3u << AC_INTENSET_COMP_Pos) +#define AC_INTENSET_COMP(value) ((AC_INTENSET_COMP_Msk & ((value) << AC_INTENSET_COMP_Pos))) +#define AC_INTENSET_WIN0_Pos 4 /**< \brief (AC_INTENSET) Window 0 Interrupt Enable */ +#define AC_INTENSET_WIN0 (1 << AC_INTENSET_WIN0_Pos) +#define AC_INTENSET_WIN_Pos 4 /**< \brief (AC_INTENSET) Window x Interrupt Enable */ +#define AC_INTENSET_WIN_Msk (0x1u << AC_INTENSET_WIN_Pos) +#define AC_INTENSET_WIN(value) ((AC_INTENSET_WIN_Msk & ((value) << AC_INTENSET_WIN_Pos))) +#define AC_INTENSET_MASK 0x13u /**< \brief (AC_INTENSET) MASK Register */ + +/* -------- AC_INTFLAG : (AC Offset: 0x06) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COMP0:1; /*!< bit: 0 Comparator 0 */ + uint8_t COMP1:1; /*!< bit: 1 Comparator 1 */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN0:1; /*!< bit: 4 Window 0 */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN:1; /*!< bit: 4 Window x */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTFLAG_OFFSET 0x06 /**< \brief (AC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define AC_INTFLAG_RESETVALUE 0x00 /**< \brief (AC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define AC_INTFLAG_COMP0_Pos 0 /**< \brief (AC_INTFLAG) Comparator 0 */ +#define AC_INTFLAG_COMP0 (1 << AC_INTFLAG_COMP0_Pos) +#define AC_INTFLAG_COMP1_Pos 1 /**< \brief (AC_INTFLAG) Comparator 1 */ +#define AC_INTFLAG_COMP1 (1 << AC_INTFLAG_COMP1_Pos) +#define AC_INTFLAG_COMP_Pos 0 /**< \brief (AC_INTFLAG) Comparator x */ +#define AC_INTFLAG_COMP_Msk (0x3u << AC_INTFLAG_COMP_Pos) +#define AC_INTFLAG_COMP(value) ((AC_INTFLAG_COMP_Msk & ((value) << AC_INTFLAG_COMP_Pos))) +#define AC_INTFLAG_WIN0_Pos 4 /**< \brief (AC_INTFLAG) Window 0 */ +#define AC_INTFLAG_WIN0 (1 << AC_INTFLAG_WIN0_Pos) +#define AC_INTFLAG_WIN_Pos 4 /**< \brief (AC_INTFLAG) Window x */ +#define AC_INTFLAG_WIN_Msk (0x1u << AC_INTFLAG_WIN_Pos) +#define AC_INTFLAG_WIN(value) ((AC_INTFLAG_WIN_Msk & ((value) << AC_INTFLAG_WIN_Pos))) +#define AC_INTFLAG_MASK 0x13u /**< \brief (AC_INTFLAG) MASK Register */ + +/* -------- AC_STATUSA : (AC Offset: 0x08) (R/ 8) Status A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STATE0:1; /*!< bit: 0 Comparator 0 Current State */ + uint8_t STATE1:1; /*!< bit: 1 Comparator 1 Current State */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WSTATE0:2; /*!< bit: 4.. 5 Window 0 Current State */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t STATE:2; /*!< bit: 0.. 1 Comparator x Current State */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSA_OFFSET 0x08 /**< \brief (AC_STATUSA offset) Status A */ +#define AC_STATUSA_RESETVALUE 0x00 /**< \brief (AC_STATUSA reset_value) Status A */ + +#define AC_STATUSA_STATE0_Pos 0 /**< \brief (AC_STATUSA) Comparator 0 Current State */ +#define AC_STATUSA_STATE0 (1 << AC_STATUSA_STATE0_Pos) +#define AC_STATUSA_STATE1_Pos 1 /**< \brief (AC_STATUSA) Comparator 1 Current State */ +#define AC_STATUSA_STATE1 (1 << AC_STATUSA_STATE1_Pos) +#define AC_STATUSA_STATE_Pos 0 /**< \brief (AC_STATUSA) Comparator x Current State */ +#define AC_STATUSA_STATE_Msk (0x3u << AC_STATUSA_STATE_Pos) +#define AC_STATUSA_STATE(value) ((AC_STATUSA_STATE_Msk & ((value) << AC_STATUSA_STATE_Pos))) +#define AC_STATUSA_WSTATE0_Pos 4 /**< \brief (AC_STATUSA) Window 0 Current State */ +#define AC_STATUSA_WSTATE0_Msk (0x3u << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0(value) ((AC_STATUSA_WSTATE0_Msk & ((value) << AC_STATUSA_WSTATE0_Pos))) +#define AC_STATUSA_WSTATE0_ABOVE_Val 0x0u /**< \brief (AC_STATUSA) Signal is above window */ +#define AC_STATUSA_WSTATE0_INSIDE_Val 0x1u /**< \brief (AC_STATUSA) Signal is inside window */ +#define AC_STATUSA_WSTATE0_BELOW_Val 0x2u /**< \brief (AC_STATUSA) Signal is below window */ +#define AC_STATUSA_WSTATE0_ABOVE (AC_STATUSA_WSTATE0_ABOVE_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0_INSIDE (AC_STATUSA_WSTATE0_INSIDE_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0_BELOW (AC_STATUSA_WSTATE0_BELOW_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_MASK 0x33u /**< \brief (AC_STATUSA) MASK Register */ + +/* -------- AC_STATUSB : (AC Offset: 0x09) (R/ 8) Status B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t READY0:1; /*!< bit: 0 Comparator 0 Ready */ + uint8_t READY1:1; /*!< bit: 1 Comparator 1 Ready */ + uint8_t :5; /*!< bit: 2.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t READY:2; /*!< bit: 0.. 1 Comparator x Ready */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSB_OFFSET 0x09 /**< \brief (AC_STATUSB offset) Status B */ +#define AC_STATUSB_RESETVALUE 0x00 /**< \brief (AC_STATUSB reset_value) Status B */ + +#define AC_STATUSB_READY0_Pos 0 /**< \brief (AC_STATUSB) Comparator 0 Ready */ +#define AC_STATUSB_READY0 (1 << AC_STATUSB_READY0_Pos) +#define AC_STATUSB_READY1_Pos 1 /**< \brief (AC_STATUSB) Comparator 1 Ready */ +#define AC_STATUSB_READY1 (1 << AC_STATUSB_READY1_Pos) +#define AC_STATUSB_READY_Pos 0 /**< \brief (AC_STATUSB) Comparator x Ready */ +#define AC_STATUSB_READY_Msk (0x3u << AC_STATUSB_READY_Pos) +#define AC_STATUSB_READY(value) ((AC_STATUSB_READY_Msk & ((value) << AC_STATUSB_READY_Pos))) +#define AC_STATUSB_SYNCBUSY_Pos 7 /**< \brief (AC_STATUSB) Synchronization Busy */ +#define AC_STATUSB_SYNCBUSY (0x1u << AC_STATUSB_SYNCBUSY_Pos) +#define AC_STATUSB_MASK 0x83u /**< \brief (AC_STATUSB) MASK Register */ + +/* -------- AC_STATUSC : (AC Offset: 0x0A) (R/ 8) Status C -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STATE0:1; /*!< bit: 0 Comparator 0 Current State */ + uint8_t STATE1:1; /*!< bit: 1 Comparator 1 Current State */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WSTATE0:2; /*!< bit: 4.. 5 Window 0 Current State */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t STATE:2; /*!< bit: 0.. 1 Comparator x Current State */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSC_OFFSET 0x0A /**< \brief (AC_STATUSC offset) Status C */ +#define AC_STATUSC_RESETVALUE 0x00 /**< \brief (AC_STATUSC reset_value) Status C */ + +#define AC_STATUSC_STATE0_Pos 0 /**< \brief (AC_STATUSC) Comparator 0 Current State */ +#define AC_STATUSC_STATE0 (1 << AC_STATUSC_STATE0_Pos) +#define AC_STATUSC_STATE1_Pos 1 /**< \brief (AC_STATUSC) Comparator 1 Current State */ +#define AC_STATUSC_STATE1 (1 << AC_STATUSC_STATE1_Pos) +#define AC_STATUSC_STATE_Pos 0 /**< \brief (AC_STATUSC) Comparator x Current State */ +#define AC_STATUSC_STATE_Msk (0x3u << AC_STATUSC_STATE_Pos) +#define AC_STATUSC_STATE(value) ((AC_STATUSC_STATE_Msk & ((value) << AC_STATUSC_STATE_Pos))) +#define AC_STATUSC_WSTATE0_Pos 4 /**< \brief (AC_STATUSC) Window 0 Current State */ +#define AC_STATUSC_WSTATE0_Msk (0x3u << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0(value) ((AC_STATUSC_WSTATE0_Msk & ((value) << AC_STATUSC_WSTATE0_Pos))) +#define AC_STATUSC_WSTATE0_ABOVE_Val 0x0u /**< \brief (AC_STATUSC) Signal is above window */ +#define AC_STATUSC_WSTATE0_INSIDE_Val 0x1u /**< \brief (AC_STATUSC) Signal is inside window */ +#define AC_STATUSC_WSTATE0_BELOW_Val 0x2u /**< \brief (AC_STATUSC) Signal is below window */ +#define AC_STATUSC_WSTATE0_ABOVE (AC_STATUSC_WSTATE0_ABOVE_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0_INSIDE (AC_STATUSC_WSTATE0_INSIDE_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0_BELOW (AC_STATUSC_WSTATE0_BELOW_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_MASK 0x33u /**< \brief (AC_STATUSC) MASK Register */ + +/* -------- AC_WINCTRL : (AC Offset: 0x0C) (R/W 8) Window Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t WEN0:1; /*!< bit: 0 Window 0 Mode Enable */ + uint8_t WINTSEL0:2; /*!< bit: 1.. 2 Window 0 Interrupt Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_WINCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_WINCTRL_OFFSET 0x0C /**< \brief (AC_WINCTRL offset) Window Control */ +#define AC_WINCTRL_RESETVALUE 0x00 /**< \brief (AC_WINCTRL reset_value) Window Control */ + +#define AC_WINCTRL_WEN0_Pos 0 /**< \brief (AC_WINCTRL) Window 0 Mode Enable */ +#define AC_WINCTRL_WEN0 (0x1u << AC_WINCTRL_WEN0_Pos) +#define AC_WINCTRL_WINTSEL0_Pos 1 /**< \brief (AC_WINCTRL) Window 0 Interrupt Selection */ +#define AC_WINCTRL_WINTSEL0_Msk (0x3u << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0(value) ((AC_WINCTRL_WINTSEL0_Msk & ((value) << AC_WINCTRL_WINTSEL0_Pos))) +#define AC_WINCTRL_WINTSEL0_ABOVE_Val 0x0u /**< \brief (AC_WINCTRL) Interrupt on signal above window */ +#define AC_WINCTRL_WINTSEL0_INSIDE_Val 0x1u /**< \brief (AC_WINCTRL) Interrupt on signal inside window */ +#define AC_WINCTRL_WINTSEL0_BELOW_Val 0x2u /**< \brief (AC_WINCTRL) Interrupt on signal below window */ +#define AC_WINCTRL_WINTSEL0_OUTSIDE_Val 0x3u /**< \brief (AC_WINCTRL) Interrupt on signal outside window */ +#define AC_WINCTRL_WINTSEL0_ABOVE (AC_WINCTRL_WINTSEL0_ABOVE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_INSIDE (AC_WINCTRL_WINTSEL0_INSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_BELOW (AC_WINCTRL_WINTSEL0_BELOW_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_OUTSIDE (AC_WINCTRL_WINTSEL0_OUTSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_MASK 0x07u /**< \brief (AC_WINCTRL) MASK Register */ + +/* -------- AC_COMPCTRL : (AC Offset: 0x10) (R/W 32) Comparator Control n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ENABLE:1; /*!< bit: 0 Enable */ + uint32_t SINGLE:1; /*!< bit: 1 Single-Shot Mode */ + uint32_t SPEED:2; /*!< bit: 2.. 3 Speed Selection */ + uint32_t :1; /*!< bit: 4 Reserved */ + uint32_t INTSEL:2; /*!< bit: 5.. 6 Interrupt Selection */ + uint32_t :1; /*!< bit: 7 Reserved */ + uint32_t MUXNEG:3; /*!< bit: 8..10 Negative Input Mux Selection */ + uint32_t :1; /*!< bit: 11 Reserved */ + uint32_t MUXPOS:2; /*!< bit: 12..13 Positive Input Mux Selection */ + uint32_t :1; /*!< bit: 14 Reserved */ + uint32_t SWAP:1; /*!< bit: 15 Swap Inputs and Invert */ + uint32_t OUT:2; /*!< bit: 16..17 Output */ + uint32_t :1; /*!< bit: 18 Reserved */ + uint32_t HYST:1; /*!< bit: 19 Hysteresis Enable */ + uint32_t :4; /*!< bit: 20..23 Reserved */ + uint32_t FLEN:3; /*!< bit: 24..26 Filter Length */ + uint32_t :5; /*!< bit: 27..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} AC_COMPCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_COMPCTRL_OFFSET 0x10 /**< \brief (AC_COMPCTRL offset) Comparator Control n */ +#define AC_COMPCTRL_RESETVALUE 0x00000000 /**< \brief (AC_COMPCTRL reset_value) Comparator Control n */ + +#define AC_COMPCTRL_ENABLE_Pos 0 /**< \brief (AC_COMPCTRL) Enable */ +#define AC_COMPCTRL_ENABLE (0x1u << AC_COMPCTRL_ENABLE_Pos) +#define AC_COMPCTRL_SINGLE_Pos 1 /**< \brief (AC_COMPCTRL) Single-Shot Mode */ +#define AC_COMPCTRL_SINGLE (0x1u << AC_COMPCTRL_SINGLE_Pos) +#define AC_COMPCTRL_SPEED_Pos 2 /**< \brief (AC_COMPCTRL) Speed Selection */ +#define AC_COMPCTRL_SPEED_Msk (0x3u << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_SPEED(value) ((AC_COMPCTRL_SPEED_Msk & ((value) << AC_COMPCTRL_SPEED_Pos))) +#define AC_COMPCTRL_SPEED_LOW_Val 0x0u /**< \brief (AC_COMPCTRL) Low speed */ +#define AC_COMPCTRL_SPEED_HIGH_Val 0x1u /**< \brief (AC_COMPCTRL) High speed */ +#define AC_COMPCTRL_SPEED_LOW (AC_COMPCTRL_SPEED_LOW_Val << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_SPEED_HIGH (AC_COMPCTRL_SPEED_HIGH_Val << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_INTSEL_Pos 5 /**< \brief (AC_COMPCTRL) Interrupt Selection */ +#define AC_COMPCTRL_INTSEL_Msk (0x3u << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL(value) ((AC_COMPCTRL_INTSEL_Msk & ((value) << AC_COMPCTRL_INTSEL_Pos))) +#define AC_COMPCTRL_INTSEL_TOGGLE_Val 0x0u /**< \brief (AC_COMPCTRL) Interrupt on comparator output toggle */ +#define AC_COMPCTRL_INTSEL_RISING_Val 0x1u /**< \brief (AC_COMPCTRL) Interrupt on comparator output rising */ +#define AC_COMPCTRL_INTSEL_FALLING_Val 0x2u /**< \brief (AC_COMPCTRL) Interrupt on comparator output falling */ +#define AC_COMPCTRL_INTSEL_EOC_Val 0x3u /**< \brief (AC_COMPCTRL) Interrupt on end of comparison (single-shot mode only) */ +#define AC_COMPCTRL_INTSEL_TOGGLE (AC_COMPCTRL_INTSEL_TOGGLE_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_RISING (AC_COMPCTRL_INTSEL_RISING_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_FALLING (AC_COMPCTRL_INTSEL_FALLING_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_EOC (AC_COMPCTRL_INTSEL_EOC_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_MUXNEG_Pos 8 /**< \brief (AC_COMPCTRL) Negative Input Mux Selection */ +#define AC_COMPCTRL_MUXNEG_Msk (0x7u << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG(value) ((AC_COMPCTRL_MUXNEG_Msk & ((value) << AC_COMPCTRL_MUXNEG_Pos))) +#define AC_COMPCTRL_MUXNEG_PIN0_Val 0x0u /**< \brief (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXNEG_PIN1_Val 0x1u /**< \brief (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXNEG_PIN2_Val 0x2u /**< \brief (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXNEG_PIN3_Val 0x3u /**< \brief (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXNEG_GND_Val 0x4u /**< \brief (AC_COMPCTRL) Ground */ +#define AC_COMPCTRL_MUXNEG_VSCALE_Val 0x5u /**< \brief (AC_COMPCTRL) VDD scaler */ +#define AC_COMPCTRL_MUXNEG_BANDGAP_Val 0x6u /**< \brief (AC_COMPCTRL) Internal bandgap voltage */ +#define AC_COMPCTRL_MUXNEG_DAC_Val 0x7u /**< \brief (AC_COMPCTRL) DAC output */ +#define AC_COMPCTRL_MUXNEG_PIN0 (AC_COMPCTRL_MUXNEG_PIN0_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN1 (AC_COMPCTRL_MUXNEG_PIN1_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN2 (AC_COMPCTRL_MUXNEG_PIN2_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN3 (AC_COMPCTRL_MUXNEG_PIN3_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_GND (AC_COMPCTRL_MUXNEG_GND_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_VSCALE (AC_COMPCTRL_MUXNEG_VSCALE_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_BANDGAP (AC_COMPCTRL_MUXNEG_BANDGAP_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_DAC (AC_COMPCTRL_MUXNEG_DAC_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXPOS_Pos 12 /**< \brief (AC_COMPCTRL) Positive Input Mux Selection */ +#define AC_COMPCTRL_MUXPOS_Msk (0x3u << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS(value) ((AC_COMPCTRL_MUXPOS_Msk & ((value) << AC_COMPCTRL_MUXPOS_Pos))) +#define AC_COMPCTRL_MUXPOS_PIN0_Val 0x0u /**< \brief (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXPOS_PIN1_Val 0x1u /**< \brief (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXPOS_PIN2_Val 0x2u /**< \brief (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXPOS_PIN3_Val 0x3u /**< \brief (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXPOS_PIN0 (AC_COMPCTRL_MUXPOS_PIN0_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN1 (AC_COMPCTRL_MUXPOS_PIN1_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN2 (AC_COMPCTRL_MUXPOS_PIN2_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN3 (AC_COMPCTRL_MUXPOS_PIN3_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_SWAP_Pos 15 /**< \brief (AC_COMPCTRL) Swap Inputs and Invert */ +#define AC_COMPCTRL_SWAP (0x1u << AC_COMPCTRL_SWAP_Pos) +#define AC_COMPCTRL_OUT_Pos 16 /**< \brief (AC_COMPCTRL) Output */ +#define AC_COMPCTRL_OUT_Msk (0x3u << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT(value) ((AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos))) +#define AC_COMPCTRL_OUT_OFF_Val 0x0u /**< \brief (AC_COMPCTRL) The output of COMPn is not routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_ASYNC_Val 0x1u /**< \brief (AC_COMPCTRL) The asynchronous output of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_SYNC_Val 0x2u /**< \brief (AC_COMPCTRL) The synchronous output (including filtering) of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_OFF (AC_COMPCTRL_OUT_OFF_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT_ASYNC (AC_COMPCTRL_OUT_ASYNC_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT_SYNC (AC_COMPCTRL_OUT_SYNC_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_HYST_Pos 19 /**< \brief (AC_COMPCTRL) Hysteresis Enable */ +#define AC_COMPCTRL_HYST (0x1u << AC_COMPCTRL_HYST_Pos) +#define AC_COMPCTRL_FLEN_Pos 24 /**< \brief (AC_COMPCTRL) Filter Length */ +#define AC_COMPCTRL_FLEN_Msk (0x7u << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN(value) ((AC_COMPCTRL_FLEN_Msk & ((value) << AC_COMPCTRL_FLEN_Pos))) +#define AC_COMPCTRL_FLEN_OFF_Val 0x0u /**< \brief (AC_COMPCTRL) No filtering */ +#define AC_COMPCTRL_FLEN_MAJ3_Val 0x1u /**< \brief (AC_COMPCTRL) 3-bit majority function (2 of 3) */ +#define AC_COMPCTRL_FLEN_MAJ5_Val 0x2u /**< \brief (AC_COMPCTRL) 5-bit majority function (3 of 5) */ +#define AC_COMPCTRL_FLEN_OFF (AC_COMPCTRL_FLEN_OFF_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN_MAJ3 (AC_COMPCTRL_FLEN_MAJ3_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN_MAJ5 (AC_COMPCTRL_FLEN_MAJ5_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_MASK 0x070BB76Fu /**< \brief (AC_COMPCTRL) MASK Register */ + +/* -------- AC_SCALER : (AC Offset: 0x20) (R/W 8) Scaler n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t VALUE:6; /*!< bit: 0.. 5 Scaler Value */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_SCALER_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_SCALER_OFFSET 0x20 /**< \brief (AC_SCALER offset) Scaler n */ +#define AC_SCALER_RESETVALUE 0x00 /**< \brief (AC_SCALER reset_value) Scaler n */ + +#define AC_SCALER_VALUE_Pos 0 /**< \brief (AC_SCALER) Scaler Value */ +#define AC_SCALER_VALUE_Msk (0x3Fu << AC_SCALER_VALUE_Pos) +#define AC_SCALER_VALUE(value) ((AC_SCALER_VALUE_Msk & ((value) << AC_SCALER_VALUE_Pos))) +#define AC_SCALER_MASK 0x3Fu /**< \brief (AC_SCALER) MASK Register */ + +/** \brief AC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO AC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 8) Control A */ + __O AC_CTRLB_Type CTRLB; /**< \brief Offset: 0x01 ( /W 8) Control B */ + __IO AC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x02 (R/W 16) Event Control */ + __IO AC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x04 (R/W 8) Interrupt Enable Clear */ + __IO AC_INTENSET_Type INTENSET; /**< \brief Offset: 0x05 (R/W 8) Interrupt Enable Set */ + __IO AC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x06 (R/W 8) Interrupt Flag Status and Clear */ + RoReg8 Reserved1[0x1]; + __I AC_STATUSA_Type STATUSA; /**< \brief Offset: 0x08 (R/ 8) Status A */ + __I AC_STATUSB_Type STATUSB; /**< \brief Offset: 0x09 (R/ 8) Status B */ + __I AC_STATUSC_Type STATUSC; /**< \brief Offset: 0x0A (R/ 8) Status C */ + RoReg8 Reserved2[0x1]; + __IO AC_WINCTRL_Type WINCTRL; /**< \brief Offset: 0x0C (R/W 8) Window Control */ + RoReg8 Reserved3[0x3]; + __IO AC_COMPCTRL_Type COMPCTRL[2]; /**< \brief Offset: 0x10 (R/W 32) Comparator Control n */ + RoReg8 Reserved4[0x8]; + __IO AC_SCALER_Type SCALER[2]; /**< \brief Offset: 0x20 (R/W 8) Scaler n */ +} Ac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_AC_COMPONENT_ */ diff --git a/loader/samd20/component/adc.h b/loader/samd20/component/adc.h new file mode 100644 index 0000000..2c37d22 --- /dev/null +++ b/loader/samd20/component/adc.h @@ -0,0 +1,699 @@ +/** + * \file + * + * \brief Component description for ADC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_ADC_COMPONENT_ +#define _SAMD20_ADC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR ADC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_ADC Analog Digital Converter */ +/*@{*/ + +#define ADC_U2204 +#define REV_ADC 0x111 + +/* -------- ADC_CTRLA : (ADC Offset: 0x00) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CTRLA_OFFSET 0x00 /**< \brief (ADC_CTRLA offset) Control A */ +#define ADC_CTRLA_RESETVALUE 0x00 /**< \brief (ADC_CTRLA reset_value) Control A */ + +#define ADC_CTRLA_SWRST_Pos 0 /**< \brief (ADC_CTRLA) Software Reset */ +#define ADC_CTRLA_SWRST (0x1u << ADC_CTRLA_SWRST_Pos) +#define ADC_CTRLA_ENABLE_Pos 1 /**< \brief (ADC_CTRLA) Enable */ +#define ADC_CTRLA_ENABLE (0x1u << ADC_CTRLA_ENABLE_Pos) +#define ADC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (ADC_CTRLA) Run in Standby */ +#define ADC_CTRLA_RUNSTDBY (0x1u << ADC_CTRLA_RUNSTDBY_Pos) +#define ADC_CTRLA_MASK 0x07u /**< \brief (ADC_CTRLA) MASK Register */ + +/* -------- ADC_REFCTRL : (ADC Offset: 0x01) (R/W 8) Reference Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t REFSEL:4; /*!< bit: 0.. 3 Reference Selection */ + uint8_t :3; /*!< bit: 4.. 6 Reserved */ + uint8_t REFCOMP:1; /*!< bit: 7 Reference Buffer Offset Compensation Enable */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_REFCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_REFCTRL_OFFSET 0x01 /**< \brief (ADC_REFCTRL offset) Reference Control */ +#define ADC_REFCTRL_RESETVALUE 0x00 /**< \brief (ADC_REFCTRL reset_value) Reference Control */ + +#define ADC_REFCTRL_REFSEL_Pos 0 /**< \brief (ADC_REFCTRL) Reference Selection */ +#define ADC_REFCTRL_REFSEL_Msk (0xFu << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL(value) ((ADC_REFCTRL_REFSEL_Msk & ((value) << ADC_REFCTRL_REFSEL_Pos))) +#define ADC_REFCTRL_REFSEL_INT1V_Val 0x0u /**< \brief (ADC_REFCTRL) 1.0V voltage reference */ +#define ADC_REFCTRL_REFSEL_INTVCC0_Val 0x1u /**< \brief (ADC_REFCTRL) 1/1.48 VDDANA */ +#define ADC_REFCTRL_REFSEL_INTVCC1_Val 0x2u /**< \brief (ADC_REFCTRL) 1/2 VDDANA (only for VDDANA > 2.0V) */ +#define ADC_REFCTRL_REFSEL_AREFA_Val 0x3u /**< \brief (ADC_REFCTRL) External reference */ +#define ADC_REFCTRL_REFSEL_AREFB_Val 0x4u /**< \brief (ADC_REFCTRL) External reference */ +#define ADC_REFCTRL_REFSEL_INT1V (ADC_REFCTRL_REFSEL_INT1V_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_INTVCC0 (ADC_REFCTRL_REFSEL_INTVCC0_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_INTVCC1 (ADC_REFCTRL_REFSEL_INTVCC1_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_AREFA (ADC_REFCTRL_REFSEL_AREFA_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_AREFB (ADC_REFCTRL_REFSEL_AREFB_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFCOMP_Pos 7 /**< \brief (ADC_REFCTRL) Reference Buffer Offset Compensation Enable */ +#define ADC_REFCTRL_REFCOMP (0x1u << ADC_REFCTRL_REFCOMP_Pos) +#define ADC_REFCTRL_MASK 0x8Fu /**< \brief (ADC_REFCTRL) MASK Register */ + +/* -------- ADC_AVGCTRL : (ADC Offset: 0x02) (R/W 8) Average Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SAMPLENUM:4; /*!< bit: 0.. 3 Number of Samples to be Collected */ + uint8_t ADJRES:3; /*!< bit: 4.. 6 Adjusting Result / Division Coefficient */ + uint8_t :1; /*!< bit: 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_AVGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_AVGCTRL_OFFSET 0x02 /**< \brief (ADC_AVGCTRL offset) Average Control */ +#define ADC_AVGCTRL_RESETVALUE 0x00 /**< \brief (ADC_AVGCTRL reset_value) Average Control */ + +#define ADC_AVGCTRL_SAMPLENUM_Pos 0 /**< \brief (ADC_AVGCTRL) Number of Samples to be Collected */ +#define ADC_AVGCTRL_SAMPLENUM_Msk (0xFu << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM(value) ((ADC_AVGCTRL_SAMPLENUM_Msk & ((value) << ADC_AVGCTRL_SAMPLENUM_Pos))) +#define ADC_AVGCTRL_SAMPLENUM_1_Val 0x0u /**< \brief (ADC_AVGCTRL) 1 sample */ +#define ADC_AVGCTRL_SAMPLENUM_2_Val 0x1u /**< \brief (ADC_AVGCTRL) 2 samples */ +#define ADC_AVGCTRL_SAMPLENUM_4_Val 0x2u /**< \brief (ADC_AVGCTRL) 4 samples */ +#define ADC_AVGCTRL_SAMPLENUM_8_Val 0x3u /**< \brief (ADC_AVGCTRL) 8 samples */ +#define ADC_AVGCTRL_SAMPLENUM_16_Val 0x4u /**< \brief (ADC_AVGCTRL) 16 samples */ +#define ADC_AVGCTRL_SAMPLENUM_32_Val 0x5u /**< \brief (ADC_AVGCTRL) 32 samples */ +#define ADC_AVGCTRL_SAMPLENUM_64_Val 0x6u /**< \brief (ADC_AVGCTRL) 64 samples */ +#define ADC_AVGCTRL_SAMPLENUM_128_Val 0x7u /**< \brief (ADC_AVGCTRL) 128 samples */ +#define ADC_AVGCTRL_SAMPLENUM_256_Val 0x8u /**< \brief (ADC_AVGCTRL) 256 samples */ +#define ADC_AVGCTRL_SAMPLENUM_512_Val 0x9u /**< \brief (ADC_AVGCTRL) 512 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1024_Val 0xAu /**< \brief (ADC_AVGCTRL) 1024 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1 (ADC_AVGCTRL_SAMPLENUM_1_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_2 (ADC_AVGCTRL_SAMPLENUM_2_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_4 (ADC_AVGCTRL_SAMPLENUM_4_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_8 (ADC_AVGCTRL_SAMPLENUM_8_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_16 (ADC_AVGCTRL_SAMPLENUM_16_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_32 (ADC_AVGCTRL_SAMPLENUM_32_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_64 (ADC_AVGCTRL_SAMPLENUM_64_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_128 (ADC_AVGCTRL_SAMPLENUM_128_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_256 (ADC_AVGCTRL_SAMPLENUM_256_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_512 (ADC_AVGCTRL_SAMPLENUM_512_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_1024 (ADC_AVGCTRL_SAMPLENUM_1024_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_ADJRES_Pos 4 /**< \brief (ADC_AVGCTRL) Adjusting Result / Division Coefficient */ +#define ADC_AVGCTRL_ADJRES_Msk (0x7u << ADC_AVGCTRL_ADJRES_Pos) +#define ADC_AVGCTRL_ADJRES(value) ((ADC_AVGCTRL_ADJRES_Msk & ((value) << ADC_AVGCTRL_ADJRES_Pos))) +#define ADC_AVGCTRL_MASK 0x7Fu /**< \brief (ADC_AVGCTRL) MASK Register */ + +/* -------- ADC_SAMPCTRL : (ADC Offset: 0x03) (R/W 8) Sampling Time Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SAMPLEN:6; /*!< bit: 0.. 5 Sampling Time Length */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_SAMPCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_SAMPCTRL_OFFSET 0x03 /**< \brief (ADC_SAMPCTRL offset) Sampling Time Control */ +#define ADC_SAMPCTRL_RESETVALUE 0x00 /**< \brief (ADC_SAMPCTRL reset_value) Sampling Time Control */ + +#define ADC_SAMPCTRL_SAMPLEN_Pos 0 /**< \brief (ADC_SAMPCTRL) Sampling Time Length */ +#define ADC_SAMPCTRL_SAMPLEN_Msk (0x3Fu << ADC_SAMPCTRL_SAMPLEN_Pos) +#define ADC_SAMPCTRL_SAMPLEN(value) ((ADC_SAMPCTRL_SAMPLEN_Msk & ((value) << ADC_SAMPCTRL_SAMPLEN_Pos))) +#define ADC_SAMPCTRL_MASK 0x3Fu /**< \brief (ADC_SAMPCTRL) MASK Register */ + +/* -------- ADC_CTRLB : (ADC Offset: 0x04) (R/W 16) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DIFFMODE:1; /*!< bit: 0 Differential Mode */ + uint16_t LEFTADJ:1; /*!< bit: 1 Left Adjusted Result */ + uint16_t FREERUN:1; /*!< bit: 2 Free Running Mode */ + uint16_t CORREN:1; /*!< bit: 3 Digital Correction Logic Enabled */ + uint16_t RESSEL:2; /*!< bit: 4.. 5 Conversion Result Resolution */ + uint16_t :2; /*!< bit: 6.. 7 Reserved */ + uint16_t PRESCALER:3; /*!< bit: 8..10 Prescaler Configuration */ + uint16_t :5; /*!< bit: 11..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CTRLB_OFFSET 0x04 /**< \brief (ADC_CTRLB offset) Control B */ +#define ADC_CTRLB_RESETVALUE 0x0000 /**< \brief (ADC_CTRLB reset_value) Control B */ + +#define ADC_CTRLB_DIFFMODE_Pos 0 /**< \brief (ADC_CTRLB) Differential Mode */ +#define ADC_CTRLB_DIFFMODE (0x1u << ADC_CTRLB_DIFFMODE_Pos) +#define ADC_CTRLB_LEFTADJ_Pos 1 /**< \brief (ADC_CTRLB) Left Adjusted Result */ +#define ADC_CTRLB_LEFTADJ (0x1u << ADC_CTRLB_LEFTADJ_Pos) +#define ADC_CTRLB_FREERUN_Pos 2 /**< \brief (ADC_CTRLB) Free Running Mode */ +#define ADC_CTRLB_FREERUN (0x1u << ADC_CTRLB_FREERUN_Pos) +#define ADC_CTRLB_CORREN_Pos 3 /**< \brief (ADC_CTRLB) Digital Correction Logic Enabled */ +#define ADC_CTRLB_CORREN (0x1u << ADC_CTRLB_CORREN_Pos) +#define ADC_CTRLB_RESSEL_Pos 4 /**< \brief (ADC_CTRLB) Conversion Result Resolution */ +#define ADC_CTRLB_RESSEL_Msk (0x3u << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL(value) ((ADC_CTRLB_RESSEL_Msk & ((value) << ADC_CTRLB_RESSEL_Pos))) +#define ADC_CTRLB_RESSEL_12BIT_Val 0x0u /**< \brief (ADC_CTRLB) 12-bit result */ +#define ADC_CTRLB_RESSEL_16BIT_Val 0x1u /**< \brief (ADC_CTRLB) For averaging mode output */ +#define ADC_CTRLB_RESSEL_10BIT_Val 0x2u /**< \brief (ADC_CTRLB) 10-bit result */ +#define ADC_CTRLB_RESSEL_8BIT_Val 0x3u /**< \brief (ADC_CTRLB) 8-bit result */ +#define ADC_CTRLB_RESSEL_12BIT (ADC_CTRLB_RESSEL_12BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_16BIT (ADC_CTRLB_RESSEL_16BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_10BIT (ADC_CTRLB_RESSEL_10BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_8BIT (ADC_CTRLB_RESSEL_8BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_PRESCALER_Pos 8 /**< \brief (ADC_CTRLB) Prescaler Configuration */ +#define ADC_CTRLB_PRESCALER_Msk (0x7u << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER(value) ((ADC_CTRLB_PRESCALER_Msk & ((value) << ADC_CTRLB_PRESCALER_Pos))) +#define ADC_CTRLB_PRESCALER_DIV4_Val 0x0u /**< \brief (ADC_CTRLB) Peripheral clock divided by 4 */ +#define ADC_CTRLB_PRESCALER_DIV8_Val 0x1u /**< \brief (ADC_CTRLB) Peripheral clock divided by 8 */ +#define ADC_CTRLB_PRESCALER_DIV16_Val 0x2u /**< \brief (ADC_CTRLB) Peripheral clock divided by 16 */ +#define ADC_CTRLB_PRESCALER_DIV32_Val 0x3u /**< \brief (ADC_CTRLB) Peripheral clock divided by 32 */ +#define ADC_CTRLB_PRESCALER_DIV64_Val 0x4u /**< \brief (ADC_CTRLB) Peripheral clock divided by 64 */ +#define ADC_CTRLB_PRESCALER_DIV128_Val 0x5u /**< \brief (ADC_CTRLB) Peripheral clock divided by 128 */ +#define ADC_CTRLB_PRESCALER_DIV256_Val 0x6u /**< \brief (ADC_CTRLB) Peripheral clock divided by 256 */ +#define ADC_CTRLB_PRESCALER_DIV512_Val 0x7u /**< \brief (ADC_CTRLB) Peripheral clock divided by 512 */ +#define ADC_CTRLB_PRESCALER_DIV4 (ADC_CTRLB_PRESCALER_DIV4_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV8 (ADC_CTRLB_PRESCALER_DIV8_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV16 (ADC_CTRLB_PRESCALER_DIV16_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV32 (ADC_CTRLB_PRESCALER_DIV32_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV64 (ADC_CTRLB_PRESCALER_DIV64_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV128 (ADC_CTRLB_PRESCALER_DIV128_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV256 (ADC_CTRLB_PRESCALER_DIV256_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV512 (ADC_CTRLB_PRESCALER_DIV512_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_MASK 0x073Fu /**< \brief (ADC_CTRLB) MASK Register */ + +/* -------- ADC_WINCTRL : (ADC Offset: 0x08) (R/W 8) Window Monitor Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t WINMODE:3; /*!< bit: 0.. 2 Window Monitor Mode */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_WINCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINCTRL_OFFSET 0x08 /**< \brief (ADC_WINCTRL offset) Window Monitor Control */ +#define ADC_WINCTRL_RESETVALUE 0x00 /**< \brief (ADC_WINCTRL reset_value) Window Monitor Control */ + +#define ADC_WINCTRL_WINMODE_Pos 0 /**< \brief (ADC_WINCTRL) Window Monitor Mode */ +#define ADC_WINCTRL_WINMODE_Msk (0x7u << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE(value) ((ADC_WINCTRL_WINMODE_Msk & ((value) << ADC_WINCTRL_WINMODE_Pos))) +#define ADC_WINCTRL_WINMODE_DISABLE_Val 0x0u /**< \brief (ADC_WINCTRL) No window mode (default) */ +#define ADC_WINCTRL_WINMODE_MODE1_Val 0x1u /**< \brief (ADC_WINCTRL) Mode 1: RESULT > WINLT */ +#define ADC_WINCTRL_WINMODE_MODE2_Val 0x2u /**< \brief (ADC_WINCTRL) Mode 2: RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE3_Val 0x3u /**< \brief (ADC_WINCTRL) Mode 3: WINLT < RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE4_Val 0x4u /**< \brief (ADC_WINCTRL) Mode 4: !(WINLT < RESULT < WINUT) */ +#define ADC_WINCTRL_WINMODE_DISABLE (ADC_WINCTRL_WINMODE_DISABLE_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE1 (ADC_WINCTRL_WINMODE_MODE1_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE2 (ADC_WINCTRL_WINMODE_MODE2_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE3 (ADC_WINCTRL_WINMODE_MODE3_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE4 (ADC_WINCTRL_WINMODE_MODE4_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_MASK 0x07u /**< \brief (ADC_WINCTRL) MASK Register */ + +/* -------- ADC_SWTRIG : (ADC Offset: 0x0C) (R/W 8) Software Trigger -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t FLUSH:1; /*!< bit: 0 ADC Conversion Flush */ + uint8_t START:1; /*!< bit: 1 ADC Start Conversion */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_SWTRIG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_SWTRIG_OFFSET 0x0C /**< \brief (ADC_SWTRIG offset) Software Trigger */ +#define ADC_SWTRIG_RESETVALUE 0x00 /**< \brief (ADC_SWTRIG reset_value) Software Trigger */ + +#define ADC_SWTRIG_FLUSH_Pos 0 /**< \brief (ADC_SWTRIG) ADC Conversion Flush */ +#define ADC_SWTRIG_FLUSH (0x1u << ADC_SWTRIG_FLUSH_Pos) +#define ADC_SWTRIG_START_Pos 1 /**< \brief (ADC_SWTRIG) ADC Start Conversion */ +#define ADC_SWTRIG_START (0x1u << ADC_SWTRIG_START_Pos) +#define ADC_SWTRIG_MASK 0x03u /**< \brief (ADC_SWTRIG) MASK Register */ + +/* -------- ADC_INPUTCTRL : (ADC Offset: 0x10) (R/W 32) Inputs Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t MUXPOS:5; /*!< bit: 0.. 4 Positive MUX Input Selection */ + uint32_t :3; /*!< bit: 5.. 7 Reserved */ + uint32_t MUXNEG:5; /*!< bit: 8..12 Negative MUX Input Selection */ + uint32_t :3; /*!< bit: 13..15 Reserved */ + uint32_t INPUTSCAN:4; /*!< bit: 16..19 Number of Input Channels Included in Scan */ + uint32_t INPUTOFFSET:4; /*!< bit: 20..23 Positive MUX Setting Offset */ + uint32_t GAIN:4; /*!< bit: 24..27 Gain Factor Selection */ + uint32_t :4; /*!< bit: 28..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} ADC_INPUTCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INPUTCTRL_OFFSET 0x10 /**< \brief (ADC_INPUTCTRL offset) Inputs Control */ +#define ADC_INPUTCTRL_RESETVALUE 0x00000000 /**< \brief (ADC_INPUTCTRL reset_value) Inputs Control */ + +#define ADC_INPUTCTRL_MUXPOS_Pos 0 /**< \brief (ADC_INPUTCTRL) Positive MUX Input Selection */ +#define ADC_INPUTCTRL_MUXPOS_Msk (0x1Fu << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS(value) ((ADC_INPUTCTRL_MUXPOS_Msk & ((value) << ADC_INPUTCTRL_MUXPOS_Pos))) +#define ADC_INPUTCTRL_MUXPOS_PIN0_Val 0x0u /**< \brief (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN1_Val 0x1u /**< \brief (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN2_Val 0x2u /**< \brief (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN3_Val 0x3u /**< \brief (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN4_Val 0x4u /**< \brief (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN5_Val 0x5u /**< \brief (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN6_Val 0x6u /**< \brief (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN7_Val 0x7u /**< \brief (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN8_Val 0x8u /**< \brief (ADC_INPUTCTRL) ADC AIN8 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN9_Val 0x9u /**< \brief (ADC_INPUTCTRL) ADC AIN9 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN10_Val 0xAu /**< \brief (ADC_INPUTCTRL) ADC AIN10 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN11_Val 0xBu /**< \brief (ADC_INPUTCTRL) ADC AIN11 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN12_Val 0xCu /**< \brief (ADC_INPUTCTRL) ADC AIN12 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN13_Val 0xDu /**< \brief (ADC_INPUTCTRL) ADC AIN13 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN14_Val 0xEu /**< \brief (ADC_INPUTCTRL) ADC AIN14 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN15_Val 0xFu /**< \brief (ADC_INPUTCTRL) ADC AIN15 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN16_Val 0x10u /**< \brief (ADC_INPUTCTRL) ADC AIN16 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN17_Val 0x11u /**< \brief (ADC_INPUTCTRL) ADC AIN17 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN18_Val 0x12u /**< \brief (ADC_INPUTCTRL) ADC AIN18 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN19_Val 0x13u /**< \brief (ADC_INPUTCTRL) ADC AIN19 Pin */ +#define ADC_INPUTCTRL_MUXPOS_TEMP_Val 0x18u /**< \brief (ADC_INPUTCTRL) Temperature Reference */ +#define ADC_INPUTCTRL_MUXPOS_BANDGAP_Val 0x19u /**< \brief (ADC_INPUTCTRL) Bandgap Voltage */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val 0x1Au /**< \brief (ADC_INPUTCTRL) 1/4 Scaled Core Supply */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val 0x1Bu /**< \brief (ADC_INPUTCTRL) 1/4 Scaled I/O Supply */ +#define ADC_INPUTCTRL_MUXPOS_DAC_Val 0x1Cu /**< \brief (ADC_INPUTCTRL) DAC Output */ +#define ADC_INPUTCTRL_MUXPOS_PIN0 (ADC_INPUTCTRL_MUXPOS_PIN0_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN1 (ADC_INPUTCTRL_MUXPOS_PIN1_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN2 (ADC_INPUTCTRL_MUXPOS_PIN2_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN3 (ADC_INPUTCTRL_MUXPOS_PIN3_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN4 (ADC_INPUTCTRL_MUXPOS_PIN4_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN5 (ADC_INPUTCTRL_MUXPOS_PIN5_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN6 (ADC_INPUTCTRL_MUXPOS_PIN6_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN7 (ADC_INPUTCTRL_MUXPOS_PIN7_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN8 (ADC_INPUTCTRL_MUXPOS_PIN8_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN9 (ADC_INPUTCTRL_MUXPOS_PIN9_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN10 (ADC_INPUTCTRL_MUXPOS_PIN10_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN11 (ADC_INPUTCTRL_MUXPOS_PIN11_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN12 (ADC_INPUTCTRL_MUXPOS_PIN12_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN13 (ADC_INPUTCTRL_MUXPOS_PIN13_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN14 (ADC_INPUTCTRL_MUXPOS_PIN14_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN15 (ADC_INPUTCTRL_MUXPOS_PIN15_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN16 (ADC_INPUTCTRL_MUXPOS_PIN16_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN17 (ADC_INPUTCTRL_MUXPOS_PIN17_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN18 (ADC_INPUTCTRL_MUXPOS_PIN18_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN19 (ADC_INPUTCTRL_MUXPOS_PIN19_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_TEMP (ADC_INPUTCTRL_MUXPOS_TEMP_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_BANDGAP (ADC_INPUTCTRL_MUXPOS_BANDGAP_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC (ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC (ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_DAC (ADC_INPUTCTRL_MUXPOS_DAC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXNEG_Pos 8 /**< \brief (ADC_INPUTCTRL) Negative MUX Input Selection */ +#define ADC_INPUTCTRL_MUXNEG_Msk (0x1Fu << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG(value) ((ADC_INPUTCTRL_MUXNEG_Msk & ((value) << ADC_INPUTCTRL_MUXNEG_Pos))) +#define ADC_INPUTCTRL_MUXNEG_PIN0_Val 0x0u /**< \brief (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN1_Val 0x1u /**< \brief (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN2_Val 0x2u /**< \brief (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN3_Val 0x3u /**< \brief (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN4_Val 0x4u /**< \brief (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN5_Val 0x5u /**< \brief (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN6_Val 0x6u /**< \brief (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN7_Val 0x7u /**< \brief (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXNEG_GND_Val 0x18u /**< \brief (ADC_INPUTCTRL) Internal ground */ +#define ADC_INPUTCTRL_MUXNEG_IOGND_Val 0x19u /**< \brief (ADC_INPUTCTRL) IO ground */ +#define ADC_INPUTCTRL_MUXNEG_PIN0 (ADC_INPUTCTRL_MUXNEG_PIN0_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN1 (ADC_INPUTCTRL_MUXNEG_PIN1_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN2 (ADC_INPUTCTRL_MUXNEG_PIN2_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN3 (ADC_INPUTCTRL_MUXNEG_PIN3_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN4 (ADC_INPUTCTRL_MUXNEG_PIN4_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN5 (ADC_INPUTCTRL_MUXNEG_PIN5_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN6 (ADC_INPUTCTRL_MUXNEG_PIN6_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN7 (ADC_INPUTCTRL_MUXNEG_PIN7_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_GND (ADC_INPUTCTRL_MUXNEG_GND_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_IOGND (ADC_INPUTCTRL_MUXNEG_IOGND_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_INPUTSCAN_Pos 16 /**< \brief (ADC_INPUTCTRL) Number of Input Channels Included in Scan */ +#define ADC_INPUTCTRL_INPUTSCAN_Msk (0xFu << ADC_INPUTCTRL_INPUTSCAN_Pos) +#define ADC_INPUTCTRL_INPUTSCAN(value) ((ADC_INPUTCTRL_INPUTSCAN_Msk & ((value) << ADC_INPUTCTRL_INPUTSCAN_Pos))) +#define ADC_INPUTCTRL_INPUTOFFSET_Pos 20 /**< \brief (ADC_INPUTCTRL) Positive MUX Setting Offset */ +#define ADC_INPUTCTRL_INPUTOFFSET_Msk (0xFu << ADC_INPUTCTRL_INPUTOFFSET_Pos) +#define ADC_INPUTCTRL_INPUTOFFSET(value) ((ADC_INPUTCTRL_INPUTOFFSET_Msk & ((value) << ADC_INPUTCTRL_INPUTOFFSET_Pos))) +#define ADC_INPUTCTRL_GAIN_Pos 24 /**< \brief (ADC_INPUTCTRL) Gain Factor Selection */ +#define ADC_INPUTCTRL_GAIN_Msk (0xFu << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN(value) ((ADC_INPUTCTRL_GAIN_Msk & ((value) << ADC_INPUTCTRL_GAIN_Pos))) +#define ADC_INPUTCTRL_GAIN_1X_Val 0x0u /**< \brief (ADC_INPUTCTRL) 1x */ +#define ADC_INPUTCTRL_GAIN_2X_Val 0x1u /**< \brief (ADC_INPUTCTRL) 2x */ +#define ADC_INPUTCTRL_GAIN_4X_Val 0x2u /**< \brief (ADC_INPUTCTRL) 4x */ +#define ADC_INPUTCTRL_GAIN_8X_Val 0x3u /**< \brief (ADC_INPUTCTRL) 8x */ +#define ADC_INPUTCTRL_GAIN_16X_Val 0x4u /**< \brief (ADC_INPUTCTRL) 16x */ +#define ADC_INPUTCTRL_GAIN_DIV2_Val 0xFu /**< \brief (ADC_INPUTCTRL) 1/2x */ +#define ADC_INPUTCTRL_GAIN_1X (ADC_INPUTCTRL_GAIN_1X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_2X (ADC_INPUTCTRL_GAIN_2X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_4X (ADC_INPUTCTRL_GAIN_4X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_8X (ADC_INPUTCTRL_GAIN_8X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_16X (ADC_INPUTCTRL_GAIN_16X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_DIV2 (ADC_INPUTCTRL_GAIN_DIV2_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_MASK 0x0FFF1F1Fu /**< \brief (ADC_INPUTCTRL) MASK Register */ + +/* -------- ADC_EVCTRL : (ADC Offset: 0x14) (R/W 8) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STARTEI:1; /*!< bit: 0 Start Conversion Event In */ + uint8_t SYNCEI:1; /*!< bit: 1 Synchronization Event In */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t RESRDYEO:1; /*!< bit: 4 Result Ready Event Out */ + uint8_t WINMONEO:1; /*!< bit: 5 Window Monitor Event Out */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_EVCTRL_OFFSET 0x14 /**< \brief (ADC_EVCTRL offset) Event Control */ +#define ADC_EVCTRL_RESETVALUE 0x00 /**< \brief (ADC_EVCTRL reset_value) Event Control */ + +#define ADC_EVCTRL_STARTEI_Pos 0 /**< \brief (ADC_EVCTRL) Start Conversion Event In */ +#define ADC_EVCTRL_STARTEI (0x1u << ADC_EVCTRL_STARTEI_Pos) +#define ADC_EVCTRL_SYNCEI_Pos 1 /**< \brief (ADC_EVCTRL) Synchronization Event In */ +#define ADC_EVCTRL_SYNCEI (0x1u << ADC_EVCTRL_SYNCEI_Pos) +#define ADC_EVCTRL_RESRDYEO_Pos 4 /**< \brief (ADC_EVCTRL) Result Ready Event Out */ +#define ADC_EVCTRL_RESRDYEO (0x1u << ADC_EVCTRL_RESRDYEO_Pos) +#define ADC_EVCTRL_WINMONEO_Pos 5 /**< \brief (ADC_EVCTRL) Window Monitor Event Out */ +#define ADC_EVCTRL_WINMONEO (0x1u << ADC_EVCTRL_WINMONEO_Pos) +#define ADC_EVCTRL_MASK 0x33u /**< \brief (ADC_EVCTRL) MASK Register */ + +/* -------- ADC_INTENCLR : (ADC Offset: 0x16) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t RESRDY:1; /*!< bit: 0 Result Ready Interrupt Enable */ + uint8_t OVERRUN:1; /*!< bit: 1 Overrun Interrupt Enable */ + uint8_t WINMON:1; /*!< bit: 2 Window Monitor Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTENCLR_OFFSET 0x16 /**< \brief (ADC_INTENCLR offset) Interrupt Enable Clear */ +#define ADC_INTENCLR_RESETVALUE 0x00 /**< \brief (ADC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define ADC_INTENCLR_RESRDY_Pos 0 /**< \brief (ADC_INTENCLR) Result Ready Interrupt Enable */ +#define ADC_INTENCLR_RESRDY (0x1u << ADC_INTENCLR_RESRDY_Pos) +#define ADC_INTENCLR_OVERRUN_Pos 1 /**< \brief (ADC_INTENCLR) Overrun Interrupt Enable */ +#define ADC_INTENCLR_OVERRUN (0x1u << ADC_INTENCLR_OVERRUN_Pos) +#define ADC_INTENCLR_WINMON_Pos 2 /**< \brief (ADC_INTENCLR) Window Monitor Interrupt Enable */ +#define ADC_INTENCLR_WINMON (0x1u << ADC_INTENCLR_WINMON_Pos) +#define ADC_INTENCLR_SYNCRDY_Pos 3 /**< \brief (ADC_INTENCLR) Synchronization Ready Interrupt Enable */ +#define ADC_INTENCLR_SYNCRDY (0x1u << ADC_INTENCLR_SYNCRDY_Pos) +#define ADC_INTENCLR_MASK 0x0Fu /**< \brief (ADC_INTENCLR) MASK Register */ + +/* -------- ADC_INTENSET : (ADC Offset: 0x17) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t RESRDY:1; /*!< bit: 0 Result Ready Interrupt Enable */ + uint8_t OVERRUN:1; /*!< bit: 1 Overrun Interrupt Enable */ + uint8_t WINMON:1; /*!< bit: 2 Window Monitor Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTENSET_OFFSET 0x17 /**< \brief (ADC_INTENSET offset) Interrupt Enable Set */ +#define ADC_INTENSET_RESETVALUE 0x00 /**< \brief (ADC_INTENSET reset_value) Interrupt Enable Set */ + +#define ADC_INTENSET_RESRDY_Pos 0 /**< \brief (ADC_INTENSET) Result Ready Interrupt Enable */ +#define ADC_INTENSET_RESRDY (0x1u << ADC_INTENSET_RESRDY_Pos) +#define ADC_INTENSET_OVERRUN_Pos 1 /**< \brief (ADC_INTENSET) Overrun Interrupt Enable */ +#define ADC_INTENSET_OVERRUN (0x1u << ADC_INTENSET_OVERRUN_Pos) +#define ADC_INTENSET_WINMON_Pos 2 /**< \brief (ADC_INTENSET) Window Monitor Interrupt Enable */ +#define ADC_INTENSET_WINMON (0x1u << ADC_INTENSET_WINMON_Pos) +#define ADC_INTENSET_SYNCRDY_Pos 3 /**< \brief (ADC_INTENSET) Synchronization Ready Interrupt Enable */ +#define ADC_INTENSET_SYNCRDY (0x1u << ADC_INTENSET_SYNCRDY_Pos) +#define ADC_INTENSET_MASK 0x0Fu /**< \brief (ADC_INTENSET) MASK Register */ + +/* -------- ADC_INTFLAG : (ADC Offset: 0x18) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t RESRDY:1; /*!< bit: 0 Result Ready */ + uint8_t OVERRUN:1; /*!< bit: 1 Overrun */ + uint8_t WINMON:1; /*!< bit: 2 Window Monitor */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTFLAG_OFFSET 0x18 /**< \brief (ADC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define ADC_INTFLAG_RESETVALUE 0x00 /**< \brief (ADC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define ADC_INTFLAG_RESRDY_Pos 0 /**< \brief (ADC_INTFLAG) Result Ready */ +#define ADC_INTFLAG_RESRDY (0x1u << ADC_INTFLAG_RESRDY_Pos) +#define ADC_INTFLAG_OVERRUN_Pos 1 /**< \brief (ADC_INTFLAG) Overrun */ +#define ADC_INTFLAG_OVERRUN (0x1u << ADC_INTFLAG_OVERRUN_Pos) +#define ADC_INTFLAG_WINMON_Pos 2 /**< \brief (ADC_INTFLAG) Window Monitor */ +#define ADC_INTFLAG_WINMON (0x1u << ADC_INTFLAG_WINMON_Pos) +#define ADC_INTFLAG_SYNCRDY_Pos 3 /**< \brief (ADC_INTFLAG) Synchronization Ready */ +#define ADC_INTFLAG_SYNCRDY (0x1u << ADC_INTFLAG_SYNCRDY_Pos) +#define ADC_INTFLAG_MASK 0x0Fu /**< \brief (ADC_INTFLAG) MASK Register */ + +/* -------- ADC_STATUS : (ADC Offset: 0x19) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_STATUS_OFFSET 0x19 /**< \brief (ADC_STATUS offset) Status */ +#define ADC_STATUS_RESETVALUE 0x00 /**< \brief (ADC_STATUS reset_value) Status */ + +#define ADC_STATUS_SYNCBUSY_Pos 7 /**< \brief (ADC_STATUS) Synchronization Busy */ +#define ADC_STATUS_SYNCBUSY (0x1u << ADC_STATUS_SYNCBUSY_Pos) +#define ADC_STATUS_MASK 0x80u /**< \brief (ADC_STATUS) MASK Register */ + +/* -------- ADC_RESULT : (ADC Offset: 0x1A) (R/ 16) Result -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t RESULT:16; /*!< bit: 0..15 Result Conversion Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_RESULT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_RESULT_OFFSET 0x1A /**< \brief (ADC_RESULT offset) Result */ +#define ADC_RESULT_RESETVALUE 0x0000 /**< \brief (ADC_RESULT reset_value) Result */ + +#define ADC_RESULT_RESULT_Pos 0 /**< \brief (ADC_RESULT) Result Conversion Value */ +#define ADC_RESULT_RESULT_Msk (0xFFFFu << ADC_RESULT_RESULT_Pos) +#define ADC_RESULT_RESULT(value) ((ADC_RESULT_RESULT_Msk & ((value) << ADC_RESULT_RESULT_Pos))) +#define ADC_RESULT_MASK 0xFFFFu /**< \brief (ADC_RESULT) MASK Register */ + +/* -------- ADC_WINLT : (ADC Offset: 0x1C) (R/W 16) Window Monitor Lower Threshold -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t WINLT:16; /*!< bit: 0..15 Window Lower Threshold */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_WINLT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINLT_OFFSET 0x1C /**< \brief (ADC_WINLT offset) Window Monitor Lower Threshold */ +#define ADC_WINLT_RESETVALUE 0x0000 /**< \brief (ADC_WINLT reset_value) Window Monitor Lower Threshold */ + +#define ADC_WINLT_WINLT_Pos 0 /**< \brief (ADC_WINLT) Window Lower Threshold */ +#define ADC_WINLT_WINLT_Msk (0xFFFFu << ADC_WINLT_WINLT_Pos) +#define ADC_WINLT_WINLT(value) ((ADC_WINLT_WINLT_Msk & ((value) << ADC_WINLT_WINLT_Pos))) +#define ADC_WINLT_MASK 0xFFFFu /**< \brief (ADC_WINLT) MASK Register */ + +/* -------- ADC_WINUT : (ADC Offset: 0x20) (R/W 16) Window Monitor Upper Threshold -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t WINUT:16; /*!< bit: 0..15 Window Upper Threshold */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_WINUT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINUT_OFFSET 0x20 /**< \brief (ADC_WINUT offset) Window Monitor Upper Threshold */ +#define ADC_WINUT_RESETVALUE 0x0000 /**< \brief (ADC_WINUT reset_value) Window Monitor Upper Threshold */ + +#define ADC_WINUT_WINUT_Pos 0 /**< \brief (ADC_WINUT) Window Upper Threshold */ +#define ADC_WINUT_WINUT_Msk (0xFFFFu << ADC_WINUT_WINUT_Pos) +#define ADC_WINUT_WINUT(value) ((ADC_WINUT_WINUT_Msk & ((value) << ADC_WINUT_WINUT_Pos))) +#define ADC_WINUT_MASK 0xFFFFu /**< \brief (ADC_WINUT) MASK Register */ + +/* -------- ADC_GAINCORR : (ADC Offset: 0x24) (R/W 16) Gain Correction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t GAINCORR:12; /*!< bit: 0..11 Gain Correction Value */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_GAINCORR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_GAINCORR_OFFSET 0x24 /**< \brief (ADC_GAINCORR offset) Gain Correction */ +#define ADC_GAINCORR_RESETVALUE 0x0000 /**< \brief (ADC_GAINCORR reset_value) Gain Correction */ + +#define ADC_GAINCORR_GAINCORR_Pos 0 /**< \brief (ADC_GAINCORR) Gain Correction Value */ +#define ADC_GAINCORR_GAINCORR_Msk (0xFFFu << ADC_GAINCORR_GAINCORR_Pos) +#define ADC_GAINCORR_GAINCORR(value) ((ADC_GAINCORR_GAINCORR_Msk & ((value) << ADC_GAINCORR_GAINCORR_Pos))) +#define ADC_GAINCORR_MASK 0x0FFFu /**< \brief (ADC_GAINCORR) MASK Register */ + +/* -------- ADC_OFFSETCORR : (ADC Offset: 0x26) (R/W 16) Offset Correction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t OFFSETCORR:12; /*!< bit: 0..11 Offset Correction Value */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_OFFSETCORR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_OFFSETCORR_OFFSET 0x26 /**< \brief (ADC_OFFSETCORR offset) Offset Correction */ +#define ADC_OFFSETCORR_RESETVALUE 0x0000 /**< \brief (ADC_OFFSETCORR reset_value) Offset Correction */ + +#define ADC_OFFSETCORR_OFFSETCORR_Pos 0 /**< \brief (ADC_OFFSETCORR) Offset Correction Value */ +#define ADC_OFFSETCORR_OFFSETCORR_Msk (0xFFFu << ADC_OFFSETCORR_OFFSETCORR_Pos) +#define ADC_OFFSETCORR_OFFSETCORR(value) ((ADC_OFFSETCORR_OFFSETCORR_Msk & ((value) << ADC_OFFSETCORR_OFFSETCORR_Pos))) +#define ADC_OFFSETCORR_MASK 0x0FFFu /**< \brief (ADC_OFFSETCORR) MASK Register */ + +/* -------- ADC_CALIB : (ADC Offset: 0x28) (R/W 16) Calibration -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t LINEARITY_CAL:8; /*!< bit: 0.. 7 Linearity Calibration Value */ + uint16_t BIAS_CAL:3; /*!< bit: 8..10 Bias Calibration Value */ + uint16_t :5; /*!< bit: 11..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_CALIB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CALIB_OFFSET 0x28 /**< \brief (ADC_CALIB offset) Calibration */ +#define ADC_CALIB_RESETVALUE 0x0000 /**< \brief (ADC_CALIB reset_value) Calibration */ + +#define ADC_CALIB_LINEARITY_CAL_Pos 0 /**< \brief (ADC_CALIB) Linearity Calibration Value */ +#define ADC_CALIB_LINEARITY_CAL_Msk (0xFFu << ADC_CALIB_LINEARITY_CAL_Pos) +#define ADC_CALIB_LINEARITY_CAL(value) ((ADC_CALIB_LINEARITY_CAL_Msk & ((value) << ADC_CALIB_LINEARITY_CAL_Pos))) +#define ADC_CALIB_BIAS_CAL_Pos 8 /**< \brief (ADC_CALIB) Bias Calibration Value */ +#define ADC_CALIB_BIAS_CAL_Msk (0x7u << ADC_CALIB_BIAS_CAL_Pos) +#define ADC_CALIB_BIAS_CAL(value) ((ADC_CALIB_BIAS_CAL_Msk & ((value) << ADC_CALIB_BIAS_CAL_Pos))) +#define ADC_CALIB_MASK 0x07FFu /**< \brief (ADC_CALIB) MASK Register */ + +/* -------- ADC_DBGCTRL : (ADC Offset: 0x2A) (R/W 8) Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGRUN:1; /*!< bit: 0 Debug Run */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_DBGCTRL_OFFSET 0x2A /**< \brief (ADC_DBGCTRL offset) Debug Control */ +#define ADC_DBGCTRL_RESETVALUE 0x00 /**< \brief (ADC_DBGCTRL reset_value) Debug Control */ + +#define ADC_DBGCTRL_DBGRUN_Pos 0 /**< \brief (ADC_DBGCTRL) Debug Run */ +#define ADC_DBGCTRL_DBGRUN (0x1u << ADC_DBGCTRL_DBGRUN_Pos) +#define ADC_DBGCTRL_MASK 0x01u /**< \brief (ADC_DBGCTRL) MASK Register */ + +/** \brief ADC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO ADC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 8) Control A */ + __IO ADC_REFCTRL_Type REFCTRL; /**< \brief Offset: 0x01 (R/W 8) Reference Control */ + __IO ADC_AVGCTRL_Type AVGCTRL; /**< \brief Offset: 0x02 (R/W 8) Average Control */ + __IO ADC_SAMPCTRL_Type SAMPCTRL; /**< \brief Offset: 0x03 (R/W 8) Sampling Time Control */ + __IO ADC_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 16) Control B */ + RoReg8 Reserved1[0x2]; + __IO ADC_WINCTRL_Type WINCTRL; /**< \brief Offset: 0x08 (R/W 8) Window Monitor Control */ + RoReg8 Reserved2[0x3]; + __IO ADC_SWTRIG_Type SWTRIG; /**< \brief Offset: 0x0C (R/W 8) Software Trigger */ + RoReg8 Reserved3[0x3]; + __IO ADC_INPUTCTRL_Type INPUTCTRL; /**< \brief Offset: 0x10 (R/W 32) Inputs Control */ + __IO ADC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x14 (R/W 8) Event Control */ + RoReg8 Reserved4[0x1]; + __IO ADC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x16 (R/W 8) Interrupt Enable Clear */ + __IO ADC_INTENSET_Type INTENSET; /**< \brief Offset: 0x17 (R/W 8) Interrupt Enable Set */ + __IO ADC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x18 (R/W 8) Interrupt Flag Status and Clear */ + __I ADC_STATUS_Type STATUS; /**< \brief Offset: 0x19 (R/ 8) Status */ + __I ADC_RESULT_Type RESULT; /**< \brief Offset: 0x1A (R/ 16) Result */ + __IO ADC_WINLT_Type WINLT; /**< \brief Offset: 0x1C (R/W 16) Window Monitor Lower Threshold */ + RoReg8 Reserved5[0x2]; + __IO ADC_WINUT_Type WINUT; /**< \brief Offset: 0x20 (R/W 16) Window Monitor Upper Threshold */ + RoReg8 Reserved6[0x2]; + __IO ADC_GAINCORR_Type GAINCORR; /**< \brief Offset: 0x24 (R/W 16) Gain Correction */ + __IO ADC_OFFSETCORR_Type OFFSETCORR; /**< \brief Offset: 0x26 (R/W 16) Offset Correction */ + __IO ADC_CALIB_Type CALIB; /**< \brief Offset: 0x28 (R/W 16) Calibration */ + __IO ADC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x2A (R/W 8) Debug Control */ +} Adc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_ADC_COMPONENT_ */ diff --git a/loader/samd20/component/dac.h b/loader/samd20/component/dac.h new file mode 100644 index 0000000..7cf0e5a --- /dev/null +++ b/loader/samd20/component/dac.h @@ -0,0 +1,283 @@ +/** + * \file + * + * \brief Component description for DAC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_DAC_COMPONENT_ +#define _SAMD20_DAC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR DAC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_DAC Digital Analog Converter */ +/*@{*/ + +#define DAC_U2214 +#define REV_DAC 0x101 + +/* -------- DAC_CTRLA : (DAC Offset: 0x0) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_CTRLA_OFFSET 0x0 /**< \brief (DAC_CTRLA offset) Control A */ +#define DAC_CTRLA_RESETVALUE 0x00 /**< \brief (DAC_CTRLA reset_value) Control A */ + +#define DAC_CTRLA_SWRST_Pos 0 /**< \brief (DAC_CTRLA) Software Reset */ +#define DAC_CTRLA_SWRST (0x1u << DAC_CTRLA_SWRST_Pos) +#define DAC_CTRLA_ENABLE_Pos 1 /**< \brief (DAC_CTRLA) Enable */ +#define DAC_CTRLA_ENABLE (0x1u << DAC_CTRLA_ENABLE_Pos) +#define DAC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (DAC_CTRLA) Run in Standby */ +#define DAC_CTRLA_RUNSTDBY (0x1u << DAC_CTRLA_RUNSTDBY_Pos) +#define DAC_CTRLA_MASK 0x07u /**< \brief (DAC_CTRLA) MASK Register */ + +/* -------- DAC_CTRLB : (DAC Offset: 0x1) (R/W 8) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EOEN:1; /*!< bit: 0 External Output Enable */ + uint8_t IOEN:1; /*!< bit: 1 Internal Output Enable */ + uint8_t LEFTADJ:1; /*!< bit: 2 Left Adjusted Data */ + uint8_t VPD:1; /*!< bit: 3 Voltage Pump Disable */ + uint8_t :2; /*!< bit: 4.. 5 Reserved */ + uint8_t REFSEL:2; /*!< bit: 6.. 7 Reference Selection */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_CTRLB_OFFSET 0x1 /**< \brief (DAC_CTRLB offset) Control B */ +#define DAC_CTRLB_RESETVALUE 0x00 /**< \brief (DAC_CTRLB reset_value) Control B */ + +#define DAC_CTRLB_EOEN_Pos 0 /**< \brief (DAC_CTRLB) External Output Enable */ +#define DAC_CTRLB_EOEN (0x1u << DAC_CTRLB_EOEN_Pos) +#define DAC_CTRLB_IOEN_Pos 1 /**< \brief (DAC_CTRLB) Internal Output Enable */ +#define DAC_CTRLB_IOEN (0x1u << DAC_CTRLB_IOEN_Pos) +#define DAC_CTRLB_LEFTADJ_Pos 2 /**< \brief (DAC_CTRLB) Left Adjusted Data */ +#define DAC_CTRLB_LEFTADJ (0x1u << DAC_CTRLB_LEFTADJ_Pos) +#define DAC_CTRLB_VPD_Pos 3 /**< \brief (DAC_CTRLB) Voltage Pump Disable */ +#define DAC_CTRLB_VPD (0x1u << DAC_CTRLB_VPD_Pos) +#define DAC_CTRLB_REFSEL_Pos 6 /**< \brief (DAC_CTRLB) Reference Selection */ +#define DAC_CTRLB_REFSEL_Msk (0x3u << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL(value) ((DAC_CTRLB_REFSEL_Msk & ((value) << DAC_CTRLB_REFSEL_Pos))) +#define DAC_CTRLB_REFSEL_INT1V_Val 0x0u /**< \brief (DAC_CTRLB) Internal 1.0V reference */ +#define DAC_CTRLB_REFSEL_AVCC_Val 0x1u /**< \brief (DAC_CTRLB) AVCC */ +#define DAC_CTRLB_REFSEL_VREFP_Val 0x2u /**< \brief (DAC_CTRLB) External reference */ +#define DAC_CTRLB_REFSEL_INT1V (DAC_CTRLB_REFSEL_INT1V_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL_AVCC (DAC_CTRLB_REFSEL_AVCC_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL_VREFP (DAC_CTRLB_REFSEL_VREFP_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_MASK 0xCFu /**< \brief (DAC_CTRLB) MASK Register */ + +/* -------- DAC_EVCTRL : (DAC Offset: 0x2) (R/W 8) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STARTEI:1; /*!< bit: 0 Start Conversion Event Input */ + uint8_t EMPTYEO:1; /*!< bit: 1 Data Buffer Empty Event Output */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_EVCTRL_OFFSET 0x2 /**< \brief (DAC_EVCTRL offset) Event Control */ +#define DAC_EVCTRL_RESETVALUE 0x00 /**< \brief (DAC_EVCTRL reset_value) Event Control */ + +#define DAC_EVCTRL_STARTEI_Pos 0 /**< \brief (DAC_EVCTRL) Start Conversion Event Input */ +#define DAC_EVCTRL_STARTEI (0x1u << DAC_EVCTRL_STARTEI_Pos) +#define DAC_EVCTRL_EMPTYEO_Pos 1 /**< \brief (DAC_EVCTRL) Data Buffer Empty Event Output */ +#define DAC_EVCTRL_EMPTYEO (0x1u << DAC_EVCTRL_EMPTYEO_Pos) +#define DAC_EVCTRL_MASK 0x03u /**< \brief (DAC_EVCTRL) MASK Register */ + +/* -------- DAC_INTENCLR : (DAC Offset: 0x4) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t UNDERRUN:1; /*!< bit: 0 Underrun Interrupt Enable */ + uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTENCLR_OFFSET 0x4 /**< \brief (DAC_INTENCLR offset) Interrupt Enable Clear */ +#define DAC_INTENCLR_RESETVALUE 0x00 /**< \brief (DAC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define DAC_INTENCLR_UNDERRUN_Pos 0 /**< \brief (DAC_INTENCLR) Underrun Interrupt Enable */ +#define DAC_INTENCLR_UNDERRUN (0x1u << DAC_INTENCLR_UNDERRUN_Pos) +#define DAC_INTENCLR_EMPTY_Pos 1 /**< \brief (DAC_INTENCLR) Data Buffer Empty Interrupt Enable */ +#define DAC_INTENCLR_EMPTY (0x1u << DAC_INTENCLR_EMPTY_Pos) +#define DAC_INTENCLR_SYNCRDY_Pos 2 /**< \brief (DAC_INTENCLR) Synchronization Ready Interrupt Enable */ +#define DAC_INTENCLR_SYNCRDY (0x1u << DAC_INTENCLR_SYNCRDY_Pos) +#define DAC_INTENCLR_MASK 0x07u /**< \brief (DAC_INTENCLR) MASK Register */ + +/* -------- DAC_INTENSET : (DAC Offset: 0x5) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t UNDERRUN:1; /*!< bit: 0 Underrun Interrupt Enable */ + uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTENSET_OFFSET 0x5 /**< \brief (DAC_INTENSET offset) Interrupt Enable Set */ +#define DAC_INTENSET_RESETVALUE 0x00 /**< \brief (DAC_INTENSET reset_value) Interrupt Enable Set */ + +#define DAC_INTENSET_UNDERRUN_Pos 0 /**< \brief (DAC_INTENSET) Underrun Interrupt Enable */ +#define DAC_INTENSET_UNDERRUN (0x1u << DAC_INTENSET_UNDERRUN_Pos) +#define DAC_INTENSET_EMPTY_Pos 1 /**< \brief (DAC_INTENSET) Data Buffer Empty Interrupt Enable */ +#define DAC_INTENSET_EMPTY (0x1u << DAC_INTENSET_EMPTY_Pos) +#define DAC_INTENSET_SYNCRDY_Pos 2 /**< \brief (DAC_INTENSET) Synchronization Ready Interrupt Enable */ +#define DAC_INTENSET_SYNCRDY (0x1u << DAC_INTENSET_SYNCRDY_Pos) +#define DAC_INTENSET_MASK 0x07u /**< \brief (DAC_INTENSET) MASK Register */ + +/* -------- DAC_INTFLAG : (DAC Offset: 0x6) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t UNDERRUN:1; /*!< bit: 0 Underrun */ + uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty */ + uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTFLAG_OFFSET 0x6 /**< \brief (DAC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define DAC_INTFLAG_RESETVALUE 0x00 /**< \brief (DAC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define DAC_INTFLAG_UNDERRUN_Pos 0 /**< \brief (DAC_INTFLAG) Underrun */ +#define DAC_INTFLAG_UNDERRUN (0x1u << DAC_INTFLAG_UNDERRUN_Pos) +#define DAC_INTFLAG_EMPTY_Pos 1 /**< \brief (DAC_INTFLAG) Data Buffer Empty */ +#define DAC_INTFLAG_EMPTY (0x1u << DAC_INTFLAG_EMPTY_Pos) +#define DAC_INTFLAG_SYNCRDY_Pos 2 /**< \brief (DAC_INTFLAG) Synchronization Ready */ +#define DAC_INTFLAG_SYNCRDY (0x1u << DAC_INTFLAG_SYNCRDY_Pos) +#define DAC_INTFLAG_MASK 0x07u /**< \brief (DAC_INTFLAG) MASK Register */ + +/* -------- DAC_STATUS : (DAC Offset: 0x7) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy Status */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_STATUS_OFFSET 0x7 /**< \brief (DAC_STATUS offset) Status */ +#define DAC_STATUS_RESETVALUE 0x00 /**< \brief (DAC_STATUS reset_value) Status */ + +#define DAC_STATUS_SYNCBUSY_Pos 7 /**< \brief (DAC_STATUS) Synchronization Busy Status */ +#define DAC_STATUS_SYNCBUSY (0x1u << DAC_STATUS_SYNCBUSY_Pos) +#define DAC_STATUS_MASK 0x80u /**< \brief (DAC_STATUS) MASK Register */ + +/* -------- DAC_DATA : (DAC Offset: 0x8) (R/W 16) Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATA:16; /*!< bit: 0..15 Data to be converted */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DAC_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_DATA_OFFSET 0x8 /**< \brief (DAC_DATA offset) Data */ +#define DAC_DATA_RESETVALUE 0x0000 /**< \brief (DAC_DATA reset_value) Data */ + +#define DAC_DATA_DATA_Pos 0 /**< \brief (DAC_DATA) Data to be converted */ +#define DAC_DATA_DATA_Msk (0xFFFFu << DAC_DATA_DATA_Pos) +#define DAC_DATA_DATA(value) ((DAC_DATA_DATA_Msk & ((value) << DAC_DATA_DATA_Pos))) +#define DAC_DATA_MASK 0xFFFFu /**< \brief (DAC_DATA) MASK Register */ + +/* -------- DAC_DATABUF : (DAC Offset: 0xC) (R/W 16) Data Buffer -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATABUF:16; /*!< bit: 0..15 Data Buffer */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DAC_DATABUF_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_DATABUF_OFFSET 0xC /**< \brief (DAC_DATABUF offset) Data Buffer */ +#define DAC_DATABUF_RESETVALUE 0x0000 /**< \brief (DAC_DATABUF reset_value) Data Buffer */ + +#define DAC_DATABUF_DATABUF_Pos 0 /**< \brief (DAC_DATABUF) Data Buffer */ +#define DAC_DATABUF_DATABUF_Msk (0xFFFFu << DAC_DATABUF_DATABUF_Pos) +#define DAC_DATABUF_DATABUF(value) ((DAC_DATABUF_DATABUF_Msk & ((value) << DAC_DATABUF_DATABUF_Pos))) +#define DAC_DATABUF_MASK 0xFFFFu /**< \brief (DAC_DATABUF) MASK Register */ + +/** \brief DAC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO DAC_CTRLA_Type CTRLA; /**< \brief Offset: 0x0 (R/W 8) Control A */ + __IO DAC_CTRLB_Type CTRLB; /**< \brief Offset: 0x1 (R/W 8) Control B */ + __IO DAC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x2 (R/W 8) Event Control */ + RoReg8 Reserved1[0x1]; + __IO DAC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x4 (R/W 8) Interrupt Enable Clear */ + __IO DAC_INTENSET_Type INTENSET; /**< \brief Offset: 0x5 (R/W 8) Interrupt Enable Set */ + __IO DAC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x6 (R/W 8) Interrupt Flag Status and Clear */ + __I DAC_STATUS_Type STATUS; /**< \brief Offset: 0x7 (R/ 8) Status */ + __IO DAC_DATA_Type DATA; /**< \brief Offset: 0x8 (R/W 16) Data */ + RoReg8 Reserved2[0x2]; + __IO DAC_DATABUF_Type DATABUF; /**< \brief Offset: 0xC (R/W 16) Data Buffer */ +} Dac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_DAC_COMPONENT_ */ diff --git a/loader/samd20/component/dsu.h b/loader/samd20/component/dsu.h new file mode 100644 index 0000000..e796c09 --- /dev/null +++ b/loader/samd20/component/dsu.h @@ -0,0 +1,628 @@ +/** + * \file + * + * \brief Component description for DSU + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_DSU_COMPONENT_ +#define _SAMD20_DSU_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR DSU */ +/* ========================================================================== */ +/** \addtogroup SAMD20_DSU Device Service Unit */ +/*@{*/ + +#define DSU_U2209 +#define REV_DSU 0x102 + +/* -------- DSU_CTRL : (DSU Offset: 0x0000) ( /W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t :1; /*!< bit: 1 Reserved */ + uint8_t CRC:1; /*!< bit: 2 32-bit Cyclic Redundancy Code */ + uint8_t MBIST:1; /*!< bit: 3 Memory built-in self-test */ + uint8_t CE:1; /*!< bit: 4 Chip-Erase */ + uint8_t :1; /*!< bit: 5 Reserved */ + uint8_t ARR:1; /*!< bit: 6 Auxiliary Row Read */ + uint8_t SMSA:1; /*!< bit: 7 Start Memory Stream Access */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DSU_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_CTRL_OFFSET 0x0000 /**< \brief (DSU_CTRL offset) Control */ +#define DSU_CTRL_RESETVALUE 0x00 /**< \brief (DSU_CTRL reset_value) Control */ + +#define DSU_CTRL_SWRST_Pos 0 /**< \brief (DSU_CTRL) Software Reset */ +#define DSU_CTRL_SWRST (0x1u << DSU_CTRL_SWRST_Pos) +#define DSU_CTRL_CRC_Pos 2 /**< \brief (DSU_CTRL) 32-bit Cyclic Redundancy Code */ +#define DSU_CTRL_CRC (0x1u << DSU_CTRL_CRC_Pos) +#define DSU_CTRL_MBIST_Pos 3 /**< \brief (DSU_CTRL) Memory built-in self-test */ +#define DSU_CTRL_MBIST (0x1u << DSU_CTRL_MBIST_Pos) +#define DSU_CTRL_CE_Pos 4 /**< \brief (DSU_CTRL) Chip-Erase */ +#define DSU_CTRL_CE (0x1u << DSU_CTRL_CE_Pos) +#define DSU_CTRL_ARR_Pos 6 /**< \brief (DSU_CTRL) Auxiliary Row Read */ +#define DSU_CTRL_ARR (0x1u << DSU_CTRL_ARR_Pos) +#define DSU_CTRL_SMSA_Pos 7 /**< \brief (DSU_CTRL) Start Memory Stream Access */ +#define DSU_CTRL_SMSA (0x1u << DSU_CTRL_SMSA_Pos) +#define DSU_CTRL_MASK 0xDDu /**< \brief (DSU_CTRL) MASK Register */ + +/* -------- DSU_STATUSA : (DSU Offset: 0x0001) (R/W 8) Status A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DONE:1; /*!< bit: 0 Done */ + uint8_t CRSTEXT:1; /*!< bit: 1 CPU Reset Phase Extension */ + uint8_t BERR:1; /*!< bit: 2 Bus Error */ + uint8_t FAIL:1; /*!< bit: 3 Failure */ + uint8_t PERR:1; /*!< bit: 4 Protection Error */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DSU_STATUSA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_STATUSA_OFFSET 0x0001 /**< \brief (DSU_STATUSA offset) Status A */ +#define DSU_STATUSA_RESETVALUE 0x00 /**< \brief (DSU_STATUSA reset_value) Status A */ + +#define DSU_STATUSA_DONE_Pos 0 /**< \brief (DSU_STATUSA) Done */ +#define DSU_STATUSA_DONE (0x1u << DSU_STATUSA_DONE_Pos) +#define DSU_STATUSA_CRSTEXT_Pos 1 /**< \brief (DSU_STATUSA) CPU Reset Phase Extension */ +#define DSU_STATUSA_CRSTEXT (0x1u << DSU_STATUSA_CRSTEXT_Pos) +#define DSU_STATUSA_BERR_Pos 2 /**< \brief (DSU_STATUSA) Bus Error */ +#define DSU_STATUSA_BERR (0x1u << DSU_STATUSA_BERR_Pos) +#define DSU_STATUSA_FAIL_Pos 3 /**< \brief (DSU_STATUSA) Failure */ +#define DSU_STATUSA_FAIL (0x1u << DSU_STATUSA_FAIL_Pos) +#define DSU_STATUSA_PERR_Pos 4 /**< \brief (DSU_STATUSA) Protection Error */ +#define DSU_STATUSA_PERR (0x1u << DSU_STATUSA_PERR_Pos) +#define DSU_STATUSA_MASK 0x1Fu /**< \brief (DSU_STATUSA) MASK Register */ + +/* -------- DSU_STATUSB : (DSU Offset: 0x0002) (R/ 8) Status B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PROT:1; /*!< bit: 0 Protected */ + uint8_t DBGPRES:1; /*!< bit: 1 Debugger Present */ + uint8_t DCCD0:1; /*!< bit: 2 Debug Communication Channel 0 Dirty */ + uint8_t DCCD1:1; /*!< bit: 3 Debug Communication Channel 1 Dirty */ + uint8_t HPE:1; /*!< bit: 4 Hot-Plugging Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t :2; /*!< bit: 0.. 1 Reserved */ + uint8_t DCCD:2; /*!< bit: 2.. 3 Debug Communication Channel x Dirty */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} DSU_STATUSB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_STATUSB_OFFSET 0x0002 /**< \brief (DSU_STATUSB offset) Status B */ +#define DSU_STATUSB_RESETVALUE 0x00 /**< \brief (DSU_STATUSB reset_value) Status B */ + +#define DSU_STATUSB_PROT_Pos 0 /**< \brief (DSU_STATUSB) Protected */ +#define DSU_STATUSB_PROT (0x1u << DSU_STATUSB_PROT_Pos) +#define DSU_STATUSB_DBGPRES_Pos 1 /**< \brief (DSU_STATUSB) Debugger Present */ +#define DSU_STATUSB_DBGPRES (0x1u << DSU_STATUSB_DBGPRES_Pos) +#define DSU_STATUSB_DCCD0_Pos 2 /**< \brief (DSU_STATUSB) Debug Communication Channel 0 Dirty */ +#define DSU_STATUSB_DCCD0 (1 << DSU_STATUSB_DCCD0_Pos) +#define DSU_STATUSB_DCCD1_Pos 3 /**< \brief (DSU_STATUSB) Debug Communication Channel 1 Dirty */ +#define DSU_STATUSB_DCCD1 (1 << DSU_STATUSB_DCCD1_Pos) +#define DSU_STATUSB_DCCD_Pos 2 /**< \brief (DSU_STATUSB) Debug Communication Channel x Dirty */ +#define DSU_STATUSB_DCCD_Msk (0x3u << DSU_STATUSB_DCCD_Pos) +#define DSU_STATUSB_DCCD(value) ((DSU_STATUSB_DCCD_Msk & ((value) << DSU_STATUSB_DCCD_Pos))) +#define DSU_STATUSB_HPE_Pos 4 /**< \brief (DSU_STATUSB) Hot-Plugging Enable */ +#define DSU_STATUSB_HPE (0x1u << DSU_STATUSB_HPE_Pos) +#define DSU_STATUSB_MASK 0x1Fu /**< \brief (DSU_STATUSB) MASK Register */ + +/* -------- DSU_ADDR : (DSU Offset: 0x0004) (R/W 32) Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t AMOD:2; /*!< bit: 0.. 1 Access Mode */ + uint32_t ADDR:30; /*!< bit: 2..31 Address */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_ADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_ADDR_OFFSET 0x0004 /**< \brief (DSU_ADDR offset) Address */ +#define DSU_ADDR_RESETVALUE 0x00000000 /**< \brief (DSU_ADDR reset_value) Address */ + +#define DSU_ADDR_AMOD_Pos 0 /**< \brief (DSU_ADDR) Access Mode */ +#define DSU_ADDR_AMOD_Msk (0x3u << DSU_ADDR_AMOD_Pos) +#define DSU_ADDR_AMOD(value) ((DSU_ADDR_AMOD_Msk & ((value) << DSU_ADDR_AMOD_Pos))) +#define DSU_ADDR_ADDR_Pos 2 /**< \brief (DSU_ADDR) Address */ +#define DSU_ADDR_ADDR_Msk (0x3FFFFFFFu << DSU_ADDR_ADDR_Pos) +#define DSU_ADDR_ADDR(value) ((DSU_ADDR_ADDR_Msk & ((value) << DSU_ADDR_ADDR_Pos))) +#define DSU_ADDR_MASK 0xFFFFFFFFu /**< \brief (DSU_ADDR) MASK Register */ + +/* -------- DSU_LENGTH : (DSU Offset: 0x0008) (R/W 32) Length -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :2; /*!< bit: 0.. 1 Reserved */ + uint32_t LENGTH:30; /*!< bit: 2..31 Length */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_LENGTH_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_LENGTH_OFFSET 0x0008 /**< \brief (DSU_LENGTH offset) Length */ +#define DSU_LENGTH_RESETVALUE 0x00000000 /**< \brief (DSU_LENGTH reset_value) Length */ + +#define DSU_LENGTH_LENGTH_Pos 2 /**< \brief (DSU_LENGTH) Length */ +#define DSU_LENGTH_LENGTH_Msk (0x3FFFFFFFu << DSU_LENGTH_LENGTH_Pos) +#define DSU_LENGTH_LENGTH(value) ((DSU_LENGTH_LENGTH_Msk & ((value) << DSU_LENGTH_LENGTH_Pos))) +#define DSU_LENGTH_MASK 0xFFFFFFFCu /**< \brief (DSU_LENGTH) MASK Register */ + +/* -------- DSU_DATA : (DSU Offset: 0x000C) (R/W 32) Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DATA:32; /*!< bit: 0..31 Data */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_DATA_OFFSET 0x000C /**< \brief (DSU_DATA offset) Data */ +#define DSU_DATA_RESETVALUE 0x00000000 /**< \brief (DSU_DATA reset_value) Data */ + +#define DSU_DATA_DATA_Pos 0 /**< \brief (DSU_DATA) Data */ +#define DSU_DATA_DATA_Msk (0xFFFFFFFFu << DSU_DATA_DATA_Pos) +#define DSU_DATA_DATA(value) ((DSU_DATA_DATA_Msk & ((value) << DSU_DATA_DATA_Pos))) +#define DSU_DATA_MASK 0xFFFFFFFFu /**< \brief (DSU_DATA) MASK Register */ + +/* -------- DSU_DCC : (DSU Offset: 0x0010) (R/W 32) Debug Communication Channel n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DATA:32; /*!< bit: 0..31 Data */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_DCC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_DCC_OFFSET 0x0010 /**< \brief (DSU_DCC offset) Debug Communication Channel n */ +#define DSU_DCC_RESETVALUE 0x00000000 /**< \brief (DSU_DCC reset_value) Debug Communication Channel n */ + +#define DSU_DCC_DATA_Pos 0 /**< \brief (DSU_DCC) Data */ +#define DSU_DCC_DATA_Msk (0xFFFFFFFFu << DSU_DCC_DATA_Pos) +#define DSU_DCC_DATA(value) ((DSU_DCC_DATA_Msk & ((value) << DSU_DCC_DATA_Pos))) +#define DSU_DCC_MASK 0xFFFFFFFFu /**< \brief (DSU_DCC) MASK Register */ + +/* -------- DSU_DID : (DSU Offset: 0x0018) (R/ 32) Device Identification -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DEVSEL:8; /*!< bit: 0.. 7 Device Select */ + uint32_t REVISION:4; /*!< bit: 8..11 Revision Number */ + uint32_t DIE:4; /*!< bit: 12..15 Die Number */ + uint32_t SERIES:6; /*!< bit: 16..21 Series */ + uint32_t :1; /*!< bit: 22 Reserved */ + uint32_t FAMILY:5; /*!< bit: 23..27 Family */ + uint32_t PROCESSOR:4; /*!< bit: 28..31 Processor */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_DID_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_DID_OFFSET 0x0018 /**< \brief (DSU_DID offset) Device Identification */ + +#define DSU_DID_DEVSEL_Pos 0 /**< \brief (DSU_DID) Device Select */ +#define DSU_DID_DEVSEL_Msk (0xFFu << DSU_DID_DEVSEL_Pos) +#define DSU_DID_DEVSEL(value) ((DSU_DID_DEVSEL_Msk & ((value) << DSU_DID_DEVSEL_Pos))) +#define DSU_DID_REVISION_Pos 8 /**< \brief (DSU_DID) Revision Number */ +#define DSU_DID_REVISION_Msk (0xFu << DSU_DID_REVISION_Pos) +#define DSU_DID_REVISION(value) ((DSU_DID_REVISION_Msk & ((value) << DSU_DID_REVISION_Pos))) +#define DSU_DID_DIE_Pos 12 /**< \brief (DSU_DID) Die Number */ +#define DSU_DID_DIE_Msk (0xFu << DSU_DID_DIE_Pos) +#define DSU_DID_DIE(value) ((DSU_DID_DIE_Msk & ((value) << DSU_DID_DIE_Pos))) +#define DSU_DID_SERIES_Pos 16 /**< \brief (DSU_DID) Series */ +#define DSU_DID_SERIES_Msk (0x3Fu << DSU_DID_SERIES_Pos) +#define DSU_DID_SERIES(value) ((DSU_DID_SERIES_Msk & ((value) << DSU_DID_SERIES_Pos))) +#define DSU_DID_SERIES_0_Val 0x0u /**< \brief (DSU_DID) Cortex-M0+ processor, basic feature set */ +#define DSU_DID_SERIES_1_Val 0x1u /**< \brief (DSU_DID) Cortex-M0+ processor, USB */ +#define DSU_DID_SERIES_0 (DSU_DID_SERIES_0_Val << DSU_DID_SERIES_Pos) +#define DSU_DID_SERIES_1 (DSU_DID_SERIES_1_Val << DSU_DID_SERIES_Pos) +#define DSU_DID_FAMILY_Pos 23 /**< \brief (DSU_DID) Family */ +#define DSU_DID_FAMILY_Msk (0x1Fu << DSU_DID_FAMILY_Pos) +#define DSU_DID_FAMILY(value) ((DSU_DID_FAMILY_Msk & ((value) << DSU_DID_FAMILY_Pos))) +#define DSU_DID_FAMILY_0_Val 0x0u /**< \brief (DSU_DID) General purpose microcontroller */ +#define DSU_DID_FAMILY_1_Val 0x1u /**< \brief (DSU_DID) PicoPower */ +#define DSU_DID_FAMILY_0 (DSU_DID_FAMILY_0_Val << DSU_DID_FAMILY_Pos) +#define DSU_DID_FAMILY_1 (DSU_DID_FAMILY_1_Val << DSU_DID_FAMILY_Pos) +#define DSU_DID_PROCESSOR_Pos 28 /**< \brief (DSU_DID) Processor */ +#define DSU_DID_PROCESSOR_Msk (0xFu << DSU_DID_PROCESSOR_Pos) +#define DSU_DID_PROCESSOR(value) ((DSU_DID_PROCESSOR_Msk & ((value) << DSU_DID_PROCESSOR_Pos))) +#define DSU_DID_PROCESSOR_0_Val 0x0u /**< \brief (DSU_DID) Cortex-M0 */ +#define DSU_DID_PROCESSOR_1_Val 0x1u /**< \brief (DSU_DID) Cortex-M0+ */ +#define DSU_DID_PROCESSOR_2_Val 0x2u /**< \brief (DSU_DID) Cortex-M3 */ +#define DSU_DID_PROCESSOR_3_Val 0x3u /**< \brief (DSU_DID) Cortex-M4 */ +#define DSU_DID_PROCESSOR_0 (DSU_DID_PROCESSOR_0_Val << DSU_DID_PROCESSOR_Pos) +#define DSU_DID_PROCESSOR_1 (DSU_DID_PROCESSOR_1_Val << DSU_DID_PROCESSOR_Pos) +#define DSU_DID_PROCESSOR_2 (DSU_DID_PROCESSOR_2_Val << DSU_DID_PROCESSOR_Pos) +#define DSU_DID_PROCESSOR_3 (DSU_DID_PROCESSOR_3_Val << DSU_DID_PROCESSOR_Pos) +#define DSU_DID_MASK 0xFFBFFFFFu /**< \brief (DSU_DID) MASK Register */ + +/* -------- DSU_DCFG : (DSU Offset: 0x00F0) (R/W 32) Device Configuration -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DCFG:32; /*!< bit: 0..31 Device Configuration */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_DCFG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_DCFG_OFFSET 0x00F0 /**< \brief (DSU_DCFG offset) Device Configuration */ +#define DSU_DCFG_RESETVALUE 0x00000000 /**< \brief (DSU_DCFG reset_value) Device Configuration */ + +#define DSU_DCFG_DCFG_Pos 0 /**< \brief (DSU_DCFG) Device Configuration */ +#define DSU_DCFG_DCFG_Msk (0xFFFFFFFFu << DSU_DCFG_DCFG_Pos) +#define DSU_DCFG_DCFG(value) ((DSU_DCFG_DCFG_Msk & ((value) << DSU_DCFG_DCFG_Pos))) +#define DSU_DCFG_MASK 0xFFFFFFFFu /**< \brief (DSU_DCFG) MASK Register */ + +/* -------- DSU_ENTRY : (DSU Offset: 0x1000) (R/ 32) Coresight ROM Table Entry n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EPRES:1; /*!< bit: 0 Entry Present */ + uint32_t FMT:1; /*!< bit: 1 Format */ + uint32_t :10; /*!< bit: 2..11 Reserved */ + uint32_t ADDOFF:20; /*!< bit: 12..31 Address Offset */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_ENTRY_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_ENTRY_OFFSET 0x1000 /**< \brief (DSU_ENTRY offset) Coresight ROM Table Entry n */ +#define DSU_ENTRY_RESETVALUE 0x00000002 /**< \brief (DSU_ENTRY reset_value) Coresight ROM Table Entry n */ + +#define DSU_ENTRY_EPRES_Pos 0 /**< \brief (DSU_ENTRY) Entry Present */ +#define DSU_ENTRY_EPRES (0x1u << DSU_ENTRY_EPRES_Pos) +#define DSU_ENTRY_FMT_Pos 1 /**< \brief (DSU_ENTRY) Format */ +#define DSU_ENTRY_FMT (0x1u << DSU_ENTRY_FMT_Pos) +#define DSU_ENTRY_ADDOFF_Pos 12 /**< \brief (DSU_ENTRY) Address Offset */ +#define DSU_ENTRY_ADDOFF_Msk (0xFFFFFu << DSU_ENTRY_ADDOFF_Pos) +#define DSU_ENTRY_ADDOFF(value) ((DSU_ENTRY_ADDOFF_Msk & ((value) << DSU_ENTRY_ADDOFF_Pos))) +#define DSU_ENTRY_MASK 0xFFFFF003u /**< \brief (DSU_ENTRY) MASK Register */ + +/* -------- DSU_END : (DSU Offset: 0x1008) (R/ 32) Coresight ROM Table End -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t END:32; /*!< bit: 0..31 End Marker */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_END_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_END_OFFSET 0x1008 /**< \brief (DSU_END offset) Coresight ROM Table End */ +#define DSU_END_RESETVALUE 0x00000000 /**< \brief (DSU_END reset_value) Coresight ROM Table End */ + +#define DSU_END_END_Pos 0 /**< \brief (DSU_END) End Marker */ +#define DSU_END_END_Msk (0xFFFFFFFFu << DSU_END_END_Pos) +#define DSU_END_END(value) ((DSU_END_END_Msk & ((value) << DSU_END_END_Pos))) +#define DSU_END_MASK 0xFFFFFFFFu /**< \brief (DSU_END) MASK Register */ + +/* -------- DSU_MEMTYPE : (DSU Offset: 0x1FCC) (R/ 32) Coresight ROM Table Memory Type -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SMEMP:1; /*!< bit: 0 System Memory Present */ + uint32_t :31; /*!< bit: 1..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_MEMTYPE_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_MEMTYPE_OFFSET 0x1FCC /**< \brief (DSU_MEMTYPE offset) Coresight ROM Table Memory Type */ +#define DSU_MEMTYPE_RESETVALUE 0x00000000 /**< \brief (DSU_MEMTYPE reset_value) Coresight ROM Table Memory Type */ + +#define DSU_MEMTYPE_SMEMP_Pos 0 /**< \brief (DSU_MEMTYPE) System Memory Present */ +#define DSU_MEMTYPE_SMEMP (0x1u << DSU_MEMTYPE_SMEMP_Pos) +#define DSU_MEMTYPE_MASK 0x00000001u /**< \brief (DSU_MEMTYPE) MASK Register */ + +/* -------- DSU_PID4 : (DSU Offset: 0x1FD0) (R/ 32) Peripheral Identification 4 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t JEPCC:4; /*!< bit: 0.. 3 JEP-106 Continuation Code */ + uint32_t FKBC:4; /*!< bit: 4.. 7 4KB count */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_PID4_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID4_OFFSET 0x1FD0 /**< \brief (DSU_PID4 offset) Peripheral Identification 4 */ +#define DSU_PID4_RESETVALUE 0x00000000 /**< \brief (DSU_PID4 reset_value) Peripheral Identification 4 */ + +#define DSU_PID4_JEPCC_Pos 0 /**< \brief (DSU_PID4) JEP-106 Continuation Code */ +#define DSU_PID4_JEPCC_Msk (0xFu << DSU_PID4_JEPCC_Pos) +#define DSU_PID4_JEPCC(value) ((DSU_PID4_JEPCC_Msk & ((value) << DSU_PID4_JEPCC_Pos))) +#define DSU_PID4_FKBC_Pos 4 /**< \brief (DSU_PID4) 4KB count */ +#define DSU_PID4_FKBC_Msk (0xFu << DSU_PID4_FKBC_Pos) +#define DSU_PID4_FKBC(value) ((DSU_PID4_FKBC_Msk & ((value) << DSU_PID4_FKBC_Pos))) +#define DSU_PID4_MASK 0x000000FFu /**< \brief (DSU_PID4) MASK Register */ + +/* -------- DSU_PID5 : (DSU Offset: 0x1FD4) (R/ 32) Peripheral Identification 5 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + uint32_t reg; /*!< Type used for register access */ +} DSU_PID5_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID5_OFFSET 0x1FD4 /**< \brief (DSU_PID5 offset) Peripheral Identification 5 */ +#define DSU_PID5_MASK 0x00000000u /**< \brief (DSU_PID5) MASK Register */ + +/* -------- DSU_PID6 : (DSU Offset: 0x1FD8) (R/ 32) Peripheral Identification 6 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + uint32_t reg; /*!< Type used for register access */ +} DSU_PID6_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID6_OFFSET 0x1FD8 /**< \brief (DSU_PID6 offset) Peripheral Identification 6 */ +#define DSU_PID6_MASK 0x00000000u /**< \brief (DSU_PID6) MASK Register */ + +/* -------- DSU_PID7 : (DSU Offset: 0x1FDC) (R/ 32) Peripheral Identification 7 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + uint32_t reg; /*!< Type used for register access */ +} DSU_PID7_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID7_OFFSET 0x1FDC /**< \brief (DSU_PID7 offset) Peripheral Identification 7 */ +#define DSU_PID7_MASK 0x00000000u /**< \brief (DSU_PID7) MASK Register */ + +/* -------- DSU_PID0 : (DSU Offset: 0x1FE0) (R/ 32) Peripheral Identification 0 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PARTNBL:8; /*!< bit: 0.. 7 Part Number Low */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_PID0_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID0_OFFSET 0x1FE0 /**< \brief (DSU_PID0 offset) Peripheral Identification 0 */ +#define DSU_PID0_RESETVALUE 0x000000D0 /**< \brief (DSU_PID0 reset_value) Peripheral Identification 0 */ + +#define DSU_PID0_PARTNBL_Pos 0 /**< \brief (DSU_PID0) Part Number Low */ +#define DSU_PID0_PARTNBL_Msk (0xFFu << DSU_PID0_PARTNBL_Pos) +#define DSU_PID0_PARTNBL(value) ((DSU_PID0_PARTNBL_Msk & ((value) << DSU_PID0_PARTNBL_Pos))) +#define DSU_PID0_MASK 0x000000FFu /**< \brief (DSU_PID0) MASK Register */ + +/* -------- DSU_PID1 : (DSU Offset: 0x1FE4) (R/ 32) Peripheral Identification 1 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PARTNBH:4; /*!< bit: 0.. 3 Part Number High */ + uint32_t JEPIDCL:4; /*!< bit: 4.. 7 Low part of the JEP-106 Identity Code */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_PID1_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID1_OFFSET 0x1FE4 /**< \brief (DSU_PID1 offset) Peripheral Identification 1 */ +#define DSU_PID1_RESETVALUE 0x000000FC /**< \brief (DSU_PID1 reset_value) Peripheral Identification 1 */ + +#define DSU_PID1_PARTNBH_Pos 0 /**< \brief (DSU_PID1) Part Number High */ +#define DSU_PID1_PARTNBH_Msk (0xFu << DSU_PID1_PARTNBH_Pos) +#define DSU_PID1_PARTNBH(value) ((DSU_PID1_PARTNBH_Msk & ((value) << DSU_PID1_PARTNBH_Pos))) +#define DSU_PID1_JEPIDCL_Pos 4 /**< \brief (DSU_PID1) Low part of the JEP-106 Identity Code */ +#define DSU_PID1_JEPIDCL_Msk (0xFu << DSU_PID1_JEPIDCL_Pos) +#define DSU_PID1_JEPIDCL(value) ((DSU_PID1_JEPIDCL_Msk & ((value) << DSU_PID1_JEPIDCL_Pos))) +#define DSU_PID1_MASK 0x000000FFu /**< \brief (DSU_PID1) MASK Register */ + +/* -------- DSU_PID2 : (DSU Offset: 0x1FE8) (R/ 32) Peripheral Identification 2 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t JEPIDCH:3; /*!< bit: 0.. 2 JEP-106 Identity Code High */ + uint32_t JEPU:1; /*!< bit: 3 JEP-106 Identity Code is used */ + uint32_t REVISION:4; /*!< bit: 4.. 7 Revision Number */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_PID2_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID2_OFFSET 0x1FE8 /**< \brief (DSU_PID2 offset) Peripheral Identification 2 */ +#define DSU_PID2_RESETVALUE 0x00000009 /**< \brief (DSU_PID2 reset_value) Peripheral Identification 2 */ + +#define DSU_PID2_JEPIDCH_Pos 0 /**< \brief (DSU_PID2) JEP-106 Identity Code High */ +#define DSU_PID2_JEPIDCH_Msk (0x7u << DSU_PID2_JEPIDCH_Pos) +#define DSU_PID2_JEPIDCH(value) ((DSU_PID2_JEPIDCH_Msk & ((value) << DSU_PID2_JEPIDCH_Pos))) +#define DSU_PID2_JEPU_Pos 3 /**< \brief (DSU_PID2) JEP-106 Identity Code is used */ +#define DSU_PID2_JEPU (0x1u << DSU_PID2_JEPU_Pos) +#define DSU_PID2_REVISION_Pos 4 /**< \brief (DSU_PID2) Revision Number */ +#define DSU_PID2_REVISION_Msk (0xFu << DSU_PID2_REVISION_Pos) +#define DSU_PID2_REVISION(value) ((DSU_PID2_REVISION_Msk & ((value) << DSU_PID2_REVISION_Pos))) +#define DSU_PID2_MASK 0x000000FFu /**< \brief (DSU_PID2) MASK Register */ + +/* -------- DSU_PID3 : (DSU Offset: 0x1FEC) (R/ 32) Peripheral Identification 3 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CUSMOD:4; /*!< bit: 0.. 3 ARM CUSMOD */ + uint32_t REVAND:4; /*!< bit: 4.. 7 Revision Number */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_PID3_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_PID3_OFFSET 0x1FEC /**< \brief (DSU_PID3 offset) Peripheral Identification 3 */ +#define DSU_PID3_RESETVALUE 0x00000000 /**< \brief (DSU_PID3 reset_value) Peripheral Identification 3 */ + +#define DSU_PID3_CUSMOD_Pos 0 /**< \brief (DSU_PID3) ARM CUSMOD */ +#define DSU_PID3_CUSMOD_Msk (0xFu << DSU_PID3_CUSMOD_Pos) +#define DSU_PID3_CUSMOD(value) ((DSU_PID3_CUSMOD_Msk & ((value) << DSU_PID3_CUSMOD_Pos))) +#define DSU_PID3_REVAND_Pos 4 /**< \brief (DSU_PID3) Revision Number */ +#define DSU_PID3_REVAND_Msk (0xFu << DSU_PID3_REVAND_Pos) +#define DSU_PID3_REVAND(value) ((DSU_PID3_REVAND_Msk & ((value) << DSU_PID3_REVAND_Pos))) +#define DSU_PID3_MASK 0x000000FFu /**< \brief (DSU_PID3) MASK Register */ + +/* -------- DSU_CID0 : (DSU Offset: 0x1FF0) (R/ 32) Component Identification 0 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PREAMBLEB0:8; /*!< bit: 0.. 7 Preamble Byte 0 */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_CID0_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_CID0_OFFSET 0x1FF0 /**< \brief (DSU_CID0 offset) Component Identification 0 */ +#define DSU_CID0_RESETVALUE 0x0000000D /**< \brief (DSU_CID0 reset_value) Component Identification 0 */ + +#define DSU_CID0_PREAMBLEB0_Pos 0 /**< \brief (DSU_CID0) Preamble Byte 0 */ +#define DSU_CID0_PREAMBLEB0_Msk (0xFFu << DSU_CID0_PREAMBLEB0_Pos) +#define DSU_CID0_PREAMBLEB0(value) ((DSU_CID0_PREAMBLEB0_Msk & ((value) << DSU_CID0_PREAMBLEB0_Pos))) +#define DSU_CID0_MASK 0x000000FFu /**< \brief (DSU_CID0) MASK Register */ + +/* -------- DSU_CID1 : (DSU Offset: 0x1FF4) (R/ 32) Component Identification 1 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PREAMBLE:4; /*!< bit: 0.. 3 Preamble */ + uint32_t CCLASS:4; /*!< bit: 4.. 7 Component Class */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_CID1_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_CID1_OFFSET 0x1FF4 /**< \brief (DSU_CID1 offset) Component Identification 1 */ +#define DSU_CID1_RESETVALUE 0x00000010 /**< \brief (DSU_CID1 reset_value) Component Identification 1 */ + +#define DSU_CID1_PREAMBLE_Pos 0 /**< \brief (DSU_CID1) Preamble */ +#define DSU_CID1_PREAMBLE_Msk (0xFu << DSU_CID1_PREAMBLE_Pos) +#define DSU_CID1_PREAMBLE(value) ((DSU_CID1_PREAMBLE_Msk & ((value) << DSU_CID1_PREAMBLE_Pos))) +#define DSU_CID1_CCLASS_Pos 4 /**< \brief (DSU_CID1) Component Class */ +#define DSU_CID1_CCLASS_Msk (0xFu << DSU_CID1_CCLASS_Pos) +#define DSU_CID1_CCLASS(value) ((DSU_CID1_CCLASS_Msk & ((value) << DSU_CID1_CCLASS_Pos))) +#define DSU_CID1_MASK 0x000000FFu /**< \brief (DSU_CID1) MASK Register */ + +/* -------- DSU_CID2 : (DSU Offset: 0x1FF8) (R/ 32) Component Identification 2 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PREAMBLEB2:8; /*!< bit: 0.. 7 Preamble Byte 2 */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_CID2_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_CID2_OFFSET 0x1FF8 /**< \brief (DSU_CID2 offset) Component Identification 2 */ +#define DSU_CID2_RESETVALUE 0x00000005 /**< \brief (DSU_CID2 reset_value) Component Identification 2 */ + +#define DSU_CID2_PREAMBLEB2_Pos 0 /**< \brief (DSU_CID2) Preamble Byte 2 */ +#define DSU_CID2_PREAMBLEB2_Msk (0xFFu << DSU_CID2_PREAMBLEB2_Pos) +#define DSU_CID2_PREAMBLEB2(value) ((DSU_CID2_PREAMBLEB2_Msk & ((value) << DSU_CID2_PREAMBLEB2_Pos))) +#define DSU_CID2_MASK 0x000000FFu /**< \brief (DSU_CID2) MASK Register */ + +/* -------- DSU_CID3 : (DSU Offset: 0x1FFC) (R/ 32) Component Identification 3 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PREAMBLEB3:8; /*!< bit: 0.. 7 Preamble Byte 3 */ + uint32_t :24; /*!< bit: 8..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DSU_CID3_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DSU_CID3_OFFSET 0x1FFC /**< \brief (DSU_CID3 offset) Component Identification 3 */ +#define DSU_CID3_RESETVALUE 0x000000B1 /**< \brief (DSU_CID3 reset_value) Component Identification 3 */ + +#define DSU_CID3_PREAMBLEB3_Pos 0 /**< \brief (DSU_CID3) Preamble Byte 3 */ +#define DSU_CID3_PREAMBLEB3_Msk (0xFFu << DSU_CID3_PREAMBLEB3_Pos) +#define DSU_CID3_PREAMBLEB3(value) ((DSU_CID3_PREAMBLEB3_Msk & ((value) << DSU_CID3_PREAMBLEB3_Pos))) +#define DSU_CID3_MASK 0x000000FFu /**< \brief (DSU_CID3) MASK Register */ + +/** \brief DSU hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __O DSU_CTRL_Type CTRL; /**< \brief Offset: 0x0000 ( /W 8) Control */ + __IO DSU_STATUSA_Type STATUSA; /**< \brief Offset: 0x0001 (R/W 8) Status A */ + __I DSU_STATUSB_Type STATUSB; /**< \brief Offset: 0x0002 (R/ 8) Status B */ + RoReg8 Reserved1[0x1]; + __IO DSU_ADDR_Type ADDR; /**< \brief Offset: 0x0004 (R/W 32) Address */ + __IO DSU_LENGTH_Type LENGTH; /**< \brief Offset: 0x0008 (R/W 32) Length */ + __IO DSU_DATA_Type DATA; /**< \brief Offset: 0x000C (R/W 32) Data */ + __IO DSU_DCC_Type DCC[2]; /**< \brief Offset: 0x0010 (R/W 32) Debug Communication Channel n */ + __I DSU_DID_Type DID; /**< \brief Offset: 0x0018 (R/ 32) Device Identification */ + RoReg8 Reserved2[0xD4]; + __IO DSU_DCFG_Type DCFG[2]; /**< \brief Offset: 0x00F0 (R/W 32) Device Configuration */ + RoReg8 Reserved3[0xF08]; + __I DSU_ENTRY_Type ENTRY[2]; /**< \brief Offset: 0x1000 (R/ 32) Coresight ROM Table Entry n */ + __I DSU_END_Type END; /**< \brief Offset: 0x1008 (R/ 32) Coresight ROM Table End */ + RoReg8 Reserved4[0xFC0]; + __I DSU_MEMTYPE_Type MEMTYPE; /**< \brief Offset: 0x1FCC (R/ 32) Coresight ROM Table Memory Type */ + __I DSU_PID4_Type PID4; /**< \brief Offset: 0x1FD0 (R/ 32) Peripheral Identification 4 */ + __I DSU_PID5_Type PID5; /**< \brief Offset: 0x1FD4 (R/ 32) Peripheral Identification 5 */ + __I DSU_PID6_Type PID6; /**< \brief Offset: 0x1FD8 (R/ 32) Peripheral Identification 6 */ + __I DSU_PID7_Type PID7; /**< \brief Offset: 0x1FDC (R/ 32) Peripheral Identification 7 */ + __I DSU_PID0_Type PID0; /**< \brief Offset: 0x1FE0 (R/ 32) Peripheral Identification 0 */ + __I DSU_PID1_Type PID1; /**< \brief Offset: 0x1FE4 (R/ 32) Peripheral Identification 1 */ + __I DSU_PID2_Type PID2; /**< \brief Offset: 0x1FE8 (R/ 32) Peripheral Identification 2 */ + __I DSU_PID3_Type PID3; /**< \brief Offset: 0x1FEC (R/ 32) Peripheral Identification 3 */ + __I DSU_CID0_Type CID0; /**< \brief Offset: 0x1FF0 (R/ 32) Component Identification 0 */ + __I DSU_CID1_Type CID1; /**< \brief Offset: 0x1FF4 (R/ 32) Component Identification 1 */ + __I DSU_CID2_Type CID2; /**< \brief Offset: 0x1FF8 (R/ 32) Component Identification 2 */ + __I DSU_CID3_Type CID3; /**< \brief Offset: 0x1FFC (R/ 32) Component Identification 3 */ +} Dsu; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_DSU_COMPONENT_ */ diff --git a/loader/samd20/component/eic.h b/loader/samd20/component/eic.h new file mode 100644 index 0000000..68b65bc --- /dev/null +++ b/loader/samd20/component/eic.h @@ -0,0 +1,681 @@ +/** + * \file + * + * \brief Component description for EIC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_EIC_COMPONENT_ +#define _SAMD20_EIC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR EIC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_EIC External Interrupt Controller */ +/*@{*/ + +#define EIC_U2217 +#define REV_EIC 0x101 + +/* -------- EIC_CTRL : (EIC Offset: 0x00) (R/W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} EIC_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_CTRL_OFFSET 0x00 /**< \brief (EIC_CTRL offset) Control */ +#define EIC_CTRL_RESETVALUE 0x00 /**< \brief (EIC_CTRL reset_value) Control */ + +#define EIC_CTRL_SWRST_Pos 0 /**< \brief (EIC_CTRL) Software Reset */ +#define EIC_CTRL_SWRST (0x1u << EIC_CTRL_SWRST_Pos) +#define EIC_CTRL_ENABLE_Pos 1 /**< \brief (EIC_CTRL) Enable */ +#define EIC_CTRL_ENABLE (0x1u << EIC_CTRL_ENABLE_Pos) +#define EIC_CTRL_MASK 0x03u /**< \brief (EIC_CTRL) MASK Register */ + +/* -------- EIC_STATUS : (EIC Offset: 0x01) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} EIC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_STATUS_OFFSET 0x01 /**< \brief (EIC_STATUS offset) Status */ +#define EIC_STATUS_RESETVALUE 0x00 /**< \brief (EIC_STATUS reset_value) Status */ + +#define EIC_STATUS_SYNCBUSY_Pos 7 /**< \brief (EIC_STATUS) Synchronization Busy */ +#define EIC_STATUS_SYNCBUSY (0x1u << EIC_STATUS_SYNCBUSY_Pos) +#define EIC_STATUS_MASK 0x80u /**< \brief (EIC_STATUS) MASK Register */ + +/* -------- EIC_NMICTRL : (EIC Offset: 0x02) (R/W 8) Non-Maskable Interrupt Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t NMISENSE:3; /*!< bit: 0.. 2 Non-Maskable Interrupt Sense */ + uint8_t NMIFILTEN:1; /*!< bit: 3 Non-Maskable Interrupt Filter Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} EIC_NMICTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_NMICTRL_OFFSET 0x02 /**< \brief (EIC_NMICTRL offset) Non-Maskable Interrupt Control */ +#define EIC_NMICTRL_RESETVALUE 0x00 /**< \brief (EIC_NMICTRL reset_value) Non-Maskable Interrupt Control */ + +#define EIC_NMICTRL_NMISENSE_Pos 0 /**< \brief (EIC_NMICTRL) Non-Maskable Interrupt Sense */ +#define EIC_NMICTRL_NMISENSE_Msk (0x7u << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE(value) ((EIC_NMICTRL_NMISENSE_Msk & ((value) << EIC_NMICTRL_NMISENSE_Pos))) +#define EIC_NMICTRL_NMISENSE_NONE_Val 0x0u /**< \brief (EIC_NMICTRL) No detection */ +#define EIC_NMICTRL_NMISENSE_RISE_Val 0x1u /**< \brief (EIC_NMICTRL) Rising-edge detection */ +#define EIC_NMICTRL_NMISENSE_FALL_Val 0x2u /**< \brief (EIC_NMICTRL) Falling-edge detection */ +#define EIC_NMICTRL_NMISENSE_BOTH_Val 0x3u /**< \brief (EIC_NMICTRL) Both-edges detection */ +#define EIC_NMICTRL_NMISENSE_HIGH_Val 0x4u /**< \brief (EIC_NMICTRL) High-level detection */ +#define EIC_NMICTRL_NMISENSE_LOW_Val 0x5u /**< \brief (EIC_NMICTRL) Low-level detection */ +#define EIC_NMICTRL_NMISENSE_NONE (EIC_NMICTRL_NMISENSE_NONE_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE_RISE (EIC_NMICTRL_NMISENSE_RISE_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE_FALL (EIC_NMICTRL_NMISENSE_FALL_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE_BOTH (EIC_NMICTRL_NMISENSE_BOTH_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE_HIGH (EIC_NMICTRL_NMISENSE_HIGH_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMISENSE_LOW (EIC_NMICTRL_NMISENSE_LOW_Val << EIC_NMICTRL_NMISENSE_Pos) +#define EIC_NMICTRL_NMIFILTEN_Pos 3 /**< \brief (EIC_NMICTRL) Non-Maskable Interrupt Filter Enable */ +#define EIC_NMICTRL_NMIFILTEN (0x1u << EIC_NMICTRL_NMIFILTEN_Pos) +#define EIC_NMICTRL_MASK 0x0Fu /**< \brief (EIC_NMICTRL) MASK Register */ + +/* -------- EIC_NMIFLAG : (EIC Offset: 0x03) (R/W 8) Non-Maskable Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t NMI:1; /*!< bit: 0 Non-Maskable Interrupt */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} EIC_NMIFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_NMIFLAG_OFFSET 0x03 /**< \brief (EIC_NMIFLAG offset) Non-Maskable Interrupt Flag Status and Clear */ +#define EIC_NMIFLAG_RESETVALUE 0x00 /**< \brief (EIC_NMIFLAG reset_value) Non-Maskable Interrupt Flag Status and Clear */ + +#define EIC_NMIFLAG_NMI_Pos 0 /**< \brief (EIC_NMIFLAG) Non-Maskable Interrupt */ +#define EIC_NMIFLAG_NMI (0x1u << EIC_NMIFLAG_NMI_Pos) +#define EIC_NMIFLAG_MASK 0x01u /**< \brief (EIC_NMIFLAG) MASK Register */ + +/* -------- EIC_EVCTRL : (EIC Offset: 0x04) (R/W 32) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EXTINTEO0:1; /*!< bit: 0 External Interrupt 0 Event Output Enable */ + uint32_t EXTINTEO1:1; /*!< bit: 1 External Interrupt 1 Event Output Enable */ + uint32_t EXTINTEO2:1; /*!< bit: 2 External Interrupt 2 Event Output Enable */ + uint32_t EXTINTEO3:1; /*!< bit: 3 External Interrupt 3 Event Output Enable */ + uint32_t EXTINTEO4:1; /*!< bit: 4 External Interrupt 4 Event Output Enable */ + uint32_t EXTINTEO5:1; /*!< bit: 5 External Interrupt 5 Event Output Enable */ + uint32_t EXTINTEO6:1; /*!< bit: 6 External Interrupt 6 Event Output Enable */ + uint32_t EXTINTEO7:1; /*!< bit: 7 External Interrupt 7 Event Output Enable */ + uint32_t EXTINTEO8:1; /*!< bit: 8 External Interrupt 8 Event Output Enable */ + uint32_t EXTINTEO9:1; /*!< bit: 9 External Interrupt 9 Event Output Enable */ + uint32_t EXTINTEO10:1; /*!< bit: 10 External Interrupt 10 Event Output Enable */ + uint32_t EXTINTEO11:1; /*!< bit: 11 External Interrupt 11 Event Output Enable */ + uint32_t EXTINTEO12:1; /*!< bit: 12 External Interrupt 12 Event Output Enable */ + uint32_t EXTINTEO13:1; /*!< bit: 13 External Interrupt 13 Event Output Enable */ + uint32_t EXTINTEO14:1; /*!< bit: 14 External Interrupt 14 Event Output Enable */ + uint32_t EXTINTEO15:1; /*!< bit: 15 External Interrupt 15 Event Output Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t EXTINTEO:16; /*!< bit: 0..15 External Interrupt x Event Output Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_EVCTRL_OFFSET 0x04 /**< \brief (EIC_EVCTRL offset) Event Control */ +#define EIC_EVCTRL_RESETVALUE 0x00000000 /**< \brief (EIC_EVCTRL reset_value) Event Control */ + +#define EIC_EVCTRL_EXTINTEO0_Pos 0 /**< \brief (EIC_EVCTRL) External Interrupt 0 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO0 (1 << EIC_EVCTRL_EXTINTEO0_Pos) +#define EIC_EVCTRL_EXTINTEO1_Pos 1 /**< \brief (EIC_EVCTRL) External Interrupt 1 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO1 (1 << EIC_EVCTRL_EXTINTEO1_Pos) +#define EIC_EVCTRL_EXTINTEO2_Pos 2 /**< \brief (EIC_EVCTRL) External Interrupt 2 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO2 (1 << EIC_EVCTRL_EXTINTEO2_Pos) +#define EIC_EVCTRL_EXTINTEO3_Pos 3 /**< \brief (EIC_EVCTRL) External Interrupt 3 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO3 (1 << EIC_EVCTRL_EXTINTEO3_Pos) +#define EIC_EVCTRL_EXTINTEO4_Pos 4 /**< \brief (EIC_EVCTRL) External Interrupt 4 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO4 (1 << EIC_EVCTRL_EXTINTEO4_Pos) +#define EIC_EVCTRL_EXTINTEO5_Pos 5 /**< \brief (EIC_EVCTRL) External Interrupt 5 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO5 (1 << EIC_EVCTRL_EXTINTEO5_Pos) +#define EIC_EVCTRL_EXTINTEO6_Pos 6 /**< \brief (EIC_EVCTRL) External Interrupt 6 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO6 (1 << EIC_EVCTRL_EXTINTEO6_Pos) +#define EIC_EVCTRL_EXTINTEO7_Pos 7 /**< \brief (EIC_EVCTRL) External Interrupt 7 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO7 (1 << EIC_EVCTRL_EXTINTEO7_Pos) +#define EIC_EVCTRL_EXTINTEO8_Pos 8 /**< \brief (EIC_EVCTRL) External Interrupt 8 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO8 (1 << EIC_EVCTRL_EXTINTEO8_Pos) +#define EIC_EVCTRL_EXTINTEO9_Pos 9 /**< \brief (EIC_EVCTRL) External Interrupt 9 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO9 (1 << EIC_EVCTRL_EXTINTEO9_Pos) +#define EIC_EVCTRL_EXTINTEO10_Pos 10 /**< \brief (EIC_EVCTRL) External Interrupt 10 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO10 (1 << EIC_EVCTRL_EXTINTEO10_Pos) +#define EIC_EVCTRL_EXTINTEO11_Pos 11 /**< \brief (EIC_EVCTRL) External Interrupt 11 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO11 (1 << EIC_EVCTRL_EXTINTEO11_Pos) +#define EIC_EVCTRL_EXTINTEO12_Pos 12 /**< \brief (EIC_EVCTRL) External Interrupt 12 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO12 (1 << EIC_EVCTRL_EXTINTEO12_Pos) +#define EIC_EVCTRL_EXTINTEO13_Pos 13 /**< \brief (EIC_EVCTRL) External Interrupt 13 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO13 (1 << EIC_EVCTRL_EXTINTEO13_Pos) +#define EIC_EVCTRL_EXTINTEO14_Pos 14 /**< \brief (EIC_EVCTRL) External Interrupt 14 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO14 (1 << EIC_EVCTRL_EXTINTEO14_Pos) +#define EIC_EVCTRL_EXTINTEO15_Pos 15 /**< \brief (EIC_EVCTRL) External Interrupt 15 Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO15 (1 << EIC_EVCTRL_EXTINTEO15_Pos) +#define EIC_EVCTRL_EXTINTEO_Pos 0 /**< \brief (EIC_EVCTRL) External Interrupt x Event Output Enable */ +#define EIC_EVCTRL_EXTINTEO_Msk (0xFFFFu << EIC_EVCTRL_EXTINTEO_Pos) +#define EIC_EVCTRL_EXTINTEO(value) ((EIC_EVCTRL_EXTINTEO_Msk & ((value) << EIC_EVCTRL_EXTINTEO_Pos))) +#define EIC_EVCTRL_MASK 0x0000FFFFu /**< \brief (EIC_EVCTRL) MASK Register */ + +/* -------- EIC_INTENCLR : (EIC Offset: 0x08) (R/W 32) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EXTINT0:1; /*!< bit: 0 External Interrupt 0 Enable */ + uint32_t EXTINT1:1; /*!< bit: 1 External Interrupt 1 Enable */ + uint32_t EXTINT2:1; /*!< bit: 2 External Interrupt 2 Enable */ + uint32_t EXTINT3:1; /*!< bit: 3 External Interrupt 3 Enable */ + uint32_t EXTINT4:1; /*!< bit: 4 External Interrupt 4 Enable */ + uint32_t EXTINT5:1; /*!< bit: 5 External Interrupt 5 Enable */ + uint32_t EXTINT6:1; /*!< bit: 6 External Interrupt 6 Enable */ + uint32_t EXTINT7:1; /*!< bit: 7 External Interrupt 7 Enable */ + uint32_t EXTINT8:1; /*!< bit: 8 External Interrupt 8 Enable */ + uint32_t EXTINT9:1; /*!< bit: 9 External Interrupt 9 Enable */ + uint32_t EXTINT10:1; /*!< bit: 10 External Interrupt 10 Enable */ + uint32_t EXTINT11:1; /*!< bit: 11 External Interrupt 11 Enable */ + uint32_t EXTINT12:1; /*!< bit: 12 External Interrupt 12 Enable */ + uint32_t EXTINT13:1; /*!< bit: 13 External Interrupt 13 Enable */ + uint32_t EXTINT14:1; /*!< bit: 14 External Interrupt 14 Enable */ + uint32_t EXTINT15:1; /*!< bit: 15 External Interrupt 15 Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t EXTINT:16; /*!< bit: 0..15 External Interrupt x Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_INTENCLR_OFFSET 0x08 /**< \brief (EIC_INTENCLR offset) Interrupt Enable Clear */ +#define EIC_INTENCLR_RESETVALUE 0x00000000 /**< \brief (EIC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define EIC_INTENCLR_EXTINT0_Pos 0 /**< \brief (EIC_INTENCLR) External Interrupt 0 Enable */ +#define EIC_INTENCLR_EXTINT0 (1 << EIC_INTENCLR_EXTINT0_Pos) +#define EIC_INTENCLR_EXTINT1_Pos 1 /**< \brief (EIC_INTENCLR) External Interrupt 1 Enable */ +#define EIC_INTENCLR_EXTINT1 (1 << EIC_INTENCLR_EXTINT1_Pos) +#define EIC_INTENCLR_EXTINT2_Pos 2 /**< \brief (EIC_INTENCLR) External Interrupt 2 Enable */ +#define EIC_INTENCLR_EXTINT2 (1 << EIC_INTENCLR_EXTINT2_Pos) +#define EIC_INTENCLR_EXTINT3_Pos 3 /**< \brief (EIC_INTENCLR) External Interrupt 3 Enable */ +#define EIC_INTENCLR_EXTINT3 (1 << EIC_INTENCLR_EXTINT3_Pos) +#define EIC_INTENCLR_EXTINT4_Pos 4 /**< \brief (EIC_INTENCLR) External Interrupt 4 Enable */ +#define EIC_INTENCLR_EXTINT4 (1 << EIC_INTENCLR_EXTINT4_Pos) +#define EIC_INTENCLR_EXTINT5_Pos 5 /**< \brief (EIC_INTENCLR) External Interrupt 5 Enable */ +#define EIC_INTENCLR_EXTINT5 (1 << EIC_INTENCLR_EXTINT5_Pos) +#define EIC_INTENCLR_EXTINT6_Pos 6 /**< \brief (EIC_INTENCLR) External Interrupt 6 Enable */ +#define EIC_INTENCLR_EXTINT6 (1 << EIC_INTENCLR_EXTINT6_Pos) +#define EIC_INTENCLR_EXTINT7_Pos 7 /**< \brief (EIC_INTENCLR) External Interrupt 7 Enable */ +#define EIC_INTENCLR_EXTINT7 (1 << EIC_INTENCLR_EXTINT7_Pos) +#define EIC_INTENCLR_EXTINT8_Pos 8 /**< \brief (EIC_INTENCLR) External Interrupt 8 Enable */ +#define EIC_INTENCLR_EXTINT8 (1 << EIC_INTENCLR_EXTINT8_Pos) +#define EIC_INTENCLR_EXTINT9_Pos 9 /**< \brief (EIC_INTENCLR) External Interrupt 9 Enable */ +#define EIC_INTENCLR_EXTINT9 (1 << EIC_INTENCLR_EXTINT9_Pos) +#define EIC_INTENCLR_EXTINT10_Pos 10 /**< \brief (EIC_INTENCLR) External Interrupt 10 Enable */ +#define EIC_INTENCLR_EXTINT10 (1 << EIC_INTENCLR_EXTINT10_Pos) +#define EIC_INTENCLR_EXTINT11_Pos 11 /**< \brief (EIC_INTENCLR) External Interrupt 11 Enable */ +#define EIC_INTENCLR_EXTINT11 (1 << EIC_INTENCLR_EXTINT11_Pos) +#define EIC_INTENCLR_EXTINT12_Pos 12 /**< \brief (EIC_INTENCLR) External Interrupt 12 Enable */ +#define EIC_INTENCLR_EXTINT12 (1 << EIC_INTENCLR_EXTINT12_Pos) +#define EIC_INTENCLR_EXTINT13_Pos 13 /**< \brief (EIC_INTENCLR) External Interrupt 13 Enable */ +#define EIC_INTENCLR_EXTINT13 (1 << EIC_INTENCLR_EXTINT13_Pos) +#define EIC_INTENCLR_EXTINT14_Pos 14 /**< \brief (EIC_INTENCLR) External Interrupt 14 Enable */ +#define EIC_INTENCLR_EXTINT14 (1 << EIC_INTENCLR_EXTINT14_Pos) +#define EIC_INTENCLR_EXTINT15_Pos 15 /**< \brief (EIC_INTENCLR) External Interrupt 15 Enable */ +#define EIC_INTENCLR_EXTINT15 (1 << EIC_INTENCLR_EXTINT15_Pos) +#define EIC_INTENCLR_EXTINT_Pos 0 /**< \brief (EIC_INTENCLR) External Interrupt x Enable */ +#define EIC_INTENCLR_EXTINT_Msk (0xFFFFu << EIC_INTENCLR_EXTINT_Pos) +#define EIC_INTENCLR_EXTINT(value) ((EIC_INTENCLR_EXTINT_Msk & ((value) << EIC_INTENCLR_EXTINT_Pos))) +#define EIC_INTENCLR_MASK 0x0000FFFFu /**< \brief (EIC_INTENCLR) MASK Register */ + +/* -------- EIC_INTENSET : (EIC Offset: 0x0C) (R/W 32) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EXTINT0:1; /*!< bit: 0 External Interrupt 0 Enable */ + uint32_t EXTINT1:1; /*!< bit: 1 External Interrupt 1 Enable */ + uint32_t EXTINT2:1; /*!< bit: 2 External Interrupt 2 Enable */ + uint32_t EXTINT3:1; /*!< bit: 3 External Interrupt 3 Enable */ + uint32_t EXTINT4:1; /*!< bit: 4 External Interrupt 4 Enable */ + uint32_t EXTINT5:1; /*!< bit: 5 External Interrupt 5 Enable */ + uint32_t EXTINT6:1; /*!< bit: 6 External Interrupt 6 Enable */ + uint32_t EXTINT7:1; /*!< bit: 7 External Interrupt 7 Enable */ + uint32_t EXTINT8:1; /*!< bit: 8 External Interrupt 8 Enable */ + uint32_t EXTINT9:1; /*!< bit: 9 External Interrupt 9 Enable */ + uint32_t EXTINT10:1; /*!< bit: 10 External Interrupt 10 Enable */ + uint32_t EXTINT11:1; /*!< bit: 11 External Interrupt 11 Enable */ + uint32_t EXTINT12:1; /*!< bit: 12 External Interrupt 12 Enable */ + uint32_t EXTINT13:1; /*!< bit: 13 External Interrupt 13 Enable */ + uint32_t EXTINT14:1; /*!< bit: 14 External Interrupt 14 Enable */ + uint32_t EXTINT15:1; /*!< bit: 15 External Interrupt 15 Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t EXTINT:16; /*!< bit: 0..15 External Interrupt x Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_INTENSET_OFFSET 0x0C /**< \brief (EIC_INTENSET offset) Interrupt Enable Set */ +#define EIC_INTENSET_RESETVALUE 0x00000000 /**< \brief (EIC_INTENSET reset_value) Interrupt Enable Set */ + +#define EIC_INTENSET_EXTINT0_Pos 0 /**< \brief (EIC_INTENSET) External Interrupt 0 Enable */ +#define EIC_INTENSET_EXTINT0 (1 << EIC_INTENSET_EXTINT0_Pos) +#define EIC_INTENSET_EXTINT1_Pos 1 /**< \brief (EIC_INTENSET) External Interrupt 1 Enable */ +#define EIC_INTENSET_EXTINT1 (1 << EIC_INTENSET_EXTINT1_Pos) +#define EIC_INTENSET_EXTINT2_Pos 2 /**< \brief (EIC_INTENSET) External Interrupt 2 Enable */ +#define EIC_INTENSET_EXTINT2 (1 << EIC_INTENSET_EXTINT2_Pos) +#define EIC_INTENSET_EXTINT3_Pos 3 /**< \brief (EIC_INTENSET) External Interrupt 3 Enable */ +#define EIC_INTENSET_EXTINT3 (1 << EIC_INTENSET_EXTINT3_Pos) +#define EIC_INTENSET_EXTINT4_Pos 4 /**< \brief (EIC_INTENSET) External Interrupt 4 Enable */ +#define EIC_INTENSET_EXTINT4 (1 << EIC_INTENSET_EXTINT4_Pos) +#define EIC_INTENSET_EXTINT5_Pos 5 /**< \brief (EIC_INTENSET) External Interrupt 5 Enable */ +#define EIC_INTENSET_EXTINT5 (1 << EIC_INTENSET_EXTINT5_Pos) +#define EIC_INTENSET_EXTINT6_Pos 6 /**< \brief (EIC_INTENSET) External Interrupt 6 Enable */ +#define EIC_INTENSET_EXTINT6 (1 << EIC_INTENSET_EXTINT6_Pos) +#define EIC_INTENSET_EXTINT7_Pos 7 /**< \brief (EIC_INTENSET) External Interrupt 7 Enable */ +#define EIC_INTENSET_EXTINT7 (1 << EIC_INTENSET_EXTINT7_Pos) +#define EIC_INTENSET_EXTINT8_Pos 8 /**< \brief (EIC_INTENSET) External Interrupt 8 Enable */ +#define EIC_INTENSET_EXTINT8 (1 << EIC_INTENSET_EXTINT8_Pos) +#define EIC_INTENSET_EXTINT9_Pos 9 /**< \brief (EIC_INTENSET) External Interrupt 9 Enable */ +#define EIC_INTENSET_EXTINT9 (1 << EIC_INTENSET_EXTINT9_Pos) +#define EIC_INTENSET_EXTINT10_Pos 10 /**< \brief (EIC_INTENSET) External Interrupt 10 Enable */ +#define EIC_INTENSET_EXTINT10 (1 << EIC_INTENSET_EXTINT10_Pos) +#define EIC_INTENSET_EXTINT11_Pos 11 /**< \brief (EIC_INTENSET) External Interrupt 11 Enable */ +#define EIC_INTENSET_EXTINT11 (1 << EIC_INTENSET_EXTINT11_Pos) +#define EIC_INTENSET_EXTINT12_Pos 12 /**< \brief (EIC_INTENSET) External Interrupt 12 Enable */ +#define EIC_INTENSET_EXTINT12 (1 << EIC_INTENSET_EXTINT12_Pos) +#define EIC_INTENSET_EXTINT13_Pos 13 /**< \brief (EIC_INTENSET) External Interrupt 13 Enable */ +#define EIC_INTENSET_EXTINT13 (1 << EIC_INTENSET_EXTINT13_Pos) +#define EIC_INTENSET_EXTINT14_Pos 14 /**< \brief (EIC_INTENSET) External Interrupt 14 Enable */ +#define EIC_INTENSET_EXTINT14 (1 << EIC_INTENSET_EXTINT14_Pos) +#define EIC_INTENSET_EXTINT15_Pos 15 /**< \brief (EIC_INTENSET) External Interrupt 15 Enable */ +#define EIC_INTENSET_EXTINT15 (1 << EIC_INTENSET_EXTINT15_Pos) +#define EIC_INTENSET_EXTINT_Pos 0 /**< \brief (EIC_INTENSET) External Interrupt x Enable */ +#define EIC_INTENSET_EXTINT_Msk (0xFFFFu << EIC_INTENSET_EXTINT_Pos) +#define EIC_INTENSET_EXTINT(value) ((EIC_INTENSET_EXTINT_Msk & ((value) << EIC_INTENSET_EXTINT_Pos))) +#define EIC_INTENSET_MASK 0x0000FFFFu /**< \brief (EIC_INTENSET) MASK Register */ + +/* -------- EIC_INTFLAG : (EIC Offset: 0x10) (R/W 32) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EXTINT0:1; /*!< bit: 0 External Interrupt 0 */ + uint32_t EXTINT1:1; /*!< bit: 1 External Interrupt 1 */ + uint32_t EXTINT2:1; /*!< bit: 2 External Interrupt 2 */ + uint32_t EXTINT3:1; /*!< bit: 3 External Interrupt 3 */ + uint32_t EXTINT4:1; /*!< bit: 4 External Interrupt 4 */ + uint32_t EXTINT5:1; /*!< bit: 5 External Interrupt 5 */ + uint32_t EXTINT6:1; /*!< bit: 6 External Interrupt 6 */ + uint32_t EXTINT7:1; /*!< bit: 7 External Interrupt 7 */ + uint32_t EXTINT8:1; /*!< bit: 8 External Interrupt 8 */ + uint32_t EXTINT9:1; /*!< bit: 9 External Interrupt 9 */ + uint32_t EXTINT10:1; /*!< bit: 10 External Interrupt 10 */ + uint32_t EXTINT11:1; /*!< bit: 11 External Interrupt 11 */ + uint32_t EXTINT12:1; /*!< bit: 12 External Interrupt 12 */ + uint32_t EXTINT13:1; /*!< bit: 13 External Interrupt 13 */ + uint32_t EXTINT14:1; /*!< bit: 14 External Interrupt 14 */ + uint32_t EXTINT15:1; /*!< bit: 15 External Interrupt 15 */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t EXTINT:16; /*!< bit: 0..15 External Interrupt x */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_INTFLAG_OFFSET 0x10 /**< \brief (EIC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define EIC_INTFLAG_RESETVALUE 0x00000000 /**< \brief (EIC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define EIC_INTFLAG_EXTINT0_Pos 0 /**< \brief (EIC_INTFLAG) External Interrupt 0 */ +#define EIC_INTFLAG_EXTINT0 (1 << EIC_INTFLAG_EXTINT0_Pos) +#define EIC_INTFLAG_EXTINT1_Pos 1 /**< \brief (EIC_INTFLAG) External Interrupt 1 */ +#define EIC_INTFLAG_EXTINT1 (1 << EIC_INTFLAG_EXTINT1_Pos) +#define EIC_INTFLAG_EXTINT2_Pos 2 /**< \brief (EIC_INTFLAG) External Interrupt 2 */ +#define EIC_INTFLAG_EXTINT2 (1 << EIC_INTFLAG_EXTINT2_Pos) +#define EIC_INTFLAG_EXTINT3_Pos 3 /**< \brief (EIC_INTFLAG) External Interrupt 3 */ +#define EIC_INTFLAG_EXTINT3 (1 << EIC_INTFLAG_EXTINT3_Pos) +#define EIC_INTFLAG_EXTINT4_Pos 4 /**< \brief (EIC_INTFLAG) External Interrupt 4 */ +#define EIC_INTFLAG_EXTINT4 (1 << EIC_INTFLAG_EXTINT4_Pos) +#define EIC_INTFLAG_EXTINT5_Pos 5 /**< \brief (EIC_INTFLAG) External Interrupt 5 */ +#define EIC_INTFLAG_EXTINT5 (1 << EIC_INTFLAG_EXTINT5_Pos) +#define EIC_INTFLAG_EXTINT6_Pos 6 /**< \brief (EIC_INTFLAG) External Interrupt 6 */ +#define EIC_INTFLAG_EXTINT6 (1 << EIC_INTFLAG_EXTINT6_Pos) +#define EIC_INTFLAG_EXTINT7_Pos 7 /**< \brief (EIC_INTFLAG) External Interrupt 7 */ +#define EIC_INTFLAG_EXTINT7 (1 << EIC_INTFLAG_EXTINT7_Pos) +#define EIC_INTFLAG_EXTINT8_Pos 8 /**< \brief (EIC_INTFLAG) External Interrupt 8 */ +#define EIC_INTFLAG_EXTINT8 (1 << EIC_INTFLAG_EXTINT8_Pos) +#define EIC_INTFLAG_EXTINT9_Pos 9 /**< \brief (EIC_INTFLAG) External Interrupt 9 */ +#define EIC_INTFLAG_EXTINT9 (1 << EIC_INTFLAG_EXTINT9_Pos) +#define EIC_INTFLAG_EXTINT10_Pos 10 /**< \brief (EIC_INTFLAG) External Interrupt 10 */ +#define EIC_INTFLAG_EXTINT10 (1 << EIC_INTFLAG_EXTINT10_Pos) +#define EIC_INTFLAG_EXTINT11_Pos 11 /**< \brief (EIC_INTFLAG) External Interrupt 11 */ +#define EIC_INTFLAG_EXTINT11 (1 << EIC_INTFLAG_EXTINT11_Pos) +#define EIC_INTFLAG_EXTINT12_Pos 12 /**< \brief (EIC_INTFLAG) External Interrupt 12 */ +#define EIC_INTFLAG_EXTINT12 (1 << EIC_INTFLAG_EXTINT12_Pos) +#define EIC_INTFLAG_EXTINT13_Pos 13 /**< \brief (EIC_INTFLAG) External Interrupt 13 */ +#define EIC_INTFLAG_EXTINT13 (1 << EIC_INTFLAG_EXTINT13_Pos) +#define EIC_INTFLAG_EXTINT14_Pos 14 /**< \brief (EIC_INTFLAG) External Interrupt 14 */ +#define EIC_INTFLAG_EXTINT14 (1 << EIC_INTFLAG_EXTINT14_Pos) +#define EIC_INTFLAG_EXTINT15_Pos 15 /**< \brief (EIC_INTFLAG) External Interrupt 15 */ +#define EIC_INTFLAG_EXTINT15 (1 << EIC_INTFLAG_EXTINT15_Pos) +#define EIC_INTFLAG_EXTINT_Pos 0 /**< \brief (EIC_INTFLAG) External Interrupt x */ +#define EIC_INTFLAG_EXTINT_Msk (0xFFFFu << EIC_INTFLAG_EXTINT_Pos) +#define EIC_INTFLAG_EXTINT(value) ((EIC_INTFLAG_EXTINT_Msk & ((value) << EIC_INTFLAG_EXTINT_Pos))) +#define EIC_INTFLAG_MASK 0x0000FFFFu /**< \brief (EIC_INTFLAG) MASK Register */ + +/* -------- EIC_WAKEUP : (EIC Offset: 0x14) (R/W 32) Wake-Up Enable -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t WAKEUPEN0:1; /*!< bit: 0 External Interrupt 0 Wake-up Enable */ + uint32_t WAKEUPEN1:1; /*!< bit: 1 External Interrupt 1 Wake-up Enable */ + uint32_t WAKEUPEN2:1; /*!< bit: 2 External Interrupt 2 Wake-up Enable */ + uint32_t WAKEUPEN3:1; /*!< bit: 3 External Interrupt 3 Wake-up Enable */ + uint32_t WAKEUPEN4:1; /*!< bit: 4 External Interrupt 4 Wake-up Enable */ + uint32_t WAKEUPEN5:1; /*!< bit: 5 External Interrupt 5 Wake-up Enable */ + uint32_t WAKEUPEN6:1; /*!< bit: 6 External Interrupt 6 Wake-up Enable */ + uint32_t WAKEUPEN7:1; /*!< bit: 7 External Interrupt 7 Wake-up Enable */ + uint32_t WAKEUPEN8:1; /*!< bit: 8 External Interrupt 8 Wake-up Enable */ + uint32_t WAKEUPEN9:1; /*!< bit: 9 External Interrupt 9 Wake-up Enable */ + uint32_t WAKEUPEN10:1; /*!< bit: 10 External Interrupt 10 Wake-up Enable */ + uint32_t WAKEUPEN11:1; /*!< bit: 11 External Interrupt 11 Wake-up Enable */ + uint32_t WAKEUPEN12:1; /*!< bit: 12 External Interrupt 12 Wake-up Enable */ + uint32_t WAKEUPEN13:1; /*!< bit: 13 External Interrupt 13 Wake-up Enable */ + uint32_t WAKEUPEN14:1; /*!< bit: 14 External Interrupt 14 Wake-up Enable */ + uint32_t WAKEUPEN15:1; /*!< bit: 15 External Interrupt 15 Wake-up Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t WAKEUPEN:16; /*!< bit: 0..15 External Interrupt x Wake-up Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_WAKEUP_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_WAKEUP_OFFSET 0x14 /**< \brief (EIC_WAKEUP offset) Wake-Up Enable */ +#define EIC_WAKEUP_RESETVALUE 0x00000000 /**< \brief (EIC_WAKEUP reset_value) Wake-Up Enable */ + +#define EIC_WAKEUP_WAKEUPEN0_Pos 0 /**< \brief (EIC_WAKEUP) External Interrupt 0 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN0 (1 << EIC_WAKEUP_WAKEUPEN0_Pos) +#define EIC_WAKEUP_WAKEUPEN1_Pos 1 /**< \brief (EIC_WAKEUP) External Interrupt 1 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN1 (1 << EIC_WAKEUP_WAKEUPEN1_Pos) +#define EIC_WAKEUP_WAKEUPEN2_Pos 2 /**< \brief (EIC_WAKEUP) External Interrupt 2 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN2 (1 << EIC_WAKEUP_WAKEUPEN2_Pos) +#define EIC_WAKEUP_WAKEUPEN3_Pos 3 /**< \brief (EIC_WAKEUP) External Interrupt 3 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN3 (1 << EIC_WAKEUP_WAKEUPEN3_Pos) +#define EIC_WAKEUP_WAKEUPEN4_Pos 4 /**< \brief (EIC_WAKEUP) External Interrupt 4 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN4 (1 << EIC_WAKEUP_WAKEUPEN4_Pos) +#define EIC_WAKEUP_WAKEUPEN5_Pos 5 /**< \brief (EIC_WAKEUP) External Interrupt 5 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN5 (1 << EIC_WAKEUP_WAKEUPEN5_Pos) +#define EIC_WAKEUP_WAKEUPEN6_Pos 6 /**< \brief (EIC_WAKEUP) External Interrupt 6 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN6 (1 << EIC_WAKEUP_WAKEUPEN6_Pos) +#define EIC_WAKEUP_WAKEUPEN7_Pos 7 /**< \brief (EIC_WAKEUP) External Interrupt 7 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN7 (1 << EIC_WAKEUP_WAKEUPEN7_Pos) +#define EIC_WAKEUP_WAKEUPEN8_Pos 8 /**< \brief (EIC_WAKEUP) External Interrupt 8 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN8 (1 << EIC_WAKEUP_WAKEUPEN8_Pos) +#define EIC_WAKEUP_WAKEUPEN9_Pos 9 /**< \brief (EIC_WAKEUP) External Interrupt 9 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN9 (1 << EIC_WAKEUP_WAKEUPEN9_Pos) +#define EIC_WAKEUP_WAKEUPEN10_Pos 10 /**< \brief (EIC_WAKEUP) External Interrupt 10 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN10 (1 << EIC_WAKEUP_WAKEUPEN10_Pos) +#define EIC_WAKEUP_WAKEUPEN11_Pos 11 /**< \brief (EIC_WAKEUP) External Interrupt 11 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN11 (1 << EIC_WAKEUP_WAKEUPEN11_Pos) +#define EIC_WAKEUP_WAKEUPEN12_Pos 12 /**< \brief (EIC_WAKEUP) External Interrupt 12 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN12 (1 << EIC_WAKEUP_WAKEUPEN12_Pos) +#define EIC_WAKEUP_WAKEUPEN13_Pos 13 /**< \brief (EIC_WAKEUP) External Interrupt 13 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN13 (1 << EIC_WAKEUP_WAKEUPEN13_Pos) +#define EIC_WAKEUP_WAKEUPEN14_Pos 14 /**< \brief (EIC_WAKEUP) External Interrupt 14 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN14 (1 << EIC_WAKEUP_WAKEUPEN14_Pos) +#define EIC_WAKEUP_WAKEUPEN15_Pos 15 /**< \brief (EIC_WAKEUP) External Interrupt 15 Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN15 (1 << EIC_WAKEUP_WAKEUPEN15_Pos) +#define EIC_WAKEUP_WAKEUPEN_Pos 0 /**< \brief (EIC_WAKEUP) External Interrupt x Wake-up Enable */ +#define EIC_WAKEUP_WAKEUPEN_Msk (0xFFFFu << EIC_WAKEUP_WAKEUPEN_Pos) +#define EIC_WAKEUP_WAKEUPEN(value) ((EIC_WAKEUP_WAKEUPEN_Msk & ((value) << EIC_WAKEUP_WAKEUPEN_Pos))) +#define EIC_WAKEUP_MASK 0x0000FFFFu /**< \brief (EIC_WAKEUP) MASK Register */ + +/* -------- EIC_CONFIG : (EIC Offset: 0x18) (R/W 32) Configuration n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SENSE0:3; /*!< bit: 0.. 2 Input Sense 0 Configuration */ + uint32_t FILTEN0:1; /*!< bit: 3 Filter 0 Enable */ + uint32_t SENSE1:3; /*!< bit: 4.. 6 Input Sense 1 Configuration */ + uint32_t FILTEN1:1; /*!< bit: 7 Filter 1 Enable */ + uint32_t SENSE2:3; /*!< bit: 8..10 Input Sense 2 Configuration */ + uint32_t FILTEN2:1; /*!< bit: 11 Filter 2 Enable */ + uint32_t SENSE3:3; /*!< bit: 12..14 Input Sense 3 Configuration */ + uint32_t FILTEN3:1; /*!< bit: 15 Filter 3 Enable */ + uint32_t SENSE4:3; /*!< bit: 16..18 Input Sense 4 Configuration */ + uint32_t FILTEN4:1; /*!< bit: 19 Filter 4 Enable */ + uint32_t SENSE5:3; /*!< bit: 20..22 Input Sense 5 Configuration */ + uint32_t FILTEN5:1; /*!< bit: 23 Filter 5 Enable */ + uint32_t SENSE6:3; /*!< bit: 24..26 Input Sense 6 Configuration */ + uint32_t FILTEN6:1; /*!< bit: 27 Filter 6 Enable */ + uint32_t SENSE7:3; /*!< bit: 28..30 Input Sense 7 Configuration */ + uint32_t FILTEN7:1; /*!< bit: 31 Filter 7 Enable */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} EIC_CONFIG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EIC_CONFIG_OFFSET 0x18 /**< \brief (EIC_CONFIG offset) Configuration n */ +#define EIC_CONFIG_RESETVALUE 0x00000000 /**< \brief (EIC_CONFIG reset_value) Configuration n */ + +#define EIC_CONFIG_SENSE0_Pos 0 /**< \brief (EIC_CONFIG) Input Sense 0 Configuration */ +#define EIC_CONFIG_SENSE0_Msk (0x7u << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0(value) ((EIC_CONFIG_SENSE0_Msk & ((value) << EIC_CONFIG_SENSE0_Pos))) +#define EIC_CONFIG_SENSE0_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE0_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising-edge detection */ +#define EIC_CONFIG_SENSE0_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling-edge detection */ +#define EIC_CONFIG_SENSE0_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both-edges detection */ +#define EIC_CONFIG_SENSE0_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High-level detection */ +#define EIC_CONFIG_SENSE0_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low-level detection */ +#define EIC_CONFIG_SENSE0_NONE (EIC_CONFIG_SENSE0_NONE_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0_RISE (EIC_CONFIG_SENSE0_RISE_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0_FALL (EIC_CONFIG_SENSE0_FALL_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0_BOTH (EIC_CONFIG_SENSE0_BOTH_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0_HIGH (EIC_CONFIG_SENSE0_HIGH_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_SENSE0_LOW (EIC_CONFIG_SENSE0_LOW_Val << EIC_CONFIG_SENSE0_Pos) +#define EIC_CONFIG_FILTEN0_Pos 3 /**< \brief (EIC_CONFIG) Filter 0 Enable */ +#define EIC_CONFIG_FILTEN0 (0x1u << EIC_CONFIG_FILTEN0_Pos) +#define EIC_CONFIG_SENSE1_Pos 4 /**< \brief (EIC_CONFIG) Input Sense 1 Configuration */ +#define EIC_CONFIG_SENSE1_Msk (0x7u << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1(value) ((EIC_CONFIG_SENSE1_Msk & ((value) << EIC_CONFIG_SENSE1_Pos))) +#define EIC_CONFIG_SENSE1_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE1_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE1_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE1_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE1_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE1_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE1_NONE (EIC_CONFIG_SENSE1_NONE_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1_RISE (EIC_CONFIG_SENSE1_RISE_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1_FALL (EIC_CONFIG_SENSE1_FALL_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1_BOTH (EIC_CONFIG_SENSE1_BOTH_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1_HIGH (EIC_CONFIG_SENSE1_HIGH_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_SENSE1_LOW (EIC_CONFIG_SENSE1_LOW_Val << EIC_CONFIG_SENSE1_Pos) +#define EIC_CONFIG_FILTEN1_Pos 7 /**< \brief (EIC_CONFIG) Filter 1 Enable */ +#define EIC_CONFIG_FILTEN1 (0x1u << EIC_CONFIG_FILTEN1_Pos) +#define EIC_CONFIG_SENSE2_Pos 8 /**< \brief (EIC_CONFIG) Input Sense 2 Configuration */ +#define EIC_CONFIG_SENSE2_Msk (0x7u << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2(value) ((EIC_CONFIG_SENSE2_Msk & ((value) << EIC_CONFIG_SENSE2_Pos))) +#define EIC_CONFIG_SENSE2_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE2_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE2_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE2_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE2_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE2_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE2_NONE (EIC_CONFIG_SENSE2_NONE_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2_RISE (EIC_CONFIG_SENSE2_RISE_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2_FALL (EIC_CONFIG_SENSE2_FALL_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2_BOTH (EIC_CONFIG_SENSE2_BOTH_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2_HIGH (EIC_CONFIG_SENSE2_HIGH_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_SENSE2_LOW (EIC_CONFIG_SENSE2_LOW_Val << EIC_CONFIG_SENSE2_Pos) +#define EIC_CONFIG_FILTEN2_Pos 11 /**< \brief (EIC_CONFIG) Filter 2 Enable */ +#define EIC_CONFIG_FILTEN2 (0x1u << EIC_CONFIG_FILTEN2_Pos) +#define EIC_CONFIG_SENSE3_Pos 12 /**< \brief (EIC_CONFIG) Input Sense 3 Configuration */ +#define EIC_CONFIG_SENSE3_Msk (0x7u << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3(value) ((EIC_CONFIG_SENSE3_Msk & ((value) << EIC_CONFIG_SENSE3_Pos))) +#define EIC_CONFIG_SENSE3_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE3_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE3_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE3_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE3_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE3_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE3_NONE (EIC_CONFIG_SENSE3_NONE_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3_RISE (EIC_CONFIG_SENSE3_RISE_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3_FALL (EIC_CONFIG_SENSE3_FALL_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3_BOTH (EIC_CONFIG_SENSE3_BOTH_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3_HIGH (EIC_CONFIG_SENSE3_HIGH_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_SENSE3_LOW (EIC_CONFIG_SENSE3_LOW_Val << EIC_CONFIG_SENSE3_Pos) +#define EIC_CONFIG_FILTEN3_Pos 15 /**< \brief (EIC_CONFIG) Filter 3 Enable */ +#define EIC_CONFIG_FILTEN3 (0x1u << EIC_CONFIG_FILTEN3_Pos) +#define EIC_CONFIG_SENSE4_Pos 16 /**< \brief (EIC_CONFIG) Input Sense 4 Configuration */ +#define EIC_CONFIG_SENSE4_Msk (0x7u << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4(value) ((EIC_CONFIG_SENSE4_Msk & ((value) << EIC_CONFIG_SENSE4_Pos))) +#define EIC_CONFIG_SENSE4_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE4_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE4_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE4_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE4_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE4_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE4_NONE (EIC_CONFIG_SENSE4_NONE_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4_RISE (EIC_CONFIG_SENSE4_RISE_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4_FALL (EIC_CONFIG_SENSE4_FALL_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4_BOTH (EIC_CONFIG_SENSE4_BOTH_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4_HIGH (EIC_CONFIG_SENSE4_HIGH_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_SENSE4_LOW (EIC_CONFIG_SENSE4_LOW_Val << EIC_CONFIG_SENSE4_Pos) +#define EIC_CONFIG_FILTEN4_Pos 19 /**< \brief (EIC_CONFIG) Filter 4 Enable */ +#define EIC_CONFIG_FILTEN4 (0x1u << EIC_CONFIG_FILTEN4_Pos) +#define EIC_CONFIG_SENSE5_Pos 20 /**< \brief (EIC_CONFIG) Input Sense 5 Configuration */ +#define EIC_CONFIG_SENSE5_Msk (0x7u << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5(value) ((EIC_CONFIG_SENSE5_Msk & ((value) << EIC_CONFIG_SENSE5_Pos))) +#define EIC_CONFIG_SENSE5_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE5_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE5_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE5_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE5_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE5_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE5_NONE (EIC_CONFIG_SENSE5_NONE_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5_RISE (EIC_CONFIG_SENSE5_RISE_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5_FALL (EIC_CONFIG_SENSE5_FALL_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5_BOTH (EIC_CONFIG_SENSE5_BOTH_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5_HIGH (EIC_CONFIG_SENSE5_HIGH_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_SENSE5_LOW (EIC_CONFIG_SENSE5_LOW_Val << EIC_CONFIG_SENSE5_Pos) +#define EIC_CONFIG_FILTEN5_Pos 23 /**< \brief (EIC_CONFIG) Filter 5 Enable */ +#define EIC_CONFIG_FILTEN5 (0x1u << EIC_CONFIG_FILTEN5_Pos) +#define EIC_CONFIG_SENSE6_Pos 24 /**< \brief (EIC_CONFIG) Input Sense 6 Configuration */ +#define EIC_CONFIG_SENSE6_Msk (0x7u << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6(value) ((EIC_CONFIG_SENSE6_Msk & ((value) << EIC_CONFIG_SENSE6_Pos))) +#define EIC_CONFIG_SENSE6_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE6_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE6_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE6_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE6_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE6_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE6_NONE (EIC_CONFIG_SENSE6_NONE_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6_RISE (EIC_CONFIG_SENSE6_RISE_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6_FALL (EIC_CONFIG_SENSE6_FALL_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6_BOTH (EIC_CONFIG_SENSE6_BOTH_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6_HIGH (EIC_CONFIG_SENSE6_HIGH_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_SENSE6_LOW (EIC_CONFIG_SENSE6_LOW_Val << EIC_CONFIG_SENSE6_Pos) +#define EIC_CONFIG_FILTEN6_Pos 27 /**< \brief (EIC_CONFIG) Filter 6 Enable */ +#define EIC_CONFIG_FILTEN6 (0x1u << EIC_CONFIG_FILTEN6_Pos) +#define EIC_CONFIG_SENSE7_Pos 28 /**< \brief (EIC_CONFIG) Input Sense 7 Configuration */ +#define EIC_CONFIG_SENSE7_Msk (0x7u << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7(value) ((EIC_CONFIG_SENSE7_Msk & ((value) << EIC_CONFIG_SENSE7_Pos))) +#define EIC_CONFIG_SENSE7_NONE_Val 0x0u /**< \brief (EIC_CONFIG) No detection */ +#define EIC_CONFIG_SENSE7_RISE_Val 0x1u /**< \brief (EIC_CONFIG) Rising edge detection */ +#define EIC_CONFIG_SENSE7_FALL_Val 0x2u /**< \brief (EIC_CONFIG) Falling edge detection */ +#define EIC_CONFIG_SENSE7_BOTH_Val 0x3u /**< \brief (EIC_CONFIG) Both edges detection */ +#define EIC_CONFIG_SENSE7_HIGH_Val 0x4u /**< \brief (EIC_CONFIG) High level detection */ +#define EIC_CONFIG_SENSE7_LOW_Val 0x5u /**< \brief (EIC_CONFIG) Low level detection */ +#define EIC_CONFIG_SENSE7_NONE (EIC_CONFIG_SENSE7_NONE_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7_RISE (EIC_CONFIG_SENSE7_RISE_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7_FALL (EIC_CONFIG_SENSE7_FALL_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7_BOTH (EIC_CONFIG_SENSE7_BOTH_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7_HIGH (EIC_CONFIG_SENSE7_HIGH_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_SENSE7_LOW (EIC_CONFIG_SENSE7_LOW_Val << EIC_CONFIG_SENSE7_Pos) +#define EIC_CONFIG_FILTEN7_Pos 31 /**< \brief (EIC_CONFIG) Filter 7 Enable */ +#define EIC_CONFIG_FILTEN7 (0x1u << EIC_CONFIG_FILTEN7_Pos) +#define EIC_CONFIG_MASK 0xFFFFFFFFu /**< \brief (EIC_CONFIG) MASK Register */ + +/** \brief EIC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO EIC_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 8) Control */ + __I EIC_STATUS_Type STATUS; /**< \brief Offset: 0x01 (R/ 8) Status */ + __IO EIC_NMICTRL_Type NMICTRL; /**< \brief Offset: 0x02 (R/W 8) Non-Maskable Interrupt Control */ + __IO EIC_NMIFLAG_Type NMIFLAG; /**< \brief Offset: 0x03 (R/W 8) Non-Maskable Interrupt Flag Status and Clear */ + __IO EIC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x04 (R/W 32) Event Control */ + __IO EIC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x08 (R/W 32) Interrupt Enable Clear */ + __IO EIC_INTENSET_Type INTENSET; /**< \brief Offset: 0x0C (R/W 32) Interrupt Enable Set */ + __IO EIC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x10 (R/W 32) Interrupt Flag Status and Clear */ + __IO EIC_WAKEUP_Type WAKEUP; /**< \brief Offset: 0x14 (R/W 32) Wake-Up Enable */ + __IO EIC_CONFIG_Type CONFIG[2]; /**< \brief Offset: 0x18 (R/W 32) Configuration n */ +} Eic; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_EIC_COMPONENT_ */ diff --git a/loader/samd20/component/evsys.h b/loader/samd20/component/evsys.h new file mode 100644 index 0000000..87b26e5 --- /dev/null +++ b/loader/samd20/component/evsys.h @@ -0,0 +1,466 @@ +/** + * \file + * + * \brief Component description for EVSYS + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_EVSYS_COMPONENT_ +#define _SAMD20_EVSYS_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR EVSYS */ +/* ========================================================================== */ +/** \addtogroup SAMD20_EVSYS Event System Interface */ +/*@{*/ + +#define EVSYS_U2208 +#define REV_EVSYS 0x101 + +/* -------- EVSYS_CTRL : (EVSYS Offset: 0x00) ( /W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t :3; /*!< bit: 1.. 3 Reserved */ + uint8_t GCLKREQ:1; /*!< bit: 4 Generic Clock Requests */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} EVSYS_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_CTRL_OFFSET 0x00 /**< \brief (EVSYS_CTRL offset) Control */ +#define EVSYS_CTRL_RESETVALUE 0x00 /**< \brief (EVSYS_CTRL reset_value) Control */ + +#define EVSYS_CTRL_SWRST_Pos 0 /**< \brief (EVSYS_CTRL) Software Reset */ +#define EVSYS_CTRL_SWRST (0x1u << EVSYS_CTRL_SWRST_Pos) +#define EVSYS_CTRL_GCLKREQ_Pos 4 /**< \brief (EVSYS_CTRL) Generic Clock Requests */ +#define EVSYS_CTRL_GCLKREQ (0x1u << EVSYS_CTRL_GCLKREQ_Pos) +#define EVSYS_CTRL_MASK 0x11u /**< \brief (EVSYS_CTRL) MASK Register */ + +/* -------- EVSYS_CHANNEL : (EVSYS Offset: 0x04) (R/W 32) Channel -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CHANNEL:3; /*!< bit: 0.. 2 Channel Selection */ + uint32_t :5; /*!< bit: 3.. 7 Reserved */ + uint32_t SWEVT:1; /*!< bit: 8 Software Event */ + uint32_t :7; /*!< bit: 9..15 Reserved */ + uint32_t EVGEN:6; /*!< bit: 16..21 Event Generator Selection */ + uint32_t :2; /*!< bit: 22..23 Reserved */ + uint32_t PATH:2; /*!< bit: 24..25 Path Selection */ + uint32_t EDGSEL:2; /*!< bit: 26..27 Edge Detection Selection */ + uint32_t :4; /*!< bit: 28..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} EVSYS_CHANNEL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_CHANNEL_OFFSET 0x04 /**< \brief (EVSYS_CHANNEL offset) Channel */ +#define EVSYS_CHANNEL_RESETVALUE 0x00000000 /**< \brief (EVSYS_CHANNEL reset_value) Channel */ + +#define EVSYS_CHANNEL_CHANNEL_Pos 0 /**< \brief (EVSYS_CHANNEL) Channel Selection */ +#define EVSYS_CHANNEL_CHANNEL_Msk (0x7u << EVSYS_CHANNEL_CHANNEL_Pos) +#define EVSYS_CHANNEL_CHANNEL(value) ((EVSYS_CHANNEL_CHANNEL_Msk & ((value) << EVSYS_CHANNEL_CHANNEL_Pos))) +#define EVSYS_CHANNEL_SWEVT_Pos 8 /**< \brief (EVSYS_CHANNEL) Software Event */ +#define EVSYS_CHANNEL_SWEVT (0x1u << EVSYS_CHANNEL_SWEVT_Pos) +#define EVSYS_CHANNEL_EVGEN_Pos 16 /**< \brief (EVSYS_CHANNEL) Event Generator Selection */ +#define EVSYS_CHANNEL_EVGEN_Msk (0x3Fu << EVSYS_CHANNEL_EVGEN_Pos) +#define EVSYS_CHANNEL_EVGEN(value) ((EVSYS_CHANNEL_EVGEN_Msk & ((value) << EVSYS_CHANNEL_EVGEN_Pos))) +#define EVSYS_CHANNEL_PATH_Pos 24 /**< \brief (EVSYS_CHANNEL) Path Selection */ +#define EVSYS_CHANNEL_PATH_Msk (0x3u << EVSYS_CHANNEL_PATH_Pos) +#define EVSYS_CHANNEL_PATH(value) ((EVSYS_CHANNEL_PATH_Msk & ((value) << EVSYS_CHANNEL_PATH_Pos))) +#define EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val 0x0u /**< \brief (EVSYS_CHANNEL) Synchronous path */ +#define EVSYS_CHANNEL_PATH_RESYNCHRONIZED_Val 0x1u /**< \brief (EVSYS_CHANNEL) Resynchronized path */ +#define EVSYS_CHANNEL_PATH_ASYNCHRONOUS_Val 0x2u /**< \brief (EVSYS_CHANNEL) Asynchronous path */ +#define EVSYS_CHANNEL_PATH_SYNCHRONOUS (EVSYS_CHANNEL_PATH_SYNCHRONOUS_Val << EVSYS_CHANNEL_PATH_Pos) +#define EVSYS_CHANNEL_PATH_RESYNCHRONIZED (EVSYS_CHANNEL_PATH_RESYNCHRONIZED_Val << EVSYS_CHANNEL_PATH_Pos) +#define EVSYS_CHANNEL_PATH_ASYNCHRONOUS (EVSYS_CHANNEL_PATH_ASYNCHRONOUS_Val << EVSYS_CHANNEL_PATH_Pos) +#define EVSYS_CHANNEL_EDGSEL_Pos 26 /**< \brief (EVSYS_CHANNEL) Edge Detection Selection */ +#define EVSYS_CHANNEL_EDGSEL_Msk (0x3u << EVSYS_CHANNEL_EDGSEL_Pos) +#define EVSYS_CHANNEL_EDGSEL(value) ((EVSYS_CHANNEL_EDGSEL_Msk & ((value) << EVSYS_CHANNEL_EDGSEL_Pos))) +#define EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT_Val 0x0u /**< \brief (EVSYS_CHANNEL) No event output when using the resynchronized or synchronous path */ +#define EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val 0x1u /**< \brief (EVSYS_CHANNEL) Event detection only on the rising edge of the signal from the event generator when using the resynchronized or synchronous path */ +#define EVSYS_CHANNEL_EDGSEL_FALLING_EDGE_Val 0x2u /**< \brief (EVSYS_CHANNEL) Event detection only on the falling edge of the signal from the event generator when using the resynchronized or synchronous path */ +#define EVSYS_CHANNEL_EDGSEL_BOTH_EDGES_Val 0x3u /**< \brief (EVSYS_CHANNEL) Event detection on rising and falling edges of the signal from the event generator when using the resynchronized or synchronous path */ +#define EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT (EVSYS_CHANNEL_EDGSEL_NO_EVT_OUTPUT_Val << EVSYS_CHANNEL_EDGSEL_Pos) +#define EVSYS_CHANNEL_EDGSEL_RISING_EDGE (EVSYS_CHANNEL_EDGSEL_RISING_EDGE_Val << EVSYS_CHANNEL_EDGSEL_Pos) +#define EVSYS_CHANNEL_EDGSEL_FALLING_EDGE (EVSYS_CHANNEL_EDGSEL_FALLING_EDGE_Val << EVSYS_CHANNEL_EDGSEL_Pos) +#define EVSYS_CHANNEL_EDGSEL_BOTH_EDGES (EVSYS_CHANNEL_EDGSEL_BOTH_EDGES_Val << EVSYS_CHANNEL_EDGSEL_Pos) +#define EVSYS_CHANNEL_MASK 0x0F3F0107u /**< \brief (EVSYS_CHANNEL) MASK Register */ + +/* -------- EVSYS_USER : (EVSYS Offset: 0x08) (R/W 16) User Multiplexer -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t USER:4; /*!< bit: 0.. 3 User Multiplexer Selection */ + uint16_t :4; /*!< bit: 4.. 7 Reserved */ + uint16_t CHANNEL:4; /*!< bit: 8..11 Channel Event Selection */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} EVSYS_USER_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_USER_OFFSET 0x08 /**< \brief (EVSYS_USER offset) User Multiplexer */ +#define EVSYS_USER_RESETVALUE 0x0000 /**< \brief (EVSYS_USER reset_value) User Multiplexer */ + +#define EVSYS_USER_USER_Pos 0 /**< \brief (EVSYS_USER) User Multiplexer Selection */ +#define EVSYS_USER_USER_Msk (0xFu << EVSYS_USER_USER_Pos) +#define EVSYS_USER_USER(value) ((EVSYS_USER_USER_Msk & ((value) << EVSYS_USER_USER_Pos))) +#define EVSYS_USER_CHANNEL_Pos 8 /**< \brief (EVSYS_USER) Channel Event Selection */ +#define EVSYS_USER_CHANNEL_Msk (0xFu << EVSYS_USER_CHANNEL_Pos) +#define EVSYS_USER_CHANNEL(value) ((EVSYS_USER_CHANNEL_Msk & ((value) << EVSYS_USER_CHANNEL_Pos))) +#define EVSYS_USER_MASK 0x0F0Fu /**< \brief (EVSYS_USER) MASK Register */ + +/* -------- EVSYS_CHSTATUS : (EVSYS Offset: 0x0C) (R/ 32) Channel Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t USRRDY0:1; /*!< bit: 0 Channel 0 User Ready */ + uint32_t USRRDY1:1; /*!< bit: 1 Channel 1 User Ready */ + uint32_t USRRDY2:1; /*!< bit: 2 Channel 2 User Ready */ + uint32_t USRRDY3:1; /*!< bit: 3 Channel 3 User Ready */ + uint32_t USRRDY4:1; /*!< bit: 4 Channel 4 User Ready */ + uint32_t USRRDY5:1; /*!< bit: 5 Channel 5 User Ready */ + uint32_t USRRDY6:1; /*!< bit: 6 Channel 6 User Ready */ + uint32_t USRRDY7:1; /*!< bit: 7 Channel 7 User Ready */ + uint32_t CHBUSY0:1; /*!< bit: 8 Channel 0 Busy */ + uint32_t CHBUSY1:1; /*!< bit: 9 Channel 1 Busy */ + uint32_t CHBUSY2:1; /*!< bit: 10 Channel 2 Busy */ + uint32_t CHBUSY3:1; /*!< bit: 11 Channel 3 Busy */ + uint32_t CHBUSY4:1; /*!< bit: 12 Channel 4 Busy */ + uint32_t CHBUSY5:1; /*!< bit: 13 Channel 5 Busy */ + uint32_t CHBUSY6:1; /*!< bit: 14 Channel 6 Busy */ + uint32_t CHBUSY7:1; /*!< bit: 15 Channel 7 Busy */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t USRRDY:8; /*!< bit: 0.. 7 Channel x User Ready */ + uint32_t CHBUSY:8; /*!< bit: 8..15 Channel x Busy */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EVSYS_CHSTATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_CHSTATUS_OFFSET 0x0C /**< \brief (EVSYS_CHSTATUS offset) Channel Status */ +#define EVSYS_CHSTATUS_RESETVALUE 0x00000000 /**< \brief (EVSYS_CHSTATUS reset_value) Channel Status */ + +#define EVSYS_CHSTATUS_USRRDY0_Pos 0 /**< \brief (EVSYS_CHSTATUS) Channel 0 User Ready */ +#define EVSYS_CHSTATUS_USRRDY0 (1 << EVSYS_CHSTATUS_USRRDY0_Pos) +#define EVSYS_CHSTATUS_USRRDY1_Pos 1 /**< \brief (EVSYS_CHSTATUS) Channel 1 User Ready */ +#define EVSYS_CHSTATUS_USRRDY1 (1 << EVSYS_CHSTATUS_USRRDY1_Pos) +#define EVSYS_CHSTATUS_USRRDY2_Pos 2 /**< \brief (EVSYS_CHSTATUS) Channel 2 User Ready */ +#define EVSYS_CHSTATUS_USRRDY2 (1 << EVSYS_CHSTATUS_USRRDY2_Pos) +#define EVSYS_CHSTATUS_USRRDY3_Pos 3 /**< \brief (EVSYS_CHSTATUS) Channel 3 User Ready */ +#define EVSYS_CHSTATUS_USRRDY3 (1 << EVSYS_CHSTATUS_USRRDY3_Pos) +#define EVSYS_CHSTATUS_USRRDY4_Pos 4 /**< \brief (EVSYS_CHSTATUS) Channel 4 User Ready */ +#define EVSYS_CHSTATUS_USRRDY4 (1 << EVSYS_CHSTATUS_USRRDY4_Pos) +#define EVSYS_CHSTATUS_USRRDY5_Pos 5 /**< \brief (EVSYS_CHSTATUS) Channel 5 User Ready */ +#define EVSYS_CHSTATUS_USRRDY5 (1 << EVSYS_CHSTATUS_USRRDY5_Pos) +#define EVSYS_CHSTATUS_USRRDY6_Pos 6 /**< \brief (EVSYS_CHSTATUS) Channel 6 User Ready */ +#define EVSYS_CHSTATUS_USRRDY6 (1 << EVSYS_CHSTATUS_USRRDY6_Pos) +#define EVSYS_CHSTATUS_USRRDY7_Pos 7 /**< \brief (EVSYS_CHSTATUS) Channel 7 User Ready */ +#define EVSYS_CHSTATUS_USRRDY7 (1 << EVSYS_CHSTATUS_USRRDY7_Pos) +#define EVSYS_CHSTATUS_USRRDY_Pos 0 /**< \brief (EVSYS_CHSTATUS) Channel x User Ready */ +#define EVSYS_CHSTATUS_USRRDY_Msk (0xFFu << EVSYS_CHSTATUS_USRRDY_Pos) +#define EVSYS_CHSTATUS_USRRDY(value) ((EVSYS_CHSTATUS_USRRDY_Msk & ((value) << EVSYS_CHSTATUS_USRRDY_Pos))) +#define EVSYS_CHSTATUS_CHBUSY0_Pos 8 /**< \brief (EVSYS_CHSTATUS) Channel 0 Busy */ +#define EVSYS_CHSTATUS_CHBUSY0 (1 << EVSYS_CHSTATUS_CHBUSY0_Pos) +#define EVSYS_CHSTATUS_CHBUSY1_Pos 9 /**< \brief (EVSYS_CHSTATUS) Channel 1 Busy */ +#define EVSYS_CHSTATUS_CHBUSY1 (1 << EVSYS_CHSTATUS_CHBUSY1_Pos) +#define EVSYS_CHSTATUS_CHBUSY2_Pos 10 /**< \brief (EVSYS_CHSTATUS) Channel 2 Busy */ +#define EVSYS_CHSTATUS_CHBUSY2 (1 << EVSYS_CHSTATUS_CHBUSY2_Pos) +#define EVSYS_CHSTATUS_CHBUSY3_Pos 11 /**< \brief (EVSYS_CHSTATUS) Channel 3 Busy */ +#define EVSYS_CHSTATUS_CHBUSY3 (1 << EVSYS_CHSTATUS_CHBUSY3_Pos) +#define EVSYS_CHSTATUS_CHBUSY4_Pos 12 /**< \brief (EVSYS_CHSTATUS) Channel 4 Busy */ +#define EVSYS_CHSTATUS_CHBUSY4 (1 << EVSYS_CHSTATUS_CHBUSY4_Pos) +#define EVSYS_CHSTATUS_CHBUSY5_Pos 13 /**< \brief (EVSYS_CHSTATUS) Channel 5 Busy */ +#define EVSYS_CHSTATUS_CHBUSY5 (1 << EVSYS_CHSTATUS_CHBUSY5_Pos) +#define EVSYS_CHSTATUS_CHBUSY6_Pos 14 /**< \brief (EVSYS_CHSTATUS) Channel 6 Busy */ +#define EVSYS_CHSTATUS_CHBUSY6 (1 << EVSYS_CHSTATUS_CHBUSY6_Pos) +#define EVSYS_CHSTATUS_CHBUSY7_Pos 15 /**< \brief (EVSYS_CHSTATUS) Channel 7 Busy */ +#define EVSYS_CHSTATUS_CHBUSY7 (1 << EVSYS_CHSTATUS_CHBUSY7_Pos) +#define EVSYS_CHSTATUS_CHBUSY_Pos 8 /**< \brief (EVSYS_CHSTATUS) Channel x Busy */ +#define EVSYS_CHSTATUS_CHBUSY_Msk (0xFFu << EVSYS_CHSTATUS_CHBUSY_Pos) +#define EVSYS_CHSTATUS_CHBUSY(value) ((EVSYS_CHSTATUS_CHBUSY_Msk & ((value) << EVSYS_CHSTATUS_CHBUSY_Pos))) +#define EVSYS_CHSTATUS_MASK 0x0000FFFFu /**< \brief (EVSYS_CHSTATUS) MASK Register */ + +/* -------- EVSYS_INTENCLR : (EVSYS Offset: 0x10) (R/W 32) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OVR0:1; /*!< bit: 0 Channel 0 Overrun Interrupt Enable */ + uint32_t OVR1:1; /*!< bit: 1 Channel 1 Overrun Interrupt Enable */ + uint32_t OVR2:1; /*!< bit: 2 Channel 2 Overrun Interrupt Enable */ + uint32_t OVR3:1; /*!< bit: 3 Channel 3 Overrun Interrupt Enable */ + uint32_t OVR4:1; /*!< bit: 4 Channel 4 Overrun Interrupt Enable */ + uint32_t OVR5:1; /*!< bit: 5 Channel 5 Overrun Interrupt Enable */ + uint32_t OVR6:1; /*!< bit: 6 Channel 6 Overrun Interrupt Enable */ + uint32_t OVR7:1; /*!< bit: 7 Channel 7 Overrun Interrupt Enable */ + uint32_t EVD0:1; /*!< bit: 8 Channel 0 Event Detection Interrupt Enable */ + uint32_t EVD1:1; /*!< bit: 9 Channel 1 Event Detection Interrupt Enable */ + uint32_t EVD2:1; /*!< bit: 10 Channel 2 Event Detection Interrupt Enable */ + uint32_t EVD3:1; /*!< bit: 11 Channel 3 Event Detection Interrupt Enable */ + uint32_t EVD4:1; /*!< bit: 12 Channel 4 Event Detection Interrupt Enable */ + uint32_t EVD5:1; /*!< bit: 13 Channel 5 Event Detection Interrupt Enable */ + uint32_t EVD6:1; /*!< bit: 14 Channel 6 Event Detection Interrupt Enable */ + uint32_t EVD7:1; /*!< bit: 15 Channel 7 Event Detection Interrupt Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t OVR:8; /*!< bit: 0.. 7 Channel x Overrun Interrupt Enable */ + uint32_t EVD:8; /*!< bit: 8..15 Channel x Event Detection Interrupt Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EVSYS_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_INTENCLR_OFFSET 0x10 /**< \brief (EVSYS_INTENCLR offset) Interrupt Enable Clear */ +#define EVSYS_INTENCLR_RESETVALUE 0x00000000 /**< \brief (EVSYS_INTENCLR reset_value) Interrupt Enable Clear */ + +#define EVSYS_INTENCLR_OVR0_Pos 0 /**< \brief (EVSYS_INTENCLR) Channel 0 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR0 (1 << EVSYS_INTENCLR_OVR0_Pos) +#define EVSYS_INTENCLR_OVR1_Pos 1 /**< \brief (EVSYS_INTENCLR) Channel 1 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR1 (1 << EVSYS_INTENCLR_OVR1_Pos) +#define EVSYS_INTENCLR_OVR2_Pos 2 /**< \brief (EVSYS_INTENCLR) Channel 2 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR2 (1 << EVSYS_INTENCLR_OVR2_Pos) +#define EVSYS_INTENCLR_OVR3_Pos 3 /**< \brief (EVSYS_INTENCLR) Channel 3 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR3 (1 << EVSYS_INTENCLR_OVR3_Pos) +#define EVSYS_INTENCLR_OVR4_Pos 4 /**< \brief (EVSYS_INTENCLR) Channel 4 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR4 (1 << EVSYS_INTENCLR_OVR4_Pos) +#define EVSYS_INTENCLR_OVR5_Pos 5 /**< \brief (EVSYS_INTENCLR) Channel 5 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR5 (1 << EVSYS_INTENCLR_OVR5_Pos) +#define EVSYS_INTENCLR_OVR6_Pos 6 /**< \brief (EVSYS_INTENCLR) Channel 6 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR6 (1 << EVSYS_INTENCLR_OVR6_Pos) +#define EVSYS_INTENCLR_OVR7_Pos 7 /**< \brief (EVSYS_INTENCLR) Channel 7 Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR7 (1 << EVSYS_INTENCLR_OVR7_Pos) +#define EVSYS_INTENCLR_OVR_Pos 0 /**< \brief (EVSYS_INTENCLR) Channel x Overrun Interrupt Enable */ +#define EVSYS_INTENCLR_OVR_Msk (0xFFu << EVSYS_INTENCLR_OVR_Pos) +#define EVSYS_INTENCLR_OVR(value) ((EVSYS_INTENCLR_OVR_Msk & ((value) << EVSYS_INTENCLR_OVR_Pos))) +#define EVSYS_INTENCLR_EVD0_Pos 8 /**< \brief (EVSYS_INTENCLR) Channel 0 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD0 (1 << EVSYS_INTENCLR_EVD0_Pos) +#define EVSYS_INTENCLR_EVD1_Pos 9 /**< \brief (EVSYS_INTENCLR) Channel 1 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD1 (1 << EVSYS_INTENCLR_EVD1_Pos) +#define EVSYS_INTENCLR_EVD2_Pos 10 /**< \brief (EVSYS_INTENCLR) Channel 2 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD2 (1 << EVSYS_INTENCLR_EVD2_Pos) +#define EVSYS_INTENCLR_EVD3_Pos 11 /**< \brief (EVSYS_INTENCLR) Channel 3 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD3 (1 << EVSYS_INTENCLR_EVD3_Pos) +#define EVSYS_INTENCLR_EVD4_Pos 12 /**< \brief (EVSYS_INTENCLR) Channel 4 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD4 (1 << EVSYS_INTENCLR_EVD4_Pos) +#define EVSYS_INTENCLR_EVD5_Pos 13 /**< \brief (EVSYS_INTENCLR) Channel 5 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD5 (1 << EVSYS_INTENCLR_EVD5_Pos) +#define EVSYS_INTENCLR_EVD6_Pos 14 /**< \brief (EVSYS_INTENCLR) Channel 6 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD6 (1 << EVSYS_INTENCLR_EVD6_Pos) +#define EVSYS_INTENCLR_EVD7_Pos 15 /**< \brief (EVSYS_INTENCLR) Channel 7 Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD7 (1 << EVSYS_INTENCLR_EVD7_Pos) +#define EVSYS_INTENCLR_EVD_Pos 8 /**< \brief (EVSYS_INTENCLR) Channel x Event Detection Interrupt Enable */ +#define EVSYS_INTENCLR_EVD_Msk (0xFFu << EVSYS_INTENCLR_EVD_Pos) +#define EVSYS_INTENCLR_EVD(value) ((EVSYS_INTENCLR_EVD_Msk & ((value) << EVSYS_INTENCLR_EVD_Pos))) +#define EVSYS_INTENCLR_MASK 0x0000FFFFu /**< \brief (EVSYS_INTENCLR) MASK Register */ + +/* -------- EVSYS_INTENSET : (EVSYS Offset: 0x14) (R/W 32) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OVR0:1; /*!< bit: 0 Channel 0 Overrun Interrupt Enable */ + uint32_t OVR1:1; /*!< bit: 1 Channel 1 Overrun Interrupt Enable */ + uint32_t OVR2:1; /*!< bit: 2 Channel 2 Overrun Interrupt Enable */ + uint32_t OVR3:1; /*!< bit: 3 Channel 3 Overrun Interrupt Enable */ + uint32_t OVR4:1; /*!< bit: 4 Channel 4 Overrun Interrupt Enable */ + uint32_t OVR5:1; /*!< bit: 5 Channel 5 Overrun Interrupt Enable */ + uint32_t OVR6:1; /*!< bit: 6 Channel 6 Overrun Interrupt Enable */ + uint32_t OVR7:1; /*!< bit: 7 Channel 7 Overrun Interrupt Enable */ + uint32_t EVD0:1; /*!< bit: 8 Channel 0 Event Detection Interrupt Enable */ + uint32_t EVD1:1; /*!< bit: 9 Channel 1 Event Detection Interrupt Enable */ + uint32_t EVD2:1; /*!< bit: 10 Channel 2 Event Detection Interrupt Enable */ + uint32_t EVD3:1; /*!< bit: 11 Channel 3 Event Detection Interrupt Enable */ + uint32_t EVD4:1; /*!< bit: 12 Channel 4 Event Detection Interrupt Enable */ + uint32_t EVD5:1; /*!< bit: 13 Channel 5 Event Detection Interrupt Enable */ + uint32_t EVD6:1; /*!< bit: 14 Channel 6 Event Detection Interrupt Enable */ + uint32_t EVD7:1; /*!< bit: 15 Channel 7 Event Detection Interrupt Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t OVR:8; /*!< bit: 0.. 7 Channel x Overrun Interrupt Enable */ + uint32_t EVD:8; /*!< bit: 8..15 Channel x Event Detection Interrupt Enable */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EVSYS_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_INTENSET_OFFSET 0x14 /**< \brief (EVSYS_INTENSET offset) Interrupt Enable Set */ +#define EVSYS_INTENSET_RESETVALUE 0x00000000 /**< \brief (EVSYS_INTENSET reset_value) Interrupt Enable Set */ + +#define EVSYS_INTENSET_OVR0_Pos 0 /**< \brief (EVSYS_INTENSET) Channel 0 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR0 (1 << EVSYS_INTENSET_OVR0_Pos) +#define EVSYS_INTENSET_OVR1_Pos 1 /**< \brief (EVSYS_INTENSET) Channel 1 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR1 (1 << EVSYS_INTENSET_OVR1_Pos) +#define EVSYS_INTENSET_OVR2_Pos 2 /**< \brief (EVSYS_INTENSET) Channel 2 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR2 (1 << EVSYS_INTENSET_OVR2_Pos) +#define EVSYS_INTENSET_OVR3_Pos 3 /**< \brief (EVSYS_INTENSET) Channel 3 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR3 (1 << EVSYS_INTENSET_OVR3_Pos) +#define EVSYS_INTENSET_OVR4_Pos 4 /**< \brief (EVSYS_INTENSET) Channel 4 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR4 (1 << EVSYS_INTENSET_OVR4_Pos) +#define EVSYS_INTENSET_OVR5_Pos 5 /**< \brief (EVSYS_INTENSET) Channel 5 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR5 (1 << EVSYS_INTENSET_OVR5_Pos) +#define EVSYS_INTENSET_OVR6_Pos 6 /**< \brief (EVSYS_INTENSET) Channel 6 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR6 (1 << EVSYS_INTENSET_OVR6_Pos) +#define EVSYS_INTENSET_OVR7_Pos 7 /**< \brief (EVSYS_INTENSET) Channel 7 Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR7 (1 << EVSYS_INTENSET_OVR7_Pos) +#define EVSYS_INTENSET_OVR_Pos 0 /**< \brief (EVSYS_INTENSET) Channel x Overrun Interrupt Enable */ +#define EVSYS_INTENSET_OVR_Msk (0xFFu << EVSYS_INTENSET_OVR_Pos) +#define EVSYS_INTENSET_OVR(value) ((EVSYS_INTENSET_OVR_Msk & ((value) << EVSYS_INTENSET_OVR_Pos))) +#define EVSYS_INTENSET_EVD0_Pos 8 /**< \brief (EVSYS_INTENSET) Channel 0 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD0 (1 << EVSYS_INTENSET_EVD0_Pos) +#define EVSYS_INTENSET_EVD1_Pos 9 /**< \brief (EVSYS_INTENSET) Channel 1 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD1 (1 << EVSYS_INTENSET_EVD1_Pos) +#define EVSYS_INTENSET_EVD2_Pos 10 /**< \brief (EVSYS_INTENSET) Channel 2 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD2 (1 << EVSYS_INTENSET_EVD2_Pos) +#define EVSYS_INTENSET_EVD3_Pos 11 /**< \brief (EVSYS_INTENSET) Channel 3 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD3 (1 << EVSYS_INTENSET_EVD3_Pos) +#define EVSYS_INTENSET_EVD4_Pos 12 /**< \brief (EVSYS_INTENSET) Channel 4 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD4 (1 << EVSYS_INTENSET_EVD4_Pos) +#define EVSYS_INTENSET_EVD5_Pos 13 /**< \brief (EVSYS_INTENSET) Channel 5 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD5 (1 << EVSYS_INTENSET_EVD5_Pos) +#define EVSYS_INTENSET_EVD6_Pos 14 /**< \brief (EVSYS_INTENSET) Channel 6 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD6 (1 << EVSYS_INTENSET_EVD6_Pos) +#define EVSYS_INTENSET_EVD7_Pos 15 /**< \brief (EVSYS_INTENSET) Channel 7 Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD7 (1 << EVSYS_INTENSET_EVD7_Pos) +#define EVSYS_INTENSET_EVD_Pos 8 /**< \brief (EVSYS_INTENSET) Channel x Event Detection Interrupt Enable */ +#define EVSYS_INTENSET_EVD_Msk (0xFFu << EVSYS_INTENSET_EVD_Pos) +#define EVSYS_INTENSET_EVD(value) ((EVSYS_INTENSET_EVD_Msk & ((value) << EVSYS_INTENSET_EVD_Pos))) +#define EVSYS_INTENSET_MASK 0x0000FFFFu /**< \brief (EVSYS_INTENSET) MASK Register */ + +/* -------- EVSYS_INTFLAG : (EVSYS Offset: 0x18) (R/W 32) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OVR0:1; /*!< bit: 0 Channel 0 Overrun */ + uint32_t OVR1:1; /*!< bit: 1 Channel 1 Overrun */ + uint32_t OVR2:1; /*!< bit: 2 Channel 2 Overrun */ + uint32_t OVR3:1; /*!< bit: 3 Channel 3 Overrun */ + uint32_t OVR4:1; /*!< bit: 4 Channel 4 Overrun */ + uint32_t OVR5:1; /*!< bit: 5 Channel 5 Overrun */ + uint32_t OVR6:1; /*!< bit: 6 Channel 6 Overrun */ + uint32_t OVR7:1; /*!< bit: 7 Channel 7 Overrun */ + uint32_t EVD0:1; /*!< bit: 8 Channel 0 Event Detection */ + uint32_t EVD1:1; /*!< bit: 9 Channel 1 Event Detection */ + uint32_t EVD2:1; /*!< bit: 10 Channel 2 Event Detection */ + uint32_t EVD3:1; /*!< bit: 11 Channel 3 Event Detection */ + uint32_t EVD4:1; /*!< bit: 12 Channel 4 Event Detection */ + uint32_t EVD5:1; /*!< bit: 13 Channel 5 Event Detection */ + uint32_t EVD6:1; /*!< bit: 14 Channel 6 Event Detection */ + uint32_t EVD7:1; /*!< bit: 15 Channel 7 Event Detection */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t OVR:8; /*!< bit: 0.. 7 Channel x Overrun */ + uint32_t EVD:8; /*!< bit: 8..15 Channel x Event Detection */ + uint32_t :16; /*!< bit: 16..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} EVSYS_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define EVSYS_INTFLAG_OFFSET 0x18 /**< \brief (EVSYS_INTFLAG offset) Interrupt Flag Status and Clear */ +#define EVSYS_INTFLAG_RESETVALUE 0x00000000 /**< \brief (EVSYS_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define EVSYS_INTFLAG_OVR0_Pos 0 /**< \brief (EVSYS_INTFLAG) Channel 0 Overrun */ +#define EVSYS_INTFLAG_OVR0 (1 << EVSYS_INTFLAG_OVR0_Pos) +#define EVSYS_INTFLAG_OVR1_Pos 1 /**< \brief (EVSYS_INTFLAG) Channel 1 Overrun */ +#define EVSYS_INTFLAG_OVR1 (1 << EVSYS_INTFLAG_OVR1_Pos) +#define EVSYS_INTFLAG_OVR2_Pos 2 /**< \brief (EVSYS_INTFLAG) Channel 2 Overrun */ +#define EVSYS_INTFLAG_OVR2 (1 << EVSYS_INTFLAG_OVR2_Pos) +#define EVSYS_INTFLAG_OVR3_Pos 3 /**< \brief (EVSYS_INTFLAG) Channel 3 Overrun */ +#define EVSYS_INTFLAG_OVR3 (1 << EVSYS_INTFLAG_OVR3_Pos) +#define EVSYS_INTFLAG_OVR4_Pos 4 /**< \brief (EVSYS_INTFLAG) Channel 4 Overrun */ +#define EVSYS_INTFLAG_OVR4 (1 << EVSYS_INTFLAG_OVR4_Pos) +#define EVSYS_INTFLAG_OVR5_Pos 5 /**< \brief (EVSYS_INTFLAG) Channel 5 Overrun */ +#define EVSYS_INTFLAG_OVR5 (1 << EVSYS_INTFLAG_OVR5_Pos) +#define EVSYS_INTFLAG_OVR6_Pos 6 /**< \brief (EVSYS_INTFLAG) Channel 6 Overrun */ +#define EVSYS_INTFLAG_OVR6 (1 << EVSYS_INTFLAG_OVR6_Pos) +#define EVSYS_INTFLAG_OVR7_Pos 7 /**< \brief (EVSYS_INTFLAG) Channel 7 Overrun */ +#define EVSYS_INTFLAG_OVR7 (1 << EVSYS_INTFLAG_OVR7_Pos) +#define EVSYS_INTFLAG_OVR_Pos 0 /**< \brief (EVSYS_INTFLAG) Channel x Overrun */ +#define EVSYS_INTFLAG_OVR_Msk (0xFFu << EVSYS_INTFLAG_OVR_Pos) +#define EVSYS_INTFLAG_OVR(value) ((EVSYS_INTFLAG_OVR_Msk & ((value) << EVSYS_INTFLAG_OVR_Pos))) +#define EVSYS_INTFLAG_EVD0_Pos 8 /**< \brief (EVSYS_INTFLAG) Channel 0 Event Detection */ +#define EVSYS_INTFLAG_EVD0 (1 << EVSYS_INTFLAG_EVD0_Pos) +#define EVSYS_INTFLAG_EVD1_Pos 9 /**< \brief (EVSYS_INTFLAG) Channel 1 Event Detection */ +#define EVSYS_INTFLAG_EVD1 (1 << EVSYS_INTFLAG_EVD1_Pos) +#define EVSYS_INTFLAG_EVD2_Pos 10 /**< \brief (EVSYS_INTFLAG) Channel 2 Event Detection */ +#define EVSYS_INTFLAG_EVD2 (1 << EVSYS_INTFLAG_EVD2_Pos) +#define EVSYS_INTFLAG_EVD3_Pos 11 /**< \brief (EVSYS_INTFLAG) Channel 3 Event Detection */ +#define EVSYS_INTFLAG_EVD3 (1 << EVSYS_INTFLAG_EVD3_Pos) +#define EVSYS_INTFLAG_EVD4_Pos 12 /**< \brief (EVSYS_INTFLAG) Channel 4 Event Detection */ +#define EVSYS_INTFLAG_EVD4 (1 << EVSYS_INTFLAG_EVD4_Pos) +#define EVSYS_INTFLAG_EVD5_Pos 13 /**< \brief (EVSYS_INTFLAG) Channel 5 Event Detection */ +#define EVSYS_INTFLAG_EVD5 (1 << EVSYS_INTFLAG_EVD5_Pos) +#define EVSYS_INTFLAG_EVD6_Pos 14 /**< \brief (EVSYS_INTFLAG) Channel 6 Event Detection */ +#define EVSYS_INTFLAG_EVD6 (1 << EVSYS_INTFLAG_EVD6_Pos) +#define EVSYS_INTFLAG_EVD7_Pos 15 /**< \brief (EVSYS_INTFLAG) Channel 7 Event Detection */ +#define EVSYS_INTFLAG_EVD7 (1 << EVSYS_INTFLAG_EVD7_Pos) +#define EVSYS_INTFLAG_EVD_Pos 8 /**< \brief (EVSYS_INTFLAG) Channel x Event Detection */ +#define EVSYS_INTFLAG_EVD_Msk (0xFFu << EVSYS_INTFLAG_EVD_Pos) +#define EVSYS_INTFLAG_EVD(value) ((EVSYS_INTFLAG_EVD_Msk & ((value) << EVSYS_INTFLAG_EVD_Pos))) +#define EVSYS_INTFLAG_MASK 0x0000FFFFu /**< \brief (EVSYS_INTFLAG) MASK Register */ + +/** \brief EVSYS hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __O EVSYS_CTRL_Type CTRL; /**< \brief Offset: 0x00 ( /W 8) Control */ + RoReg8 Reserved1[0x3]; + __IO EVSYS_CHANNEL_Type CHANNEL; /**< \brief Offset: 0x04 (R/W 32) Channel */ + __IO EVSYS_USER_Type USER; /**< \brief Offset: 0x08 (R/W 16) User Multiplexer */ + RoReg8 Reserved2[0x2]; + __I EVSYS_CHSTATUS_Type CHSTATUS; /**< \brief Offset: 0x0C (R/ 32) Channel Status */ + __IO EVSYS_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x10 (R/W 32) Interrupt Enable Clear */ + __IO EVSYS_INTENSET_Type INTENSET; /**< \brief Offset: 0x14 (R/W 32) Interrupt Enable Set */ + __IO EVSYS_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x18 (R/W 32) Interrupt Flag Status and Clear */ +} Evsys; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_EVSYS_COMPONENT_ */ diff --git a/loader/samd20/component/gclk.h b/loader/samd20/component/gclk.h new file mode 100644 index 0000000..ad792e6 --- /dev/null +++ b/loader/samd20/component/gclk.h @@ -0,0 +1,322 @@ +/** + * \file + * + * \brief Component description for GCLK + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_GCLK_COMPONENT_ +#define _SAMD20_GCLK_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR GCLK */ +/* ========================================================================== */ +/** \addtogroup SAMD20_GCLK Generic Clock Generator */ +/*@{*/ + +#define GCLK_U2102 +#define REV_GCLK 0x210 + +/* -------- GCLK_CTRL : (GCLK Offset: 0x0) (R/W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} GCLK_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define GCLK_CTRL_OFFSET 0x0 /**< \brief (GCLK_CTRL offset) Control */ +#define GCLK_CTRL_RESETVALUE 0x00 /**< \brief (GCLK_CTRL reset_value) Control */ + +#define GCLK_CTRL_SWRST_Pos 0 /**< \brief (GCLK_CTRL) Software Reset */ +#define GCLK_CTRL_SWRST (0x1u << GCLK_CTRL_SWRST_Pos) +#define GCLK_CTRL_MASK 0x01u /**< \brief (GCLK_CTRL) MASK Register */ + +/* -------- GCLK_STATUS : (GCLK Offset: 0x1) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy Status */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} GCLK_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define GCLK_STATUS_OFFSET 0x1 /**< \brief (GCLK_STATUS offset) Status */ +#define GCLK_STATUS_RESETVALUE 0x00 /**< \brief (GCLK_STATUS reset_value) Status */ + +#define GCLK_STATUS_SYNCBUSY_Pos 7 /**< \brief (GCLK_STATUS) Synchronization Busy Status */ +#define GCLK_STATUS_SYNCBUSY (0x1u << GCLK_STATUS_SYNCBUSY_Pos) +#define GCLK_STATUS_MASK 0x80u /**< \brief (GCLK_STATUS) MASK Register */ + +/* -------- GCLK_CLKCTRL : (GCLK Offset: 0x2) (R/W 16) Generic Clock Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t ID:6; /*!< bit: 0.. 5 Generic Clock Selection ID */ + uint16_t :2; /*!< bit: 6.. 7 Reserved */ + uint16_t GEN:4; /*!< bit: 8..11 Generic Clock Generator */ + uint16_t :2; /*!< bit: 12..13 Reserved */ + uint16_t CLKEN:1; /*!< bit: 14 Clock Enable */ + uint16_t WRTLOCK:1; /*!< bit: 15 Write Lock */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} GCLK_CLKCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define GCLK_CLKCTRL_OFFSET 0x2 /**< \brief (GCLK_CLKCTRL offset) Generic Clock Control */ +#define GCLK_CLKCTRL_RESETVALUE 0x0000 /**< \brief (GCLK_CLKCTRL reset_value) Generic Clock Control */ + +#define GCLK_CLKCTRL_ID_Pos 0 /**< \brief (GCLK_CLKCTRL) Generic Clock Selection ID */ +#define GCLK_CLKCTRL_ID_Msk (0x3Fu << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID(value) ((GCLK_CLKCTRL_ID_Msk & ((value) << GCLK_CLKCTRL_ID_Pos))) +#define GCLK_CLKCTRL_ID_0_Val 0x0u /**< \brief (GCLK_CLKCTRL) DFLL48M Reference */ +#define GCLK_CLKCTRL_ID_1_Val 0x1u /**< \brief (GCLK_CLKCTRL) WDT */ +#define GCLK_CLKCTRL_ID_2_Val 0x2u /**< \brief (GCLK_CLKCTRL) RTC */ +#define GCLK_CLKCTRL_ID_3_Val 0x3u /**< \brief (GCLK_CLKCTRL) EIC */ +#define GCLK_CLKCTRL_ID_4_Val 0x4u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_0 */ +#define GCLK_CLKCTRL_ID_5_Val 0x5u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_1 */ +#define GCLK_CLKCTRL_ID_6_Val 0x6u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_2 */ +#define GCLK_CLKCTRL_ID_7_Val 0x7u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_3 */ +#define GCLK_CLKCTRL_ID_8_Val 0x8u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_4 */ +#define GCLK_CLKCTRL_ID_9_Val 0x9u /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_5 */ +#define GCLK_CLKCTRL_ID_10_Val 0xAu /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_6 */ +#define GCLK_CLKCTRL_ID_11_Val 0xBu /**< \brief (GCLK_CLKCTRL) EVSYS_CHANNEL_7 */ +#define GCLK_CLKCTRL_ID_12_Val 0xCu /**< \brief (GCLK_CLKCTRL) SERCOMx_SLOW */ +#define GCLK_CLKCTRL_ID_13_Val 0xDu /**< \brief (GCLK_CLKCTRL) SERCOM0_CORE */ +#define GCLK_CLKCTRL_ID_14_Val 0xEu /**< \brief (GCLK_CLKCTRL) SERCOM1_CORE */ +#define GCLK_CLKCTRL_ID_15_Val 0xFu /**< \brief (GCLK_CLKCTRL) SERCOM2_CORE */ +#define GCLK_CLKCTRL_ID_16_Val 0x10u /**< \brief (GCLK_CLKCTRL) SERCOM3_CORE */ +#define GCLK_CLKCTRL_ID_17_Val 0x11u /**< \brief (GCLK_CLKCTRL) SERCOM4_CORE */ +#define GCLK_CLKCTRL_ID_18_Val 0x12u /**< \brief (GCLK_CLKCTRL) SERCOM5_CORE */ +#define GCLK_CLKCTRL_ID_19_Val 0x13u /**< \brief (GCLK_CLKCTRL) TC0,TC1 */ +#define GCLK_CLKCTRL_ID_20_Val 0x14u /**< \brief (GCLK_CLKCTRL) TC2,TC3 */ +#define GCLK_CLKCTRL_ID_21_Val 0x15u /**< \brief (GCLK_CLKCTRL) TC4,TC5 */ +#define GCLK_CLKCTRL_ID_22_Val 0x16u /**< \brief (GCLK_CLKCTRL) TC6,TC7 */ +#define GCLK_CLKCTRL_ID_23_Val 0x17u /**< \brief (GCLK_CLKCTRL) ADC */ +#define GCLK_CLKCTRL_ID_24_Val 0x18u /**< \brief (GCLK_CLKCTRL) AC_DIG */ +#define GCLK_CLKCTRL_ID_25_Val 0x19u /**< \brief (GCLK_CLKCTRL) AC_ANA */ +#define GCLK_CLKCTRL_ID_26_Val 0x1Au /**< \brief (GCLK_CLKCTRL) DAC */ +#define GCLK_CLKCTRL_ID_27_Val 0x1Bu /**< \brief (GCLK_CLKCTRL) PTC */ +#define GCLK_CLKCTRL_ID_0 (GCLK_CLKCTRL_ID_0_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_1 (GCLK_CLKCTRL_ID_1_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_2 (GCLK_CLKCTRL_ID_2_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_3 (GCLK_CLKCTRL_ID_3_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_4 (GCLK_CLKCTRL_ID_4_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_5 (GCLK_CLKCTRL_ID_5_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_6 (GCLK_CLKCTRL_ID_6_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_7 (GCLK_CLKCTRL_ID_7_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_8 (GCLK_CLKCTRL_ID_8_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_9 (GCLK_CLKCTRL_ID_9_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_10 (GCLK_CLKCTRL_ID_10_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_11 (GCLK_CLKCTRL_ID_11_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_12 (GCLK_CLKCTRL_ID_12_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_13 (GCLK_CLKCTRL_ID_13_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_14 (GCLK_CLKCTRL_ID_14_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_15 (GCLK_CLKCTRL_ID_15_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_16 (GCLK_CLKCTRL_ID_16_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_17 (GCLK_CLKCTRL_ID_17_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_18 (GCLK_CLKCTRL_ID_18_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_19 (GCLK_CLKCTRL_ID_19_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_20 (GCLK_CLKCTRL_ID_20_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_21 (GCLK_CLKCTRL_ID_21_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_22 (GCLK_CLKCTRL_ID_22_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_23 (GCLK_CLKCTRL_ID_23_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_24 (GCLK_CLKCTRL_ID_24_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_25 (GCLK_CLKCTRL_ID_25_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_26 (GCLK_CLKCTRL_ID_26_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_ID_27 (GCLK_CLKCTRL_ID_27_Val << GCLK_CLKCTRL_ID_Pos) +#define GCLK_CLKCTRL_GEN_Pos 8 /**< \brief (GCLK_CLKCTRL) Generic Clock Generator */ +#define GCLK_CLKCTRL_GEN_Msk (0xFu << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN(value) ((GCLK_CLKCTRL_GEN_Msk & ((value) << GCLK_CLKCTRL_GEN_Pos))) +#define GCLK_CLKCTRL_GEN_GCLK0_Val 0x0u /**< \brief (GCLK_CLKCTRL) Generic clock generator 0 */ +#define GCLK_CLKCTRL_GEN_GCLK1_Val 0x1u /**< \brief (GCLK_CLKCTRL) Generic clock generator 1 */ +#define GCLK_CLKCTRL_GEN_GCLK2_Val 0x2u /**< \brief (GCLK_CLKCTRL) Generic clock generator 2 */ +#define GCLK_CLKCTRL_GEN_GCLK3_Val 0x3u /**< \brief (GCLK_CLKCTRL) Generic clock generator 3 */ +#define GCLK_CLKCTRL_GEN_GCLK4_Val 0x4u /**< \brief (GCLK_CLKCTRL) Generic clock generator 4 */ +#define GCLK_CLKCTRL_GEN_GCLK5_Val 0x5u /**< \brief (GCLK_CLKCTRL) Generic clock generator 5 */ +#define GCLK_CLKCTRL_GEN_GCLK6_Val 0x6u /**< \brief (GCLK_CLKCTRL) Generic clock generator 6 */ +#define GCLK_CLKCTRL_GEN_GCLK7_Val 0x7u /**< \brief (GCLK_CLKCTRL) Generic clock generator 7 */ +#define GCLK_CLKCTRL_GEN_GCLK0 (GCLK_CLKCTRL_GEN_GCLK0_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK1 (GCLK_CLKCTRL_GEN_GCLK1_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK2 (GCLK_CLKCTRL_GEN_GCLK2_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK3 (GCLK_CLKCTRL_GEN_GCLK3_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK4 (GCLK_CLKCTRL_GEN_GCLK4_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK5 (GCLK_CLKCTRL_GEN_GCLK5_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK6 (GCLK_CLKCTRL_GEN_GCLK6_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_GEN_GCLK7 (GCLK_CLKCTRL_GEN_GCLK7_Val << GCLK_CLKCTRL_GEN_Pos) +#define GCLK_CLKCTRL_CLKEN_Pos 14 /**< \brief (GCLK_CLKCTRL) Clock Enable */ +#define GCLK_CLKCTRL_CLKEN (0x1u << GCLK_CLKCTRL_CLKEN_Pos) +#define GCLK_CLKCTRL_WRTLOCK_Pos 15 /**< \brief (GCLK_CLKCTRL) Write Lock */ +#define GCLK_CLKCTRL_WRTLOCK (0x1u << GCLK_CLKCTRL_WRTLOCK_Pos) +#define GCLK_CLKCTRL_MASK 0xCF3Fu /**< \brief (GCLK_CLKCTRL) MASK Register */ + +/* -------- GCLK_GENCTRL : (GCLK Offset: 0x4) (R/W 32) Generic Clock Generator Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ID:4; /*!< bit: 0.. 3 Generic Clock Generator Selection */ + uint32_t :4; /*!< bit: 4.. 7 Reserved */ + uint32_t SRC:5; /*!< bit: 8..12 Source Select */ + uint32_t :3; /*!< bit: 13..15 Reserved */ + uint32_t GENEN:1; /*!< bit: 16 Generic Clock Generator Enable */ + uint32_t IDC:1; /*!< bit: 17 Improve Duty Cycle */ + uint32_t OOV:1; /*!< bit: 18 Output Off Value */ + uint32_t OE:1; /*!< bit: 19 Output Enable */ + uint32_t DIVSEL:1; /*!< bit: 20 Divide Selection */ + uint32_t RUNSTDBY:1; /*!< bit: 21 Run in Standby */ + uint32_t :10; /*!< bit: 22..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} GCLK_GENCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define GCLK_GENCTRL_OFFSET 0x4 /**< \brief (GCLK_GENCTRL offset) Generic Clock Generator Control */ +#define GCLK_GENCTRL_RESETVALUE 0x00000000 /**< \brief (GCLK_GENCTRL reset_value) Generic Clock Generator Control */ + +#define GCLK_GENCTRL_ID_Pos 0 /**< \brief (GCLK_GENCTRL) Generic Clock Generator Selection */ +#define GCLK_GENCTRL_ID_Msk (0xFu << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID(value) ((GCLK_GENCTRL_ID_Msk & ((value) << GCLK_GENCTRL_ID_Pos))) +#define GCLK_GENCTRL_ID_GCLK0_Val 0x0u /**< \brief (GCLK_GENCTRL) Generic clock generator 0 */ +#define GCLK_GENCTRL_ID_GCLK1_Val 0x1u /**< \brief (GCLK_GENCTRL) Generic clock generator 1 */ +#define GCLK_GENCTRL_ID_GCLK2_Val 0x2u /**< \brief (GCLK_GENCTRL) Generic clock generator 2 */ +#define GCLK_GENCTRL_ID_GCLK3_Val 0x3u /**< \brief (GCLK_GENCTRL) Generic clock generator 3 */ +#define GCLK_GENCTRL_ID_GCLK4_Val 0x4u /**< \brief (GCLK_GENCTRL) Generic clock generator 4 */ +#define GCLK_GENCTRL_ID_GCLK5_Val 0x5u /**< \brief (GCLK_GENCTRL) Generic clock generator 5 */ +#define GCLK_GENCTRL_ID_GCLK6_Val 0x6u /**< \brief (GCLK_GENCTRL) Generic clock generator 6 */ +#define GCLK_GENCTRL_ID_GCLK7_Val 0x7u /**< \brief (GCLK_GENCTRL) Generic clock generator 7 */ +#define GCLK_GENCTRL_ID_GCLK0 (GCLK_GENCTRL_ID_GCLK0_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK1 (GCLK_GENCTRL_ID_GCLK1_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK2 (GCLK_GENCTRL_ID_GCLK2_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK3 (GCLK_GENCTRL_ID_GCLK3_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK4 (GCLK_GENCTRL_ID_GCLK4_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK5 (GCLK_GENCTRL_ID_GCLK5_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK6 (GCLK_GENCTRL_ID_GCLK6_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_ID_GCLK7 (GCLK_GENCTRL_ID_GCLK7_Val << GCLK_GENCTRL_ID_Pos) +#define GCLK_GENCTRL_SRC_Pos 8 /**< \brief (GCLK_GENCTRL) Source Select */ +#define GCLK_GENCTRL_SRC_Msk (0x1Fu << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC(value) ((GCLK_GENCTRL_SRC_Msk & ((value) << GCLK_GENCTRL_SRC_Pos))) +#define GCLK_GENCTRL_SRC_XOSC_Val 0x0u /**< \brief (GCLK_GENCTRL) XOSC oscillator output */ +#define GCLK_GENCTRL_SRC_GCLKIN_Val 0x1u /**< \brief (GCLK_GENCTRL) Generator input pad */ +#define GCLK_GENCTRL_SRC_GCLKGEN1_Val 0x2u /**< \brief (GCLK_GENCTRL) Generic clock generator 1 output */ +#define GCLK_GENCTRL_SRC_OSCULP32K_Val 0x3u /**< \brief (GCLK_GENCTRL) OSCULP32K oscillator output */ +#define GCLK_GENCTRL_SRC_OSC32K_Val 0x4u /**< \brief (GCLK_GENCTRL) OSC32K oscillator output */ +#define GCLK_GENCTRL_SRC_XOSC32K_Val 0x5u /**< \brief (GCLK_GENCTRL) XOSC32K oscillator output */ +#define GCLK_GENCTRL_SRC_OSC8M_Val 0x6u /**< \brief (GCLK_GENCTRL) OSC8M oscillator output */ +#define GCLK_GENCTRL_SRC_DFLL48M_Val 0x7u /**< \brief (GCLK_GENCTRL) DFLL48M output */ +#define GCLK_GENCTRL_SRC_XOSC (GCLK_GENCTRL_SRC_XOSC_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_GCLKIN (GCLK_GENCTRL_SRC_GCLKIN_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_GCLKGEN1 (GCLK_GENCTRL_SRC_GCLKGEN1_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_OSCULP32K (GCLK_GENCTRL_SRC_OSCULP32K_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_OSC32K (GCLK_GENCTRL_SRC_OSC32K_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_XOSC32K (GCLK_GENCTRL_SRC_XOSC32K_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_OSC8M (GCLK_GENCTRL_SRC_OSC8M_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_SRC_DFLL48M (GCLK_GENCTRL_SRC_DFLL48M_Val << GCLK_GENCTRL_SRC_Pos) +#define GCLK_GENCTRL_GENEN_Pos 16 /**< \brief (GCLK_GENCTRL) Generic Clock Generator Enable */ +#define GCLK_GENCTRL_GENEN (0x1u << GCLK_GENCTRL_GENEN_Pos) +#define GCLK_GENCTRL_IDC_Pos 17 /**< \brief (GCLK_GENCTRL) Improve Duty Cycle */ +#define GCLK_GENCTRL_IDC (0x1u << GCLK_GENCTRL_IDC_Pos) +#define GCLK_GENCTRL_OOV_Pos 18 /**< \brief (GCLK_GENCTRL) Output Off Value */ +#define GCLK_GENCTRL_OOV (0x1u << GCLK_GENCTRL_OOV_Pos) +#define GCLK_GENCTRL_OE_Pos 19 /**< \brief (GCLK_GENCTRL) Output Enable */ +#define GCLK_GENCTRL_OE (0x1u << GCLK_GENCTRL_OE_Pos) +#define GCLK_GENCTRL_DIVSEL_Pos 20 /**< \brief (GCLK_GENCTRL) Divide Selection */ +#define GCLK_GENCTRL_DIVSEL (0x1u << GCLK_GENCTRL_DIVSEL_Pos) +#define GCLK_GENCTRL_RUNSTDBY_Pos 21 /**< \brief (GCLK_GENCTRL) Run in Standby */ +#define GCLK_GENCTRL_RUNSTDBY (0x1u << GCLK_GENCTRL_RUNSTDBY_Pos) +#define GCLK_GENCTRL_MASK 0x003F1F0Fu /**< \brief (GCLK_GENCTRL) MASK Register */ + +/* -------- GCLK_GENDIV : (GCLK Offset: 0x8) (R/W 32) Generic Clock Generator Division -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ID:4; /*!< bit: 0.. 3 Generic Clock Generator Selection */ + uint32_t :4; /*!< bit: 4.. 7 Reserved */ + uint32_t DIV:16; /*!< bit: 8..23 Division Factor */ + uint32_t :8; /*!< bit: 24..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} GCLK_GENDIV_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define GCLK_GENDIV_OFFSET 0x8 /**< \brief (GCLK_GENDIV offset) Generic Clock Generator Division */ +#define GCLK_GENDIV_RESETVALUE 0x00000000 /**< \brief (GCLK_GENDIV reset_value) Generic Clock Generator Division */ + +#define GCLK_GENDIV_ID_Pos 0 /**< \brief (GCLK_GENDIV) Generic Clock Generator Selection */ +#define GCLK_GENDIV_ID_Msk (0xFu << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID(value) ((GCLK_GENDIV_ID_Msk & ((value) << GCLK_GENDIV_ID_Pos))) +#define GCLK_GENDIV_ID_GCLK0_Val 0x0u /**< \brief (GCLK_GENDIV) Generic clock generator 0 */ +#define GCLK_GENDIV_ID_GCLK1_Val 0x1u /**< \brief (GCLK_GENDIV) Generic clock generator 1 */ +#define GCLK_GENDIV_ID_GCLK2_Val 0x2u /**< \brief (GCLK_GENDIV) Generic clock generator 2 */ +#define GCLK_GENDIV_ID_GCLK3_Val 0x3u /**< \brief (GCLK_GENDIV) Generic clock generator 3 */ +#define GCLK_GENDIV_ID_GCLK4_Val 0x4u /**< \brief (GCLK_GENDIV) Generic clock generator 4 */ +#define GCLK_GENDIV_ID_GCLK5_Val 0x5u /**< \brief (GCLK_GENDIV) Generic clock generator 5 */ +#define GCLK_GENDIV_ID_GCLK6_Val 0x6u /**< \brief (GCLK_GENDIV) Generic clock generator 6 */ +#define GCLK_GENDIV_ID_GCLK7_Val 0x7u /**< \brief (GCLK_GENDIV) Generic clock generator 7 */ +#define GCLK_GENDIV_ID_GCLK0 (GCLK_GENDIV_ID_GCLK0_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK1 (GCLK_GENDIV_ID_GCLK1_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK2 (GCLK_GENDIV_ID_GCLK2_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK3 (GCLK_GENDIV_ID_GCLK3_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK4 (GCLK_GENDIV_ID_GCLK4_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK5 (GCLK_GENDIV_ID_GCLK5_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK6 (GCLK_GENDIV_ID_GCLK6_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_ID_GCLK7 (GCLK_GENDIV_ID_GCLK7_Val << GCLK_GENDIV_ID_Pos) +#define GCLK_GENDIV_DIV_Pos 8 /**< \brief (GCLK_GENDIV) Division Factor */ +#define GCLK_GENDIV_DIV_Msk (0xFFFFu << GCLK_GENDIV_DIV_Pos) +#define GCLK_GENDIV_DIV(value) ((GCLK_GENDIV_DIV_Msk & ((value) << GCLK_GENDIV_DIV_Pos))) +#define GCLK_GENDIV_MASK 0x00FFFF0Fu /**< \brief (GCLK_GENDIV) MASK Register */ + +/** \brief GCLK hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO GCLK_CTRL_Type CTRL; /**< \brief Offset: 0x0 (R/W 8) Control */ + __I GCLK_STATUS_Type STATUS; /**< \brief Offset: 0x1 (R/ 8) Status */ + __IO GCLK_CLKCTRL_Type CLKCTRL; /**< \brief Offset: 0x2 (R/W 16) Generic Clock Control */ + __IO GCLK_GENCTRL_Type GENCTRL; /**< \brief Offset: 0x4 (R/W 32) Generic Clock Generator Control */ + __IO GCLK_GENDIV_Type GENDIV; /**< \brief Offset: 0x8 (R/W 32) Generic Clock Generator Division */ +} Gclk; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_GCLK_COMPONENT_ */ diff --git a/loader/samd20/component/nvmctrl.h b/loader/samd20/component/nvmctrl.h new file mode 100644 index 0000000..929da8b --- /dev/null +++ b/loader/samd20/component/nvmctrl.h @@ -0,0 +1,521 @@ +/** + * \file + * + * \brief Component description for NVMCTRL + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_NVMCTRL_COMPONENT_ +#define _SAMD20_NVMCTRL_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR NVMCTRL */ +/* ========================================================================== */ +/** \addtogroup SAMD20_NVMCTRL Non-Volatile Memory Controller */ +/*@{*/ + +#define NVMCTRL_U2207 +#define REV_NVMCTRL 0x106 + +/* -------- NVMCTRL_CTRLA : (NVMCTRL Offset: 0x00) (R/W 16) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t CMD:7; /*!< bit: 0.. 6 Command */ + uint16_t :1; /*!< bit: 7 Reserved */ + uint16_t CMDEX:8; /*!< bit: 8..15 Command Execution */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} NVMCTRL_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_CTRLA_OFFSET 0x00 /**< \brief (NVMCTRL_CTRLA offset) Control A */ +#define NVMCTRL_CTRLA_RESETVALUE 0x0000 /**< \brief (NVMCTRL_CTRLA reset_value) Control A */ + +#define NVMCTRL_CTRLA_CMD_Pos 0 /**< \brief (NVMCTRL_CTRLA) Command */ +#define NVMCTRL_CTRLA_CMD_Msk (0x7Fu << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD(value) ((NVMCTRL_CTRLA_CMD_Msk & ((value) << NVMCTRL_CTRLA_CMD_Pos))) +#define NVMCTRL_CTRLA_CMD_ER_Val 0x2u /**< \brief (NVMCTRL_CTRLA) Erase Row - Erases the row addressed by the ADDR register. */ +#define NVMCTRL_CTRLA_CMD_WP_Val 0x4u /**< \brief (NVMCTRL_CTRLA) Write Page - Writes the contents of the page buffer to the page addressed by the ADDR register. */ +#define NVMCTRL_CTRLA_CMD_EAR_Val 0x5u /**< \brief (NVMCTRL_CTRLA) Erase Auxiliary Row - Erases the auxiliary row addressed by the ADDR register. This command can be given only when the security bit is not set and only to the user configuration row. */ +#define NVMCTRL_CTRLA_CMD_WAP_Val 0x6u /**< \brief (NVMCTRL_CTRLA) Write Auxiliary Page - Writes the contents of the page buffer to the page addressed by the ADDR register. This command can be given only when the security bit is not set and only to the user configuration row. */ +#define NVMCTRL_CTRLA_CMD_SF_Val 0xAu /**< \brief (NVMCTRL_CTRLA) Security Flow Command */ +#define NVMCTRL_CTRLA_CMD_WL_Val 0xFu /**< \brief (NVMCTRL_CTRLA) Write lockbits */ +#define NVMCTRL_CTRLA_CMD_LR_Val 0x40u /**< \brief (NVMCTRL_CTRLA) Lock Region - Locks the region containing the address location in the ADDR register. */ +#define NVMCTRL_CTRLA_CMD_UR_Val 0x41u /**< \brief (NVMCTRL_CTRLA) Unlock Region - Unlocks the region containing the address location in the ADDR register. */ +#define NVMCTRL_CTRLA_CMD_SPRM_Val 0x42u /**< \brief (NVMCTRL_CTRLA) Sets the power reduction mode. */ +#define NVMCTRL_CTRLA_CMD_CPRM_Val 0x43u /**< \brief (NVMCTRL_CTRLA) Clears the power reduction mode. */ +#define NVMCTRL_CTRLA_CMD_PBC_Val 0x44u /**< \brief (NVMCTRL_CTRLA) Page Buffer Clear - Clears the page buffer. */ +#define NVMCTRL_CTRLA_CMD_SSB_Val 0x45u /**< \brief (NVMCTRL_CTRLA) Set Security Bit - Sets the security bit by writing 0x00 to the first byte in the lockbit row. */ +#define NVMCTRL_CTRLA_CMD_INVALL_Val 0x46u /**< \brief (NVMCTRL_CTRLA) Invalidate all cache lines. */ +#define NVMCTRL_CTRLA_CMD_ER (NVMCTRL_CTRLA_CMD_ER_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_WP (NVMCTRL_CTRLA_CMD_WP_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_EAR (NVMCTRL_CTRLA_CMD_EAR_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_WAP (NVMCTRL_CTRLA_CMD_WAP_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_SF (NVMCTRL_CTRLA_CMD_SF_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_WL (NVMCTRL_CTRLA_CMD_WL_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_LR (NVMCTRL_CTRLA_CMD_LR_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_UR (NVMCTRL_CTRLA_CMD_UR_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_SPRM (NVMCTRL_CTRLA_CMD_SPRM_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_CPRM (NVMCTRL_CTRLA_CMD_CPRM_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_PBC (NVMCTRL_CTRLA_CMD_PBC_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_SSB (NVMCTRL_CTRLA_CMD_SSB_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMD_INVALL (NVMCTRL_CTRLA_CMD_INVALL_Val << NVMCTRL_CTRLA_CMD_Pos) +#define NVMCTRL_CTRLA_CMDEX_Pos 8 /**< \brief (NVMCTRL_CTRLA) Command Execution */ +#define NVMCTRL_CTRLA_CMDEX_Msk (0xFFu << NVMCTRL_CTRLA_CMDEX_Pos) +#define NVMCTRL_CTRLA_CMDEX(value) ((NVMCTRL_CTRLA_CMDEX_Msk & ((value) << NVMCTRL_CTRLA_CMDEX_Pos))) +#define NVMCTRL_CTRLA_CMDEX_KEY_Val 0xA5u /**< \brief (NVMCTRL_CTRLA) Execution Key */ +#define NVMCTRL_CTRLA_CMDEX_KEY (NVMCTRL_CTRLA_CMDEX_KEY_Val << NVMCTRL_CTRLA_CMDEX_Pos) +#define NVMCTRL_CTRLA_MASK 0xFF7Fu /**< \brief (NVMCTRL_CTRLA) MASK Register */ + +/* -------- NVMCTRL_CTRLB : (NVMCTRL Offset: 0x04) (R/W 32) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t RWS:4; /*!< bit: 1.. 4 NVM Read Wait States */ + uint32_t :2; /*!< bit: 5.. 6 Reserved */ + uint32_t MANW:1; /*!< bit: 7 Manual Write */ + uint32_t SLEEPPRM:2; /*!< bit: 8.. 9 Power Reduction Mode during Sleep */ + uint32_t :6; /*!< bit: 10..15 Reserved */ + uint32_t READMODE:2; /*!< bit: 16..17 NVMCTRL Read Mode */ + uint32_t CACHEDIS:1; /*!< bit: 18 Cache Disable */ + uint32_t :13; /*!< bit: 19..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} NVMCTRL_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_CTRLB_OFFSET 0x04 /**< \brief (NVMCTRL_CTRLB offset) Control B */ +#define NVMCTRL_CTRLB_RESETVALUE 0x00000000 /**< \brief (NVMCTRL_CTRLB reset_value) Control B */ + +#define NVMCTRL_CTRLB_RWS_Pos 1 /**< \brief (NVMCTRL_CTRLB) NVM Read Wait States */ +#define NVMCTRL_CTRLB_RWS_Msk (0xFu << NVMCTRL_CTRLB_RWS_Pos) +#define NVMCTRL_CTRLB_RWS(value) ((NVMCTRL_CTRLB_RWS_Msk & ((value) << NVMCTRL_CTRLB_RWS_Pos))) +#define NVMCTRL_CTRLB_RWS_SINGLE_Val 0x0u /**< \brief (NVMCTRL_CTRLB) Single Auto Wait State */ +#define NVMCTRL_CTRLB_RWS_HALF_Val 0x1u /**< \brief (NVMCTRL_CTRLB) Half Auto Wait State */ +#define NVMCTRL_CTRLB_RWS_DUAL_Val 0x2u /**< \brief (NVMCTRL_CTRLB) Dual Auto Wait State */ +#define NVMCTRL_CTRLB_RWS_SINGLE (NVMCTRL_CTRLB_RWS_SINGLE_Val << NVMCTRL_CTRLB_RWS_Pos) +#define NVMCTRL_CTRLB_RWS_HALF (NVMCTRL_CTRLB_RWS_HALF_Val << NVMCTRL_CTRLB_RWS_Pos) +#define NVMCTRL_CTRLB_RWS_DUAL (NVMCTRL_CTRLB_RWS_DUAL_Val << NVMCTRL_CTRLB_RWS_Pos) +#define NVMCTRL_CTRLB_MANW_Pos 7 /**< \brief (NVMCTRL_CTRLB) Manual Write */ +#define NVMCTRL_CTRLB_MANW (0x1u << NVMCTRL_CTRLB_MANW_Pos) +#define NVMCTRL_CTRLB_SLEEPPRM_Pos 8 /**< \brief (NVMCTRL_CTRLB) Power Reduction Mode during Sleep */ +#define NVMCTRL_CTRLB_SLEEPPRM_Msk (0x3u << NVMCTRL_CTRLB_SLEEPPRM_Pos) +#define NVMCTRL_CTRLB_SLEEPPRM(value) ((NVMCTRL_CTRLB_SLEEPPRM_Msk & ((value) << NVMCTRL_CTRLB_SLEEPPRM_Pos))) +#define NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS_Val 0x0u /**< \brief (NVMCTRL_CTRLB) NVM block enters low-power mode when entering sleep.NVM block exits low-power mode upon first access. */ +#define NVMCTRL_CTRLB_SLEEPPRM_WAKEUPINSTANT_Val 0x1u /**< \brief (NVMCTRL_CTRLB) NVM block enters low-power mode when entering sleep.NVM block exits low-power mode when exiting sleep. */ +#define NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val 0x3u /**< \brief (NVMCTRL_CTRLB) Auto power reduction disabled. */ +#define NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS (NVMCTRL_CTRLB_SLEEPPRM_WAKEONACCESS_Val << NVMCTRL_CTRLB_SLEEPPRM_Pos) +#define NVMCTRL_CTRLB_SLEEPPRM_WAKEUPINSTANT (NVMCTRL_CTRLB_SLEEPPRM_WAKEUPINSTANT_Val << NVMCTRL_CTRLB_SLEEPPRM_Pos) +#define NVMCTRL_CTRLB_SLEEPPRM_DISABLED (NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val << NVMCTRL_CTRLB_SLEEPPRM_Pos) +#define NVMCTRL_CTRLB_READMODE_Pos 16 /**< \brief (NVMCTRL_CTRLB) NVMCTRL Read Mode */ +#define NVMCTRL_CTRLB_READMODE_Msk (0x3u << NVMCTRL_CTRLB_READMODE_Pos) +#define NVMCTRL_CTRLB_READMODE(value) ((NVMCTRL_CTRLB_READMODE_Msk & ((value) << NVMCTRL_CTRLB_READMODE_Pos))) +#define NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY_Val 0x0u /**< \brief (NVMCTRL_CTRLB) The NVM Controller (cache system) does not insert wait states on a cache miss. Gives the best system performance. */ +#define NVMCTRL_CTRLB_READMODE_LOW_POWER_Val 0x1u /**< \brief (NVMCTRL_CTRLB) Reduces power consumption of the cache system, but inserts a wait state each time there is a cache miss. This mode may not be relevant if CPU performance is required, as the application will be stalled and may lead to increase run time. */ +#define NVMCTRL_CTRLB_READMODE_DETERMINISTIC_Val 0x2u /**< \brief (NVMCTRL_CTRLB) The cache system ensures that a cache hit or miss takes the same amount of time, determined by the number of programmed flash wait states. This mode can be used for real-time applications that require deterministic execution timings. */ +#define NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY (NVMCTRL_CTRLB_READMODE_NO_MISS_PENALTY_Val << NVMCTRL_CTRLB_READMODE_Pos) +#define NVMCTRL_CTRLB_READMODE_LOW_POWER (NVMCTRL_CTRLB_READMODE_LOW_POWER_Val << NVMCTRL_CTRLB_READMODE_Pos) +#define NVMCTRL_CTRLB_READMODE_DETERMINISTIC (NVMCTRL_CTRLB_READMODE_DETERMINISTIC_Val << NVMCTRL_CTRLB_READMODE_Pos) +#define NVMCTRL_CTRLB_CACHEDIS_Pos 18 /**< \brief (NVMCTRL_CTRLB) Cache Disable */ +#define NVMCTRL_CTRLB_CACHEDIS (0x1u << NVMCTRL_CTRLB_CACHEDIS_Pos) +#define NVMCTRL_CTRLB_MASK 0x0007039Eu /**< \brief (NVMCTRL_CTRLB) MASK Register */ + +/* -------- NVMCTRL_PARAM : (NVMCTRL Offset: 0x08) (R/W 32) NVM Parameter -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t NVMP:16; /*!< bit: 0..15 NVM Pages */ + uint32_t PSZ:3; /*!< bit: 16..18 Page Size */ + uint32_t :13; /*!< bit: 19..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} NVMCTRL_PARAM_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_PARAM_OFFSET 0x08 /**< \brief (NVMCTRL_PARAM offset) NVM Parameter */ +#define NVMCTRL_PARAM_RESETVALUE 0x00000000 /**< \brief (NVMCTRL_PARAM reset_value) NVM Parameter */ + +#define NVMCTRL_PARAM_NVMP_Pos 0 /**< \brief (NVMCTRL_PARAM) NVM Pages */ +#define NVMCTRL_PARAM_NVMP_Msk (0xFFFFu << NVMCTRL_PARAM_NVMP_Pos) +#define NVMCTRL_PARAM_NVMP(value) ((NVMCTRL_PARAM_NVMP_Msk & ((value) << NVMCTRL_PARAM_NVMP_Pos))) +#define NVMCTRL_PARAM_PSZ_Pos 16 /**< \brief (NVMCTRL_PARAM) Page Size */ +#define NVMCTRL_PARAM_PSZ_Msk (0x7u << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ(value) ((NVMCTRL_PARAM_PSZ_Msk & ((value) << NVMCTRL_PARAM_PSZ_Pos))) +#define NVMCTRL_PARAM_PSZ_8_Val 0x0u /**< \brief (NVMCTRL_PARAM) 8 bytes */ +#define NVMCTRL_PARAM_PSZ_16_Val 0x1u /**< \brief (NVMCTRL_PARAM) 16 bytes */ +#define NVMCTRL_PARAM_PSZ_32_Val 0x2u /**< \brief (NVMCTRL_PARAM) 32 bytes */ +#define NVMCTRL_PARAM_PSZ_64_Val 0x3u /**< \brief (NVMCTRL_PARAM) 64 bytes */ +#define NVMCTRL_PARAM_PSZ_128_Val 0x4u /**< \brief (NVMCTRL_PARAM) 128 bytes */ +#define NVMCTRL_PARAM_PSZ_256_Val 0x5u /**< \brief (NVMCTRL_PARAM) 256 bytes */ +#define NVMCTRL_PARAM_PSZ_512_Val 0x6u /**< \brief (NVMCTRL_PARAM) 512 bytes */ +#define NVMCTRL_PARAM_PSZ_1024_Val 0x7u /**< \brief (NVMCTRL_PARAM) 1024 bytes */ +#define NVMCTRL_PARAM_PSZ_8 (NVMCTRL_PARAM_PSZ_8_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_16 (NVMCTRL_PARAM_PSZ_16_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_32 (NVMCTRL_PARAM_PSZ_32_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_64 (NVMCTRL_PARAM_PSZ_64_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_128 (NVMCTRL_PARAM_PSZ_128_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_256 (NVMCTRL_PARAM_PSZ_256_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_512 (NVMCTRL_PARAM_PSZ_512_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_PSZ_1024 (NVMCTRL_PARAM_PSZ_1024_Val << NVMCTRL_PARAM_PSZ_Pos) +#define NVMCTRL_PARAM_MASK 0x0007FFFFu /**< \brief (NVMCTRL_PARAM) MASK Register */ + +/* -------- NVMCTRL_INTENCLR : (NVMCTRL Offset: 0x0C) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t READY:1; /*!< bit: 0 NVM Ready Interrupt Enable */ + uint8_t ERROR:1; /*!< bit: 1 Error Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} NVMCTRL_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_INTENCLR_OFFSET 0x0C /**< \brief (NVMCTRL_INTENCLR offset) Interrupt Enable Clear */ +#define NVMCTRL_INTENCLR_RESETVALUE 0x00 /**< \brief (NVMCTRL_INTENCLR reset_value) Interrupt Enable Clear */ + +#define NVMCTRL_INTENCLR_READY_Pos 0 /**< \brief (NVMCTRL_INTENCLR) NVM Ready Interrupt Enable */ +#define NVMCTRL_INTENCLR_READY (0x1u << NVMCTRL_INTENCLR_READY_Pos) +#define NVMCTRL_INTENCLR_ERROR_Pos 1 /**< \brief (NVMCTRL_INTENCLR) Error Interrupt Enable */ +#define NVMCTRL_INTENCLR_ERROR (0x1u << NVMCTRL_INTENCLR_ERROR_Pos) +#define NVMCTRL_INTENCLR_MASK 0x03u /**< \brief (NVMCTRL_INTENCLR) MASK Register */ + +/* -------- NVMCTRL_INTENSET : (NVMCTRL Offset: 0x10) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t READY:1; /*!< bit: 0 NVM Ready Interrupt Enable */ + uint8_t ERROR:1; /*!< bit: 1 Error Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} NVMCTRL_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_INTENSET_OFFSET 0x10 /**< \brief (NVMCTRL_INTENSET offset) Interrupt Enable Set */ +#define NVMCTRL_INTENSET_RESETVALUE 0x00 /**< \brief (NVMCTRL_INTENSET reset_value) Interrupt Enable Set */ + +#define NVMCTRL_INTENSET_READY_Pos 0 /**< \brief (NVMCTRL_INTENSET) NVM Ready Interrupt Enable */ +#define NVMCTRL_INTENSET_READY (0x1u << NVMCTRL_INTENSET_READY_Pos) +#define NVMCTRL_INTENSET_ERROR_Pos 1 /**< \brief (NVMCTRL_INTENSET) Error Interrupt Enable */ +#define NVMCTRL_INTENSET_ERROR (0x1u << NVMCTRL_INTENSET_ERROR_Pos) +#define NVMCTRL_INTENSET_MASK 0x03u /**< \brief (NVMCTRL_INTENSET) MASK Register */ + +/* -------- NVMCTRL_INTFLAG : (NVMCTRL Offset: 0x14) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t READY:1; /*!< bit: 0 NVM Ready */ + uint8_t ERROR:1; /*!< bit: 1 Error */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} NVMCTRL_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_INTFLAG_OFFSET 0x14 /**< \brief (NVMCTRL_INTFLAG offset) Interrupt Flag Status and Clear */ +#define NVMCTRL_INTFLAG_RESETVALUE 0x00 /**< \brief (NVMCTRL_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define NVMCTRL_INTFLAG_READY_Pos 0 /**< \brief (NVMCTRL_INTFLAG) NVM Ready */ +#define NVMCTRL_INTFLAG_READY (0x1u << NVMCTRL_INTFLAG_READY_Pos) +#define NVMCTRL_INTFLAG_ERROR_Pos 1 /**< \brief (NVMCTRL_INTFLAG) Error */ +#define NVMCTRL_INTFLAG_ERROR (0x1u << NVMCTRL_INTFLAG_ERROR_Pos) +#define NVMCTRL_INTFLAG_MASK 0x03u /**< \brief (NVMCTRL_INTFLAG) MASK Register */ + +/* -------- NVMCTRL_STATUS : (NVMCTRL Offset: 0x18) (R/W 16) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PRM:1; /*!< bit: 0 Power Reduction Mode */ + uint16_t LOAD:1; /*!< bit: 1 NVM Page Buffer Active Loading */ + uint16_t PROGE:1; /*!< bit: 2 Programming Error Status */ + uint16_t LOCKE:1; /*!< bit: 3 Lock Error Status */ + uint16_t NVME:1; /*!< bit: 4 NVM Error */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t SB:1; /*!< bit: 8 Security Bit Status */ + uint16_t :7; /*!< bit: 9..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} NVMCTRL_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_STATUS_OFFSET 0x18 /**< \brief (NVMCTRL_STATUS offset) Status */ +#define NVMCTRL_STATUS_RESETVALUE 0x0000 /**< \brief (NVMCTRL_STATUS reset_value) Status */ + +#define NVMCTRL_STATUS_PRM_Pos 0 /**< \brief (NVMCTRL_STATUS) Power Reduction Mode */ +#define NVMCTRL_STATUS_PRM (0x1u << NVMCTRL_STATUS_PRM_Pos) +#define NVMCTRL_STATUS_LOAD_Pos 1 /**< \brief (NVMCTRL_STATUS) NVM Page Buffer Active Loading */ +#define NVMCTRL_STATUS_LOAD (0x1u << NVMCTRL_STATUS_LOAD_Pos) +#define NVMCTRL_STATUS_PROGE_Pos 2 /**< \brief (NVMCTRL_STATUS) Programming Error Status */ +#define NVMCTRL_STATUS_PROGE (0x1u << NVMCTRL_STATUS_PROGE_Pos) +#define NVMCTRL_STATUS_LOCKE_Pos 3 /**< \brief (NVMCTRL_STATUS) Lock Error Status */ +#define NVMCTRL_STATUS_LOCKE (0x1u << NVMCTRL_STATUS_LOCKE_Pos) +#define NVMCTRL_STATUS_NVME_Pos 4 /**< \brief (NVMCTRL_STATUS) NVM Error */ +#define NVMCTRL_STATUS_NVME (0x1u << NVMCTRL_STATUS_NVME_Pos) +#define NVMCTRL_STATUS_SB_Pos 8 /**< \brief (NVMCTRL_STATUS) Security Bit Status */ +#define NVMCTRL_STATUS_SB (0x1u << NVMCTRL_STATUS_SB_Pos) +#define NVMCTRL_STATUS_MASK 0x011Fu /**< \brief (NVMCTRL_STATUS) MASK Register */ + +/* -------- NVMCTRL_ADDR : (NVMCTRL Offset: 0x1C) (R/W 32) Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ADDR:22; /*!< bit: 0..21 NVM Address */ + uint32_t :10; /*!< bit: 22..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} NVMCTRL_ADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_ADDR_OFFSET 0x1C /**< \brief (NVMCTRL_ADDR offset) Address */ +#define NVMCTRL_ADDR_RESETVALUE 0x00000000 /**< \brief (NVMCTRL_ADDR reset_value) Address */ + +#define NVMCTRL_ADDR_ADDR_Pos 0 /**< \brief (NVMCTRL_ADDR) NVM Address */ +#define NVMCTRL_ADDR_ADDR_Msk (0x3FFFFFu << NVMCTRL_ADDR_ADDR_Pos) +#define NVMCTRL_ADDR_ADDR(value) ((NVMCTRL_ADDR_ADDR_Msk & ((value) << NVMCTRL_ADDR_ADDR_Pos))) +#define NVMCTRL_ADDR_MASK 0x003FFFFFu /**< \brief (NVMCTRL_ADDR) MASK Register */ + +/* -------- NVMCTRL_LOCK : (NVMCTRL Offset: 0x20) (R/W 16) Lock Section -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t LOCK:16; /*!< bit: 0..15 Region Lock Bits */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} NVMCTRL_LOCK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define NVMCTRL_LOCK_OFFSET 0x20 /**< \brief (NVMCTRL_LOCK offset) Lock Section */ +#define NVMCTRL_LOCK_RESETVALUE 0x0000 /**< \brief (NVMCTRL_LOCK reset_value) Lock Section */ + +#define NVMCTRL_LOCK_LOCK_Pos 0 /**< \brief (NVMCTRL_LOCK) Region Lock Bits */ +#define NVMCTRL_LOCK_LOCK_Msk (0xFFFFu << NVMCTRL_LOCK_LOCK_Pos) +#define NVMCTRL_LOCK_LOCK(value) ((NVMCTRL_LOCK_LOCK_Msk & ((value) << NVMCTRL_LOCK_LOCK_Pos))) +#define NVMCTRL_LOCK_MASK 0xFFFFu /**< \brief (NVMCTRL_LOCK) MASK Register */ + +/** \brief NVMCTRL APB hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO NVMCTRL_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 16) Control A */ + RoReg8 Reserved1[0x2]; + __IO NVMCTRL_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) Control B */ + __IO NVMCTRL_PARAM_Type PARAM; /**< \brief Offset: 0x08 (R/W 32) NVM Parameter */ + __IO NVMCTRL_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) Interrupt Enable Clear */ + RoReg8 Reserved2[0x3]; + __IO NVMCTRL_INTENSET_Type INTENSET; /**< \brief Offset: 0x10 (R/W 8) Interrupt Enable Set */ + RoReg8 Reserved3[0x3]; + __IO NVMCTRL_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x14 (R/W 8) Interrupt Flag Status and Clear */ + RoReg8 Reserved4[0x3]; + __IO NVMCTRL_STATUS_Type STATUS; /**< \brief Offset: 0x18 (R/W 16) Status */ + RoReg8 Reserved5[0x2]; + __IO NVMCTRL_ADDR_Type ADDR; /**< \brief Offset: 0x1C (R/W 32) Address */ + __IO NVMCTRL_LOCK_Type LOCK; /**< \brief Offset: 0x20 (R/W 16) Lock Section */ +} Nvmctrl; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +#define SECTION_NVMCTRL_CAL +#define SECTION_NVMCTRL_LOCKBIT +#define SECTION_NVMCTRL_OTP1 +#define SECTION_NVMCTRL_OTP2 +#define SECTION_NVMCTRL_OTP4 +#define SECTION_NVMCTRL_TEMP_LOG +#define SECTION_NVMCTRL_USER + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR NON-VOLATILE FUSES */ +/* ************************************************************************** */ +/** \addtogroup fuses_api Peripheral Software API */ +/*@{*/ + + +#define ADC_FUSES_BIASCAL_ADDR (NVMCTRL_OTP4 + 4) +#define ADC_FUSES_BIASCAL_Pos 3 /**< \brief (NVMCTRL_OTP4) ADC Bias Calibration */ +#define ADC_FUSES_BIASCAL_Msk (0x7u << ADC_FUSES_BIASCAL_Pos) +#define ADC_FUSES_BIASCAL(value) ((ADC_FUSES_BIASCAL_Msk & ((value) << ADC_FUSES_BIASCAL_Pos))) + +#define ADC_FUSES_LINEARITY_0_ADDR NVMCTRL_OTP4 +#define ADC_FUSES_LINEARITY_0_Pos 27 /**< \brief (NVMCTRL_OTP4) ADC Linearity bits 4:0 */ +#define ADC_FUSES_LINEARITY_0_Msk (0x1Fu << ADC_FUSES_LINEARITY_0_Pos) +#define ADC_FUSES_LINEARITY_0(value) ((ADC_FUSES_LINEARITY_0_Msk & ((value) << ADC_FUSES_LINEARITY_0_Pos))) + +#define ADC_FUSES_LINEARITY_1_ADDR (NVMCTRL_OTP4 + 4) +#define ADC_FUSES_LINEARITY_1_Pos 0 /**< \brief (NVMCTRL_OTP4) ADC Linearity bits 7:5 */ +#define ADC_FUSES_LINEARITY_1_Msk (0x7u << ADC_FUSES_LINEARITY_1_Pos) +#define ADC_FUSES_LINEARITY_1(value) ((ADC_FUSES_LINEARITY_1_Msk & ((value) << ADC_FUSES_LINEARITY_1_Pos))) + +#define NVMCTRL_FUSES_BOOTPROT_ADDR NVMCTRL_USER +#define NVMCTRL_FUSES_BOOTPROT_Pos 0 /**< \brief (NVMCTRL_USER) Bootloader Size */ +#define NVMCTRL_FUSES_BOOTPROT_Msk (0x7u << NVMCTRL_FUSES_BOOTPROT_Pos) +#define NVMCTRL_FUSES_BOOTPROT(value) ((NVMCTRL_FUSES_BOOTPROT_Msk & ((value) << NVMCTRL_FUSES_BOOTPROT_Pos))) + +#define NVMCTRL_FUSES_EEPROM_SIZE_ADDR NVMCTRL_USER +#define NVMCTRL_FUSES_EEPROM_SIZE_Pos 4 /**< \brief (NVMCTRL_USER) EEPROM Size */ +#define NVMCTRL_FUSES_EEPROM_SIZE_Msk (0x7u << NVMCTRL_FUSES_EEPROM_SIZE_Pos) +#define NVMCTRL_FUSES_EEPROM_SIZE(value) ((NVMCTRL_FUSES_EEPROM_SIZE_Msk & ((value) << NVMCTRL_FUSES_EEPROM_SIZE_Pos))) + +#define NVMCTRL_FUSES_HOT_ADC_VAL_ADDR (NVMCTRL_TEMP_LOG + 4) +#define NVMCTRL_FUSES_HOT_ADC_VAL_Pos 20 /**< \brief (NVMCTRL_TEMP_LOG) 12-bit ADC conversion at hot temperature */ +#define NVMCTRL_FUSES_HOT_ADC_VAL_Msk (0xFFFu << NVMCTRL_FUSES_HOT_ADC_VAL_Pos) +#define NVMCTRL_FUSES_HOT_ADC_VAL(value) ((NVMCTRL_FUSES_HOT_ADC_VAL_Msk & ((value) << NVMCTRL_FUSES_HOT_ADC_VAL_Pos))) + +#define NVMCTRL_FUSES_HOT_INT1V_VAL_ADDR (NVMCTRL_TEMP_LOG + 4) +#define NVMCTRL_FUSES_HOT_INT1V_VAL_Pos 0 /**< \brief (NVMCTRL_TEMP_LOG) 2's complement of the internal 1V reference drift at hot temperature (versus a 1.0 centered value) */ +#define NVMCTRL_FUSES_HOT_INT1V_VAL_Msk (0xFFu << NVMCTRL_FUSES_HOT_INT1V_VAL_Pos) +#define NVMCTRL_FUSES_HOT_INT1V_VAL(value) ((NVMCTRL_FUSES_HOT_INT1V_VAL_Msk & ((value) << NVMCTRL_FUSES_HOT_INT1V_VAL_Pos))) + +#define NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_ADDR NVMCTRL_TEMP_LOG +#define NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_Pos 20 /**< \brief (NVMCTRL_TEMP_LOG) Decimal part of hot temperature */ +#define NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_Msk (0xFu << NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_Pos) +#define NVMCTRL_FUSES_HOT_TEMP_VAL_DEC(value) ((NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_Msk & ((value) << NVMCTRL_FUSES_HOT_TEMP_VAL_DEC_Pos))) + +#define NVMCTRL_FUSES_HOT_TEMP_VAL_INT_ADDR NVMCTRL_TEMP_LOG +#define NVMCTRL_FUSES_HOT_TEMP_VAL_INT_Pos 12 /**< \brief (NVMCTRL_TEMP_LOG) Integer part of hot temperature in oC */ +#define NVMCTRL_FUSES_HOT_TEMP_VAL_INT_Msk (0xFFu << NVMCTRL_FUSES_HOT_TEMP_VAL_INT_Pos) +#define NVMCTRL_FUSES_HOT_TEMP_VAL_INT(value) ((NVMCTRL_FUSES_HOT_TEMP_VAL_INT_Msk & ((value) << NVMCTRL_FUSES_HOT_TEMP_VAL_INT_Pos))) + +#define NVMCTRL_FUSES_NVMP_ADDR NVMCTRL_OTP1 +#define NVMCTRL_FUSES_NVMP_Pos 16 /**< \brief (NVMCTRL_OTP1) Number of NVM Pages */ +#define NVMCTRL_FUSES_NVMP_Msk (0xFFFFu << NVMCTRL_FUSES_NVMP_Pos) +#define NVMCTRL_FUSES_NVMP(value) ((NVMCTRL_FUSES_NVMP_Msk & ((value) << NVMCTRL_FUSES_NVMP_Pos))) + +#define NVMCTRL_FUSES_NVM_LOCK_ADDR NVMCTRL_OTP1 +#define NVMCTRL_FUSES_NVM_LOCK_Pos 0 /**< \brief (NVMCTRL_OTP1) NVM Lock */ +#define NVMCTRL_FUSES_NVM_LOCK_Msk (0xFFu << NVMCTRL_FUSES_NVM_LOCK_Pos) +#define NVMCTRL_FUSES_NVM_LOCK(value) ((NVMCTRL_FUSES_NVM_LOCK_Msk & ((value) << NVMCTRL_FUSES_NVM_LOCK_Pos))) + +#define NVMCTRL_FUSES_PSZ_ADDR NVMCTRL_OTP1 +#define NVMCTRL_FUSES_PSZ_Pos 8 /**< \brief (NVMCTRL_OTP1) NVM Page Size */ +#define NVMCTRL_FUSES_PSZ_Msk (0xFu << NVMCTRL_FUSES_PSZ_Pos) +#define NVMCTRL_FUSES_PSZ(value) ((NVMCTRL_FUSES_PSZ_Msk & ((value) << NVMCTRL_FUSES_PSZ_Pos))) + +#define NVMCTRL_FUSES_REGION_LOCKS_ADDR (NVMCTRL_USER + 4) +#define NVMCTRL_FUSES_REGION_LOCKS_Pos 16 /**< \brief (NVMCTRL_USER) NVM Region Locks */ +#define NVMCTRL_FUSES_REGION_LOCKS_Msk (0xFFFFu << NVMCTRL_FUSES_REGION_LOCKS_Pos) +#define NVMCTRL_FUSES_REGION_LOCKS(value) ((NVMCTRL_FUSES_REGION_LOCKS_Msk & ((value) << NVMCTRL_FUSES_REGION_LOCKS_Pos))) + +#define NVMCTRL_FUSES_ROOM_ADC_VAL_ADDR (NVMCTRL_TEMP_LOG + 4) +#define NVMCTRL_FUSES_ROOM_ADC_VAL_Pos 8 /**< \brief (NVMCTRL_TEMP_LOG) 12-bit ADC conversion at room temperature */ +#define NVMCTRL_FUSES_ROOM_ADC_VAL_Msk (0xFFFu << NVMCTRL_FUSES_ROOM_ADC_VAL_Pos) +#define NVMCTRL_FUSES_ROOM_ADC_VAL(value) ((NVMCTRL_FUSES_ROOM_ADC_VAL_Msk & ((value) << NVMCTRL_FUSES_ROOM_ADC_VAL_Pos))) + +#define NVMCTRL_FUSES_ROOM_INT1V_VAL_ADDR NVMCTRL_TEMP_LOG +#define NVMCTRL_FUSES_ROOM_INT1V_VAL_Pos 24 /**< \brief (NVMCTRL_TEMP_LOG) 2's complement of the internal 1V reference drift at room temperature (versus a 1.0 centered value) */ +#define NVMCTRL_FUSES_ROOM_INT1V_VAL_Msk (0xFFu << NVMCTRL_FUSES_ROOM_INT1V_VAL_Pos) +#define NVMCTRL_FUSES_ROOM_INT1V_VAL(value) ((NVMCTRL_FUSES_ROOM_INT1V_VAL_Msk & ((value) << NVMCTRL_FUSES_ROOM_INT1V_VAL_Pos))) + +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_ADDR NVMCTRL_TEMP_LOG +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_Pos 8 /**< \brief (NVMCTRL_TEMP_LOG) Decimal part of room temperature */ +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_Msk (0xFu << NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_Pos) +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC(value) ((NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_Msk & ((value) << NVMCTRL_FUSES_ROOM_TEMP_VAL_DEC_Pos))) + +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_ADDR NVMCTRL_TEMP_LOG +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_Pos 0 /**< \brief (NVMCTRL_TEMP_LOG) Integer part of room temperature in oC */ +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_Msk (0xFFu << NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_Pos) +#define NVMCTRL_FUSES_ROOM_TEMP_VAL_INT(value) ((NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_Msk & ((value) << NVMCTRL_FUSES_ROOM_TEMP_VAL_INT_Pos))) + +#define SYSCTRL_FUSES_BOD33USERLEVEL_ADDR NVMCTRL_USER +#define SYSCTRL_FUSES_BOD33USERLEVEL_Pos 8 /**< \brief (NVMCTRL_USER) BOD33 User Level */ +#define SYSCTRL_FUSES_BOD33USERLEVEL_Msk (0x3Fu << SYSCTRL_FUSES_BOD33USERLEVEL_Pos) +#define SYSCTRL_FUSES_BOD33USERLEVEL(value) ((SYSCTRL_FUSES_BOD33USERLEVEL_Msk & ((value) << SYSCTRL_FUSES_BOD33USERLEVEL_Pos))) + +#define SYSCTRL_FUSES_BOD33_ACTION_ADDR NVMCTRL_USER +#define SYSCTRL_FUSES_BOD33_ACTION_Pos 15 /**< \brief (NVMCTRL_USER) BOD33 Action */ +#define SYSCTRL_FUSES_BOD33_ACTION_Msk (0x3u << SYSCTRL_FUSES_BOD33_ACTION_Pos) +#define SYSCTRL_FUSES_BOD33_ACTION(value) ((SYSCTRL_FUSES_BOD33_ACTION_Msk & ((value) << SYSCTRL_FUSES_BOD33_ACTION_Pos))) + +#define SYSCTRL_FUSES_BOD33_EN_ADDR NVMCTRL_USER +#define SYSCTRL_FUSES_BOD33_EN_Pos 14 /**< \brief (NVMCTRL_USER) BOD33 Enable */ +#define SYSCTRL_FUSES_BOD33_EN_Msk (0x1u << SYSCTRL_FUSES_BOD33_EN_Pos) + +#define SYSCTRL_FUSES_BOD33_HYST_ADDR (NVMCTRL_USER + 4) +#define SYSCTRL_FUSES_BOD33_HYST_Pos 8 /**< \brief (NVMCTRL_USER) BOD33 Hysteresis */ +#define SYSCTRL_FUSES_BOD33_HYST_Msk (0x1u << SYSCTRL_FUSES_BOD33_HYST_Pos) + +#define SYSCTRL_FUSES_DFLL48M_COARSE_CAL_ADDR (NVMCTRL_OTP4 + 4) +#define SYSCTRL_FUSES_DFLL48M_COARSE_CAL_Pos 26 /**< \brief (NVMCTRL_OTP4) DFLL48M Coarse Calibration */ +#define SYSCTRL_FUSES_DFLL48M_COARSE_CAL_Msk (0x3Fu << SYSCTRL_FUSES_DFLL48M_COARSE_CAL_Pos) +#define SYSCTRL_FUSES_DFLL48M_COARSE_CAL(value) ((SYSCTRL_FUSES_DFLL48M_COARSE_CAL_Msk & ((value) << SYSCTRL_FUSES_DFLL48M_COARSE_CAL_Pos))) + +#define SYSCTRL_FUSES_DFLL48M_FINE_CAL_ADDR (NVMCTRL_OTP4 + 8) +#define SYSCTRL_FUSES_DFLL48M_FINE_CAL_Pos 0 /**< \brief (NVMCTRL_OTP4) DFLL48M Fine Calibration */ +#define SYSCTRL_FUSES_DFLL48M_FINE_CAL_Msk (0x3FFu << SYSCTRL_FUSES_DFLL48M_FINE_CAL_Pos) +#define SYSCTRL_FUSES_DFLL48M_FINE_CAL(value) ((SYSCTRL_FUSES_DFLL48M_FINE_CAL_Msk & ((value) << SYSCTRL_FUSES_DFLL48M_FINE_CAL_Pos))) + +#define SYSCTRL_FUSES_OSC32KCAL_ADDR (NVMCTRL_OTP4 + 4) +#define SYSCTRL_FUSES_OSC32KCAL_Pos 6 /**< \brief (NVMCTRL_OTP4) OSC32K Calibration */ +#define SYSCTRL_FUSES_OSC32KCAL_Msk (0x7Fu << SYSCTRL_FUSES_OSC32KCAL_Pos) +#define SYSCTRL_FUSES_OSC32KCAL(value) ((SYSCTRL_FUSES_OSC32KCAL_Msk & ((value) << SYSCTRL_FUSES_OSC32KCAL_Pos))) + +#define WDT_FUSES_ALWAYSON_ADDR NVMCTRL_USER +#define WDT_FUSES_ALWAYSON_Pos 26 /**< \brief (NVMCTRL_USER) WDT Always On */ +#define WDT_FUSES_ALWAYSON_Msk (0x1u << WDT_FUSES_ALWAYSON_Pos) + +#define WDT_FUSES_ENABLE_ADDR NVMCTRL_USER +#define WDT_FUSES_ENABLE_Pos 25 /**< \brief (NVMCTRL_USER) WDT Enable */ +#define WDT_FUSES_ENABLE_Msk (0x1u << WDT_FUSES_ENABLE_Pos) + +#define WDT_FUSES_EWOFFSET_ADDR (NVMCTRL_USER + 4) +#define WDT_FUSES_EWOFFSET_Pos 3 /**< \brief (NVMCTRL_USER) WDT Early Warning Offset */ +#define WDT_FUSES_EWOFFSET_Msk (0xFu << WDT_FUSES_EWOFFSET_Pos) +#define WDT_FUSES_EWOFFSET(value) ((WDT_FUSES_EWOFFSET_Msk & ((value) << WDT_FUSES_EWOFFSET_Pos))) + +#define WDT_FUSES_PER_ADDR NVMCTRL_USER +#define WDT_FUSES_PER_Pos 27 /**< \brief (NVMCTRL_USER) WDT Period */ +#define WDT_FUSES_PER_Msk (0xFu << WDT_FUSES_PER_Pos) +#define WDT_FUSES_PER(value) ((WDT_FUSES_PER_Msk & ((value) << WDT_FUSES_PER_Pos))) + +#define WDT_FUSES_WEN_ADDR (NVMCTRL_USER + 4) +#define WDT_FUSES_WEN_Pos 7 /**< \brief (NVMCTRL_USER) WDT Window Mode Enable */ +#define WDT_FUSES_WEN_Msk (0x1u << WDT_FUSES_WEN_Pos) + +#define WDT_FUSES_WINDOW_0_ADDR NVMCTRL_USER +#define WDT_FUSES_WINDOW_0_Pos 31 /**< \brief (NVMCTRL_USER) WDT Window bit 0 */ +#define WDT_FUSES_WINDOW_0_Msk (0x1u << WDT_FUSES_WINDOW_0_Pos) + +#define WDT_FUSES_WINDOW_1_ADDR (NVMCTRL_USER + 4) +#define WDT_FUSES_WINDOW_1_Pos 0 /**< \brief (NVMCTRL_USER) WDT Window bits 3:1 */ +#define WDT_FUSES_WINDOW_1_Msk (0x7u << WDT_FUSES_WINDOW_1_Pos) +#define WDT_FUSES_WINDOW_1(value) ((WDT_FUSES_WINDOW_1_Msk & ((value) << WDT_FUSES_WINDOW_1_Pos))) + +/*@}*/ + +#endif /* _SAMD20_NVMCTRL_COMPONENT_ */ diff --git a/loader/samd20/component/pac.h b/loader/samd20/component/pac.h new file mode 100644 index 0000000..957fb9c --- /dev/null +++ b/loader/samd20/component/pac.h @@ -0,0 +1,104 @@ +/** + * \file + * + * \brief Component description for PAC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_PAC_COMPONENT_ +#define _SAMD20_PAC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR PAC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_PAC Peripheral Access Controller */ +/*@{*/ + +#define PAC_U2211 +#define REV_PAC 0x101 + +/* -------- PAC_WPCLR : (PAC Offset: 0x0) (R/W 32) Write Protection Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t WP:31; /*!< bit: 1..31 Write Protection Clear */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PAC_WPCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PAC_WPCLR_OFFSET 0x0 /**< \brief (PAC_WPCLR offset) Write Protection Clear */ +#define PAC_WPCLR_RESETVALUE 0x00000000 /**< \brief (PAC_WPCLR reset_value) Write Protection Clear */ + +#define PAC_WPCLR_WP_Pos 1 /**< \brief (PAC_WPCLR) Write Protection Clear */ +#define PAC_WPCLR_WP_Msk (0x7FFFFFFFu << PAC_WPCLR_WP_Pos) +#define PAC_WPCLR_WP(value) ((PAC_WPCLR_WP_Msk & ((value) << PAC_WPCLR_WP_Pos))) +#define PAC_WPCLR_MASK 0xFFFFFFFEu /**< \brief (PAC_WPCLR) MASK Register */ + +/* -------- PAC_WPSET : (PAC Offset: 0x4) (R/W 32) Write Protection Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t WP:31; /*!< bit: 1..31 Write Protection Set */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PAC_WPSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PAC_WPSET_OFFSET 0x4 /**< \brief (PAC_WPSET offset) Write Protection Set */ +#define PAC_WPSET_RESETVALUE 0x00000000 /**< \brief (PAC_WPSET reset_value) Write Protection Set */ + +#define PAC_WPSET_WP_Pos 1 /**< \brief (PAC_WPSET) Write Protection Set */ +#define PAC_WPSET_WP_Msk (0x7FFFFFFFu << PAC_WPSET_WP_Pos) +#define PAC_WPSET_WP(value) ((PAC_WPSET_WP_Msk & ((value) << PAC_WPSET_WP_Pos))) +#define PAC_WPSET_MASK 0xFFFFFFFEu /**< \brief (PAC_WPSET) MASK Register */ + +/** \brief PAC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO PAC_WPCLR_Type WPCLR; /**< \brief Offset: 0x0 (R/W 32) Write Protection Clear */ + __IO PAC_WPSET_Type WPSET; /**< \brief Offset: 0x4 (R/W 32) Write Protection Set */ +} Pac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_PAC_COMPONENT_ */ diff --git a/loader/samd20/component/pm.h b/loader/samd20/component/pm.h new file mode 100644 index 0000000..58e8a27 --- /dev/null +++ b/loader/samd20/component/pm.h @@ -0,0 +1,515 @@ +/** + * \file + * + * \brief Component description for PM + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_PM_COMPONENT_ +#define _SAMD20_PM_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR PM */ +/* ========================================================================== */ +/** \addtogroup SAMD20_PM Power Manager */ +/*@{*/ + +#define PM_U2206 +#define REV_PM 0x201 + +/* -------- PM_CTRL : (PM Offset: 0x00) (R/W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + uint8_t reg; /*!< Type used for register access */ +} PM_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_CTRL_OFFSET 0x00 /**< \brief (PM_CTRL offset) Control */ +#define PM_CTRL_RESETVALUE 0x00 /**< \brief (PM_CTRL reset_value) Control */ + +#define PM_CTRL_MASK 0x00u /**< \brief (PM_CTRL) MASK Register */ + +/* -------- PM_SLEEP : (PM Offset: 0x01) (R/W 8) Sleep Mode -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t IDLE:2; /*!< bit: 0.. 1 Idle Mode Configuration */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_SLEEP_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_SLEEP_OFFSET 0x01 /**< \brief (PM_SLEEP offset) Sleep Mode */ +#define PM_SLEEP_RESETVALUE 0x00 /**< \brief (PM_SLEEP reset_value) Sleep Mode */ + +#define PM_SLEEP_IDLE_Pos 0 /**< \brief (PM_SLEEP) Idle Mode Configuration */ +#define PM_SLEEP_IDLE_Msk (0x3u << PM_SLEEP_IDLE_Pos) +#define PM_SLEEP_IDLE(value) ((PM_SLEEP_IDLE_Msk & ((value) << PM_SLEEP_IDLE_Pos))) +#define PM_SLEEP_IDLE_CPU_Val 0x0u /**< \brief (PM_SLEEP) The CPU clock domain is stopped */ +#define PM_SLEEP_IDLE_AHB_Val 0x1u /**< \brief (PM_SLEEP) The CPU and AHB clock domains are stopped */ +#define PM_SLEEP_IDLE_APB_Val 0x2u /**< \brief (PM_SLEEP) The CPU, AHB and APB clock domains are stopped */ +#define PM_SLEEP_IDLE_CPU (PM_SLEEP_IDLE_CPU_Val << PM_SLEEP_IDLE_Pos) +#define PM_SLEEP_IDLE_AHB (PM_SLEEP_IDLE_AHB_Val << PM_SLEEP_IDLE_Pos) +#define PM_SLEEP_IDLE_APB (PM_SLEEP_IDLE_APB_Val << PM_SLEEP_IDLE_Pos) +#define PM_SLEEP_MASK 0x03u /**< \brief (PM_SLEEP) MASK Register */ + +/* -------- PM_CPUSEL : (PM Offset: 0x08) (R/W 8) CPU Clock Select -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CPUDIV:3; /*!< bit: 0.. 2 CPU Prescaler Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_CPUSEL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_CPUSEL_OFFSET 0x08 /**< \brief (PM_CPUSEL offset) CPU Clock Select */ +#define PM_CPUSEL_RESETVALUE 0x00 /**< \brief (PM_CPUSEL reset_value) CPU Clock Select */ + +#define PM_CPUSEL_CPUDIV_Pos 0 /**< \brief (PM_CPUSEL) CPU Prescaler Selection */ +#define PM_CPUSEL_CPUDIV_Msk (0x7u << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV(value) ((PM_CPUSEL_CPUDIV_Msk & ((value) << PM_CPUSEL_CPUDIV_Pos))) +#define PM_CPUSEL_CPUDIV_DIV1_Val 0x0u /**< \brief (PM_CPUSEL) Divide by 1 */ +#define PM_CPUSEL_CPUDIV_DIV2_Val 0x1u /**< \brief (PM_CPUSEL) Divide by 2 */ +#define PM_CPUSEL_CPUDIV_DIV4_Val 0x2u /**< \brief (PM_CPUSEL) Divide by 4 */ +#define PM_CPUSEL_CPUDIV_DIV8_Val 0x3u /**< \brief (PM_CPUSEL) Divide by 8 */ +#define PM_CPUSEL_CPUDIV_DIV16_Val 0x4u /**< \brief (PM_CPUSEL) Divide by 16 */ +#define PM_CPUSEL_CPUDIV_DIV32_Val 0x5u /**< \brief (PM_CPUSEL) Divide by 32 */ +#define PM_CPUSEL_CPUDIV_DIV64_Val 0x6u /**< \brief (PM_CPUSEL) Divide by 64 */ +#define PM_CPUSEL_CPUDIV_DIV128_Val 0x7u /**< \brief (PM_CPUSEL) Divide by 128 */ +#define PM_CPUSEL_CPUDIV_DIV1 (PM_CPUSEL_CPUDIV_DIV1_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV2 (PM_CPUSEL_CPUDIV_DIV2_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV4 (PM_CPUSEL_CPUDIV_DIV4_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV8 (PM_CPUSEL_CPUDIV_DIV8_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV16 (PM_CPUSEL_CPUDIV_DIV16_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV32 (PM_CPUSEL_CPUDIV_DIV32_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV64 (PM_CPUSEL_CPUDIV_DIV64_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_CPUDIV_DIV128 (PM_CPUSEL_CPUDIV_DIV128_Val << PM_CPUSEL_CPUDIV_Pos) +#define PM_CPUSEL_MASK 0x07u /**< \brief (PM_CPUSEL) MASK Register */ + +/* -------- PM_APBASEL : (PM Offset: 0x09) (R/W 8) APBA Clock Select -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t APBADIV:3; /*!< bit: 0.. 2 APBA Prescaler Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_APBASEL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBASEL_OFFSET 0x09 /**< \brief (PM_APBASEL offset) APBA Clock Select */ +#define PM_APBASEL_RESETVALUE 0x00 /**< \brief (PM_APBASEL reset_value) APBA Clock Select */ + +#define PM_APBASEL_APBADIV_Pos 0 /**< \brief (PM_APBASEL) APBA Prescaler Selection */ +#define PM_APBASEL_APBADIV_Msk (0x7u << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV(value) ((PM_APBASEL_APBADIV_Msk & ((value) << PM_APBASEL_APBADIV_Pos))) +#define PM_APBASEL_APBADIV_DIV1_Val 0x0u /**< \brief (PM_APBASEL) Divide by 1 */ +#define PM_APBASEL_APBADIV_DIV2_Val 0x1u /**< \brief (PM_APBASEL) Divide by 2 */ +#define PM_APBASEL_APBADIV_DIV4_Val 0x2u /**< \brief (PM_APBASEL) Divide by 4 */ +#define PM_APBASEL_APBADIV_DIV8_Val 0x3u /**< \brief (PM_APBASEL) Divide by 8 */ +#define PM_APBASEL_APBADIV_DIV16_Val 0x4u /**< \brief (PM_APBASEL) Divide by 16 */ +#define PM_APBASEL_APBADIV_DIV32_Val 0x5u /**< \brief (PM_APBASEL) Divide by 32 */ +#define PM_APBASEL_APBADIV_DIV64_Val 0x6u /**< \brief (PM_APBASEL) Divide by 64 */ +#define PM_APBASEL_APBADIV_DIV128_Val 0x7u /**< \brief (PM_APBASEL) Divide by 128 */ +#define PM_APBASEL_APBADIV_DIV1 (PM_APBASEL_APBADIV_DIV1_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV2 (PM_APBASEL_APBADIV_DIV2_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV4 (PM_APBASEL_APBADIV_DIV4_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV8 (PM_APBASEL_APBADIV_DIV8_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV16 (PM_APBASEL_APBADIV_DIV16_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV32 (PM_APBASEL_APBADIV_DIV32_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV64 (PM_APBASEL_APBADIV_DIV64_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_APBADIV_DIV128 (PM_APBASEL_APBADIV_DIV128_Val << PM_APBASEL_APBADIV_Pos) +#define PM_APBASEL_MASK 0x07u /**< \brief (PM_APBASEL) MASK Register */ + +/* -------- PM_APBBSEL : (PM Offset: 0x0A) (R/W 8) APBB Clock Select -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t APBBDIV:3; /*!< bit: 0.. 2 APBB Prescaler Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_APBBSEL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBBSEL_OFFSET 0x0A /**< \brief (PM_APBBSEL offset) APBB Clock Select */ +#define PM_APBBSEL_RESETVALUE 0x00 /**< \brief (PM_APBBSEL reset_value) APBB Clock Select */ + +#define PM_APBBSEL_APBBDIV_Pos 0 /**< \brief (PM_APBBSEL) APBB Prescaler Selection */ +#define PM_APBBSEL_APBBDIV_Msk (0x7u << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV(value) ((PM_APBBSEL_APBBDIV_Msk & ((value) << PM_APBBSEL_APBBDIV_Pos))) +#define PM_APBBSEL_APBBDIV_DIV1_Val 0x0u /**< \brief (PM_APBBSEL) Divide by 1 */ +#define PM_APBBSEL_APBBDIV_DIV2_Val 0x1u /**< \brief (PM_APBBSEL) Divide by 2 */ +#define PM_APBBSEL_APBBDIV_DIV4_Val 0x2u /**< \brief (PM_APBBSEL) Divide by 4 */ +#define PM_APBBSEL_APBBDIV_DIV8_Val 0x3u /**< \brief (PM_APBBSEL) Divide by 8 */ +#define PM_APBBSEL_APBBDIV_DIV16_Val 0x4u /**< \brief (PM_APBBSEL) Divide by 16 */ +#define PM_APBBSEL_APBBDIV_DIV32_Val 0x5u /**< \brief (PM_APBBSEL) Divide by 32 */ +#define PM_APBBSEL_APBBDIV_DIV64_Val 0x6u /**< \brief (PM_APBBSEL) Divide by 64 */ +#define PM_APBBSEL_APBBDIV_DIV128_Val 0x7u /**< \brief (PM_APBBSEL) Divide by 128 */ +#define PM_APBBSEL_APBBDIV_DIV1 (PM_APBBSEL_APBBDIV_DIV1_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV2 (PM_APBBSEL_APBBDIV_DIV2_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV4 (PM_APBBSEL_APBBDIV_DIV4_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV8 (PM_APBBSEL_APBBDIV_DIV8_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV16 (PM_APBBSEL_APBBDIV_DIV16_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV32 (PM_APBBSEL_APBBDIV_DIV32_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV64 (PM_APBBSEL_APBBDIV_DIV64_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_APBBDIV_DIV128 (PM_APBBSEL_APBBDIV_DIV128_Val << PM_APBBSEL_APBBDIV_Pos) +#define PM_APBBSEL_MASK 0x07u /**< \brief (PM_APBBSEL) MASK Register */ + +/* -------- PM_APBCSEL : (PM Offset: 0x0B) (R/W 8) APBC Clock Select -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t APBCDIV:3; /*!< bit: 0.. 2 APBC Prescaler Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_APBCSEL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBCSEL_OFFSET 0x0B /**< \brief (PM_APBCSEL offset) APBC Clock Select */ +#define PM_APBCSEL_RESETVALUE 0x00 /**< \brief (PM_APBCSEL reset_value) APBC Clock Select */ + +#define PM_APBCSEL_APBCDIV_Pos 0 /**< \brief (PM_APBCSEL) APBC Prescaler Selection */ +#define PM_APBCSEL_APBCDIV_Msk (0x7u << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV(value) ((PM_APBCSEL_APBCDIV_Msk & ((value) << PM_APBCSEL_APBCDIV_Pos))) +#define PM_APBCSEL_APBCDIV_DIV1_Val 0x0u /**< \brief (PM_APBCSEL) Divide by 1 */ +#define PM_APBCSEL_APBCDIV_DIV2_Val 0x1u /**< \brief (PM_APBCSEL) Divide by 2 */ +#define PM_APBCSEL_APBCDIV_DIV4_Val 0x2u /**< \brief (PM_APBCSEL) Divide by 4 */ +#define PM_APBCSEL_APBCDIV_DIV8_Val 0x3u /**< \brief (PM_APBCSEL) Divide by 8 */ +#define PM_APBCSEL_APBCDIV_DIV16_Val 0x4u /**< \brief (PM_APBCSEL) Divide by 16 */ +#define PM_APBCSEL_APBCDIV_DIV32_Val 0x5u /**< \brief (PM_APBCSEL) Divide by 32 */ +#define PM_APBCSEL_APBCDIV_DIV64_Val 0x6u /**< \brief (PM_APBCSEL) Divide by 64 */ +#define PM_APBCSEL_APBCDIV_DIV128_Val 0x7u /**< \brief (PM_APBCSEL) Divide by 128 */ +#define PM_APBCSEL_APBCDIV_DIV1 (PM_APBCSEL_APBCDIV_DIV1_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV2 (PM_APBCSEL_APBCDIV_DIV2_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV4 (PM_APBCSEL_APBCDIV_DIV4_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV8 (PM_APBCSEL_APBCDIV_DIV8_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV16 (PM_APBCSEL_APBCDIV_DIV16_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV32 (PM_APBCSEL_APBCDIV_DIV32_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV64 (PM_APBCSEL_APBCDIV_DIV64_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_APBCDIV_DIV128 (PM_APBCSEL_APBCDIV_DIV128_Val << PM_APBCSEL_APBCDIV_Pos) +#define PM_APBCSEL_MASK 0x07u /**< \brief (PM_APBCSEL) MASK Register */ + +/* -------- PM_AHBMASK : (PM Offset: 0x14) (R/W 32) AHB Mask -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t HPB0:1; /*!< bit: 0 HPB0 AHB Clock Mask */ + uint32_t HPB1:1; /*!< bit: 1 HPB1 AHB Clock Mask */ + uint32_t HPB2:1; /*!< bit: 2 HPB2 AHB Clock Mask */ + uint32_t DSU:1; /*!< bit: 3 DSU AHB Clock Mask */ + uint32_t NVMCTRL:1; /*!< bit: 4 NVMCTRL AHB Clock Mask */ + uint32_t :27; /*!< bit: 5..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PM_AHBMASK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_AHBMASK_OFFSET 0x14 /**< \brief (PM_AHBMASK offset) AHB Mask */ +#define PM_AHBMASK_RESETVALUE 0x0000001F /**< \brief (PM_AHBMASK reset_value) AHB Mask */ + +#define PM_AHBMASK_HPB0_Pos 0 /**< \brief (PM_AHBMASK) HPB0 AHB Clock Mask */ +#define PM_AHBMASK_HPB0 (0x1u << PM_AHBMASK_HPB0_Pos) +#define PM_AHBMASK_HPB1_Pos 1 /**< \brief (PM_AHBMASK) HPB1 AHB Clock Mask */ +#define PM_AHBMASK_HPB1 (0x1u << PM_AHBMASK_HPB1_Pos) +#define PM_AHBMASK_HPB2_Pos 2 /**< \brief (PM_AHBMASK) HPB2 AHB Clock Mask */ +#define PM_AHBMASK_HPB2 (0x1u << PM_AHBMASK_HPB2_Pos) +#define PM_AHBMASK_DSU_Pos 3 /**< \brief (PM_AHBMASK) DSU AHB Clock Mask */ +#define PM_AHBMASK_DSU (0x1u << PM_AHBMASK_DSU_Pos) +#define PM_AHBMASK_NVMCTRL_Pos 4 /**< \brief (PM_AHBMASK) NVMCTRL AHB Clock Mask */ +#define PM_AHBMASK_NVMCTRL (0x1u << PM_AHBMASK_NVMCTRL_Pos) +#define PM_AHBMASK_MASK 0x0000001Fu /**< \brief (PM_AHBMASK) MASK Register */ + +/* -------- PM_APBAMASK : (PM Offset: 0x18) (R/W 32) APBA Mask -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PAC0:1; /*!< bit: 0 PAC0 APB Clock Enable */ + uint32_t PM:1; /*!< bit: 1 PM APB Clock Enable */ + uint32_t SYSCTRL:1; /*!< bit: 2 SYSCTRL APB Clock Enable */ + uint32_t GCLK:1; /*!< bit: 3 GCLK APB Clock Enable */ + uint32_t WDT:1; /*!< bit: 4 WDT APB Clock Enable */ + uint32_t RTC:1; /*!< bit: 5 RTC APB Clock Enable */ + uint32_t EIC:1; /*!< bit: 6 EIC APB Clock Enable */ + uint32_t :25; /*!< bit: 7..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PM_APBAMASK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBAMASK_OFFSET 0x18 /**< \brief (PM_APBAMASK offset) APBA Mask */ +#define PM_APBAMASK_RESETVALUE 0x0000007F /**< \brief (PM_APBAMASK reset_value) APBA Mask */ + +#define PM_APBAMASK_PAC0_Pos 0 /**< \brief (PM_APBAMASK) PAC0 APB Clock Enable */ +#define PM_APBAMASK_PAC0 (0x1u << PM_APBAMASK_PAC0_Pos) +#define PM_APBAMASK_PM_Pos 1 /**< \brief (PM_APBAMASK) PM APB Clock Enable */ +#define PM_APBAMASK_PM (0x1u << PM_APBAMASK_PM_Pos) +#define PM_APBAMASK_SYSCTRL_Pos 2 /**< \brief (PM_APBAMASK) SYSCTRL APB Clock Enable */ +#define PM_APBAMASK_SYSCTRL (0x1u << PM_APBAMASK_SYSCTRL_Pos) +#define PM_APBAMASK_GCLK_Pos 3 /**< \brief (PM_APBAMASK) GCLK APB Clock Enable */ +#define PM_APBAMASK_GCLK (0x1u << PM_APBAMASK_GCLK_Pos) +#define PM_APBAMASK_WDT_Pos 4 /**< \brief (PM_APBAMASK) WDT APB Clock Enable */ +#define PM_APBAMASK_WDT (0x1u << PM_APBAMASK_WDT_Pos) +#define PM_APBAMASK_RTC_Pos 5 /**< \brief (PM_APBAMASK) RTC APB Clock Enable */ +#define PM_APBAMASK_RTC (0x1u << PM_APBAMASK_RTC_Pos) +#define PM_APBAMASK_EIC_Pos 6 /**< \brief (PM_APBAMASK) EIC APB Clock Enable */ +#define PM_APBAMASK_EIC (0x1u << PM_APBAMASK_EIC_Pos) +#define PM_APBAMASK_MASK 0x0000007Fu /**< \brief (PM_APBAMASK) MASK Register */ + +/* -------- PM_APBBMASK : (PM Offset: 0x1C) (R/W 32) APBB Mask -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PAC1:1; /*!< bit: 0 PAC1 APB Clock Enable */ + uint32_t DSU:1; /*!< bit: 1 DSU APB Clock Enable */ + uint32_t NVMCTRL:1; /*!< bit: 2 NVMCTRL APB Clock Enable */ + uint32_t PORT:1; /*!< bit: 3 PORT APB Clock Enable */ + uint32_t :28; /*!< bit: 4..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PM_APBBMASK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBBMASK_OFFSET 0x1C /**< \brief (PM_APBBMASK offset) APBB Mask */ +#define PM_APBBMASK_RESETVALUE 0x0000001F /**< \brief (PM_APBBMASK reset_value) APBB Mask */ + +#define PM_APBBMASK_PAC1_Pos 0 /**< \brief (PM_APBBMASK) PAC1 APB Clock Enable */ +#define PM_APBBMASK_PAC1 (0x1u << PM_APBBMASK_PAC1_Pos) +#define PM_APBBMASK_DSU_Pos 1 /**< \brief (PM_APBBMASK) DSU APB Clock Enable */ +#define PM_APBBMASK_DSU (0x1u << PM_APBBMASK_DSU_Pos) +#define PM_APBBMASK_NVMCTRL_Pos 2 /**< \brief (PM_APBBMASK) NVMCTRL APB Clock Enable */ +#define PM_APBBMASK_NVMCTRL (0x1u << PM_APBBMASK_NVMCTRL_Pos) +#define PM_APBBMASK_PORT_Pos 3 /**< \brief (PM_APBBMASK) PORT APB Clock Enable */ +#define PM_APBBMASK_PORT (0x1u << PM_APBBMASK_PORT_Pos) +#define PM_APBBMASK_MASK 0x0000000Fu /**< \brief (PM_APBBMASK) MASK Register */ + +/* -------- PM_APBCMASK : (PM Offset: 0x20) (R/W 32) APBC Mask -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PAC2:1; /*!< bit: 0 PAC2 APB Clock Enable */ + uint32_t EVSYS:1; /*!< bit: 1 EVSYS APB Clock Enable */ + uint32_t SERCOM0:1; /*!< bit: 2 SERCOM0 APB Clock Enable */ + uint32_t SERCOM1:1; /*!< bit: 3 SERCOM1 APB Clock Enable */ + uint32_t SERCOM2:1; /*!< bit: 4 SERCOM2 APB Clock Enable */ + uint32_t SERCOM3:1; /*!< bit: 5 SERCOM3 APB Clock Enable */ + uint32_t SERCOM4:1; /*!< bit: 6 SERCOM4 APB Clock Enable */ + uint32_t SERCOM5:1; /*!< bit: 7 SERCOM5 APB Clock Enable */ + uint32_t TC0:1; /*!< bit: 8 TC0 APB Clock Enable */ + uint32_t TC1:1; /*!< bit: 9 TC1 APB Clock Enable */ + uint32_t TC2:1; /*!< bit: 10 TC2 APB Clock Enable */ + uint32_t TC3:1; /*!< bit: 11 TC3 APB Clock Enable */ + uint32_t TC4:1; /*!< bit: 12 TC4 APB Clock Enable */ + uint32_t TC5:1; /*!< bit: 13 TC5 APB Clock Enable */ + uint32_t TC6:1; /*!< bit: 14 TC6 APB Clock Enable */ + uint32_t TC7:1; /*!< bit: 15 TC7 APB Clock Enable */ + uint32_t ADC:1; /*!< bit: 16 ADC APB Clock Enable */ + uint32_t AC:1; /*!< bit: 17 AC APB Clock Enable */ + uint32_t DAC:1; /*!< bit: 18 DAC APB Clock Enable */ + uint32_t PTC:1; /*!< bit: 19 PTC APB Clock Enable */ + uint32_t :12; /*!< bit: 20..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PM_APBCMASK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_APBCMASK_OFFSET 0x20 /**< \brief (PM_APBCMASK offset) APBC Mask */ +#define PM_APBCMASK_RESETVALUE 0x00010000 /**< \brief (PM_APBCMASK reset_value) APBC Mask */ + +#define PM_APBCMASK_PAC2_Pos 0 /**< \brief (PM_APBCMASK) PAC2 APB Clock Enable */ +#define PM_APBCMASK_PAC2 (0x1u << PM_APBCMASK_PAC2_Pos) +#define PM_APBCMASK_EVSYS_Pos 1 /**< \brief (PM_APBCMASK) EVSYS APB Clock Enable */ +#define PM_APBCMASK_EVSYS (0x1u << PM_APBCMASK_EVSYS_Pos) +#define PM_APBCMASK_SERCOM0_Pos 2 /**< \brief (PM_APBCMASK) SERCOM0 APB Clock Enable */ +#define PM_APBCMASK_SERCOM0 (0x1u << PM_APBCMASK_SERCOM0_Pos) +#define PM_APBCMASK_SERCOM1_Pos 3 /**< \brief (PM_APBCMASK) SERCOM1 APB Clock Enable */ +#define PM_APBCMASK_SERCOM1 (0x1u << PM_APBCMASK_SERCOM1_Pos) +#define PM_APBCMASK_SERCOM2_Pos 4 /**< \brief (PM_APBCMASK) SERCOM2 APB Clock Enable */ +#define PM_APBCMASK_SERCOM2 (0x1u << PM_APBCMASK_SERCOM2_Pos) +#define PM_APBCMASK_SERCOM3_Pos 5 /**< \brief (PM_APBCMASK) SERCOM3 APB Clock Enable */ +#define PM_APBCMASK_SERCOM3 (0x1u << PM_APBCMASK_SERCOM3_Pos) +#define PM_APBCMASK_SERCOM4_Pos 6 /**< \brief (PM_APBCMASK) SERCOM4 APB Clock Enable */ +#define PM_APBCMASK_SERCOM4 (0x1u << PM_APBCMASK_SERCOM4_Pos) +#define PM_APBCMASK_SERCOM5_Pos 7 /**< \brief (PM_APBCMASK) SERCOM5 APB Clock Enable */ +#define PM_APBCMASK_SERCOM5 (0x1u << PM_APBCMASK_SERCOM5_Pos) +#define PM_APBCMASK_TC0_Pos 8 /**< \brief (PM_APBCMASK) TC0 APB Clock Enable */ +#define PM_APBCMASK_TC0 (0x1u << PM_APBCMASK_TC0_Pos) +#define PM_APBCMASK_TC1_Pos 9 /**< \brief (PM_APBCMASK) TC1 APB Clock Enable */ +#define PM_APBCMASK_TC1 (0x1u << PM_APBCMASK_TC1_Pos) +#define PM_APBCMASK_TC2_Pos 10 /**< \brief (PM_APBCMASK) TC2 APB Clock Enable */ +#define PM_APBCMASK_TC2 (0x1u << PM_APBCMASK_TC2_Pos) +#define PM_APBCMASK_TC3_Pos 11 /**< \brief (PM_APBCMASK) TC3 APB Clock Enable */ +#define PM_APBCMASK_TC3 (0x1u << PM_APBCMASK_TC3_Pos) +#define PM_APBCMASK_TC4_Pos 12 /**< \brief (PM_APBCMASK) TC4 APB Clock Enable */ +#define PM_APBCMASK_TC4 (0x1u << PM_APBCMASK_TC4_Pos) +#define PM_APBCMASK_TC5_Pos 13 /**< \brief (PM_APBCMASK) TC5 APB Clock Enable */ +#define PM_APBCMASK_TC5 (0x1u << PM_APBCMASK_TC5_Pos) +#define PM_APBCMASK_TC6_Pos 14 /**< \brief (PM_APBCMASK) TC6 APB Clock Enable */ +#define PM_APBCMASK_TC6 (0x1u << PM_APBCMASK_TC6_Pos) +#define PM_APBCMASK_TC7_Pos 15 /**< \brief (PM_APBCMASK) TC7 APB Clock Enable */ +#define PM_APBCMASK_TC7 (0x1u << PM_APBCMASK_TC7_Pos) +#define PM_APBCMASK_ADC_Pos 16 /**< \brief (PM_APBCMASK) ADC APB Clock Enable */ +#define PM_APBCMASK_ADC (0x1u << PM_APBCMASK_ADC_Pos) +#define PM_APBCMASK_AC_Pos 17 /**< \brief (PM_APBCMASK) AC APB Clock Enable */ +#define PM_APBCMASK_AC (0x1u << PM_APBCMASK_AC_Pos) +#define PM_APBCMASK_DAC_Pos 18 /**< \brief (PM_APBCMASK) DAC APB Clock Enable */ +#define PM_APBCMASK_DAC (0x1u << PM_APBCMASK_DAC_Pos) +#define PM_APBCMASK_PTC_Pos 19 /**< \brief (PM_APBCMASK) PTC APB Clock Enable */ +#define PM_APBCMASK_PTC (0x1u << PM_APBCMASK_PTC_Pos) +#define PM_APBCMASK_MASK 0x000FFFFFu /**< \brief (PM_APBCMASK) MASK Register */ + +/* -------- PM_INTENCLR : (PM Offset: 0x34) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CKRDY:1; /*!< bit: 0 Clock Ready Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_INTENCLR_OFFSET 0x34 /**< \brief (PM_INTENCLR offset) Interrupt Enable Clear */ +#define PM_INTENCLR_RESETVALUE 0x00 /**< \brief (PM_INTENCLR reset_value) Interrupt Enable Clear */ + +#define PM_INTENCLR_CKRDY_Pos 0 /**< \brief (PM_INTENCLR) Clock Ready Interrupt Enable */ +#define PM_INTENCLR_CKRDY (0x1u << PM_INTENCLR_CKRDY_Pos) +#define PM_INTENCLR_MASK 0x01u /**< \brief (PM_INTENCLR) MASK Register */ + +/* -------- PM_INTENSET : (PM Offset: 0x35) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CKRDY:1; /*!< bit: 0 Clock Ready Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_INTENSET_OFFSET 0x35 /**< \brief (PM_INTENSET offset) Interrupt Enable Set */ +#define PM_INTENSET_RESETVALUE 0x00 /**< \brief (PM_INTENSET reset_value) Interrupt Enable Set */ + +#define PM_INTENSET_CKRDY_Pos 0 /**< \brief (PM_INTENSET) Clock Ready Interrupt Enable */ +#define PM_INTENSET_CKRDY (0x1u << PM_INTENSET_CKRDY_Pos) +#define PM_INTENSET_MASK 0x01u /**< \brief (PM_INTENSET) MASK Register */ + +/* -------- PM_INTFLAG : (PM Offset: 0x36) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CKRDY:1; /*!< bit: 0 Clock Ready */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_INTFLAG_OFFSET 0x36 /**< \brief (PM_INTFLAG offset) Interrupt Flag Status and Clear */ +#define PM_INTFLAG_RESETVALUE 0x00 /**< \brief (PM_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define PM_INTFLAG_CKRDY_Pos 0 /**< \brief (PM_INTFLAG) Clock Ready */ +#define PM_INTFLAG_CKRDY (0x1u << PM_INTFLAG_CKRDY_Pos) +#define PM_INTFLAG_MASK 0x01u /**< \brief (PM_INTFLAG) MASK Register */ + +/* -------- PM_RCAUSE : (PM Offset: 0x38) (R/ 8) Reset Cause -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t POR:1; /*!< bit: 0 Power On Reset */ + uint8_t BOD12:1; /*!< bit: 1 Brown Out 12 Detector Reset */ + uint8_t BOD33:1; /*!< bit: 2 Brown Out 33 Detector Reset */ + uint8_t :1; /*!< bit: 3 Reserved */ + uint8_t EXT:1; /*!< bit: 4 External Reset */ + uint8_t WDT:1; /*!< bit: 5 Watchdog Reset */ + uint8_t SYST:1; /*!< bit: 6 System Reset Request */ + uint8_t :1; /*!< bit: 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PM_RCAUSE_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PM_RCAUSE_OFFSET 0x38 /**< \brief (PM_RCAUSE offset) Reset Cause */ +#define PM_RCAUSE_RESETVALUE 0x01 /**< \brief (PM_RCAUSE reset_value) Reset Cause */ + +#define PM_RCAUSE_POR_Pos 0 /**< \brief (PM_RCAUSE) Power On Reset */ +#define PM_RCAUSE_POR (0x1u << PM_RCAUSE_POR_Pos) +#define PM_RCAUSE_BOD12_Pos 1 /**< \brief (PM_RCAUSE) Brown Out 12 Detector Reset */ +#define PM_RCAUSE_BOD12 (0x1u << PM_RCAUSE_BOD12_Pos) +#define PM_RCAUSE_BOD33_Pos 2 /**< \brief (PM_RCAUSE) Brown Out 33 Detector Reset */ +#define PM_RCAUSE_BOD33 (0x1u << PM_RCAUSE_BOD33_Pos) +#define PM_RCAUSE_EXT_Pos 4 /**< \brief (PM_RCAUSE) External Reset */ +#define PM_RCAUSE_EXT (0x1u << PM_RCAUSE_EXT_Pos) +#define PM_RCAUSE_WDT_Pos 5 /**< \brief (PM_RCAUSE) Watchdog Reset */ +#define PM_RCAUSE_WDT (0x1u << PM_RCAUSE_WDT_Pos) +#define PM_RCAUSE_SYST_Pos 6 /**< \brief (PM_RCAUSE) System Reset Request */ +#define PM_RCAUSE_SYST (0x1u << PM_RCAUSE_SYST_Pos) +#define PM_RCAUSE_MASK 0x77u /**< \brief (PM_RCAUSE) MASK Register */ + +/** \brief PM hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO PM_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 8) Control */ + __IO PM_SLEEP_Type SLEEP; /**< \brief Offset: 0x01 (R/W 8) Sleep Mode */ + RoReg8 Reserved1[0x6]; + __IO PM_CPUSEL_Type CPUSEL; /**< \brief Offset: 0x08 (R/W 8) CPU Clock Select */ + __IO PM_APBASEL_Type APBASEL; /**< \brief Offset: 0x09 (R/W 8) APBA Clock Select */ + __IO PM_APBBSEL_Type APBBSEL; /**< \brief Offset: 0x0A (R/W 8) APBB Clock Select */ + __IO PM_APBCSEL_Type APBCSEL; /**< \brief Offset: 0x0B (R/W 8) APBC Clock Select */ + RoReg8 Reserved2[0x8]; + __IO PM_AHBMASK_Type AHBMASK; /**< \brief Offset: 0x14 (R/W 32) AHB Mask */ + __IO PM_APBAMASK_Type APBAMASK; /**< \brief Offset: 0x18 (R/W 32) APBA Mask */ + __IO PM_APBBMASK_Type APBBMASK; /**< \brief Offset: 0x1C (R/W 32) APBB Mask */ + __IO PM_APBCMASK_Type APBCMASK; /**< \brief Offset: 0x20 (R/W 32) APBC Mask */ + RoReg8 Reserved3[0x10]; + __IO PM_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x34 (R/W 8) Interrupt Enable Clear */ + __IO PM_INTENSET_Type INTENSET; /**< \brief Offset: 0x35 (R/W 8) Interrupt Enable Set */ + __IO PM_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x36 (R/W 8) Interrupt Flag Status and Clear */ + RoReg8 Reserved4[0x1]; + __I PM_RCAUSE_Type RCAUSE; /**< \brief Offset: 0x38 (R/ 8) Reset Cause */ +} Pm; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_PM_COMPONENT_ */ diff --git a/loader/samd20/component/port.h b/loader/samd20/component/port.h new file mode 100644 index 0000000..5094fbc --- /dev/null +++ b/loader/samd20/component/port.h @@ -0,0 +1,395 @@ +/** + * \file + * + * \brief Component description for PORT + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_PORT_COMPONENT_ +#define _SAMD20_PORT_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR PORT */ +/* ========================================================================== */ +/** \addtogroup SAMD20_PORT Port Module */ +/*@{*/ + +#define PORT_U2210 +#define REV_PORT 0x100 + +/* -------- PORT_DIR : (PORT Offset: 0x00) (R/W 32) GROUP Data Direction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DIR:32; /*!< bit: 0..31 Port Data Direction */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_DIR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_DIR_OFFSET 0x00 /**< \brief (PORT_DIR offset) Data Direction */ +#define PORT_DIR_RESETVALUE 0x00000000 /**< \brief (PORT_DIR reset_value) Data Direction */ + +#define PORT_DIR_DIR_Pos 0 /**< \brief (PORT_DIR) Port Data Direction */ +#define PORT_DIR_DIR_Msk (0xFFFFFFFFu << PORT_DIR_DIR_Pos) +#define PORT_DIR_DIR(value) ((PORT_DIR_DIR_Msk & ((value) << PORT_DIR_DIR_Pos))) +#define PORT_DIR_MASK 0xFFFFFFFFu /**< \brief (PORT_DIR) MASK Register */ + +/* -------- PORT_DIRCLR : (PORT Offset: 0x04) (R/W 32) GROUP Data Direction Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DIRCLR:32; /*!< bit: 0..31 Port Data Direction Clear */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_DIRCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_DIRCLR_OFFSET 0x04 /**< \brief (PORT_DIRCLR offset) Data Direction Clear */ +#define PORT_DIRCLR_RESETVALUE 0x00000000 /**< \brief (PORT_DIRCLR reset_value) Data Direction Clear */ + +#define PORT_DIRCLR_DIRCLR_Pos 0 /**< \brief (PORT_DIRCLR) Port Data Direction Clear */ +#define PORT_DIRCLR_DIRCLR_Msk (0xFFFFFFFFu << PORT_DIRCLR_DIRCLR_Pos) +#define PORT_DIRCLR_DIRCLR(value) ((PORT_DIRCLR_DIRCLR_Msk & ((value) << PORT_DIRCLR_DIRCLR_Pos))) +#define PORT_DIRCLR_MASK 0xFFFFFFFFu /**< \brief (PORT_DIRCLR) MASK Register */ + +/* -------- PORT_DIRSET : (PORT Offset: 0x08) (R/W 32) GROUP Data Direction Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DIRSET:32; /*!< bit: 0..31 Port Data Direction Set */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_DIRSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_DIRSET_OFFSET 0x08 /**< \brief (PORT_DIRSET offset) Data Direction Set */ +#define PORT_DIRSET_RESETVALUE 0x00000000 /**< \brief (PORT_DIRSET reset_value) Data Direction Set */ + +#define PORT_DIRSET_DIRSET_Pos 0 /**< \brief (PORT_DIRSET) Port Data Direction Set */ +#define PORT_DIRSET_DIRSET_Msk (0xFFFFFFFFu << PORT_DIRSET_DIRSET_Pos) +#define PORT_DIRSET_DIRSET(value) ((PORT_DIRSET_DIRSET_Msk & ((value) << PORT_DIRSET_DIRSET_Pos))) +#define PORT_DIRSET_MASK 0xFFFFFFFFu /**< \brief (PORT_DIRSET) MASK Register */ + +/* -------- PORT_DIRTGL : (PORT Offset: 0x0C) (R/W 32) GROUP Data Direction Toggle -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t DIRTGL:32; /*!< bit: 0..31 Port Data Direction Toggle */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_DIRTGL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_DIRTGL_OFFSET 0x0C /**< \brief (PORT_DIRTGL offset) Data Direction Toggle */ +#define PORT_DIRTGL_RESETVALUE 0x00000000 /**< \brief (PORT_DIRTGL reset_value) Data Direction Toggle */ + +#define PORT_DIRTGL_DIRTGL_Pos 0 /**< \brief (PORT_DIRTGL) Port Data Direction Toggle */ +#define PORT_DIRTGL_DIRTGL_Msk (0xFFFFFFFFu << PORT_DIRTGL_DIRTGL_Pos) +#define PORT_DIRTGL_DIRTGL(value) ((PORT_DIRTGL_DIRTGL_Msk & ((value) << PORT_DIRTGL_DIRTGL_Pos))) +#define PORT_DIRTGL_MASK 0xFFFFFFFFu /**< \brief (PORT_DIRTGL) MASK Register */ + +/* -------- PORT_OUT : (PORT Offset: 0x10) (R/W 32) GROUP Data Output Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OUT:32; /*!< bit: 0..31 Port Data Output Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_OUT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_OUT_OFFSET 0x10 /**< \brief (PORT_OUT offset) Data Output Value */ +#define PORT_OUT_RESETVALUE 0x00000000 /**< \brief (PORT_OUT reset_value) Data Output Value */ + +#define PORT_OUT_OUT_Pos 0 /**< \brief (PORT_OUT) Port Data Output Value */ +#define PORT_OUT_OUT_Msk (0xFFFFFFFFu << PORT_OUT_OUT_Pos) +#define PORT_OUT_OUT(value) ((PORT_OUT_OUT_Msk & ((value) << PORT_OUT_OUT_Pos))) +#define PORT_OUT_MASK 0xFFFFFFFFu /**< \brief (PORT_OUT) MASK Register */ + +/* -------- PORT_OUTCLR : (PORT Offset: 0x14) (R/W 32) GROUP Data Output Value Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OUTCLR:32; /*!< bit: 0..31 Port Data Output Value Clear */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_OUTCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_OUTCLR_OFFSET 0x14 /**< \brief (PORT_OUTCLR offset) Data Output Value Clear */ +#define PORT_OUTCLR_RESETVALUE 0x00000000 /**< \brief (PORT_OUTCLR reset_value) Data Output Value Clear */ + +#define PORT_OUTCLR_OUTCLR_Pos 0 /**< \brief (PORT_OUTCLR) Port Data Output Value Clear */ +#define PORT_OUTCLR_OUTCLR_Msk (0xFFFFFFFFu << PORT_OUTCLR_OUTCLR_Pos) +#define PORT_OUTCLR_OUTCLR(value) ((PORT_OUTCLR_OUTCLR_Msk & ((value) << PORT_OUTCLR_OUTCLR_Pos))) +#define PORT_OUTCLR_MASK 0xFFFFFFFFu /**< \brief (PORT_OUTCLR) MASK Register */ + +/* -------- PORT_OUTSET : (PORT Offset: 0x18) (R/W 32) GROUP Data Output Value Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OUTSET:32; /*!< bit: 0..31 Port Data Output Value Set */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_OUTSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_OUTSET_OFFSET 0x18 /**< \brief (PORT_OUTSET offset) Data Output Value Set */ +#define PORT_OUTSET_RESETVALUE 0x00000000 /**< \brief (PORT_OUTSET reset_value) Data Output Value Set */ + +#define PORT_OUTSET_OUTSET_Pos 0 /**< \brief (PORT_OUTSET) Port Data Output Value Set */ +#define PORT_OUTSET_OUTSET_Msk (0xFFFFFFFFu << PORT_OUTSET_OUTSET_Pos) +#define PORT_OUTSET_OUTSET(value) ((PORT_OUTSET_OUTSET_Msk & ((value) << PORT_OUTSET_OUTSET_Pos))) +#define PORT_OUTSET_MASK 0xFFFFFFFFu /**< \brief (PORT_OUTSET) MASK Register */ + +/* -------- PORT_OUTTGL : (PORT Offset: 0x1C) (R/W 32) GROUP Data Output Value Toggle -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t OUTTGL:32; /*!< bit: 0..31 Port Data Output Value Toggle */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_OUTTGL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_OUTTGL_OFFSET 0x1C /**< \brief (PORT_OUTTGL offset) Data Output Value Toggle */ +#define PORT_OUTTGL_RESETVALUE 0x00000000 /**< \brief (PORT_OUTTGL reset_value) Data Output Value Toggle */ + +#define PORT_OUTTGL_OUTTGL_Pos 0 /**< \brief (PORT_OUTTGL) Port Data Output Value Toggle */ +#define PORT_OUTTGL_OUTTGL_Msk (0xFFFFFFFFu << PORT_OUTTGL_OUTTGL_Pos) +#define PORT_OUTTGL_OUTTGL(value) ((PORT_OUTTGL_OUTTGL_Msk & ((value) << PORT_OUTTGL_OUTTGL_Pos))) +#define PORT_OUTTGL_MASK 0xFFFFFFFFu /**< \brief (PORT_OUTTGL) MASK Register */ + +/* -------- PORT_IN : (PORT Offset: 0x20) (R/ 32) GROUP Data Input Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t IN:32; /*!< bit: 0..31 Port Data Input Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_IN_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_IN_OFFSET 0x20 /**< \brief (PORT_IN offset) Data Input Value */ +#define PORT_IN_RESETVALUE 0x00000000 /**< \brief (PORT_IN reset_value) Data Input Value */ + +#define PORT_IN_IN_Pos 0 /**< \brief (PORT_IN) Port Data Input Value */ +#define PORT_IN_IN_Msk (0xFFFFFFFFu << PORT_IN_IN_Pos) +#define PORT_IN_IN(value) ((PORT_IN_IN_Msk & ((value) << PORT_IN_IN_Pos))) +#define PORT_IN_MASK 0xFFFFFFFFu /**< \brief (PORT_IN) MASK Register */ + +/* -------- PORT_CTRL : (PORT Offset: 0x24) (R/W 32) GROUP Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SAMPLING:32; /*!< bit: 0..31 Input Sampling Mode */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_CTRL_OFFSET 0x24 /**< \brief (PORT_CTRL offset) Control */ +#define PORT_CTRL_RESETVALUE 0x00000000 /**< \brief (PORT_CTRL reset_value) Control */ + +#define PORT_CTRL_SAMPLING_Pos 0 /**< \brief (PORT_CTRL) Input Sampling Mode */ +#define PORT_CTRL_SAMPLING_Msk (0xFFFFFFFFu << PORT_CTRL_SAMPLING_Pos) +#define PORT_CTRL_SAMPLING(value) ((PORT_CTRL_SAMPLING_Msk & ((value) << PORT_CTRL_SAMPLING_Pos))) +#define PORT_CTRL_MASK 0xFFFFFFFFu /**< \brief (PORT_CTRL) MASK Register */ + +/* -------- PORT_WRCONFIG : (PORT Offset: 0x28) ( /W 32) GROUP Write Configuration -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PINMASK:16; /*!< bit: 0..15 Pin Mask for Multiple Pin Configuration */ + uint32_t PMUXEN:1; /*!< bit: 16 Peripheral Multiplexer Enable */ + uint32_t INEN:1; /*!< bit: 17 Input Enable */ + uint32_t PULLEN:1; /*!< bit: 18 Pull Enable */ + uint32_t :3; /*!< bit: 19..21 Reserved */ + uint32_t DRVSTR:1; /*!< bit: 22 Output Driver Strength Selection */ + uint32_t :1; /*!< bit: 23 Reserved */ + uint32_t PMUX:4; /*!< bit: 24..27 Peripheral Multiplexing */ + uint32_t WRPMUX:1; /*!< bit: 28 Write PMUX */ + uint32_t :1; /*!< bit: 29 Reserved */ + uint32_t WRPINCFG:1; /*!< bit: 30 Write PINCFG */ + uint32_t HWSEL:1; /*!< bit: 31 Half-Word Select */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} PORT_WRCONFIG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_WRCONFIG_OFFSET 0x28 /**< \brief (PORT_WRCONFIG offset) Write Configuration */ +#define PORT_WRCONFIG_RESETVALUE 0x00000000 /**< \brief (PORT_WRCONFIG reset_value) Write Configuration */ + +#define PORT_WRCONFIG_PINMASK_Pos 0 /**< \brief (PORT_WRCONFIG) Pin Mask for Multiple Pin Configuration */ +#define PORT_WRCONFIG_PINMASK_Msk (0xFFFFu << PORT_WRCONFIG_PINMASK_Pos) +#define PORT_WRCONFIG_PINMASK(value) ((PORT_WRCONFIG_PINMASK_Msk & ((value) << PORT_WRCONFIG_PINMASK_Pos))) +#define PORT_WRCONFIG_PMUXEN_Pos 16 /**< \brief (PORT_WRCONFIG) Peripheral Multiplexer Enable */ +#define PORT_WRCONFIG_PMUXEN (0x1u << PORT_WRCONFIG_PMUXEN_Pos) +#define PORT_WRCONFIG_INEN_Pos 17 /**< \brief (PORT_WRCONFIG) Input Enable */ +#define PORT_WRCONFIG_INEN (0x1u << PORT_WRCONFIG_INEN_Pos) +#define PORT_WRCONFIG_PULLEN_Pos 18 /**< \brief (PORT_WRCONFIG) Pull Enable */ +#define PORT_WRCONFIG_PULLEN (0x1u << PORT_WRCONFIG_PULLEN_Pos) +#define PORT_WRCONFIG_DRVSTR_Pos 22 /**< \brief (PORT_WRCONFIG) Output Driver Strength Selection */ +#define PORT_WRCONFIG_DRVSTR (0x1u << PORT_WRCONFIG_DRVSTR_Pos) +#define PORT_WRCONFIG_PMUX_Pos 24 /**< \brief (PORT_WRCONFIG) Peripheral Multiplexing */ +#define PORT_WRCONFIG_PMUX_Msk (0xFu << PORT_WRCONFIG_PMUX_Pos) +#define PORT_WRCONFIG_PMUX(value) ((PORT_WRCONFIG_PMUX_Msk & ((value) << PORT_WRCONFIG_PMUX_Pos))) +#define PORT_WRCONFIG_WRPMUX_Pos 28 /**< \brief (PORT_WRCONFIG) Write PMUX */ +#define PORT_WRCONFIG_WRPMUX (0x1u << PORT_WRCONFIG_WRPMUX_Pos) +#define PORT_WRCONFIG_WRPINCFG_Pos 30 /**< \brief (PORT_WRCONFIG) Write PINCFG */ +#define PORT_WRCONFIG_WRPINCFG (0x1u << PORT_WRCONFIG_WRPINCFG_Pos) +#define PORT_WRCONFIG_HWSEL_Pos 31 /**< \brief (PORT_WRCONFIG) Half-Word Select */ +#define PORT_WRCONFIG_HWSEL (0x1u << PORT_WRCONFIG_HWSEL_Pos) +#define PORT_WRCONFIG_MASK 0xDF47FFFFu /**< \brief (PORT_WRCONFIG) MASK Register */ + +/* -------- PORT_PMUX : (PORT Offset: 0x30) (R/W 8) GROUP Peripheral Multiplexing n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PMUXE:4; /*!< bit: 0.. 3 Peripheral Multiplexing Even */ + uint8_t PMUXO:4; /*!< bit: 4.. 7 Peripheral Multiplexing Odd */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PORT_PMUX_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_PMUX_OFFSET 0x30 /**< \brief (PORT_PMUX offset) Peripheral Multiplexing n */ +#define PORT_PMUX_RESETVALUE 0x00 /**< \brief (PORT_PMUX reset_value) Peripheral Multiplexing n */ + +#define PORT_PMUX_PMUXE_Pos 0 /**< \brief (PORT_PMUX) Peripheral Multiplexing Even */ +#define PORT_PMUX_PMUXE_Msk (0xFu << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE(value) ((PORT_PMUX_PMUXE_Msk & ((value) << PORT_PMUX_PMUXE_Pos))) +#define PORT_PMUX_PMUXE_A_Val 0x0u /**< \brief (PORT_PMUX) Peripheral function A selected */ +#define PORT_PMUX_PMUXE_B_Val 0x1u /**< \brief (PORT_PMUX) Peripheral function B selected */ +#define PORT_PMUX_PMUXE_C_Val 0x2u /**< \brief (PORT_PMUX) Peripheral function C selected */ +#define PORT_PMUX_PMUXE_D_Val 0x3u /**< \brief (PORT_PMUX) Peripheral function D selected */ +#define PORT_PMUX_PMUXE_E_Val 0x4u /**< \brief (PORT_PMUX) Peripheral function E selected */ +#define PORT_PMUX_PMUXE_F_Val 0x5u /**< \brief (PORT_PMUX) Peripheral function F selected */ +#define PORT_PMUX_PMUXE_G_Val 0x6u /**< \brief (PORT_PMUX) Peripheral function G selected */ +#define PORT_PMUX_PMUXE_H_Val 0x7u /**< \brief (PORT_PMUX) Peripheral function H selected */ +#define PORT_PMUX_PMUXE_A (PORT_PMUX_PMUXE_A_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_B (PORT_PMUX_PMUXE_B_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_C (PORT_PMUX_PMUXE_C_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_D (PORT_PMUX_PMUXE_D_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_E (PORT_PMUX_PMUXE_E_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_F (PORT_PMUX_PMUXE_F_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_G (PORT_PMUX_PMUXE_G_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXE_H (PORT_PMUX_PMUXE_H_Val << PORT_PMUX_PMUXE_Pos) +#define PORT_PMUX_PMUXO_Pos 4 /**< \brief (PORT_PMUX) Peripheral Multiplexing Odd */ +#define PORT_PMUX_PMUXO_Msk (0xFu << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO(value) ((PORT_PMUX_PMUXO_Msk & ((value) << PORT_PMUX_PMUXO_Pos))) +#define PORT_PMUX_PMUXO_A_Val 0x0u /**< \brief (PORT_PMUX) Peripheral function A selected */ +#define PORT_PMUX_PMUXO_B_Val 0x1u /**< \brief (PORT_PMUX) Peripheral function B selected */ +#define PORT_PMUX_PMUXO_C_Val 0x2u /**< \brief (PORT_PMUX) Peripheral function C selected */ +#define PORT_PMUX_PMUXO_D_Val 0x3u /**< \brief (PORT_PMUX) Peripheral function D selected */ +#define PORT_PMUX_PMUXO_E_Val 0x4u /**< \brief (PORT_PMUX) Peripheral function E selected */ +#define PORT_PMUX_PMUXO_F_Val 0x5u /**< \brief (PORT_PMUX) Peripheral function F selected */ +#define PORT_PMUX_PMUXO_G_Val 0x6u /**< \brief (PORT_PMUX) Peripheral function G selected */ +#define PORT_PMUX_PMUXO_H_Val 0x7u /**< \brief (PORT_PMUX) Peripheral function H selected */ +#define PORT_PMUX_PMUXO_A (PORT_PMUX_PMUXO_A_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_B (PORT_PMUX_PMUXO_B_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_C (PORT_PMUX_PMUXO_C_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_D (PORT_PMUX_PMUXO_D_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_E (PORT_PMUX_PMUXO_E_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_F (PORT_PMUX_PMUXO_F_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_G (PORT_PMUX_PMUXO_G_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_PMUXO_H (PORT_PMUX_PMUXO_H_Val << PORT_PMUX_PMUXO_Pos) +#define PORT_PMUX_MASK 0xFFu /**< \brief (PORT_PMUX) MASK Register */ + +/* -------- PORT_PINCFG : (PORT Offset: 0x40) (R/W 8) GROUP Pin Configuration n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PMUXEN:1; /*!< bit: 0 Peripheral Multiplexer Enable */ + uint8_t INEN:1; /*!< bit: 1 Input Enable */ + uint8_t PULLEN:1; /*!< bit: 2 Pull Enable */ + uint8_t :3; /*!< bit: 3.. 5 Reserved */ + uint8_t DRVSTR:1; /*!< bit: 6 Output Driver Strength Selection */ + uint8_t :1; /*!< bit: 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} PORT_PINCFG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define PORT_PINCFG_OFFSET 0x40 /**< \brief (PORT_PINCFG offset) Pin Configuration n */ +#define PORT_PINCFG_RESETVALUE 0x00 /**< \brief (PORT_PINCFG reset_value) Pin Configuration n */ + +#define PORT_PINCFG_PMUXEN_Pos 0 /**< \brief (PORT_PINCFG) Peripheral Multiplexer Enable */ +#define PORT_PINCFG_PMUXEN (0x1u << PORT_PINCFG_PMUXEN_Pos) +#define PORT_PINCFG_INEN_Pos 1 /**< \brief (PORT_PINCFG) Input Enable */ +#define PORT_PINCFG_INEN (0x1u << PORT_PINCFG_INEN_Pos) +#define PORT_PINCFG_PULLEN_Pos 2 /**< \brief (PORT_PINCFG) Pull Enable */ +#define PORT_PINCFG_PULLEN (0x1u << PORT_PINCFG_PULLEN_Pos) +#define PORT_PINCFG_DRVSTR_Pos 6 /**< \brief (PORT_PINCFG) Output Driver Strength Selection */ +#define PORT_PINCFG_DRVSTR (0x1u << PORT_PINCFG_DRVSTR_Pos) +#define PORT_PINCFG_MASK 0x47u /**< \brief (PORT_PINCFG) MASK Register */ + +/** \brief PortGroup hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO PORT_DIR_Type DIR; /**< \brief Offset: 0x00 (R/W 32) Data Direction */ + __IO PORT_DIRCLR_Type DIRCLR; /**< \brief Offset: 0x04 (R/W 32) Data Direction Clear */ + __IO PORT_DIRSET_Type DIRSET; /**< \brief Offset: 0x08 (R/W 32) Data Direction Set */ + __IO PORT_DIRTGL_Type DIRTGL; /**< \brief Offset: 0x0C (R/W 32) Data Direction Toggle */ + __IO PORT_OUT_Type OUT; /**< \brief Offset: 0x10 (R/W 32) Data Output Value */ + __IO PORT_OUTCLR_Type OUTCLR; /**< \brief Offset: 0x14 (R/W 32) Data Output Value Clear */ + __IO PORT_OUTSET_Type OUTSET; /**< \brief Offset: 0x18 (R/W 32) Data Output Value Set */ + __IO PORT_OUTTGL_Type OUTTGL; /**< \brief Offset: 0x1C (R/W 32) Data Output Value Toggle */ + __I PORT_IN_Type IN; /**< \brief Offset: 0x20 (R/ 32) Data Input Value */ + __IO PORT_CTRL_Type CTRL; /**< \brief Offset: 0x24 (R/W 32) Control */ + __O PORT_WRCONFIG_Type WRCONFIG; /**< \brief Offset: 0x28 ( /W 32) Write Configuration */ + RoReg8 Reserved1[0x4]; + __IO PORT_PMUX_Type PMUX[16]; /**< \brief Offset: 0x30 (R/W 8) Peripheral Multiplexing n */ + __IO PORT_PINCFG_Type PINCFG[32]; /**< \brief Offset: 0x40 (R/W 8) Pin Configuration n */ + RoReg8 Reserved2[0x20]; +} PortGroup; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief PORT APB hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + PortGroup Group[2]; /**< \brief Offset: 0x00 PortGroup groups [GROUPS] */ +} Port; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +#define SECTION_PORT_IOBUS + +/*@}*/ + +#endif /* _SAMD20_PORT_COMPONENT_ */ diff --git a/loader/samd20/component/rtc.h b/loader/samd20/component/rtc.h new file mode 100644 index 0000000..684ef67 --- /dev/null +++ b/loader/samd20/component/rtc.h @@ -0,0 +1,1062 @@ +/** + * \file + * + * \brief Component description for RTC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_RTC_COMPONENT_ +#define _SAMD20_RTC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR RTC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_RTC Real-Time Counter */ +/*@{*/ + +#define RTC_U2202 +#define REV_RTC 0x101 + +/* -------- RTC_MODE0_CTRL : (RTC Offset: 0x00) (R/W 16) MODE0 MODE0 Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t SWRST:1; /*!< bit: 0 Software Reset */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t MODE:2; /*!< bit: 2.. 3 Operating Mode */ + uint16_t :3; /*!< bit: 4.. 6 Reserved */ + uint16_t MATCHCLR:1; /*!< bit: 7 Clear on Match */ + uint16_t PRESCALER:4; /*!< bit: 8..11 Prescaler */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE0_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_CTRL_OFFSET 0x00 /**< \brief (RTC_MODE0_CTRL offset) MODE0 Control */ +#define RTC_MODE0_CTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE0_CTRL reset_value) MODE0 Control */ + +#define RTC_MODE0_CTRL_SWRST_Pos 0 /**< \brief (RTC_MODE0_CTRL) Software Reset */ +#define RTC_MODE0_CTRL_SWRST (0x1u << RTC_MODE0_CTRL_SWRST_Pos) +#define RTC_MODE0_CTRL_ENABLE_Pos 1 /**< \brief (RTC_MODE0_CTRL) Enable */ +#define RTC_MODE0_CTRL_ENABLE (0x1u << RTC_MODE0_CTRL_ENABLE_Pos) +#define RTC_MODE0_CTRL_MODE_Pos 2 /**< \brief (RTC_MODE0_CTRL) Operating Mode */ +#define RTC_MODE0_CTRL_MODE_Msk (0x3u << RTC_MODE0_CTRL_MODE_Pos) +#define RTC_MODE0_CTRL_MODE(value) ((RTC_MODE0_CTRL_MODE_Msk & ((value) << RTC_MODE0_CTRL_MODE_Pos))) +#define RTC_MODE0_CTRL_MODE_COUNT32_Val 0x0u /**< \brief (RTC_MODE0_CTRL) Mode 0: 32-bit Counter */ +#define RTC_MODE0_CTRL_MODE_COUNT16_Val 0x1u /**< \brief (RTC_MODE0_CTRL) Mode 1: 16-bit Counter */ +#define RTC_MODE0_CTRL_MODE_CLOCK_Val 0x2u /**< \brief (RTC_MODE0_CTRL) Mode 2: Clock/Calendar */ +#define RTC_MODE0_CTRL_MODE_COUNT32 (RTC_MODE0_CTRL_MODE_COUNT32_Val << RTC_MODE0_CTRL_MODE_Pos) +#define RTC_MODE0_CTRL_MODE_COUNT16 (RTC_MODE0_CTRL_MODE_COUNT16_Val << RTC_MODE0_CTRL_MODE_Pos) +#define RTC_MODE0_CTRL_MODE_CLOCK (RTC_MODE0_CTRL_MODE_CLOCK_Val << RTC_MODE0_CTRL_MODE_Pos) +#define RTC_MODE0_CTRL_MATCHCLR_Pos 7 /**< \brief (RTC_MODE0_CTRL) Clear on Match */ +#define RTC_MODE0_CTRL_MATCHCLR (0x1u << RTC_MODE0_CTRL_MATCHCLR_Pos) +#define RTC_MODE0_CTRL_PRESCALER_Pos 8 /**< \brief (RTC_MODE0_CTRL) Prescaler */ +#define RTC_MODE0_CTRL_PRESCALER_Msk (0xFu << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER(value) ((RTC_MODE0_CTRL_PRESCALER_Msk & ((value) << RTC_MODE0_CTRL_PRESCALER_Pos))) +#define RTC_MODE0_CTRL_PRESCALER_DIV1_Val 0x0u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/1 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV2_Val 0x1u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/2 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV4_Val 0x2u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/4 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV8_Val 0x3u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/8 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV16_Val 0x4u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/16 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV32_Val 0x5u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/32 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV64_Val 0x6u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/64 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV128_Val 0x7u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/128 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV256_Val 0x8u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/256 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV512_Val 0x9u /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/512 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV1024_Val 0xAu /**< \brief (RTC_MODE0_CTRL) CLK_RTC_CNT = GCLK_RTC/1024 */ +#define RTC_MODE0_CTRL_PRESCALER_DIV1 (RTC_MODE0_CTRL_PRESCALER_DIV1_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV2 (RTC_MODE0_CTRL_PRESCALER_DIV2_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV4 (RTC_MODE0_CTRL_PRESCALER_DIV4_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV8 (RTC_MODE0_CTRL_PRESCALER_DIV8_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV16 (RTC_MODE0_CTRL_PRESCALER_DIV16_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV32 (RTC_MODE0_CTRL_PRESCALER_DIV32_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV64 (RTC_MODE0_CTRL_PRESCALER_DIV64_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV128 (RTC_MODE0_CTRL_PRESCALER_DIV128_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV256 (RTC_MODE0_CTRL_PRESCALER_DIV256_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV512 (RTC_MODE0_CTRL_PRESCALER_DIV512_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_PRESCALER_DIV1024 (RTC_MODE0_CTRL_PRESCALER_DIV1024_Val << RTC_MODE0_CTRL_PRESCALER_Pos) +#define RTC_MODE0_CTRL_MASK 0x0F8Fu /**< \brief (RTC_MODE0_CTRL) MASK Register */ + +/* -------- RTC_MODE1_CTRL : (RTC Offset: 0x00) (R/W 16) MODE1 MODE1 Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t SWRST:1; /*!< bit: 0 Software Reset */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t MODE:2; /*!< bit: 2.. 3 Operating Mode */ + uint16_t :4; /*!< bit: 4.. 7 Reserved */ + uint16_t PRESCALER:4; /*!< bit: 8..11 Prescaler */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE1_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_CTRL_OFFSET 0x00 /**< \brief (RTC_MODE1_CTRL offset) MODE1 Control */ +#define RTC_MODE1_CTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE1_CTRL reset_value) MODE1 Control */ + +#define RTC_MODE1_CTRL_SWRST_Pos 0 /**< \brief (RTC_MODE1_CTRL) Software Reset */ +#define RTC_MODE1_CTRL_SWRST (0x1u << RTC_MODE1_CTRL_SWRST_Pos) +#define RTC_MODE1_CTRL_ENABLE_Pos 1 /**< \brief (RTC_MODE1_CTRL) Enable */ +#define RTC_MODE1_CTRL_ENABLE (0x1u << RTC_MODE1_CTRL_ENABLE_Pos) +#define RTC_MODE1_CTRL_MODE_Pos 2 /**< \brief (RTC_MODE1_CTRL) Operating Mode */ +#define RTC_MODE1_CTRL_MODE_Msk (0x3u << RTC_MODE1_CTRL_MODE_Pos) +#define RTC_MODE1_CTRL_MODE(value) ((RTC_MODE1_CTRL_MODE_Msk & ((value) << RTC_MODE1_CTRL_MODE_Pos))) +#define RTC_MODE1_CTRL_MODE_COUNT32_Val 0x0u /**< \brief (RTC_MODE1_CTRL) Mode 0: 32-bit Counter */ +#define RTC_MODE1_CTRL_MODE_COUNT16_Val 0x1u /**< \brief (RTC_MODE1_CTRL) Mode 1: 16-bit Counter */ +#define RTC_MODE1_CTRL_MODE_CLOCK_Val 0x2u /**< \brief (RTC_MODE1_CTRL) Mode 2: Clock/Calendar */ +#define RTC_MODE1_CTRL_MODE_COUNT32 (RTC_MODE1_CTRL_MODE_COUNT32_Val << RTC_MODE1_CTRL_MODE_Pos) +#define RTC_MODE1_CTRL_MODE_COUNT16 (RTC_MODE1_CTRL_MODE_COUNT16_Val << RTC_MODE1_CTRL_MODE_Pos) +#define RTC_MODE1_CTRL_MODE_CLOCK (RTC_MODE1_CTRL_MODE_CLOCK_Val << RTC_MODE1_CTRL_MODE_Pos) +#define RTC_MODE1_CTRL_PRESCALER_Pos 8 /**< \brief (RTC_MODE1_CTRL) Prescaler */ +#define RTC_MODE1_CTRL_PRESCALER_Msk (0xFu << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER(value) ((RTC_MODE1_CTRL_PRESCALER_Msk & ((value) << RTC_MODE1_CTRL_PRESCALER_Pos))) +#define RTC_MODE1_CTRL_PRESCALER_DIV1_Val 0x0u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/1 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV2_Val 0x1u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/2 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV4_Val 0x2u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/4 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV8_Val 0x3u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/8 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV16_Val 0x4u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/16 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV32_Val 0x5u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/32 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV64_Val 0x6u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/64 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV128_Val 0x7u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/128 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV256_Val 0x8u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/256 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV512_Val 0x9u /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/512 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV1024_Val 0xAu /**< \brief (RTC_MODE1_CTRL) CLK_RTC_CNT = GCLK_RTC/1024 */ +#define RTC_MODE1_CTRL_PRESCALER_DIV1 (RTC_MODE1_CTRL_PRESCALER_DIV1_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV2 (RTC_MODE1_CTRL_PRESCALER_DIV2_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV4 (RTC_MODE1_CTRL_PRESCALER_DIV4_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV8 (RTC_MODE1_CTRL_PRESCALER_DIV8_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV16 (RTC_MODE1_CTRL_PRESCALER_DIV16_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV32 (RTC_MODE1_CTRL_PRESCALER_DIV32_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV64 (RTC_MODE1_CTRL_PRESCALER_DIV64_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV128 (RTC_MODE1_CTRL_PRESCALER_DIV128_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV256 (RTC_MODE1_CTRL_PRESCALER_DIV256_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV512 (RTC_MODE1_CTRL_PRESCALER_DIV512_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_PRESCALER_DIV1024 (RTC_MODE1_CTRL_PRESCALER_DIV1024_Val << RTC_MODE1_CTRL_PRESCALER_Pos) +#define RTC_MODE1_CTRL_MASK 0x0F0Fu /**< \brief (RTC_MODE1_CTRL) MASK Register */ + +/* -------- RTC_MODE2_CTRL : (RTC Offset: 0x00) (R/W 16) MODE2 MODE2 Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t SWRST:1; /*!< bit: 0 Software Reset */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t MODE:2; /*!< bit: 2.. 3 Operating Mode */ + uint16_t :2; /*!< bit: 4.. 5 Reserved */ + uint16_t CLKREP:1; /*!< bit: 6 Clock Representation */ + uint16_t MATCHCLR:1; /*!< bit: 7 Clear on Match */ + uint16_t PRESCALER:4; /*!< bit: 8..11 Prescaler */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE2_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_CTRL_OFFSET 0x00 /**< \brief (RTC_MODE2_CTRL offset) MODE2 Control */ +#define RTC_MODE2_CTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE2_CTRL reset_value) MODE2 Control */ + +#define RTC_MODE2_CTRL_SWRST_Pos 0 /**< \brief (RTC_MODE2_CTRL) Software Reset */ +#define RTC_MODE2_CTRL_SWRST (0x1u << RTC_MODE2_CTRL_SWRST_Pos) +#define RTC_MODE2_CTRL_ENABLE_Pos 1 /**< \brief (RTC_MODE2_CTRL) Enable */ +#define RTC_MODE2_CTRL_ENABLE (0x1u << RTC_MODE2_CTRL_ENABLE_Pos) +#define RTC_MODE2_CTRL_MODE_Pos 2 /**< \brief (RTC_MODE2_CTRL) Operating Mode */ +#define RTC_MODE2_CTRL_MODE_Msk (0x3u << RTC_MODE2_CTRL_MODE_Pos) +#define RTC_MODE2_CTRL_MODE(value) ((RTC_MODE2_CTRL_MODE_Msk & ((value) << RTC_MODE2_CTRL_MODE_Pos))) +#define RTC_MODE2_CTRL_MODE_COUNT32_Val 0x0u /**< \brief (RTC_MODE2_CTRL) Mode 0: 32-bit Counter */ +#define RTC_MODE2_CTRL_MODE_COUNT16_Val 0x1u /**< \brief (RTC_MODE2_CTRL) Mode 1: 16-bit Counter */ +#define RTC_MODE2_CTRL_MODE_CLOCK_Val 0x2u /**< \brief (RTC_MODE2_CTRL) Mode 2: Clock/Calendar */ +#define RTC_MODE2_CTRL_MODE_COUNT32 (RTC_MODE2_CTRL_MODE_COUNT32_Val << RTC_MODE2_CTRL_MODE_Pos) +#define RTC_MODE2_CTRL_MODE_COUNT16 (RTC_MODE2_CTRL_MODE_COUNT16_Val << RTC_MODE2_CTRL_MODE_Pos) +#define RTC_MODE2_CTRL_MODE_CLOCK (RTC_MODE2_CTRL_MODE_CLOCK_Val << RTC_MODE2_CTRL_MODE_Pos) +#define RTC_MODE2_CTRL_CLKREP_Pos 6 /**< \brief (RTC_MODE2_CTRL) Clock Representation */ +#define RTC_MODE2_CTRL_CLKREP (0x1u << RTC_MODE2_CTRL_CLKREP_Pos) +#define RTC_MODE2_CTRL_MATCHCLR_Pos 7 /**< \brief (RTC_MODE2_CTRL) Clear on Match */ +#define RTC_MODE2_CTRL_MATCHCLR (0x1u << RTC_MODE2_CTRL_MATCHCLR_Pos) +#define RTC_MODE2_CTRL_PRESCALER_Pos 8 /**< \brief (RTC_MODE2_CTRL) Prescaler */ +#define RTC_MODE2_CTRL_PRESCALER_Msk (0xFu << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER(value) ((RTC_MODE2_CTRL_PRESCALER_Msk & ((value) << RTC_MODE2_CTRL_PRESCALER_Pos))) +#define RTC_MODE2_CTRL_PRESCALER_DIV1_Val 0x0u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/1 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV2_Val 0x1u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/2 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV4_Val 0x2u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/4 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV8_Val 0x3u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/8 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV16_Val 0x4u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/16 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV32_Val 0x5u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/32 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV64_Val 0x6u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/64 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV128_Val 0x7u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/128 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV256_Val 0x8u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/256 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV512_Val 0x9u /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/512 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV1024_Val 0xAu /**< \brief (RTC_MODE2_CTRL) CLK_RTC_CNT = GCLK_RTC/1024 */ +#define RTC_MODE2_CTRL_PRESCALER_DIV1 (RTC_MODE2_CTRL_PRESCALER_DIV1_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV2 (RTC_MODE2_CTRL_PRESCALER_DIV2_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV4 (RTC_MODE2_CTRL_PRESCALER_DIV4_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV8 (RTC_MODE2_CTRL_PRESCALER_DIV8_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV16 (RTC_MODE2_CTRL_PRESCALER_DIV16_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV32 (RTC_MODE2_CTRL_PRESCALER_DIV32_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV64 (RTC_MODE2_CTRL_PRESCALER_DIV64_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV128 (RTC_MODE2_CTRL_PRESCALER_DIV128_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV256 (RTC_MODE2_CTRL_PRESCALER_DIV256_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV512 (RTC_MODE2_CTRL_PRESCALER_DIV512_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_PRESCALER_DIV1024 (RTC_MODE2_CTRL_PRESCALER_DIV1024_Val << RTC_MODE2_CTRL_PRESCALER_Pos) +#define RTC_MODE2_CTRL_MASK 0x0FCFu /**< \brief (RTC_MODE2_CTRL) MASK Register */ + +/* -------- RTC_READREQ : (RTC Offset: 0x02) (R/W 16) Read Request -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t ADDR:6; /*!< bit: 0.. 5 Address */ + uint16_t :8; /*!< bit: 6..13 Reserved */ + uint16_t RCONT:1; /*!< bit: 14 Read Continuously */ + uint16_t RREQ:1; /*!< bit: 15 Read Request */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_READREQ_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_READREQ_OFFSET 0x02 /**< \brief (RTC_READREQ offset) Read Request */ +#define RTC_READREQ_RESETVALUE 0x0010 /**< \brief (RTC_READREQ reset_value) Read Request */ + +#define RTC_READREQ_ADDR_Pos 0 /**< \brief (RTC_READREQ) Address */ +#define RTC_READREQ_ADDR_Msk (0x3Fu << RTC_READREQ_ADDR_Pos) +#define RTC_READREQ_ADDR(value) ((RTC_READREQ_ADDR_Msk & ((value) << RTC_READREQ_ADDR_Pos))) +#define RTC_READREQ_RCONT_Pos 14 /**< \brief (RTC_READREQ) Read Continuously */ +#define RTC_READREQ_RCONT (0x1u << RTC_READREQ_RCONT_Pos) +#define RTC_READREQ_RREQ_Pos 15 /**< \brief (RTC_READREQ) Read Request */ +#define RTC_READREQ_RREQ (0x1u << RTC_READREQ_RREQ_Pos) +#define RTC_READREQ_MASK 0xC03Fu /**< \brief (RTC_READREQ) MASK Register */ + +/* -------- RTC_MODE0_EVCTRL : (RTC Offset: 0x04) (R/W 16) MODE0 MODE0 Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PEREO0:1; /*!< bit: 0 Periodic Interval 0 Event Output Enable */ + uint16_t PEREO1:1; /*!< bit: 1 Periodic Interval 1 Event Output Enable */ + uint16_t PEREO2:1; /*!< bit: 2 Periodic Interval 2 Event Output Enable */ + uint16_t PEREO3:1; /*!< bit: 3 Periodic Interval 3 Event Output Enable */ + uint16_t PEREO4:1; /*!< bit: 4 Periodic Interval 4 Event Output Enable */ + uint16_t PEREO5:1; /*!< bit: 5 Periodic Interval 5 Event Output Enable */ + uint16_t PEREO6:1; /*!< bit: 6 Periodic Interval 6 Event Output Enable */ + uint16_t PEREO7:1; /*!< bit: 7 Periodic Interval 7 Event Output Enable */ + uint16_t CMPEO0:1; /*!< bit: 8 Compare 0 Event Output Enable */ + uint16_t :6; /*!< bit: 9..14 Reserved */ + uint16_t OVFEO:1; /*!< bit: 15 Overflow Event Output Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t PEREO:8; /*!< bit: 0.. 7 Periodic Interval x Event Output Enable */ + uint16_t CMPEO:1; /*!< bit: 8 Compare x Event Output Enable */ + uint16_t :7; /*!< bit: 9..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE0_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_EVCTRL_OFFSET 0x04 /**< \brief (RTC_MODE0_EVCTRL offset) MODE0 Event Control */ +#define RTC_MODE0_EVCTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE0_EVCTRL reset_value) MODE0 Event Control */ + +#define RTC_MODE0_EVCTRL_PEREO0_Pos 0 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 0 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO0 (1 << RTC_MODE0_EVCTRL_PEREO0_Pos) +#define RTC_MODE0_EVCTRL_PEREO1_Pos 1 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 1 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO1 (1 << RTC_MODE0_EVCTRL_PEREO1_Pos) +#define RTC_MODE0_EVCTRL_PEREO2_Pos 2 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 2 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO2 (1 << RTC_MODE0_EVCTRL_PEREO2_Pos) +#define RTC_MODE0_EVCTRL_PEREO3_Pos 3 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 3 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO3 (1 << RTC_MODE0_EVCTRL_PEREO3_Pos) +#define RTC_MODE0_EVCTRL_PEREO4_Pos 4 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 4 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO4 (1 << RTC_MODE0_EVCTRL_PEREO4_Pos) +#define RTC_MODE0_EVCTRL_PEREO5_Pos 5 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 5 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO5 (1 << RTC_MODE0_EVCTRL_PEREO5_Pos) +#define RTC_MODE0_EVCTRL_PEREO6_Pos 6 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 6 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO6 (1 << RTC_MODE0_EVCTRL_PEREO6_Pos) +#define RTC_MODE0_EVCTRL_PEREO7_Pos 7 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval 7 Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO7 (1 << RTC_MODE0_EVCTRL_PEREO7_Pos) +#define RTC_MODE0_EVCTRL_PEREO_Pos 0 /**< \brief (RTC_MODE0_EVCTRL) Periodic Interval x Event Output Enable */ +#define RTC_MODE0_EVCTRL_PEREO_Msk (0xFFu << RTC_MODE0_EVCTRL_PEREO_Pos) +#define RTC_MODE0_EVCTRL_PEREO(value) ((RTC_MODE0_EVCTRL_PEREO_Msk & ((value) << RTC_MODE0_EVCTRL_PEREO_Pos))) +#define RTC_MODE0_EVCTRL_CMPEO0_Pos 8 /**< \brief (RTC_MODE0_EVCTRL) Compare 0 Event Output Enable */ +#define RTC_MODE0_EVCTRL_CMPEO0 (1 << RTC_MODE0_EVCTRL_CMPEO0_Pos) +#define RTC_MODE0_EVCTRL_CMPEO_Pos 8 /**< \brief (RTC_MODE0_EVCTRL) Compare x Event Output Enable */ +#define RTC_MODE0_EVCTRL_CMPEO_Msk (0x1u << RTC_MODE0_EVCTRL_CMPEO_Pos) +#define RTC_MODE0_EVCTRL_CMPEO(value) ((RTC_MODE0_EVCTRL_CMPEO_Msk & ((value) << RTC_MODE0_EVCTRL_CMPEO_Pos))) +#define RTC_MODE0_EVCTRL_OVFEO_Pos 15 /**< \brief (RTC_MODE0_EVCTRL) Overflow Event Output Enable */ +#define RTC_MODE0_EVCTRL_OVFEO (0x1u << RTC_MODE0_EVCTRL_OVFEO_Pos) +#define RTC_MODE0_EVCTRL_MASK 0x81FFu /**< \brief (RTC_MODE0_EVCTRL) MASK Register */ + +/* -------- RTC_MODE1_EVCTRL : (RTC Offset: 0x04) (R/W 16) MODE1 MODE1 Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PEREO0:1; /*!< bit: 0 Periodic Interval 0 Event Output Enable */ + uint16_t PEREO1:1; /*!< bit: 1 Periodic Interval 1 Event Output Enable */ + uint16_t PEREO2:1; /*!< bit: 2 Periodic Interval 2 Event Output Enable */ + uint16_t PEREO3:1; /*!< bit: 3 Periodic Interval 3 Event Output Enable */ + uint16_t PEREO4:1; /*!< bit: 4 Periodic Interval 4 Event Output Enable */ + uint16_t PEREO5:1; /*!< bit: 5 Periodic Interval 5 Event Output Enable */ + uint16_t PEREO6:1; /*!< bit: 6 Periodic Interval 6 Event Output Enable */ + uint16_t PEREO7:1; /*!< bit: 7 Periodic Interval 7 Event Output Enable */ + uint16_t CMPEO0:1; /*!< bit: 8 Compare 0 Event Output Enable */ + uint16_t CMPEO1:1; /*!< bit: 9 Compare 1 Event Output Enable */ + uint16_t :5; /*!< bit: 10..14 Reserved */ + uint16_t OVFEO:1; /*!< bit: 15 Overflow Event Output Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t PEREO:8; /*!< bit: 0.. 7 Periodic Interval x Event Output Enable */ + uint16_t CMPEO:2; /*!< bit: 8.. 9 Compare x Event Output Enable */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE1_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_EVCTRL_OFFSET 0x04 /**< \brief (RTC_MODE1_EVCTRL offset) MODE1 Event Control */ +#define RTC_MODE1_EVCTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE1_EVCTRL reset_value) MODE1 Event Control */ + +#define RTC_MODE1_EVCTRL_PEREO0_Pos 0 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 0 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO0 (1 << RTC_MODE1_EVCTRL_PEREO0_Pos) +#define RTC_MODE1_EVCTRL_PEREO1_Pos 1 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 1 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO1 (1 << RTC_MODE1_EVCTRL_PEREO1_Pos) +#define RTC_MODE1_EVCTRL_PEREO2_Pos 2 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 2 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO2 (1 << RTC_MODE1_EVCTRL_PEREO2_Pos) +#define RTC_MODE1_EVCTRL_PEREO3_Pos 3 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 3 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO3 (1 << RTC_MODE1_EVCTRL_PEREO3_Pos) +#define RTC_MODE1_EVCTRL_PEREO4_Pos 4 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 4 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO4 (1 << RTC_MODE1_EVCTRL_PEREO4_Pos) +#define RTC_MODE1_EVCTRL_PEREO5_Pos 5 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 5 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO5 (1 << RTC_MODE1_EVCTRL_PEREO5_Pos) +#define RTC_MODE1_EVCTRL_PEREO6_Pos 6 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 6 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO6 (1 << RTC_MODE1_EVCTRL_PEREO6_Pos) +#define RTC_MODE1_EVCTRL_PEREO7_Pos 7 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval 7 Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO7 (1 << RTC_MODE1_EVCTRL_PEREO7_Pos) +#define RTC_MODE1_EVCTRL_PEREO_Pos 0 /**< \brief (RTC_MODE1_EVCTRL) Periodic Interval x Event Output Enable */ +#define RTC_MODE1_EVCTRL_PEREO_Msk (0xFFu << RTC_MODE1_EVCTRL_PEREO_Pos) +#define RTC_MODE1_EVCTRL_PEREO(value) ((RTC_MODE1_EVCTRL_PEREO_Msk & ((value) << RTC_MODE1_EVCTRL_PEREO_Pos))) +#define RTC_MODE1_EVCTRL_CMPEO0_Pos 8 /**< \brief (RTC_MODE1_EVCTRL) Compare 0 Event Output Enable */ +#define RTC_MODE1_EVCTRL_CMPEO0 (1 << RTC_MODE1_EVCTRL_CMPEO0_Pos) +#define RTC_MODE1_EVCTRL_CMPEO1_Pos 9 /**< \brief (RTC_MODE1_EVCTRL) Compare 1 Event Output Enable */ +#define RTC_MODE1_EVCTRL_CMPEO1 (1 << RTC_MODE1_EVCTRL_CMPEO1_Pos) +#define RTC_MODE1_EVCTRL_CMPEO_Pos 8 /**< \brief (RTC_MODE1_EVCTRL) Compare x Event Output Enable */ +#define RTC_MODE1_EVCTRL_CMPEO_Msk (0x3u << RTC_MODE1_EVCTRL_CMPEO_Pos) +#define RTC_MODE1_EVCTRL_CMPEO(value) ((RTC_MODE1_EVCTRL_CMPEO_Msk & ((value) << RTC_MODE1_EVCTRL_CMPEO_Pos))) +#define RTC_MODE1_EVCTRL_OVFEO_Pos 15 /**< \brief (RTC_MODE1_EVCTRL) Overflow Event Output Enable */ +#define RTC_MODE1_EVCTRL_OVFEO (0x1u << RTC_MODE1_EVCTRL_OVFEO_Pos) +#define RTC_MODE1_EVCTRL_MASK 0x83FFu /**< \brief (RTC_MODE1_EVCTRL) MASK Register */ + +/* -------- RTC_MODE2_EVCTRL : (RTC Offset: 0x04) (R/W 16) MODE2 MODE2 Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PEREO0:1; /*!< bit: 0 Periodic Interval 0 Event Output Enable */ + uint16_t PEREO1:1; /*!< bit: 1 Periodic Interval 1 Event Output Enable */ + uint16_t PEREO2:1; /*!< bit: 2 Periodic Interval 2 Event Output Enable */ + uint16_t PEREO3:1; /*!< bit: 3 Periodic Interval 3 Event Output Enable */ + uint16_t PEREO4:1; /*!< bit: 4 Periodic Interval 4 Event Output Enable */ + uint16_t PEREO5:1; /*!< bit: 5 Periodic Interval 5 Event Output Enable */ + uint16_t PEREO6:1; /*!< bit: 6 Periodic Interval 6 Event Output Enable */ + uint16_t PEREO7:1; /*!< bit: 7 Periodic Interval 7 Event Output Enable */ + uint16_t ALARMEO0:1; /*!< bit: 8 Alarm 0 Event Output Enable */ + uint16_t :6; /*!< bit: 9..14 Reserved */ + uint16_t OVFEO:1; /*!< bit: 15 Overflow Event Output Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t PEREO:8; /*!< bit: 0.. 7 Periodic Interval x Event Output Enable */ + uint16_t ALARMEO:1; /*!< bit: 8 Alarm x Event Output Enable */ + uint16_t :7; /*!< bit: 9..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE2_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_EVCTRL_OFFSET 0x04 /**< \brief (RTC_MODE2_EVCTRL offset) MODE2 Event Control */ +#define RTC_MODE2_EVCTRL_RESETVALUE 0x0000 /**< \brief (RTC_MODE2_EVCTRL reset_value) MODE2 Event Control */ + +#define RTC_MODE2_EVCTRL_PEREO0_Pos 0 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 0 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO0 (1 << RTC_MODE2_EVCTRL_PEREO0_Pos) +#define RTC_MODE2_EVCTRL_PEREO1_Pos 1 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 1 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO1 (1 << RTC_MODE2_EVCTRL_PEREO1_Pos) +#define RTC_MODE2_EVCTRL_PEREO2_Pos 2 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 2 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO2 (1 << RTC_MODE2_EVCTRL_PEREO2_Pos) +#define RTC_MODE2_EVCTRL_PEREO3_Pos 3 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 3 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO3 (1 << RTC_MODE2_EVCTRL_PEREO3_Pos) +#define RTC_MODE2_EVCTRL_PEREO4_Pos 4 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 4 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO4 (1 << RTC_MODE2_EVCTRL_PEREO4_Pos) +#define RTC_MODE2_EVCTRL_PEREO5_Pos 5 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 5 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO5 (1 << RTC_MODE2_EVCTRL_PEREO5_Pos) +#define RTC_MODE2_EVCTRL_PEREO6_Pos 6 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 6 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO6 (1 << RTC_MODE2_EVCTRL_PEREO6_Pos) +#define RTC_MODE2_EVCTRL_PEREO7_Pos 7 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval 7 Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO7 (1 << RTC_MODE2_EVCTRL_PEREO7_Pos) +#define RTC_MODE2_EVCTRL_PEREO_Pos 0 /**< \brief (RTC_MODE2_EVCTRL) Periodic Interval x Event Output Enable */ +#define RTC_MODE2_EVCTRL_PEREO_Msk (0xFFu << RTC_MODE2_EVCTRL_PEREO_Pos) +#define RTC_MODE2_EVCTRL_PEREO(value) ((RTC_MODE2_EVCTRL_PEREO_Msk & ((value) << RTC_MODE2_EVCTRL_PEREO_Pos))) +#define RTC_MODE2_EVCTRL_ALARMEO0_Pos 8 /**< \brief (RTC_MODE2_EVCTRL) Alarm 0 Event Output Enable */ +#define RTC_MODE2_EVCTRL_ALARMEO0 (1 << RTC_MODE2_EVCTRL_ALARMEO0_Pos) +#define RTC_MODE2_EVCTRL_ALARMEO_Pos 8 /**< \brief (RTC_MODE2_EVCTRL) Alarm x Event Output Enable */ +#define RTC_MODE2_EVCTRL_ALARMEO_Msk (0x1u << RTC_MODE2_EVCTRL_ALARMEO_Pos) +#define RTC_MODE2_EVCTRL_ALARMEO(value) ((RTC_MODE2_EVCTRL_ALARMEO_Msk & ((value) << RTC_MODE2_EVCTRL_ALARMEO_Pos))) +#define RTC_MODE2_EVCTRL_OVFEO_Pos 15 /**< \brief (RTC_MODE2_EVCTRL) Overflow Event Output Enable */ +#define RTC_MODE2_EVCTRL_OVFEO (0x1u << RTC_MODE2_EVCTRL_OVFEO_Pos) +#define RTC_MODE2_EVCTRL_MASK 0x81FFu /**< \brief (RTC_MODE2_EVCTRL) MASK Register */ + +/* -------- RTC_MODE0_INTENCLR : (RTC Offset: 0x06) (R/W 8) MODE0 MODE0 Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 Interrupt Enable */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:1; /*!< bit: 0 Compare x Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE0_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_INTENCLR_OFFSET 0x06 /**< \brief (RTC_MODE0_INTENCLR offset) MODE0 Interrupt Enable Clear */ +#define RTC_MODE0_INTENCLR_RESETVALUE 0x00 /**< \brief (RTC_MODE0_INTENCLR reset_value) MODE0 Interrupt Enable Clear */ + +#define RTC_MODE0_INTENCLR_CMP0_Pos 0 /**< \brief (RTC_MODE0_INTENCLR) Compare 0 Interrupt Enable */ +#define RTC_MODE0_INTENCLR_CMP0 (1 << RTC_MODE0_INTENCLR_CMP0_Pos) +#define RTC_MODE0_INTENCLR_CMP_Pos 0 /**< \brief (RTC_MODE0_INTENCLR) Compare x Interrupt Enable */ +#define RTC_MODE0_INTENCLR_CMP_Msk (0x1u << RTC_MODE0_INTENCLR_CMP_Pos) +#define RTC_MODE0_INTENCLR_CMP(value) ((RTC_MODE0_INTENCLR_CMP_Msk & ((value) << RTC_MODE0_INTENCLR_CMP_Pos))) +#define RTC_MODE0_INTENCLR_SYNCRDY_Pos 6 /**< \brief (RTC_MODE0_INTENCLR) Synchronization Ready Interrupt Enable */ +#define RTC_MODE0_INTENCLR_SYNCRDY (0x1u << RTC_MODE0_INTENCLR_SYNCRDY_Pos) +#define RTC_MODE0_INTENCLR_OVF_Pos 7 /**< \brief (RTC_MODE0_INTENCLR) Overflow Interrupt Enable */ +#define RTC_MODE0_INTENCLR_OVF (0x1u << RTC_MODE0_INTENCLR_OVF_Pos) +#define RTC_MODE0_INTENCLR_MASK 0xC1u /**< \brief (RTC_MODE0_INTENCLR) MASK Register */ + +/* -------- RTC_MODE1_INTENCLR : (RTC Offset: 0x06) (R/W 8) MODE1 MODE1 Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 Interrupt Enable */ + uint8_t CMP1:1; /*!< bit: 1 Compare 1 Interrupt Enable */ + uint8_t :4; /*!< bit: 2.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:2; /*!< bit: 0.. 1 Compare x Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE1_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_INTENCLR_OFFSET 0x06 /**< \brief (RTC_MODE1_INTENCLR offset) MODE1 Interrupt Enable Clear */ +#define RTC_MODE1_INTENCLR_RESETVALUE 0x00 /**< \brief (RTC_MODE1_INTENCLR reset_value) MODE1 Interrupt Enable Clear */ + +#define RTC_MODE1_INTENCLR_CMP0_Pos 0 /**< \brief (RTC_MODE1_INTENCLR) Compare 0 Interrupt Enable */ +#define RTC_MODE1_INTENCLR_CMP0 (1 << RTC_MODE1_INTENCLR_CMP0_Pos) +#define RTC_MODE1_INTENCLR_CMP1_Pos 1 /**< \brief (RTC_MODE1_INTENCLR) Compare 1 Interrupt Enable */ +#define RTC_MODE1_INTENCLR_CMP1 (1 << RTC_MODE1_INTENCLR_CMP1_Pos) +#define RTC_MODE1_INTENCLR_CMP_Pos 0 /**< \brief (RTC_MODE1_INTENCLR) Compare x Interrupt Enable */ +#define RTC_MODE1_INTENCLR_CMP_Msk (0x3u << RTC_MODE1_INTENCLR_CMP_Pos) +#define RTC_MODE1_INTENCLR_CMP(value) ((RTC_MODE1_INTENCLR_CMP_Msk & ((value) << RTC_MODE1_INTENCLR_CMP_Pos))) +#define RTC_MODE1_INTENCLR_SYNCRDY_Pos 6 /**< \brief (RTC_MODE1_INTENCLR) Synchronization Ready Interrupt Enable */ +#define RTC_MODE1_INTENCLR_SYNCRDY (0x1u << RTC_MODE1_INTENCLR_SYNCRDY_Pos) +#define RTC_MODE1_INTENCLR_OVF_Pos 7 /**< \brief (RTC_MODE1_INTENCLR) Overflow Interrupt Enable */ +#define RTC_MODE1_INTENCLR_OVF (0x1u << RTC_MODE1_INTENCLR_OVF_Pos) +#define RTC_MODE1_INTENCLR_MASK 0xC3u /**< \brief (RTC_MODE1_INTENCLR) MASK Register */ + +/* -------- RTC_MODE2_INTENCLR : (RTC Offset: 0x06) (R/W 8) MODE2 MODE2 Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t ALARM0:1; /*!< bit: 0 Alarm 0 Interrupt Enable */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t ALARM:1; /*!< bit: 0 Alarm x Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE2_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_INTENCLR_OFFSET 0x06 /**< \brief (RTC_MODE2_INTENCLR offset) MODE2 Interrupt Enable Clear */ +#define RTC_MODE2_INTENCLR_RESETVALUE 0x00 /**< \brief (RTC_MODE2_INTENCLR reset_value) MODE2 Interrupt Enable Clear */ + +#define RTC_MODE2_INTENCLR_ALARM0_Pos 0 /**< \brief (RTC_MODE2_INTENCLR) Alarm 0 Interrupt Enable */ +#define RTC_MODE2_INTENCLR_ALARM0 (1 << RTC_MODE2_INTENCLR_ALARM0_Pos) +#define RTC_MODE2_INTENCLR_ALARM_Pos 0 /**< \brief (RTC_MODE2_INTENCLR) Alarm x Interrupt Enable */ +#define RTC_MODE2_INTENCLR_ALARM_Msk (0x1u << RTC_MODE2_INTENCLR_ALARM_Pos) +#define RTC_MODE2_INTENCLR_ALARM(value) ((RTC_MODE2_INTENCLR_ALARM_Msk & ((value) << RTC_MODE2_INTENCLR_ALARM_Pos))) +#define RTC_MODE2_INTENCLR_SYNCRDY_Pos 6 /**< \brief (RTC_MODE2_INTENCLR) Synchronization Ready Interrupt Enable */ +#define RTC_MODE2_INTENCLR_SYNCRDY (0x1u << RTC_MODE2_INTENCLR_SYNCRDY_Pos) +#define RTC_MODE2_INTENCLR_OVF_Pos 7 /**< \brief (RTC_MODE2_INTENCLR) Overflow Interrupt Enable */ +#define RTC_MODE2_INTENCLR_OVF (0x1u << RTC_MODE2_INTENCLR_OVF_Pos) +#define RTC_MODE2_INTENCLR_MASK 0xC1u /**< \brief (RTC_MODE2_INTENCLR) MASK Register */ + +/* -------- RTC_MODE0_INTENSET : (RTC Offset: 0x07) (R/W 8) MODE0 MODE0 Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 Interrupt Enable */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:1; /*!< bit: 0 Compare x Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE0_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_INTENSET_OFFSET 0x07 /**< \brief (RTC_MODE0_INTENSET offset) MODE0 Interrupt Enable Set */ +#define RTC_MODE0_INTENSET_RESETVALUE 0x00 /**< \brief (RTC_MODE0_INTENSET reset_value) MODE0 Interrupt Enable Set */ + +#define RTC_MODE0_INTENSET_CMP0_Pos 0 /**< \brief (RTC_MODE0_INTENSET) Compare 0 Interrupt Enable */ +#define RTC_MODE0_INTENSET_CMP0 (1 << RTC_MODE0_INTENSET_CMP0_Pos) +#define RTC_MODE0_INTENSET_CMP_Pos 0 /**< \brief (RTC_MODE0_INTENSET) Compare x Interrupt Enable */ +#define RTC_MODE0_INTENSET_CMP_Msk (0x1u << RTC_MODE0_INTENSET_CMP_Pos) +#define RTC_MODE0_INTENSET_CMP(value) ((RTC_MODE0_INTENSET_CMP_Msk & ((value) << RTC_MODE0_INTENSET_CMP_Pos))) +#define RTC_MODE0_INTENSET_SYNCRDY_Pos 6 /**< \brief (RTC_MODE0_INTENSET) Synchronization Ready Interrupt Enable */ +#define RTC_MODE0_INTENSET_SYNCRDY (0x1u << RTC_MODE0_INTENSET_SYNCRDY_Pos) +#define RTC_MODE0_INTENSET_OVF_Pos 7 /**< \brief (RTC_MODE0_INTENSET) Overflow Interrupt Enable */ +#define RTC_MODE0_INTENSET_OVF (0x1u << RTC_MODE0_INTENSET_OVF_Pos) +#define RTC_MODE0_INTENSET_MASK 0xC1u /**< \brief (RTC_MODE0_INTENSET) MASK Register */ + +/* -------- RTC_MODE1_INTENSET : (RTC Offset: 0x07) (R/W 8) MODE1 MODE1 Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 Interrupt Enable */ + uint8_t CMP1:1; /*!< bit: 1 Compare 1 Interrupt Enable */ + uint8_t :4; /*!< bit: 2.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:2; /*!< bit: 0.. 1 Compare x Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE1_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_INTENSET_OFFSET 0x07 /**< \brief (RTC_MODE1_INTENSET offset) MODE1 Interrupt Enable Set */ +#define RTC_MODE1_INTENSET_RESETVALUE 0x00 /**< \brief (RTC_MODE1_INTENSET reset_value) MODE1 Interrupt Enable Set */ + +#define RTC_MODE1_INTENSET_CMP0_Pos 0 /**< \brief (RTC_MODE1_INTENSET) Compare 0 Interrupt Enable */ +#define RTC_MODE1_INTENSET_CMP0 (1 << RTC_MODE1_INTENSET_CMP0_Pos) +#define RTC_MODE1_INTENSET_CMP1_Pos 1 /**< \brief (RTC_MODE1_INTENSET) Compare 1 Interrupt Enable */ +#define RTC_MODE1_INTENSET_CMP1 (1 << RTC_MODE1_INTENSET_CMP1_Pos) +#define RTC_MODE1_INTENSET_CMP_Pos 0 /**< \brief (RTC_MODE1_INTENSET) Compare x Interrupt Enable */ +#define RTC_MODE1_INTENSET_CMP_Msk (0x3u << RTC_MODE1_INTENSET_CMP_Pos) +#define RTC_MODE1_INTENSET_CMP(value) ((RTC_MODE1_INTENSET_CMP_Msk & ((value) << RTC_MODE1_INTENSET_CMP_Pos))) +#define RTC_MODE1_INTENSET_SYNCRDY_Pos 6 /**< \brief (RTC_MODE1_INTENSET) Synchronization Ready Interrupt Enable */ +#define RTC_MODE1_INTENSET_SYNCRDY (0x1u << RTC_MODE1_INTENSET_SYNCRDY_Pos) +#define RTC_MODE1_INTENSET_OVF_Pos 7 /**< \brief (RTC_MODE1_INTENSET) Overflow Interrupt Enable */ +#define RTC_MODE1_INTENSET_OVF (0x1u << RTC_MODE1_INTENSET_OVF_Pos) +#define RTC_MODE1_INTENSET_MASK 0xC3u /**< \brief (RTC_MODE1_INTENSET) MASK Register */ + +/* -------- RTC_MODE2_INTENSET : (RTC Offset: 0x07) (R/W 8) MODE2 MODE2 Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t ALARM0:1; /*!< bit: 0 Alarm 0 Interrupt Enable */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready Interrupt Enable */ + uint8_t OVF:1; /*!< bit: 7 Overflow Interrupt Enable */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t ALARM:1; /*!< bit: 0 Alarm x Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE2_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_INTENSET_OFFSET 0x07 /**< \brief (RTC_MODE2_INTENSET offset) MODE2 Interrupt Enable Set */ +#define RTC_MODE2_INTENSET_RESETVALUE 0x00 /**< \brief (RTC_MODE2_INTENSET reset_value) MODE2 Interrupt Enable Set */ + +#define RTC_MODE2_INTENSET_ALARM0_Pos 0 /**< \brief (RTC_MODE2_INTENSET) Alarm 0 Interrupt Enable */ +#define RTC_MODE2_INTENSET_ALARM0 (1 << RTC_MODE2_INTENSET_ALARM0_Pos) +#define RTC_MODE2_INTENSET_ALARM_Pos 0 /**< \brief (RTC_MODE2_INTENSET) Alarm x Interrupt Enable */ +#define RTC_MODE2_INTENSET_ALARM_Msk (0x1u << RTC_MODE2_INTENSET_ALARM_Pos) +#define RTC_MODE2_INTENSET_ALARM(value) ((RTC_MODE2_INTENSET_ALARM_Msk & ((value) << RTC_MODE2_INTENSET_ALARM_Pos))) +#define RTC_MODE2_INTENSET_SYNCRDY_Pos 6 /**< \brief (RTC_MODE2_INTENSET) Synchronization Ready Interrupt Enable */ +#define RTC_MODE2_INTENSET_SYNCRDY (0x1u << RTC_MODE2_INTENSET_SYNCRDY_Pos) +#define RTC_MODE2_INTENSET_OVF_Pos 7 /**< \brief (RTC_MODE2_INTENSET) Overflow Interrupt Enable */ +#define RTC_MODE2_INTENSET_OVF (0x1u << RTC_MODE2_INTENSET_OVF_Pos) +#define RTC_MODE2_INTENSET_MASK 0xC1u /**< \brief (RTC_MODE2_INTENSET) MASK Register */ + +/* -------- RTC_MODE0_INTFLAG : (RTC Offset: 0x08) (R/W 8) MODE0 MODE0 Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready */ + uint8_t OVF:1; /*!< bit: 7 Overflow */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:1; /*!< bit: 0 Compare x */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE0_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_INTFLAG_OFFSET 0x08 /**< \brief (RTC_MODE0_INTFLAG offset) MODE0 Interrupt Flag Status and Clear */ +#define RTC_MODE0_INTFLAG_RESETVALUE 0x00 /**< \brief (RTC_MODE0_INTFLAG reset_value) MODE0 Interrupt Flag Status and Clear */ + +#define RTC_MODE0_INTFLAG_CMP0_Pos 0 /**< \brief (RTC_MODE0_INTFLAG) Compare 0 */ +#define RTC_MODE0_INTFLAG_CMP0 (1 << RTC_MODE0_INTFLAG_CMP0_Pos) +#define RTC_MODE0_INTFLAG_CMP_Pos 0 /**< \brief (RTC_MODE0_INTFLAG) Compare x */ +#define RTC_MODE0_INTFLAG_CMP_Msk (0x1u << RTC_MODE0_INTFLAG_CMP_Pos) +#define RTC_MODE0_INTFLAG_CMP(value) ((RTC_MODE0_INTFLAG_CMP_Msk & ((value) << RTC_MODE0_INTFLAG_CMP_Pos))) +#define RTC_MODE0_INTFLAG_SYNCRDY_Pos 6 /**< \brief (RTC_MODE0_INTFLAG) Synchronization Ready */ +#define RTC_MODE0_INTFLAG_SYNCRDY (0x1u << RTC_MODE0_INTFLAG_SYNCRDY_Pos) +#define RTC_MODE0_INTFLAG_OVF_Pos 7 /**< \brief (RTC_MODE0_INTFLAG) Overflow */ +#define RTC_MODE0_INTFLAG_OVF (0x1u << RTC_MODE0_INTFLAG_OVF_Pos) +#define RTC_MODE0_INTFLAG_MASK 0xC1u /**< \brief (RTC_MODE0_INTFLAG) MASK Register */ + +/* -------- RTC_MODE1_INTFLAG : (RTC Offset: 0x08) (R/W 8) MODE1 MODE1 Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CMP0:1; /*!< bit: 0 Compare 0 */ + uint8_t CMP1:1; /*!< bit: 1 Compare 1 */ + uint8_t :4; /*!< bit: 2.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready */ + uint8_t OVF:1; /*!< bit: 7 Overflow */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t CMP:2; /*!< bit: 0.. 1 Compare x */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE1_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_INTFLAG_OFFSET 0x08 /**< \brief (RTC_MODE1_INTFLAG offset) MODE1 Interrupt Flag Status and Clear */ +#define RTC_MODE1_INTFLAG_RESETVALUE 0x00 /**< \brief (RTC_MODE1_INTFLAG reset_value) MODE1 Interrupt Flag Status and Clear */ + +#define RTC_MODE1_INTFLAG_CMP0_Pos 0 /**< \brief (RTC_MODE1_INTFLAG) Compare 0 */ +#define RTC_MODE1_INTFLAG_CMP0 (1 << RTC_MODE1_INTFLAG_CMP0_Pos) +#define RTC_MODE1_INTFLAG_CMP1_Pos 1 /**< \brief (RTC_MODE1_INTFLAG) Compare 1 */ +#define RTC_MODE1_INTFLAG_CMP1 (1 << RTC_MODE1_INTFLAG_CMP1_Pos) +#define RTC_MODE1_INTFLAG_CMP_Pos 0 /**< \brief (RTC_MODE1_INTFLAG) Compare x */ +#define RTC_MODE1_INTFLAG_CMP_Msk (0x3u << RTC_MODE1_INTFLAG_CMP_Pos) +#define RTC_MODE1_INTFLAG_CMP(value) ((RTC_MODE1_INTFLAG_CMP_Msk & ((value) << RTC_MODE1_INTFLAG_CMP_Pos))) +#define RTC_MODE1_INTFLAG_SYNCRDY_Pos 6 /**< \brief (RTC_MODE1_INTFLAG) Synchronization Ready */ +#define RTC_MODE1_INTFLAG_SYNCRDY (0x1u << RTC_MODE1_INTFLAG_SYNCRDY_Pos) +#define RTC_MODE1_INTFLAG_OVF_Pos 7 /**< \brief (RTC_MODE1_INTFLAG) Overflow */ +#define RTC_MODE1_INTFLAG_OVF (0x1u << RTC_MODE1_INTFLAG_OVF_Pos) +#define RTC_MODE1_INTFLAG_MASK 0xC3u /**< \brief (RTC_MODE1_INTFLAG) MASK Register */ + +/* -------- RTC_MODE2_INTFLAG : (RTC Offset: 0x08) (R/W 8) MODE2 MODE2 Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t ALARM0:1; /*!< bit: 0 Alarm 0 */ + uint8_t :5; /*!< bit: 1.. 5 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 6 Synchronization Ready */ + uint8_t OVF:1; /*!< bit: 7 Overflow */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t ALARM:1; /*!< bit: 0 Alarm x */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE2_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_INTFLAG_OFFSET 0x08 /**< \brief (RTC_MODE2_INTFLAG offset) MODE2 Interrupt Flag Status and Clear */ +#define RTC_MODE2_INTFLAG_RESETVALUE 0x00 /**< \brief (RTC_MODE2_INTFLAG reset_value) MODE2 Interrupt Flag Status and Clear */ + +#define RTC_MODE2_INTFLAG_ALARM0_Pos 0 /**< \brief (RTC_MODE2_INTFLAG) Alarm 0 */ +#define RTC_MODE2_INTFLAG_ALARM0 (1 << RTC_MODE2_INTFLAG_ALARM0_Pos) +#define RTC_MODE2_INTFLAG_ALARM_Pos 0 /**< \brief (RTC_MODE2_INTFLAG) Alarm x */ +#define RTC_MODE2_INTFLAG_ALARM_Msk (0x1u << RTC_MODE2_INTFLAG_ALARM_Pos) +#define RTC_MODE2_INTFLAG_ALARM(value) ((RTC_MODE2_INTFLAG_ALARM_Msk & ((value) << RTC_MODE2_INTFLAG_ALARM_Pos))) +#define RTC_MODE2_INTFLAG_SYNCRDY_Pos 6 /**< \brief (RTC_MODE2_INTFLAG) Synchronization Ready */ +#define RTC_MODE2_INTFLAG_SYNCRDY (0x1u << RTC_MODE2_INTFLAG_SYNCRDY_Pos) +#define RTC_MODE2_INTFLAG_OVF_Pos 7 /**< \brief (RTC_MODE2_INTFLAG) Overflow */ +#define RTC_MODE2_INTFLAG_OVF (0x1u << RTC_MODE2_INTFLAG_OVF_Pos) +#define RTC_MODE2_INTFLAG_MASK 0xC1u /**< \brief (RTC_MODE2_INTFLAG) MASK Register */ + +/* -------- RTC_STATUS : (RTC Offset: 0x0A) (R/W 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_STATUS_OFFSET 0x0A /**< \brief (RTC_STATUS offset) Status */ +#define RTC_STATUS_RESETVALUE 0x00 /**< \brief (RTC_STATUS reset_value) Status */ + +#define RTC_STATUS_SYNCBUSY_Pos 7 /**< \brief (RTC_STATUS) Synchronization Busy */ +#define RTC_STATUS_SYNCBUSY (0x1u << RTC_STATUS_SYNCBUSY_Pos) +#define RTC_STATUS_MASK 0x80u /**< \brief (RTC_STATUS) MASK Register */ + +/* -------- RTC_DBGCTRL : (RTC Offset: 0x0B) (R/W 8) Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGRUN:1; /*!< bit: 0 Run During Debug */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_DBGCTRL_OFFSET 0x0B /**< \brief (RTC_DBGCTRL offset) Debug Control */ +#define RTC_DBGCTRL_RESETVALUE 0x00 /**< \brief (RTC_DBGCTRL reset_value) Debug Control */ + +#define RTC_DBGCTRL_DBGRUN_Pos 0 /**< \brief (RTC_DBGCTRL) Run During Debug */ +#define RTC_DBGCTRL_DBGRUN (0x1u << RTC_DBGCTRL_DBGRUN_Pos) +#define RTC_DBGCTRL_MASK 0x01u /**< \brief (RTC_DBGCTRL) MASK Register */ + +/* -------- RTC_FREQCORR : (RTC Offset: 0x0C) (R/W 8) Frequency Correction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t VALUE:7; /*!< bit: 0.. 6 Correction Value */ + uint8_t SIGN:1; /*!< bit: 7 Correction Sign */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_FREQCORR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_FREQCORR_OFFSET 0x0C /**< \brief (RTC_FREQCORR offset) Frequency Correction */ +#define RTC_FREQCORR_RESETVALUE 0x00 /**< \brief (RTC_FREQCORR reset_value) Frequency Correction */ + +#define RTC_FREQCORR_VALUE_Pos 0 /**< \brief (RTC_FREQCORR) Correction Value */ +#define RTC_FREQCORR_VALUE_Msk (0x7Fu << RTC_FREQCORR_VALUE_Pos) +#define RTC_FREQCORR_VALUE(value) ((RTC_FREQCORR_VALUE_Msk & ((value) << RTC_FREQCORR_VALUE_Pos))) +#define RTC_FREQCORR_SIGN_Pos 7 /**< \brief (RTC_FREQCORR) Correction Sign */ +#define RTC_FREQCORR_SIGN (0x1u << RTC_FREQCORR_SIGN_Pos) +#define RTC_FREQCORR_MASK 0xFFu /**< \brief (RTC_FREQCORR) MASK Register */ + +/* -------- RTC_MODE0_COUNT : (RTC Offset: 0x10) (R/W 32) MODE0 MODE0 Counter Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t COUNT:32; /*!< bit: 0..31 Counter Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} RTC_MODE0_COUNT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_COUNT_OFFSET 0x10 /**< \brief (RTC_MODE0_COUNT offset) MODE0 Counter Value */ +#define RTC_MODE0_COUNT_RESETVALUE 0x00000000 /**< \brief (RTC_MODE0_COUNT reset_value) MODE0 Counter Value */ + +#define RTC_MODE0_COUNT_COUNT_Pos 0 /**< \brief (RTC_MODE0_COUNT) Counter Value */ +#define RTC_MODE0_COUNT_COUNT_Msk (0xFFFFFFFFu << RTC_MODE0_COUNT_COUNT_Pos) +#define RTC_MODE0_COUNT_COUNT(value) ((RTC_MODE0_COUNT_COUNT_Msk & ((value) << RTC_MODE0_COUNT_COUNT_Pos))) +#define RTC_MODE0_COUNT_MASK 0xFFFFFFFFu /**< \brief (RTC_MODE0_COUNT) MASK Register */ + +/* -------- RTC_MODE1_COUNT : (RTC Offset: 0x10) (R/W 16) MODE1 MODE1 Counter Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t COUNT:16; /*!< bit: 0..15 Counter Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE1_COUNT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_COUNT_OFFSET 0x10 /**< \brief (RTC_MODE1_COUNT offset) MODE1 Counter Value */ +#define RTC_MODE1_COUNT_RESETVALUE 0x0000 /**< \brief (RTC_MODE1_COUNT reset_value) MODE1 Counter Value */ + +#define RTC_MODE1_COUNT_COUNT_Pos 0 /**< \brief (RTC_MODE1_COUNT) Counter Value */ +#define RTC_MODE1_COUNT_COUNT_Msk (0xFFFFu << RTC_MODE1_COUNT_COUNT_Pos) +#define RTC_MODE1_COUNT_COUNT(value) ((RTC_MODE1_COUNT_COUNT_Msk & ((value) << RTC_MODE1_COUNT_COUNT_Pos))) +#define RTC_MODE1_COUNT_MASK 0xFFFFu /**< \brief (RTC_MODE1_COUNT) MASK Register */ + +/* -------- RTC_MODE2_CLOCK : (RTC Offset: 0x10) (R/W 32) MODE2 MODE2 Clock Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SECOND:6; /*!< bit: 0.. 5 Second */ + uint32_t MINUTE:6; /*!< bit: 6..11 Minute */ + uint32_t HOUR:5; /*!< bit: 12..16 Hour */ + uint32_t DAY:5; /*!< bit: 17..21 Day */ + uint32_t MONTH:4; /*!< bit: 22..25 Month */ + uint32_t YEAR:6; /*!< bit: 26..31 Year */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} RTC_MODE2_CLOCK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_CLOCK_OFFSET 0x10 /**< \brief (RTC_MODE2_CLOCK offset) MODE2 Clock Value */ +#define RTC_MODE2_CLOCK_RESETVALUE 0x00000000 /**< \brief (RTC_MODE2_CLOCK reset_value) MODE2 Clock Value */ + +#define RTC_MODE2_CLOCK_SECOND_Pos 0 /**< \brief (RTC_MODE2_CLOCK) Second */ +#define RTC_MODE2_CLOCK_SECOND_Msk (0x3Fu << RTC_MODE2_CLOCK_SECOND_Pos) +#define RTC_MODE2_CLOCK_SECOND(value) ((RTC_MODE2_CLOCK_SECOND_Msk & ((value) << RTC_MODE2_CLOCK_SECOND_Pos))) +#define RTC_MODE2_CLOCK_MINUTE_Pos 6 /**< \brief (RTC_MODE2_CLOCK) Minute */ +#define RTC_MODE2_CLOCK_MINUTE_Msk (0x3Fu << RTC_MODE2_CLOCK_MINUTE_Pos) +#define RTC_MODE2_CLOCK_MINUTE(value) ((RTC_MODE2_CLOCK_MINUTE_Msk & ((value) << RTC_MODE2_CLOCK_MINUTE_Pos))) +#define RTC_MODE2_CLOCK_HOUR_Pos 12 /**< \brief (RTC_MODE2_CLOCK) Hour */ +#define RTC_MODE2_CLOCK_HOUR_Msk (0x1Fu << RTC_MODE2_CLOCK_HOUR_Pos) +#define RTC_MODE2_CLOCK_HOUR(value) ((RTC_MODE2_CLOCK_HOUR_Msk & ((value) << RTC_MODE2_CLOCK_HOUR_Pos))) +#define RTC_MODE2_CLOCK_HOUR_PM_Val 0x10u /**< \brief (RTC_MODE2_CLOCK) Afternoon Hour */ +#define RTC_MODE2_CLOCK_HOUR_PM (RTC_MODE2_CLOCK_HOUR_PM_Val << RTC_MODE2_CLOCK_HOUR_Pos) +#define RTC_MODE2_CLOCK_DAY_Pos 17 /**< \brief (RTC_MODE2_CLOCK) Day */ +#define RTC_MODE2_CLOCK_DAY_Msk (0x1Fu << RTC_MODE2_CLOCK_DAY_Pos) +#define RTC_MODE2_CLOCK_DAY(value) ((RTC_MODE2_CLOCK_DAY_Msk & ((value) << RTC_MODE2_CLOCK_DAY_Pos))) +#define RTC_MODE2_CLOCK_MONTH_Pos 22 /**< \brief (RTC_MODE2_CLOCK) Month */ +#define RTC_MODE2_CLOCK_MONTH_Msk (0xFu << RTC_MODE2_CLOCK_MONTH_Pos) +#define RTC_MODE2_CLOCK_MONTH(value) ((RTC_MODE2_CLOCK_MONTH_Msk & ((value) << RTC_MODE2_CLOCK_MONTH_Pos))) +#define RTC_MODE2_CLOCK_YEAR_Pos 26 /**< \brief (RTC_MODE2_CLOCK) Year */ +#define RTC_MODE2_CLOCK_YEAR_Msk (0x3Fu << RTC_MODE2_CLOCK_YEAR_Pos) +#define RTC_MODE2_CLOCK_YEAR(value) ((RTC_MODE2_CLOCK_YEAR_Msk & ((value) << RTC_MODE2_CLOCK_YEAR_Pos))) +#define RTC_MODE2_CLOCK_MASK 0xFFFFFFFFu /**< \brief (RTC_MODE2_CLOCK) MASK Register */ + +/* -------- RTC_MODE1_PER : (RTC Offset: 0x14) (R/W 16) MODE1 MODE1 Counter Period -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PER:16; /*!< bit: 0..15 Counter Period */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE1_PER_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_PER_OFFSET 0x14 /**< \brief (RTC_MODE1_PER offset) MODE1 Counter Period */ +#define RTC_MODE1_PER_RESETVALUE 0x0000 /**< \brief (RTC_MODE1_PER reset_value) MODE1 Counter Period */ + +#define RTC_MODE1_PER_PER_Pos 0 /**< \brief (RTC_MODE1_PER) Counter Period */ +#define RTC_MODE1_PER_PER_Msk (0xFFFFu << RTC_MODE1_PER_PER_Pos) +#define RTC_MODE1_PER_PER(value) ((RTC_MODE1_PER_PER_Msk & ((value) << RTC_MODE1_PER_PER_Pos))) +#define RTC_MODE1_PER_MASK 0xFFFFu /**< \brief (RTC_MODE1_PER) MASK Register */ + +/* -------- RTC_MODE0_COMP : (RTC Offset: 0x18) (R/W 32) MODE0 MODE0 Compare n Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t COMP:32; /*!< bit: 0..31 Compare Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} RTC_MODE0_COMP_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE0_COMP_OFFSET 0x18 /**< \brief (RTC_MODE0_COMP offset) MODE0 Compare n Value */ +#define RTC_MODE0_COMP_RESETVALUE 0x00000000 /**< \brief (RTC_MODE0_COMP reset_value) MODE0 Compare n Value */ + +#define RTC_MODE0_COMP_COMP_Pos 0 /**< \brief (RTC_MODE0_COMP) Compare Value */ +#define RTC_MODE0_COMP_COMP_Msk (0xFFFFFFFFu << RTC_MODE0_COMP_COMP_Pos) +#define RTC_MODE0_COMP_COMP(value) ((RTC_MODE0_COMP_COMP_Msk & ((value) << RTC_MODE0_COMP_COMP_Pos))) +#define RTC_MODE0_COMP_MASK 0xFFFFFFFFu /**< \brief (RTC_MODE0_COMP) MASK Register */ + +/* -------- RTC_MODE1_COMP : (RTC Offset: 0x18) (R/W 16) MODE1 MODE1 Compare n Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t COMP:16; /*!< bit: 0..15 Compare Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} RTC_MODE1_COMP_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE1_COMP_OFFSET 0x18 /**< \brief (RTC_MODE1_COMP offset) MODE1 Compare n Value */ +#define RTC_MODE1_COMP_RESETVALUE 0x0000 /**< \brief (RTC_MODE1_COMP reset_value) MODE1 Compare n Value */ + +#define RTC_MODE1_COMP_COMP_Pos 0 /**< \brief (RTC_MODE1_COMP) Compare Value */ +#define RTC_MODE1_COMP_COMP_Msk (0xFFFFu << RTC_MODE1_COMP_COMP_Pos) +#define RTC_MODE1_COMP_COMP(value) ((RTC_MODE1_COMP_COMP_Msk & ((value) << RTC_MODE1_COMP_COMP_Pos))) +#define RTC_MODE1_COMP_MASK 0xFFFFu /**< \brief (RTC_MODE1_COMP) MASK Register */ + +/* -------- RTC_MODE2_ALARM : (RTC Offset: 0x18) (R/W 32) MODE2 MODE2_ALARM Alarm n Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SECOND:6; /*!< bit: 0.. 5 Second */ + uint32_t MINUTE:6; /*!< bit: 6..11 Minute */ + uint32_t HOUR:5; /*!< bit: 12..16 Hour */ + uint32_t DAY:5; /*!< bit: 17..21 Day */ + uint32_t MONTH:4; /*!< bit: 22..25 Month */ + uint32_t YEAR:6; /*!< bit: 26..31 Year */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} RTC_MODE2_ALARM_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_ALARM_OFFSET 0x18 /**< \brief (RTC_MODE2_ALARM offset) MODE2_ALARM Alarm n Value */ +#define RTC_MODE2_ALARM_RESETVALUE 0x00000000 /**< \brief (RTC_MODE2_ALARM reset_value) MODE2_ALARM Alarm n Value */ + +#define RTC_MODE2_ALARM_SECOND_Pos 0 /**< \brief (RTC_MODE2_ALARM) Second */ +#define RTC_MODE2_ALARM_SECOND_Msk (0x3Fu << RTC_MODE2_ALARM_SECOND_Pos) +#define RTC_MODE2_ALARM_SECOND(value) ((RTC_MODE2_ALARM_SECOND_Msk & ((value) << RTC_MODE2_ALARM_SECOND_Pos))) +#define RTC_MODE2_ALARM_MINUTE_Pos 6 /**< \brief (RTC_MODE2_ALARM) Minute */ +#define RTC_MODE2_ALARM_MINUTE_Msk (0x3Fu << RTC_MODE2_ALARM_MINUTE_Pos) +#define RTC_MODE2_ALARM_MINUTE(value) ((RTC_MODE2_ALARM_MINUTE_Msk & ((value) << RTC_MODE2_ALARM_MINUTE_Pos))) +#define RTC_MODE2_ALARM_HOUR_Pos 12 /**< \brief (RTC_MODE2_ALARM) Hour */ +#define RTC_MODE2_ALARM_HOUR_Msk (0x1Fu << RTC_MODE2_ALARM_HOUR_Pos) +#define RTC_MODE2_ALARM_HOUR(value) ((RTC_MODE2_ALARM_HOUR_Msk & ((value) << RTC_MODE2_ALARM_HOUR_Pos))) +#define RTC_MODE2_ALARM_DAY_Pos 17 /**< \brief (RTC_MODE2_ALARM) Day */ +#define RTC_MODE2_ALARM_DAY_Msk (0x1Fu << RTC_MODE2_ALARM_DAY_Pos) +#define RTC_MODE2_ALARM_DAY(value) ((RTC_MODE2_ALARM_DAY_Msk & ((value) << RTC_MODE2_ALARM_DAY_Pos))) +#define RTC_MODE2_ALARM_MONTH_Pos 22 /**< \brief (RTC_MODE2_ALARM) Month */ +#define RTC_MODE2_ALARM_MONTH_Msk (0xFu << RTC_MODE2_ALARM_MONTH_Pos) +#define RTC_MODE2_ALARM_MONTH(value) ((RTC_MODE2_ALARM_MONTH_Msk & ((value) << RTC_MODE2_ALARM_MONTH_Pos))) +#define RTC_MODE2_ALARM_YEAR_Pos 26 /**< \brief (RTC_MODE2_ALARM) Year */ +#define RTC_MODE2_ALARM_YEAR_Msk (0x3Fu << RTC_MODE2_ALARM_YEAR_Pos) +#define RTC_MODE2_ALARM_YEAR(value) ((RTC_MODE2_ALARM_YEAR_Msk & ((value) << RTC_MODE2_ALARM_YEAR_Pos))) +#define RTC_MODE2_ALARM_MASK 0xFFFFFFFFu /**< \brief (RTC_MODE2_ALARM) MASK Register */ + +/* -------- RTC_MODE2_MASK : (RTC Offset: 0x1C) (R/W 8) MODE2 MODE2_ALARM Alarm n Mask -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SEL:3; /*!< bit: 0.. 2 Alarm Mask Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} RTC_MODE2_MASK_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define RTC_MODE2_MASK_OFFSET 0x1C /**< \brief (RTC_MODE2_MASK offset) MODE2_ALARM Alarm n Mask */ +#define RTC_MODE2_MASK_RESETVALUE 0x00 /**< \brief (RTC_MODE2_MASK reset_value) MODE2_ALARM Alarm n Mask */ + +#define RTC_MODE2_MASK_SEL_Pos 0 /**< \brief (RTC_MODE2_MASK) Alarm Mask Selection */ +#define RTC_MODE2_MASK_SEL_Msk (0x7u << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL(value) ((RTC_MODE2_MASK_SEL_Msk & ((value) << RTC_MODE2_MASK_SEL_Pos))) +#define RTC_MODE2_MASK_SEL_OFF_Val 0x0u /**< \brief (RTC_MODE2_MASK) Alarm Disabled */ +#define RTC_MODE2_MASK_SEL_SS_Val 0x1u /**< \brief (RTC_MODE2_MASK) Match seconds only */ +#define RTC_MODE2_MASK_SEL_MMSS_Val 0x2u /**< \brief (RTC_MODE2_MASK) Match seconds and minutes only */ +#define RTC_MODE2_MASK_SEL_HHMMSS_Val 0x3u /**< \brief (RTC_MODE2_MASK) Match seconds, minutes, and hours only */ +#define RTC_MODE2_MASK_SEL_DDHHMMSS_Val 0x4u /**< \brief (RTC_MODE2_MASK) Match seconds, minutes, hours, and days only */ +#define RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val 0x5u /**< \brief (RTC_MODE2_MASK) Match seconds, minutes, hours, days, and months only */ +#define RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val 0x6u /**< \brief (RTC_MODE2_MASK) Match seconds, minutes, hours, days, months, and years */ +#define RTC_MODE2_MASK_SEL_OFF (RTC_MODE2_MASK_SEL_OFF_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_SS (RTC_MODE2_MASK_SEL_SS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_MMSS (RTC_MODE2_MASK_SEL_MMSS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_HHMMSS (RTC_MODE2_MASK_SEL_HHMMSS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_DDHHMMSS (RTC_MODE2_MASK_SEL_DDHHMMSS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_MMDDHHMMSS (RTC_MODE2_MASK_SEL_MMDDHHMMSS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_SEL_YYMMDDHHMMSS (RTC_MODE2_MASK_SEL_YYMMDDHHMMSS_Val << RTC_MODE2_MASK_SEL_Pos) +#define RTC_MODE2_MASK_MASK 0x07u /**< \brief (RTC_MODE2_MASK) MASK Register */ + +/** \brief RtcMode2Alarm hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO RTC_MODE2_ALARM_Type ALARM; /**< \brief Offset: 0x00 (R/W 32) MODE2_ALARM Alarm n Value */ + __IO RTC_MODE2_MASK_Type MASK; /**< \brief Offset: 0x04 (R/W 8) MODE2_ALARM Alarm n Mask */ + RoReg8 Reserved1[0x3]; +} RtcMode2Alarm; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief RTC_MODE0 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* 32-bit Counter with Single 32-bit Compare */ + __IO RTC_MODE0_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 16) MODE0 Control */ + __IO RTC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO RTC_MODE0_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x04 (R/W 16) MODE0 Event Control */ + __IO RTC_MODE0_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x06 (R/W 8) MODE0 Interrupt Enable Clear */ + __IO RTC_MODE0_INTENSET_Type INTENSET; /**< \brief Offset: 0x07 (R/W 8) MODE0 Interrupt Enable Set */ + __IO RTC_MODE0_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x08 (R/W 8) MODE0 Interrupt Flag Status and Clear */ + RoReg8 Reserved1[0x1]; + __IO RTC_STATUS_Type STATUS; /**< \brief Offset: 0x0A (R/W 8) Status */ + __IO RTC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x0B (R/W 8) Debug Control */ + __IO RTC_FREQCORR_Type FREQCORR; /**< \brief Offset: 0x0C (R/W 8) Frequency Correction */ + RoReg8 Reserved2[0x3]; + __IO RTC_MODE0_COUNT_Type COUNT; /**< \brief Offset: 0x10 (R/W 32) MODE0 Counter Value */ + RoReg8 Reserved3[0x4]; + __IO RTC_MODE0_COMP_Type COMP[1]; /**< \brief Offset: 0x18 (R/W 32) MODE0 Compare n Value */ +} RtcMode0; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief RTC_MODE1 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* 16-bit Counter with Two 16-bit Compares */ + __IO RTC_MODE1_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 16) MODE1 Control */ + __IO RTC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO RTC_MODE1_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x04 (R/W 16) MODE1 Event Control */ + __IO RTC_MODE1_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x06 (R/W 8) MODE1 Interrupt Enable Clear */ + __IO RTC_MODE1_INTENSET_Type INTENSET; /**< \brief Offset: 0x07 (R/W 8) MODE1 Interrupt Enable Set */ + __IO RTC_MODE1_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x08 (R/W 8) MODE1 Interrupt Flag Status and Clear */ + RoReg8 Reserved1[0x1]; + __IO RTC_STATUS_Type STATUS; /**< \brief Offset: 0x0A (R/W 8) Status */ + __IO RTC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x0B (R/W 8) Debug Control */ + __IO RTC_FREQCORR_Type FREQCORR; /**< \brief Offset: 0x0C (R/W 8) Frequency Correction */ + RoReg8 Reserved2[0x3]; + __IO RTC_MODE1_COUNT_Type COUNT; /**< \brief Offset: 0x10 (R/W 16) MODE1 Counter Value */ + RoReg8 Reserved3[0x2]; + __IO RTC_MODE1_PER_Type PER; /**< \brief Offset: 0x14 (R/W 16) MODE1 Counter Period */ + RoReg8 Reserved4[0x2]; + __IO RTC_MODE1_COMP_Type COMP[2]; /**< \brief Offset: 0x18 (R/W 16) MODE1 Compare n Value */ +} RtcMode1; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief RTC_MODE2 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* Clock/Calendar with Alarm */ + __IO RTC_MODE2_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 16) MODE2 Control */ + __IO RTC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO RTC_MODE2_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x04 (R/W 16) MODE2 Event Control */ + __IO RTC_MODE2_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x06 (R/W 8) MODE2 Interrupt Enable Clear */ + __IO RTC_MODE2_INTENSET_Type INTENSET; /**< \brief Offset: 0x07 (R/W 8) MODE2 Interrupt Enable Set */ + __IO RTC_MODE2_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x08 (R/W 8) MODE2 Interrupt Flag Status and Clear */ + RoReg8 Reserved1[0x1]; + __IO RTC_STATUS_Type STATUS; /**< \brief Offset: 0x0A (R/W 8) Status */ + __IO RTC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x0B (R/W 8) Debug Control */ + __IO RTC_FREQCORR_Type FREQCORR; /**< \brief Offset: 0x0C (R/W 8) Frequency Correction */ + RoReg8 Reserved2[0x3]; + __IO RTC_MODE2_CLOCK_Type CLOCK; /**< \brief Offset: 0x10 (R/W 32) MODE2 Clock Value */ + RoReg8 Reserved3[0x4]; + RtcMode2Alarm Mode2Alarm[1]; /**< \brief Offset: 0x18 RtcMode2Alarm groups [ALARM_NUM] */ +} RtcMode2; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + RtcMode0 MODE0; /**< \brief Offset: 0x00 32-bit Counter with Single 32-bit Compare */ + RtcMode1 MODE1; /**< \brief Offset: 0x00 16-bit Counter with Two 16-bit Compares */ + RtcMode2 MODE2; /**< \brief Offset: 0x00 Clock/Calendar with Alarm */ +} Rtc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_RTC_COMPONENT_ */ diff --git a/loader/samd20/component/sercom.h b/loader/samd20/component/sercom.h new file mode 100644 index 0000000..c836e96 --- /dev/null +++ b/loader/samd20/component/sercom.h @@ -0,0 +1,1224 @@ +/** + * \file + * + * \brief Component description for SERCOM + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_SERCOM_COMPONENT_ +#define _SAMD20_SERCOM_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR SERCOM */ +/* ========================================================================== */ +/** \addtogroup SAMD20_SERCOM Serial Communication Interface */ +/*@{*/ + +#define SERCOM_U2201 +#define REV_SERCOM 0x102 + +/* -------- SERCOM_I2CM_CTRLA : (SERCOM Offset: 0x00) (R/W 32) I2CM I2CM Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SWRST:1; /*!< bit: 0 Software Reset */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t MODE:3; /*!< bit: 2.. 4 Operating Mode */ + uint32_t :2; /*!< bit: 5.. 6 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 7 Run in Standby */ + uint32_t :8; /*!< bit: 8..15 Reserved */ + uint32_t PINOUT:1; /*!< bit: 16 Pin Usage */ + uint32_t :3; /*!< bit: 17..19 Reserved */ + uint32_t SDAHOLD:2; /*!< bit: 20..21 SDA Hold Time */ + uint32_t :6; /*!< bit: 22..27 Reserved */ + uint32_t INACTOUT:2; /*!< bit: 28..29 Inactive Time-out */ + uint32_t LOWTOUT:1; /*!< bit: 30 SCL Low Time-out */ + uint32_t :1; /*!< bit: 31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_CTRLA_OFFSET 0x00 /**< \brief (SERCOM_I2CM_CTRLA offset) I2CM Control A */ +#define SERCOM_I2CM_CTRLA_RESETVALUE 0x00000000 /**< \brief (SERCOM_I2CM_CTRLA reset_value) I2CM Control A */ + +#define SERCOM_I2CM_CTRLA_SWRST_Pos 0 /**< \brief (SERCOM_I2CM_CTRLA) Software Reset */ +#define SERCOM_I2CM_CTRLA_SWRST (0x1u << SERCOM_I2CM_CTRLA_SWRST_Pos) +#define SERCOM_I2CM_CTRLA_ENABLE_Pos 1 /**< \brief (SERCOM_I2CM_CTRLA) Enable */ +#define SERCOM_I2CM_CTRLA_ENABLE (0x1u << SERCOM_I2CM_CTRLA_ENABLE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_Pos 2 /**< \brief (SERCOM_I2CM_CTRLA) Operating Mode */ +#define SERCOM_I2CM_CTRLA_MODE_Msk (0x7u << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE(value) ((SERCOM_I2CM_CTRLA_MODE_Msk & ((value) << SERCOM_I2CM_CTRLA_MODE_Pos))) +#define SERCOM_I2CM_CTRLA_MODE_USART_EXT_CLK_Val 0x0u /**< \brief (SERCOM_I2CM_CTRLA) USART mode with external clock */ +#define SERCOM_I2CM_CTRLA_MODE_USART_INT_CLK_Val 0x1u /**< \brief (SERCOM_I2CM_CTRLA) USART mode with internal clock */ +#define SERCOM_I2CM_CTRLA_MODE_SPI_SLAVE_Val 0x2u /**< \brief (SERCOM_I2CM_CTRLA) SPI mode with external clock */ +#define SERCOM_I2CM_CTRLA_MODE_SPI_MASTER_Val 0x3u /**< \brief (SERCOM_I2CM_CTRLA) SPI mode with internal clock */ +#define SERCOM_I2CM_CTRLA_MODE_I2C_SLAVE_Val 0x4u /**< \brief (SERCOM_I2CM_CTRLA) I2C mode with external clock */ +#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER_Val 0x5u /**< \brief (SERCOM_I2CM_CTRLA) I2C mode with internal clock */ +#define SERCOM_I2CM_CTRLA_MODE_USART_EXT_CLK (SERCOM_I2CM_CTRLA_MODE_USART_EXT_CLK_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_USART_INT_CLK (SERCOM_I2CM_CTRLA_MODE_USART_INT_CLK_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_SPI_SLAVE (SERCOM_I2CM_CTRLA_MODE_SPI_SLAVE_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_SPI_MASTER (SERCOM_I2CM_CTRLA_MODE_SPI_MASTER_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_I2C_SLAVE (SERCOM_I2CM_CTRLA_MODE_I2C_SLAVE_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_MODE_I2C_MASTER (SERCOM_I2CM_CTRLA_MODE_I2C_MASTER_Val << SERCOM_I2CM_CTRLA_MODE_Pos) +#define SERCOM_I2CM_CTRLA_RUNSTDBY_Pos 7 /**< \brief (SERCOM_I2CM_CTRLA) Run in Standby */ +#define SERCOM_I2CM_CTRLA_RUNSTDBY (0x1u << SERCOM_I2CM_CTRLA_RUNSTDBY_Pos) +#define SERCOM_I2CM_CTRLA_PINOUT_Pos 16 /**< \brief (SERCOM_I2CM_CTRLA) Pin Usage */ +#define SERCOM_I2CM_CTRLA_PINOUT (0x1u << SERCOM_I2CM_CTRLA_PINOUT_Pos) +#define SERCOM_I2CM_CTRLA_SDAHOLD_Pos 20 /**< \brief (SERCOM_I2CM_CTRLA) SDA Hold Time */ +#define SERCOM_I2CM_CTRLA_SDAHOLD_Msk (0x3u << SERCOM_I2CM_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CM_CTRLA_SDAHOLD(value) ((SERCOM_I2CM_CTRLA_SDAHOLD_Msk & ((value) << SERCOM_I2CM_CTRLA_SDAHOLD_Pos))) +#define SERCOM_I2CM_CTRLA_INACTOUT_Pos 28 /**< \brief (SERCOM_I2CM_CTRLA) Inactive Time-out */ +#define SERCOM_I2CM_CTRLA_INACTOUT_Msk (0x3u << SERCOM_I2CM_CTRLA_INACTOUT_Pos) +#define SERCOM_I2CM_CTRLA_INACTOUT(value) ((SERCOM_I2CM_CTRLA_INACTOUT_Msk & ((value) << SERCOM_I2CM_CTRLA_INACTOUT_Pos))) +#define SERCOM_I2CM_CTRLA_LOWTOUT_Pos 30 /**< \brief (SERCOM_I2CM_CTRLA) SCL Low Time-out */ +#define SERCOM_I2CM_CTRLA_LOWTOUT (0x1u << SERCOM_I2CM_CTRLA_LOWTOUT_Pos) +#define SERCOM_I2CM_CTRLA_MASK 0x7031009Fu /**< \brief (SERCOM_I2CM_CTRLA) MASK Register */ + +/* -------- SERCOM_I2CS_CTRLA : (SERCOM Offset: 0x00) (R/W 32) I2CS I2CS Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SWRST:1; /*!< bit: 0 Software Reset */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t MODE:3; /*!< bit: 2.. 4 Operating Mode */ + uint32_t :2; /*!< bit: 5.. 6 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 7 Run in Standby */ + uint32_t :8; /*!< bit: 8..15 Reserved */ + uint32_t PINOUT:1; /*!< bit: 16 Pin Usage */ + uint32_t :3; /*!< bit: 17..19 Reserved */ + uint32_t SDAHOLD:2; /*!< bit: 20..21 SDA Hold Time */ + uint32_t :8; /*!< bit: 22..29 Reserved */ + uint32_t LOWTOUT:1; /*!< bit: 30 SCL Low Time-out */ + uint32_t :1; /*!< bit: 31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_CTRLA_OFFSET 0x00 /**< \brief (SERCOM_I2CS_CTRLA offset) I2CS Control A */ +#define SERCOM_I2CS_CTRLA_RESETVALUE 0x00000000 /**< \brief (SERCOM_I2CS_CTRLA reset_value) I2CS Control A */ + +#define SERCOM_I2CS_CTRLA_SWRST_Pos 0 /**< \brief (SERCOM_I2CS_CTRLA) Software Reset */ +#define SERCOM_I2CS_CTRLA_SWRST (0x1u << SERCOM_I2CS_CTRLA_SWRST_Pos) +#define SERCOM_I2CS_CTRLA_ENABLE_Pos 1 /**< \brief (SERCOM_I2CS_CTRLA) Enable */ +#define SERCOM_I2CS_CTRLA_ENABLE (0x1u << SERCOM_I2CS_CTRLA_ENABLE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_Pos 2 /**< \brief (SERCOM_I2CS_CTRLA) Operating Mode */ +#define SERCOM_I2CS_CTRLA_MODE_Msk (0x7u << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE(value) ((SERCOM_I2CS_CTRLA_MODE_Msk & ((value) << SERCOM_I2CS_CTRLA_MODE_Pos))) +#define SERCOM_I2CS_CTRLA_MODE_USART_EXT_CLK_Val 0x0u /**< \brief (SERCOM_I2CS_CTRLA) USART mode with external clock */ +#define SERCOM_I2CS_CTRLA_MODE_USART_INT_CLK_Val 0x1u /**< \brief (SERCOM_I2CS_CTRLA) USART mode with internal clock */ +#define SERCOM_I2CS_CTRLA_MODE_SPI_SLAVE_Val 0x2u /**< \brief (SERCOM_I2CS_CTRLA) SPI mode with external clock */ +#define SERCOM_I2CS_CTRLA_MODE_SPI_MASTER_Val 0x3u /**< \brief (SERCOM_I2CS_CTRLA) SPI mode with internal clock */ +#define SERCOM_I2CS_CTRLA_MODE_I2C_SLAVE_Val 0x4u /**< \brief (SERCOM_I2CS_CTRLA) I2C mode with external clock */ +#define SERCOM_I2CS_CTRLA_MODE_I2C_MASTER_Val 0x5u /**< \brief (SERCOM_I2CS_CTRLA) I2C mode with internal clock */ +#define SERCOM_I2CS_CTRLA_MODE_USART_EXT_CLK (SERCOM_I2CS_CTRLA_MODE_USART_EXT_CLK_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_USART_INT_CLK (SERCOM_I2CS_CTRLA_MODE_USART_INT_CLK_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_SPI_SLAVE (SERCOM_I2CS_CTRLA_MODE_SPI_SLAVE_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_SPI_MASTER (SERCOM_I2CS_CTRLA_MODE_SPI_MASTER_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_I2C_SLAVE (SERCOM_I2CS_CTRLA_MODE_I2C_SLAVE_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_MODE_I2C_MASTER (SERCOM_I2CS_CTRLA_MODE_I2C_MASTER_Val << SERCOM_I2CS_CTRLA_MODE_Pos) +#define SERCOM_I2CS_CTRLA_RUNSTDBY_Pos 7 /**< \brief (SERCOM_I2CS_CTRLA) Run in Standby */ +#define SERCOM_I2CS_CTRLA_RUNSTDBY (0x1u << SERCOM_I2CS_CTRLA_RUNSTDBY_Pos) +#define SERCOM_I2CS_CTRLA_PINOUT_Pos 16 /**< \brief (SERCOM_I2CS_CTRLA) Pin Usage */ +#define SERCOM_I2CS_CTRLA_PINOUT (0x1u << SERCOM_I2CS_CTRLA_PINOUT_Pos) +#define SERCOM_I2CS_CTRLA_SDAHOLD_Pos 20 /**< \brief (SERCOM_I2CS_CTRLA) SDA Hold Time */ +#define SERCOM_I2CS_CTRLA_SDAHOLD_Msk (0x3u << SERCOM_I2CS_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CS_CTRLA_SDAHOLD(value) ((SERCOM_I2CS_CTRLA_SDAHOLD_Msk & ((value) << SERCOM_I2CS_CTRLA_SDAHOLD_Pos))) +#define SERCOM_I2CS_CTRLA_SDAHOLD_DIS_Val 0x0u /**< \brief (SERCOM_I2CS_CTRLA) Disabled */ +#define SERCOM_I2CS_CTRLA_SDAHOLD_75_Val 0x1u /**< \brief (SERCOM_I2CS_CTRLA) 50-100 ns hold time */ +#define SERCOM_I2CS_CTRLA_SDAHOLD_450_Val 0x2u /**< \brief (SERCOM_I2CS_CTRLA) 300-600 ns hold time */ +#define SERCOM_I2CS_CTRLA_SDAHOLD_600_Val 0x3u /**< \brief (SERCOM_I2CS_CTRLA) 400-800 ns hold time */ +#define SERCOM_I2CS_CTRLA_SDAHOLD_DIS (SERCOM_I2CS_CTRLA_SDAHOLD_DIS_Val << SERCOM_I2CS_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CS_CTRLA_SDAHOLD_75 (SERCOM_I2CS_CTRLA_SDAHOLD_75_Val << SERCOM_I2CS_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CS_CTRLA_SDAHOLD_450 (SERCOM_I2CS_CTRLA_SDAHOLD_450_Val << SERCOM_I2CS_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CS_CTRLA_SDAHOLD_600 (SERCOM_I2CS_CTRLA_SDAHOLD_600_Val << SERCOM_I2CS_CTRLA_SDAHOLD_Pos) +#define SERCOM_I2CS_CTRLA_LOWTOUT_Pos 30 /**< \brief (SERCOM_I2CS_CTRLA) SCL Low Time-out */ +#define SERCOM_I2CS_CTRLA_LOWTOUT (0x1u << SERCOM_I2CS_CTRLA_LOWTOUT_Pos) +#define SERCOM_I2CS_CTRLA_MASK 0x4031009Fu /**< \brief (SERCOM_I2CS_CTRLA) MASK Register */ + +/* -------- SERCOM_SPI_CTRLA : (SERCOM Offset: 0x00) (R/W 32) SPI SPI Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SWRST:1; /*!< bit: 0 Software Reset */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t MODE:3; /*!< bit: 2.. 4 Operating Mode */ + uint32_t :2; /*!< bit: 5.. 6 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 7 Run In Standby */ + uint32_t IBON:1; /*!< bit: 8 Immediate Buffer Overflow Notification */ + uint32_t :7; /*!< bit: 9..15 Reserved */ + uint32_t DOPO:2; /*!< bit: 16..17 Data Out Pinout */ + uint32_t :2; /*!< bit: 18..19 Reserved */ + uint32_t DIPO:2; /*!< bit: 20..21 Data In Pinout */ + uint32_t :2; /*!< bit: 22..23 Reserved */ + uint32_t FORM:4; /*!< bit: 24..27 Frame Format */ + uint32_t CPHA:1; /*!< bit: 28 Clock Phase */ + uint32_t CPOL:1; /*!< bit: 29 Clock Polarity */ + uint32_t DORD:1; /*!< bit: 30 Data Order */ + uint32_t :1; /*!< bit: 31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_SPI_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_CTRLA_OFFSET 0x00 /**< \brief (SERCOM_SPI_CTRLA offset) SPI Control A */ +#define SERCOM_SPI_CTRLA_RESETVALUE 0x00000000 /**< \brief (SERCOM_SPI_CTRLA reset_value) SPI Control A */ + +#define SERCOM_SPI_CTRLA_SWRST_Pos 0 /**< \brief (SERCOM_SPI_CTRLA) Software Reset */ +#define SERCOM_SPI_CTRLA_SWRST (0x1u << SERCOM_SPI_CTRLA_SWRST_Pos) +#define SERCOM_SPI_CTRLA_ENABLE_Pos 1 /**< \brief (SERCOM_SPI_CTRLA) Enable */ +#define SERCOM_SPI_CTRLA_ENABLE (0x1u << SERCOM_SPI_CTRLA_ENABLE_Pos) +#define SERCOM_SPI_CTRLA_MODE_Pos 2 /**< \brief (SERCOM_SPI_CTRLA) Operating Mode */ +#define SERCOM_SPI_CTRLA_MODE_Msk (0x7u << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE(value) ((SERCOM_SPI_CTRLA_MODE_Msk & ((value) << SERCOM_SPI_CTRLA_MODE_Pos))) +#define SERCOM_SPI_CTRLA_MODE_USART_EXT_CLK_Val 0x0u /**< \brief (SERCOM_SPI_CTRLA) USART mode with external clock */ +#define SERCOM_SPI_CTRLA_MODE_USART_INT_CLK_Val 0x1u /**< \brief (SERCOM_SPI_CTRLA) USART mode with internal clock */ +#define SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val 0x2u /**< \brief (SERCOM_SPI_CTRLA) SPI mode with external clock */ +#define SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val 0x3u /**< \brief (SERCOM_SPI_CTRLA) SPI mode with internal clock */ +#define SERCOM_SPI_CTRLA_MODE_I2C_SLAVE_Val 0x4u /**< \brief (SERCOM_SPI_CTRLA) I2C mode with external clock */ +#define SERCOM_SPI_CTRLA_MODE_I2C_MASTER_Val 0x5u /**< \brief (SERCOM_SPI_CTRLA) I2C mode with internal clock */ +#define SERCOM_SPI_CTRLA_MODE_USART_EXT_CLK (SERCOM_SPI_CTRLA_MODE_USART_EXT_CLK_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE_USART_INT_CLK (SERCOM_SPI_CTRLA_MODE_USART_INT_CLK_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE_SPI_SLAVE (SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE_SPI_MASTER (SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE_I2C_SLAVE (SERCOM_SPI_CTRLA_MODE_I2C_SLAVE_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_MODE_I2C_MASTER (SERCOM_SPI_CTRLA_MODE_I2C_MASTER_Val << SERCOM_SPI_CTRLA_MODE_Pos) +#define SERCOM_SPI_CTRLA_RUNSTDBY_Pos 7 /**< \brief (SERCOM_SPI_CTRLA) Run In Standby */ +#define SERCOM_SPI_CTRLA_RUNSTDBY (0x1u << SERCOM_SPI_CTRLA_RUNSTDBY_Pos) +#define SERCOM_SPI_CTRLA_IBON_Pos 8 /**< \brief (SERCOM_SPI_CTRLA) Immediate Buffer Overflow Notification */ +#define SERCOM_SPI_CTRLA_IBON (0x1u << SERCOM_SPI_CTRLA_IBON_Pos) +#define SERCOM_SPI_CTRLA_DOPO_Pos 16 /**< \brief (SERCOM_SPI_CTRLA) Data Out Pinout */ +#define SERCOM_SPI_CTRLA_DOPO_Msk (0x3u << SERCOM_SPI_CTRLA_DOPO_Pos) +#define SERCOM_SPI_CTRLA_DOPO(value) ((SERCOM_SPI_CTRLA_DOPO_Msk & ((value) << SERCOM_SPI_CTRLA_DOPO_Pos))) +#define SERCOM_SPI_CTRLA_DIPO_Pos 20 /**< \brief (SERCOM_SPI_CTRLA) Data In Pinout */ +#define SERCOM_SPI_CTRLA_DIPO_Msk (0x3u << SERCOM_SPI_CTRLA_DIPO_Pos) +#define SERCOM_SPI_CTRLA_DIPO(value) ((SERCOM_SPI_CTRLA_DIPO_Msk & ((value) << SERCOM_SPI_CTRLA_DIPO_Pos))) +#define SERCOM_SPI_CTRLA_FORM_Pos 24 /**< \brief (SERCOM_SPI_CTRLA) Frame Format */ +#define SERCOM_SPI_CTRLA_FORM_Msk (0xFu << SERCOM_SPI_CTRLA_FORM_Pos) +#define SERCOM_SPI_CTRLA_FORM(value) ((SERCOM_SPI_CTRLA_FORM_Msk & ((value) << SERCOM_SPI_CTRLA_FORM_Pos))) +#define SERCOM_SPI_CTRLA_FORM_SPI_Val 0x0u /**< \brief (SERCOM_SPI_CTRLA) SPI frame */ +#define SERCOM_SPI_CTRLA_FORM_SPI_ADDR_Val 0x2u /**< \brief (SERCOM_SPI_CTRLA) SPI frame with address */ +#define SERCOM_SPI_CTRLA_FORM_SPI (SERCOM_SPI_CTRLA_FORM_SPI_Val << SERCOM_SPI_CTRLA_FORM_Pos) +#define SERCOM_SPI_CTRLA_FORM_SPI_ADDR (SERCOM_SPI_CTRLA_FORM_SPI_ADDR_Val << SERCOM_SPI_CTRLA_FORM_Pos) +#define SERCOM_SPI_CTRLA_CPHA_Pos 28 /**< \brief (SERCOM_SPI_CTRLA) Clock Phase */ +#define SERCOM_SPI_CTRLA_CPHA (0x1u << SERCOM_SPI_CTRLA_CPHA_Pos) +#define SERCOM_SPI_CTRLA_CPOL_Pos 29 /**< \brief (SERCOM_SPI_CTRLA) Clock Polarity */ +#define SERCOM_SPI_CTRLA_CPOL (0x1u << SERCOM_SPI_CTRLA_CPOL_Pos) +#define SERCOM_SPI_CTRLA_DORD_Pos 30 /**< \brief (SERCOM_SPI_CTRLA) Data Order */ +#define SERCOM_SPI_CTRLA_DORD (0x1u << SERCOM_SPI_CTRLA_DORD_Pos) +#define SERCOM_SPI_CTRLA_MASK 0x7F33019Fu /**< \brief (SERCOM_SPI_CTRLA) MASK Register */ + +/* -------- SERCOM_USART_CTRLA : (SERCOM Offset: 0x00) (R/W 32) USART USART Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SWRST:1; /*!< bit: 0 Software Reset */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t MODE:3; /*!< bit: 2.. 4 Operating Mode */ + uint32_t :2; /*!< bit: 5.. 6 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 7 Run In Standby */ + uint32_t IBON:1; /*!< bit: 8 Immediate Buffer Overflow Notification */ + uint32_t :7; /*!< bit: 9..15 Reserved */ + uint32_t TXPO:1; /*!< bit: 16 Transmit Data Pinout */ + uint32_t :3; /*!< bit: 17..19 Reserved */ + uint32_t RXPO:2; /*!< bit: 20..21 Receive Data Pinout */ + uint32_t :2; /*!< bit: 22..23 Reserved */ + uint32_t FORM:4; /*!< bit: 24..27 Frame Format */ + uint32_t CMODE:1; /*!< bit: 28 Communication Mode */ + uint32_t CPOL:1; /*!< bit: 29 Clock Polarity */ + uint32_t DORD:1; /*!< bit: 30 Data Order */ + uint32_t :1; /*!< bit: 31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_USART_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_CTRLA_OFFSET 0x00 /**< \brief (SERCOM_USART_CTRLA offset) USART Control A */ +#define SERCOM_USART_CTRLA_RESETVALUE 0x00000000 /**< \brief (SERCOM_USART_CTRLA reset_value) USART Control A */ + +#define SERCOM_USART_CTRLA_SWRST_Pos 0 /**< \brief (SERCOM_USART_CTRLA) Software Reset */ +#define SERCOM_USART_CTRLA_SWRST (0x1u << SERCOM_USART_CTRLA_SWRST_Pos) +#define SERCOM_USART_CTRLA_ENABLE_Pos 1 /**< \brief (SERCOM_USART_CTRLA) Enable */ +#define SERCOM_USART_CTRLA_ENABLE (0x1u << SERCOM_USART_CTRLA_ENABLE_Pos) +#define SERCOM_USART_CTRLA_MODE_Pos 2 /**< \brief (SERCOM_USART_CTRLA) Operating Mode */ +#define SERCOM_USART_CTRLA_MODE_Msk (0x7u << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE(value) ((SERCOM_USART_CTRLA_MODE_Msk & ((value) << SERCOM_USART_CTRLA_MODE_Pos))) +#define SERCOM_USART_CTRLA_MODE_USART_EXT_CLK_Val 0x0u /**< \brief (SERCOM_USART_CTRLA) USART mode with external clock */ +#define SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val 0x1u /**< \brief (SERCOM_USART_CTRLA) USART mode with internal clock */ +#define SERCOM_USART_CTRLA_MODE_SPI_SLAVE_Val 0x2u /**< \brief (SERCOM_USART_CTRLA) SPI mode with external clock */ +#define SERCOM_USART_CTRLA_MODE_SPI_MASTER_Val 0x3u /**< \brief (SERCOM_USART_CTRLA) SPI mode with internal clock */ +#define SERCOM_USART_CTRLA_MODE_I2C_SLAVE_Val 0x4u /**< \brief (SERCOM_USART_CTRLA) I2C mode with external clock */ +#define SERCOM_USART_CTRLA_MODE_I2C_MASTER_Val 0x5u /**< \brief (SERCOM_USART_CTRLA) I2C mode with internal clock */ +#define SERCOM_USART_CTRLA_MODE_USART_EXT_CLK (SERCOM_USART_CTRLA_MODE_USART_EXT_CLK_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE_USART_INT_CLK (SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE_SPI_SLAVE (SERCOM_USART_CTRLA_MODE_SPI_SLAVE_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE_SPI_MASTER (SERCOM_USART_CTRLA_MODE_SPI_MASTER_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE_I2C_SLAVE (SERCOM_USART_CTRLA_MODE_I2C_SLAVE_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_MODE_I2C_MASTER (SERCOM_USART_CTRLA_MODE_I2C_MASTER_Val << SERCOM_USART_CTRLA_MODE_Pos) +#define SERCOM_USART_CTRLA_RUNSTDBY_Pos 7 /**< \brief (SERCOM_USART_CTRLA) Run In Standby */ +#define SERCOM_USART_CTRLA_RUNSTDBY (0x1u << SERCOM_USART_CTRLA_RUNSTDBY_Pos) +#define SERCOM_USART_CTRLA_IBON_Pos 8 /**< \brief (SERCOM_USART_CTRLA) Immediate Buffer Overflow Notification */ +#define SERCOM_USART_CTRLA_IBON (0x1u << SERCOM_USART_CTRLA_IBON_Pos) +#define SERCOM_USART_CTRLA_TXPO_Pos 16 /**< \brief (SERCOM_USART_CTRLA) Transmit Data Pinout */ +#define SERCOM_USART_CTRLA_TXPO (0x1u << SERCOM_USART_CTRLA_TXPO_Pos) +#define SERCOM_USART_CTRLA_TXPO_PAD0_Val 0x0u /**< \brief (SERCOM_USART_CTRLA) TXD at PAD0, XCK at PAD1 */ +#define SERCOM_USART_CTRLA_TXPO_PAD2_Val 0x1u /**< \brief (SERCOM_USART_CTRLA) TXD at PAD2, XCK at PAD3 */ +#define SERCOM_USART_CTRLA_TXPO_PAD0 (SERCOM_USART_CTRLA_TXPO_PAD0_Val << SERCOM_USART_CTRLA_TXPO_Pos) +#define SERCOM_USART_CTRLA_TXPO_PAD2 (SERCOM_USART_CTRLA_TXPO_PAD2_Val << SERCOM_USART_CTRLA_TXPO_Pos) +#define SERCOM_USART_CTRLA_RXPO_Pos 20 /**< \brief (SERCOM_USART_CTRLA) Receive Data Pinout */ +#define SERCOM_USART_CTRLA_RXPO_Msk (0x3u << SERCOM_USART_CTRLA_RXPO_Pos) +#define SERCOM_USART_CTRLA_RXPO(value) ((SERCOM_USART_CTRLA_RXPO_Msk & ((value) << SERCOM_USART_CTRLA_RXPO_Pos))) +#define SERCOM_USART_CTRLA_RXPO_PAD0_Val 0x0u /**< \brief (SERCOM_USART_CTRLA) SERCOM_PAD0 */ +#define SERCOM_USART_CTRLA_RXPO_PAD1_Val 0x1u /**< \brief (SERCOM_USART_CTRLA) SERCOM_PAD1 */ +#define SERCOM_USART_CTRLA_RXPO_PAD2_Val 0x2u /**< \brief (SERCOM_USART_CTRLA) SERCOM_PAD2 */ +#define SERCOM_USART_CTRLA_RXPO_PAD3_Val 0x3u /**< \brief (SERCOM_USART_CTRLA) SERCOM_PAD3 */ +#define SERCOM_USART_CTRLA_RXPO_PAD0 (SERCOM_USART_CTRLA_RXPO_PAD0_Val << SERCOM_USART_CTRLA_RXPO_Pos) +#define SERCOM_USART_CTRLA_RXPO_PAD1 (SERCOM_USART_CTRLA_RXPO_PAD1_Val << SERCOM_USART_CTRLA_RXPO_Pos) +#define SERCOM_USART_CTRLA_RXPO_PAD2 (SERCOM_USART_CTRLA_RXPO_PAD2_Val << SERCOM_USART_CTRLA_RXPO_Pos) +#define SERCOM_USART_CTRLA_RXPO_PAD3 (SERCOM_USART_CTRLA_RXPO_PAD3_Val << SERCOM_USART_CTRLA_RXPO_Pos) +#define SERCOM_USART_CTRLA_FORM_Pos 24 /**< \brief (SERCOM_USART_CTRLA) Frame Format */ +#define SERCOM_USART_CTRLA_FORM_Msk (0xFu << SERCOM_USART_CTRLA_FORM_Pos) +#define SERCOM_USART_CTRLA_FORM(value) ((SERCOM_USART_CTRLA_FORM_Msk & ((value) << SERCOM_USART_CTRLA_FORM_Pos))) +#define SERCOM_USART_CTRLA_FORM_0_Val 0x0u /**< \brief (SERCOM_USART_CTRLA) USART frame */ +#define SERCOM_USART_CTRLA_FORM_1_Val 0x1u /**< \brief (SERCOM_USART_CTRLA) USART frame with parity */ +#define SERCOM_USART_CTRLA_FORM_0 (SERCOM_USART_CTRLA_FORM_0_Val << SERCOM_USART_CTRLA_FORM_Pos) +#define SERCOM_USART_CTRLA_FORM_1 (SERCOM_USART_CTRLA_FORM_1_Val << SERCOM_USART_CTRLA_FORM_Pos) +#define SERCOM_USART_CTRLA_CMODE_Pos 28 /**< \brief (SERCOM_USART_CTRLA) Communication Mode */ +#define SERCOM_USART_CTRLA_CMODE (0x1u << SERCOM_USART_CTRLA_CMODE_Pos) +#define SERCOM_USART_CTRLA_CPOL_Pos 29 /**< \brief (SERCOM_USART_CTRLA) Clock Polarity */ +#define SERCOM_USART_CTRLA_CPOL (0x1u << SERCOM_USART_CTRLA_CPOL_Pos) +#define SERCOM_USART_CTRLA_DORD_Pos 30 /**< \brief (SERCOM_USART_CTRLA) Data Order */ +#define SERCOM_USART_CTRLA_DORD (0x1u << SERCOM_USART_CTRLA_DORD_Pos) +#define SERCOM_USART_CTRLA_MASK 0x7F31019Fu /**< \brief (SERCOM_USART_CTRLA) MASK Register */ + +/* -------- SERCOM_I2CM_CTRLB : (SERCOM Offset: 0x04) (R/W 32) I2CM I2CM Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :8; /*!< bit: 0.. 7 Reserved */ + uint32_t SMEN:1; /*!< bit: 8 Smart Mode Enable */ + uint32_t QCEN:1; /*!< bit: 9 Quick Command Enable */ + uint32_t :6; /*!< bit: 10..15 Reserved */ + uint32_t CMD:2; /*!< bit: 16..17 Command */ + uint32_t ACKACT:1; /*!< bit: 18 Acknowledge Action */ + uint32_t :13; /*!< bit: 19..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_CTRLB_OFFSET 0x04 /**< \brief (SERCOM_I2CM_CTRLB offset) I2CM Control B */ +#define SERCOM_I2CM_CTRLB_RESETVALUE 0x00000000 /**< \brief (SERCOM_I2CM_CTRLB reset_value) I2CM Control B */ + +#define SERCOM_I2CM_CTRLB_SMEN_Pos 8 /**< \brief (SERCOM_I2CM_CTRLB) Smart Mode Enable */ +#define SERCOM_I2CM_CTRLB_SMEN (0x1u << SERCOM_I2CM_CTRLB_SMEN_Pos) +#define SERCOM_I2CM_CTRLB_QCEN_Pos 9 /**< \brief (SERCOM_I2CM_CTRLB) Quick Command Enable */ +#define SERCOM_I2CM_CTRLB_QCEN (0x1u << SERCOM_I2CM_CTRLB_QCEN_Pos) +#define SERCOM_I2CM_CTRLB_CMD_Pos 16 /**< \brief (SERCOM_I2CM_CTRLB) Command */ +#define SERCOM_I2CM_CTRLB_CMD_Msk (0x3u << SERCOM_I2CM_CTRLB_CMD_Pos) +#define SERCOM_I2CM_CTRLB_CMD(value) ((SERCOM_I2CM_CTRLB_CMD_Msk & ((value) << SERCOM_I2CM_CTRLB_CMD_Pos))) +#define SERCOM_I2CM_CTRLB_ACKACT_Pos 18 /**< \brief (SERCOM_I2CM_CTRLB) Acknowledge Action */ +#define SERCOM_I2CM_CTRLB_ACKACT (0x1u << SERCOM_I2CM_CTRLB_ACKACT_Pos) +#define SERCOM_I2CM_CTRLB_MASK 0x00070300u /**< \brief (SERCOM_I2CM_CTRLB) MASK Register */ + +/* -------- SERCOM_I2CS_CTRLB : (SERCOM Offset: 0x04) (R/W 32) I2CS I2CS Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :8; /*!< bit: 0.. 7 Reserved */ + uint32_t SMEN:1; /*!< bit: 8 Smart Mode Enable */ + uint32_t :5; /*!< bit: 9..13 Reserved */ + uint32_t AMODE:2; /*!< bit: 14..15 Address Mode */ + uint32_t CMD:2; /*!< bit: 16..17 Command */ + uint32_t ACKACT:1; /*!< bit: 18 Acknowledge Action */ + uint32_t :13; /*!< bit: 19..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_CTRLB_OFFSET 0x04 /**< \brief (SERCOM_I2CS_CTRLB offset) I2CS Control B */ +#define SERCOM_I2CS_CTRLB_RESETVALUE 0x00000000 /**< \brief (SERCOM_I2CS_CTRLB reset_value) I2CS Control B */ + +#define SERCOM_I2CS_CTRLB_SMEN_Pos 8 /**< \brief (SERCOM_I2CS_CTRLB) Smart Mode Enable */ +#define SERCOM_I2CS_CTRLB_SMEN (0x1u << SERCOM_I2CS_CTRLB_SMEN_Pos) +#define SERCOM_I2CS_CTRLB_AMODE_Pos 14 /**< \brief (SERCOM_I2CS_CTRLB) Address Mode */ +#define SERCOM_I2CS_CTRLB_AMODE_Msk (0x3u << SERCOM_I2CS_CTRLB_AMODE_Pos) +#define SERCOM_I2CS_CTRLB_AMODE(value) ((SERCOM_I2CS_CTRLB_AMODE_Msk & ((value) << SERCOM_I2CS_CTRLB_AMODE_Pos))) +#define SERCOM_I2CS_CTRLB_CMD_Pos 16 /**< \brief (SERCOM_I2CS_CTRLB) Command */ +#define SERCOM_I2CS_CTRLB_CMD_Msk (0x3u << SERCOM_I2CS_CTRLB_CMD_Pos) +#define SERCOM_I2CS_CTRLB_CMD(value) ((SERCOM_I2CS_CTRLB_CMD_Msk & ((value) << SERCOM_I2CS_CTRLB_CMD_Pos))) +#define SERCOM_I2CS_CTRLB_ACKACT_Pos 18 /**< \brief (SERCOM_I2CS_CTRLB) Acknowledge Action */ +#define SERCOM_I2CS_CTRLB_ACKACT (0x1u << SERCOM_I2CS_CTRLB_ACKACT_Pos) +#define SERCOM_I2CS_CTRLB_MASK 0x0007C100u /**< \brief (SERCOM_I2CS_CTRLB) MASK Register */ + +/* -------- SERCOM_SPI_CTRLB : (SERCOM Offset: 0x04) (R/W 32) SPI SPI Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CHSIZE:3; /*!< bit: 0.. 2 Character Size */ + uint32_t :3; /*!< bit: 3.. 5 Reserved */ + uint32_t PLOADEN:1; /*!< bit: 6 Slave Data Preload Enable */ + uint32_t :7; /*!< bit: 7..13 Reserved */ + uint32_t AMODE:2; /*!< bit: 14..15 Address Mode */ + uint32_t :1; /*!< bit: 16 Reserved */ + uint32_t RXEN:1; /*!< bit: 17 Receiver Enable */ + uint32_t :14; /*!< bit: 18..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_SPI_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_CTRLB_OFFSET 0x04 /**< \brief (SERCOM_SPI_CTRLB offset) SPI Control B */ +#define SERCOM_SPI_CTRLB_RESETVALUE 0x00000000 /**< \brief (SERCOM_SPI_CTRLB reset_value) SPI Control B */ + +#define SERCOM_SPI_CTRLB_CHSIZE_Pos 0 /**< \brief (SERCOM_SPI_CTRLB) Character Size */ +#define SERCOM_SPI_CTRLB_CHSIZE_Msk (0x7u << SERCOM_SPI_CTRLB_CHSIZE_Pos) +#define SERCOM_SPI_CTRLB_CHSIZE(value) ((SERCOM_SPI_CTRLB_CHSIZE_Msk & ((value) << SERCOM_SPI_CTRLB_CHSIZE_Pos))) +#define SERCOM_SPI_CTRLB_PLOADEN_Pos 6 /**< \brief (SERCOM_SPI_CTRLB) Slave Data Preload Enable */ +#define SERCOM_SPI_CTRLB_PLOADEN (0x1u << SERCOM_SPI_CTRLB_PLOADEN_Pos) +#define SERCOM_SPI_CTRLB_AMODE_Pos 14 /**< \brief (SERCOM_SPI_CTRLB) Address Mode */ +#define SERCOM_SPI_CTRLB_AMODE_Msk (0x3u << SERCOM_SPI_CTRLB_AMODE_Pos) +#define SERCOM_SPI_CTRLB_AMODE(value) ((SERCOM_SPI_CTRLB_AMODE_Msk & ((value) << SERCOM_SPI_CTRLB_AMODE_Pos))) +#define SERCOM_SPI_CTRLB_AMODE_MASK_Val 0x0u /**< \brief (SERCOM_SPI_CTRLB) ADDRMASK is used as a mask to the ADDR register. */ +#define SERCOM_SPI_CTRLB_AMODE_2ADDR_Val 0x1u /**< \brief (SERCOM_SPI_CTRLB) The slave responds to the 2 unique addresses in ADDR and ADDRMASK. */ +#define SERCOM_SPI_CTRLB_AMODE_RANGE_Val 0x2u /**< \brief (SERCOM_SPI_CTRLB) The slave responds to the range of addresses between and including ADDR and ADDRMASK. ADDR is the upper limit. */ +#define SERCOM_SPI_CTRLB_AMODE_MASK (SERCOM_SPI_CTRLB_AMODE_MASK_Val << SERCOM_SPI_CTRLB_AMODE_Pos) +#define SERCOM_SPI_CTRLB_AMODE_2ADDR (SERCOM_SPI_CTRLB_AMODE_2ADDR_Val << SERCOM_SPI_CTRLB_AMODE_Pos) +#define SERCOM_SPI_CTRLB_AMODE_RANGE (SERCOM_SPI_CTRLB_AMODE_RANGE_Val << SERCOM_SPI_CTRLB_AMODE_Pos) +#define SERCOM_SPI_CTRLB_RXEN_Pos 17 /**< \brief (SERCOM_SPI_CTRLB) Receiver Enable */ +#define SERCOM_SPI_CTRLB_RXEN (0x1u << SERCOM_SPI_CTRLB_RXEN_Pos) +#define SERCOM_SPI_CTRLB_MASK 0x0002C047u /**< \brief (SERCOM_SPI_CTRLB) MASK Register */ + +/* -------- SERCOM_USART_CTRLB : (SERCOM Offset: 0x04) (R/W 32) USART USART Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CHSIZE:3; /*!< bit: 0.. 2 Character Size */ + uint32_t :3; /*!< bit: 3.. 5 Reserved */ + uint32_t SBMODE:1; /*!< bit: 6 Stop Bit Mode */ + uint32_t :2; /*!< bit: 7.. 8 Reserved */ + uint32_t SFDE:1; /*!< bit: 9 Start of Frame Detection Enable */ + uint32_t :3; /*!< bit: 10..12 Reserved */ + uint32_t PMODE:1; /*!< bit: 13 Parity Mode */ + uint32_t :2; /*!< bit: 14..15 Reserved */ + uint32_t TXEN:1; /*!< bit: 16 Transmitter Enable */ + uint32_t RXEN:1; /*!< bit: 17 Receiver Enable */ + uint32_t :14; /*!< bit: 18..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_USART_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_CTRLB_OFFSET 0x04 /**< \brief (SERCOM_USART_CTRLB offset) USART Control B */ +#define SERCOM_USART_CTRLB_RESETVALUE 0x00000000 /**< \brief (SERCOM_USART_CTRLB reset_value) USART Control B */ + +#define SERCOM_USART_CTRLB_CHSIZE_Pos 0 /**< \brief (SERCOM_USART_CTRLB) Character Size */ +#define SERCOM_USART_CTRLB_CHSIZE_Msk (0x7u << SERCOM_USART_CTRLB_CHSIZE_Pos) +#define SERCOM_USART_CTRLB_CHSIZE(value) ((SERCOM_USART_CTRLB_CHSIZE_Msk & ((value) << SERCOM_USART_CTRLB_CHSIZE_Pos))) +#define SERCOM_USART_CTRLB_SBMODE_Pos 6 /**< \brief (SERCOM_USART_CTRLB) Stop Bit Mode */ +#define SERCOM_USART_CTRLB_SBMODE (0x1u << SERCOM_USART_CTRLB_SBMODE_Pos) +#define SERCOM_USART_CTRLB_SFDE_Pos 9 /**< \brief (SERCOM_USART_CTRLB) Start of Frame Detection Enable */ +#define SERCOM_USART_CTRLB_SFDE (0x1u << SERCOM_USART_CTRLB_SFDE_Pos) +#define SERCOM_USART_CTRLB_PMODE_Pos 13 /**< \brief (SERCOM_USART_CTRLB) Parity Mode */ +#define SERCOM_USART_CTRLB_PMODE (0x1u << SERCOM_USART_CTRLB_PMODE_Pos) +#define SERCOM_USART_CTRLB_TXEN_Pos 16 /**< \brief (SERCOM_USART_CTRLB) Transmitter Enable */ +#define SERCOM_USART_CTRLB_TXEN (0x1u << SERCOM_USART_CTRLB_TXEN_Pos) +#define SERCOM_USART_CTRLB_RXEN_Pos 17 /**< \brief (SERCOM_USART_CTRLB) Receiver Enable */ +#define SERCOM_USART_CTRLB_RXEN (0x1u << SERCOM_USART_CTRLB_RXEN_Pos) +#define SERCOM_USART_CTRLB_MASK 0x00032247u /**< \brief (SERCOM_USART_CTRLB) MASK Register */ + +/* -------- SERCOM_I2CM_DBGCTRL : (SERCOM Offset: 0x08) (R/W 8) I2CM I2CM Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGSTOP:1; /*!< bit: 0 Debug Stop Mode */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_DBGCTRL_OFFSET 0x08 /**< \brief (SERCOM_I2CM_DBGCTRL offset) I2CM Debug Control */ +#define SERCOM_I2CM_DBGCTRL_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_DBGCTRL reset_value) I2CM Debug Control */ + +#define SERCOM_I2CM_DBGCTRL_DBGSTOP_Pos 0 /**< \brief (SERCOM_I2CM_DBGCTRL) Debug Stop Mode */ +#define SERCOM_I2CM_DBGCTRL_DBGSTOP (0x1u << SERCOM_I2CM_DBGCTRL_DBGSTOP_Pos) +#define SERCOM_I2CM_DBGCTRL_MASK 0x01u /**< \brief (SERCOM_I2CM_DBGCTRL) MASK Register */ + +/* -------- SERCOM_SPI_DBGCTRL : (SERCOM Offset: 0x08) (R/W 8) SPI SPI Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGSTOP:1; /*!< bit: 0 Debug Stop Mode */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_SPI_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_DBGCTRL_OFFSET 0x08 /**< \brief (SERCOM_SPI_DBGCTRL offset) SPI Debug Control */ +#define SERCOM_SPI_DBGCTRL_RESETVALUE 0x00 /**< \brief (SERCOM_SPI_DBGCTRL reset_value) SPI Debug Control */ + +#define SERCOM_SPI_DBGCTRL_DBGSTOP_Pos 0 /**< \brief (SERCOM_SPI_DBGCTRL) Debug Stop Mode */ +#define SERCOM_SPI_DBGCTRL_DBGSTOP (0x1u << SERCOM_SPI_DBGCTRL_DBGSTOP_Pos) +#define SERCOM_SPI_DBGCTRL_MASK 0x01u /**< \brief (SERCOM_SPI_DBGCTRL) MASK Register */ + +/* -------- SERCOM_USART_DBGCTRL : (SERCOM Offset: 0x08) (R/W 8) USART USART Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGSTOP:1; /*!< bit: 0 Debug Stop Mode */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_USART_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_DBGCTRL_OFFSET 0x08 /**< \brief (SERCOM_USART_DBGCTRL offset) USART Debug Control */ +#define SERCOM_USART_DBGCTRL_RESETVALUE 0x00 /**< \brief (SERCOM_USART_DBGCTRL reset_value) USART Debug Control */ + +#define SERCOM_USART_DBGCTRL_DBGSTOP_Pos 0 /**< \brief (SERCOM_USART_DBGCTRL) Debug Stop Mode */ +#define SERCOM_USART_DBGCTRL_DBGSTOP (0x1u << SERCOM_USART_DBGCTRL_DBGSTOP_Pos) +#define SERCOM_USART_DBGCTRL_MASK 0x01u /**< \brief (SERCOM_USART_DBGCTRL) MASK Register */ + +/* -------- SERCOM_I2CM_BAUD : (SERCOM Offset: 0x0A) (R/W 16) I2CM I2CM Baud Rate -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t BAUD:8; /*!< bit: 0.. 7 Master Baud Rate */ + uint16_t BAUDLOW:8; /*!< bit: 8..15 Master Baud Rate Low */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_BAUD_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_BAUD_OFFSET 0x0A /**< \brief (SERCOM_I2CM_BAUD offset) I2CM Baud Rate */ +#define SERCOM_I2CM_BAUD_RESETVALUE 0x0000 /**< \brief (SERCOM_I2CM_BAUD reset_value) I2CM Baud Rate */ + +#define SERCOM_I2CM_BAUD_BAUD_Pos 0 /**< \brief (SERCOM_I2CM_BAUD) Master Baud Rate */ +#define SERCOM_I2CM_BAUD_BAUD_Msk (0xFFu << SERCOM_I2CM_BAUD_BAUD_Pos) +#define SERCOM_I2CM_BAUD_BAUD(value) ((SERCOM_I2CM_BAUD_BAUD_Msk & ((value) << SERCOM_I2CM_BAUD_BAUD_Pos))) +#define SERCOM_I2CM_BAUD_BAUDLOW_Pos 8 /**< \brief (SERCOM_I2CM_BAUD) Master Baud Rate Low */ +#define SERCOM_I2CM_BAUD_BAUDLOW_Msk (0xFFu << SERCOM_I2CM_BAUD_BAUDLOW_Pos) +#define SERCOM_I2CM_BAUD_BAUDLOW(value) ((SERCOM_I2CM_BAUD_BAUDLOW_Msk & ((value) << SERCOM_I2CM_BAUD_BAUDLOW_Pos))) +#define SERCOM_I2CM_BAUD_MASK 0xFFFFu /**< \brief (SERCOM_I2CM_BAUD) MASK Register */ + +/* -------- SERCOM_SPI_BAUD : (SERCOM Offset: 0x0A) (R/W 8) SPI SPI Baud Rate -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t BAUD:8; /*!< bit: 0.. 7 Baud Register */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_SPI_BAUD_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_BAUD_OFFSET 0x0A /**< \brief (SERCOM_SPI_BAUD offset) SPI Baud Rate */ +#define SERCOM_SPI_BAUD_RESETVALUE 0x00 /**< \brief (SERCOM_SPI_BAUD reset_value) SPI Baud Rate */ + +#define SERCOM_SPI_BAUD_BAUD_Pos 0 /**< \brief (SERCOM_SPI_BAUD) Baud Register */ +#define SERCOM_SPI_BAUD_BAUD_Msk (0xFFu << SERCOM_SPI_BAUD_BAUD_Pos) +#define SERCOM_SPI_BAUD_BAUD(value) ((SERCOM_SPI_BAUD_BAUD_Msk & ((value) << SERCOM_SPI_BAUD_BAUD_Pos))) +#define SERCOM_SPI_BAUD_MASK 0xFFu /**< \brief (SERCOM_SPI_BAUD) MASK Register */ + +/* -------- SERCOM_USART_BAUD : (SERCOM Offset: 0x0A) (R/W 16) USART USART Baud -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t BAUD:16; /*!< bit: 0..15 Baud Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_USART_BAUD_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_BAUD_OFFSET 0x0A /**< \brief (SERCOM_USART_BAUD offset) USART Baud */ +#define SERCOM_USART_BAUD_RESETVALUE 0x0000 /**< \brief (SERCOM_USART_BAUD reset_value) USART Baud */ + +#define SERCOM_USART_BAUD_BAUD_Pos 0 /**< \brief (SERCOM_USART_BAUD) Baud Value */ +#define SERCOM_USART_BAUD_BAUD_Msk (0xFFFFu << SERCOM_USART_BAUD_BAUD_Pos) +#define SERCOM_USART_BAUD_BAUD(value) ((SERCOM_USART_BAUD_BAUD_Msk & ((value) << SERCOM_USART_BAUD_BAUD_Pos))) +#define SERCOM_USART_BAUD_MASK 0xFFFFu /**< \brief (SERCOM_USART_BAUD) MASK Register */ + +/* -------- SERCOM_I2CM_INTENCLR : (SERCOM Offset: 0x0C) (R/W 8) I2CM I2CM Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t MB:1; /*!< bit: 0 Master on Bus Interrupt Enable */ + uint8_t SB:1; /*!< bit: 1 Slave on Bus Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_INTENCLR_OFFSET 0x0C /**< \brief (SERCOM_I2CM_INTENCLR offset) I2CM Interrupt Enable Clear */ +#define SERCOM_I2CM_INTENCLR_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_INTENCLR reset_value) I2CM Interrupt Enable Clear */ + +#define SERCOM_I2CM_INTENCLR_MB_Pos 0 /**< \brief (SERCOM_I2CM_INTENCLR) Master on Bus Interrupt Enable */ +#define SERCOM_I2CM_INTENCLR_MB (0x1u << SERCOM_I2CM_INTENCLR_MB_Pos) +#define SERCOM_I2CM_INTENCLR_SB_Pos 1 /**< \brief (SERCOM_I2CM_INTENCLR) Slave on Bus Interrupt Enable */ +#define SERCOM_I2CM_INTENCLR_SB (0x1u << SERCOM_I2CM_INTENCLR_SB_Pos) +#define SERCOM_I2CM_INTENCLR_MASK 0x03u /**< \brief (SERCOM_I2CM_INTENCLR) MASK Register */ + +/* -------- SERCOM_I2CS_INTENCLR : (SERCOM Offset: 0x0C) (R/W 8) I2CS I2CS Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PREC:1; /*!< bit: 0 Stop Received Interrupt Enable */ + uint8_t AMATCH:1; /*!< bit: 1 Address Match Interrupt Enable */ + uint8_t DRDY:1; /*!< bit: 2 Data Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_INTENCLR_OFFSET 0x0C /**< \brief (SERCOM_I2CS_INTENCLR offset) I2CS Interrupt Enable Clear */ +#define SERCOM_I2CS_INTENCLR_RESETVALUE 0x00 /**< \brief (SERCOM_I2CS_INTENCLR reset_value) I2CS Interrupt Enable Clear */ + +#define SERCOM_I2CS_INTENCLR_PREC_Pos 0 /**< \brief (SERCOM_I2CS_INTENCLR) Stop Received Interrupt Enable */ +#define SERCOM_I2CS_INTENCLR_PREC (0x1u << SERCOM_I2CS_INTENCLR_PREC_Pos) +#define SERCOM_I2CS_INTENCLR_AMATCH_Pos 1 /**< \brief (SERCOM_I2CS_INTENCLR) Address Match Interrupt Enable */ +#define SERCOM_I2CS_INTENCLR_AMATCH (0x1u << SERCOM_I2CS_INTENCLR_AMATCH_Pos) +#define SERCOM_I2CS_INTENCLR_DRDY_Pos 2 /**< \brief (SERCOM_I2CS_INTENCLR) Data Ready Interrupt Enable */ +#define SERCOM_I2CS_INTENCLR_DRDY (0x1u << SERCOM_I2CS_INTENCLR_DRDY_Pos) +#define SERCOM_I2CS_INTENCLR_MASK 0x07u /**< \brief (SERCOM_I2CS_INTENCLR) MASK Register */ + +/* -------- SERCOM_SPI_INTENCLR : (SERCOM Offset: 0x0C) (R/W 8) SPI SPI Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty Interrupt Enable */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete Interrupt Enable */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_SPI_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_INTENCLR_OFFSET 0x0C /**< \brief (SERCOM_SPI_INTENCLR offset) SPI Interrupt Enable Clear */ +#define SERCOM_SPI_INTENCLR_RESETVALUE 0x00 /**< \brief (SERCOM_SPI_INTENCLR reset_value) SPI Interrupt Enable Clear */ + +#define SERCOM_SPI_INTENCLR_DRE_Pos 0 /**< \brief (SERCOM_SPI_INTENCLR) Data Register Empty Interrupt Enable */ +#define SERCOM_SPI_INTENCLR_DRE (0x1u << SERCOM_SPI_INTENCLR_DRE_Pos) +#define SERCOM_SPI_INTENCLR_TXC_Pos 1 /**< \brief (SERCOM_SPI_INTENCLR) Transmit Complete Interrupt Enable */ +#define SERCOM_SPI_INTENCLR_TXC (0x1u << SERCOM_SPI_INTENCLR_TXC_Pos) +#define SERCOM_SPI_INTENCLR_RXC_Pos 2 /**< \brief (SERCOM_SPI_INTENCLR) Receive Complete Interrupt Enable */ +#define SERCOM_SPI_INTENCLR_RXC (0x1u << SERCOM_SPI_INTENCLR_RXC_Pos) +#define SERCOM_SPI_INTENCLR_MASK 0x07u /**< \brief (SERCOM_SPI_INTENCLR) MASK Register */ + +/* -------- SERCOM_USART_INTENCLR : (SERCOM Offset: 0x0C) (R/W 8) USART USART Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty Interrupt Enable */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete Interrupt Enable */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete Interrupt Enable */ + uint8_t RXS:1; /*!< bit: 3 Receive Start Interrupt Disable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_USART_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_INTENCLR_OFFSET 0x0C /**< \brief (SERCOM_USART_INTENCLR offset) USART Interrupt Enable Clear */ +#define SERCOM_USART_INTENCLR_RESETVALUE 0x00 /**< \brief (SERCOM_USART_INTENCLR reset_value) USART Interrupt Enable Clear */ + +#define SERCOM_USART_INTENCLR_DRE_Pos 0 /**< \brief (SERCOM_USART_INTENCLR) Data Register Empty Interrupt Enable */ +#define SERCOM_USART_INTENCLR_DRE (0x1u << SERCOM_USART_INTENCLR_DRE_Pos) +#define SERCOM_USART_INTENCLR_TXC_Pos 1 /**< \brief (SERCOM_USART_INTENCLR) Transmit Complete Interrupt Enable */ +#define SERCOM_USART_INTENCLR_TXC (0x1u << SERCOM_USART_INTENCLR_TXC_Pos) +#define SERCOM_USART_INTENCLR_RXC_Pos 2 /**< \brief (SERCOM_USART_INTENCLR) Receive Complete Interrupt Enable */ +#define SERCOM_USART_INTENCLR_RXC (0x1u << SERCOM_USART_INTENCLR_RXC_Pos) +#define SERCOM_USART_INTENCLR_RXS_Pos 3 /**< \brief (SERCOM_USART_INTENCLR) Receive Start Interrupt Disable */ +#define SERCOM_USART_INTENCLR_RXS (0x1u << SERCOM_USART_INTENCLR_RXS_Pos) +#define SERCOM_USART_INTENCLR_MASK 0x0Fu /**< \brief (SERCOM_USART_INTENCLR) MASK Register */ + +/* -------- SERCOM_I2CM_INTENSET : (SERCOM Offset: 0x0D) (R/W 8) I2CM I2CM Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t MB:1; /*!< bit: 0 Master on Bus Interrupt Enable */ + uint8_t SB:1; /*!< bit: 1 Slave on Bus Interrupt Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_INTENSET_OFFSET 0x0D /**< \brief (SERCOM_I2CM_INTENSET offset) I2CM Interrupt Enable Set */ +#define SERCOM_I2CM_INTENSET_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_INTENSET reset_value) I2CM Interrupt Enable Set */ + +#define SERCOM_I2CM_INTENSET_MB_Pos 0 /**< \brief (SERCOM_I2CM_INTENSET) Master on Bus Interrupt Enable */ +#define SERCOM_I2CM_INTENSET_MB (0x1u << SERCOM_I2CM_INTENSET_MB_Pos) +#define SERCOM_I2CM_INTENSET_SB_Pos 1 /**< \brief (SERCOM_I2CM_INTENSET) Slave on Bus Interrupt Enable */ +#define SERCOM_I2CM_INTENSET_SB (0x1u << SERCOM_I2CM_INTENSET_SB_Pos) +#define SERCOM_I2CM_INTENSET_MASK 0x03u /**< \brief (SERCOM_I2CM_INTENSET) MASK Register */ + +/* -------- SERCOM_I2CS_INTENSET : (SERCOM Offset: 0x0D) (R/W 8) I2CS I2CS Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PREC:1; /*!< bit: 0 Stop Received Interrupt Enable */ + uint8_t AMATCH:1; /*!< bit: 1 Address Match Interrupt Enable */ + uint8_t DRDY:1; /*!< bit: 2 Data Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_INTENSET_OFFSET 0x0D /**< \brief (SERCOM_I2CS_INTENSET offset) I2CS Interrupt Enable Set */ +#define SERCOM_I2CS_INTENSET_RESETVALUE 0x00 /**< \brief (SERCOM_I2CS_INTENSET reset_value) I2CS Interrupt Enable Set */ + +#define SERCOM_I2CS_INTENSET_PREC_Pos 0 /**< \brief (SERCOM_I2CS_INTENSET) Stop Received Interrupt Enable */ +#define SERCOM_I2CS_INTENSET_PREC (0x1u << SERCOM_I2CS_INTENSET_PREC_Pos) +#define SERCOM_I2CS_INTENSET_AMATCH_Pos 1 /**< \brief (SERCOM_I2CS_INTENSET) Address Match Interrupt Enable */ +#define SERCOM_I2CS_INTENSET_AMATCH (0x1u << SERCOM_I2CS_INTENSET_AMATCH_Pos) +#define SERCOM_I2CS_INTENSET_DRDY_Pos 2 /**< \brief (SERCOM_I2CS_INTENSET) Data Ready Interrupt Enable */ +#define SERCOM_I2CS_INTENSET_DRDY (0x1u << SERCOM_I2CS_INTENSET_DRDY_Pos) +#define SERCOM_I2CS_INTENSET_MASK 0x07u /**< \brief (SERCOM_I2CS_INTENSET) MASK Register */ + +/* -------- SERCOM_SPI_INTENSET : (SERCOM Offset: 0x0D) (R/W 8) SPI SPI Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty Interrupt Enable */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete Interrupt Enable */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_SPI_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_INTENSET_OFFSET 0x0D /**< \brief (SERCOM_SPI_INTENSET offset) SPI Interrupt Enable Set */ +#define SERCOM_SPI_INTENSET_RESETVALUE 0x00 /**< \brief (SERCOM_SPI_INTENSET reset_value) SPI Interrupt Enable Set */ + +#define SERCOM_SPI_INTENSET_DRE_Pos 0 /**< \brief (SERCOM_SPI_INTENSET) Data Register Empty Interrupt Enable */ +#define SERCOM_SPI_INTENSET_DRE (0x1u << SERCOM_SPI_INTENSET_DRE_Pos) +#define SERCOM_SPI_INTENSET_TXC_Pos 1 /**< \brief (SERCOM_SPI_INTENSET) Transmit Complete Interrupt Enable */ +#define SERCOM_SPI_INTENSET_TXC (0x1u << SERCOM_SPI_INTENSET_TXC_Pos) +#define SERCOM_SPI_INTENSET_RXC_Pos 2 /**< \brief (SERCOM_SPI_INTENSET) Receive Complete Interrupt Enable */ +#define SERCOM_SPI_INTENSET_RXC (0x1u << SERCOM_SPI_INTENSET_RXC_Pos) +#define SERCOM_SPI_INTENSET_MASK 0x07u /**< \brief (SERCOM_SPI_INTENSET) MASK Register */ + +/* -------- SERCOM_USART_INTENSET : (SERCOM Offset: 0x0D) (R/W 8) USART USART Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty Interrupt Enable */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete Interrupt Enable */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete Interrupt Enable */ + uint8_t RXS:1; /*!< bit: 3 Receive Start Interrupt Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_USART_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_INTENSET_OFFSET 0x0D /**< \brief (SERCOM_USART_INTENSET offset) USART Interrupt Enable Set */ +#define SERCOM_USART_INTENSET_RESETVALUE 0x00 /**< \brief (SERCOM_USART_INTENSET reset_value) USART Interrupt Enable Set */ + +#define SERCOM_USART_INTENSET_DRE_Pos 0 /**< \brief (SERCOM_USART_INTENSET) Data Register Empty Interrupt Enable */ +#define SERCOM_USART_INTENSET_DRE (0x1u << SERCOM_USART_INTENSET_DRE_Pos) +#define SERCOM_USART_INTENSET_TXC_Pos 1 /**< \brief (SERCOM_USART_INTENSET) Transmit Complete Interrupt Enable */ +#define SERCOM_USART_INTENSET_TXC (0x1u << SERCOM_USART_INTENSET_TXC_Pos) +#define SERCOM_USART_INTENSET_RXC_Pos 2 /**< \brief (SERCOM_USART_INTENSET) Receive Complete Interrupt Enable */ +#define SERCOM_USART_INTENSET_RXC (0x1u << SERCOM_USART_INTENSET_RXC_Pos) +#define SERCOM_USART_INTENSET_RXS_Pos 3 /**< \brief (SERCOM_USART_INTENSET) Receive Start Interrupt Enable */ +#define SERCOM_USART_INTENSET_RXS (0x1u << SERCOM_USART_INTENSET_RXS_Pos) +#define SERCOM_USART_INTENSET_MASK 0x0Fu /**< \brief (SERCOM_USART_INTENSET) MASK Register */ + +/* -------- SERCOM_I2CM_INTFLAG : (SERCOM Offset: 0x0E) (R/W 8) I2CM I2CM Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t MB:1; /*!< bit: 0 Master on Bus */ + uint8_t SB:1; /*!< bit: 1 Slave on Bus */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_INTFLAG_OFFSET 0x0E /**< \brief (SERCOM_I2CM_INTFLAG offset) I2CM Interrupt Flag Status and Clear */ +#define SERCOM_I2CM_INTFLAG_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_INTFLAG reset_value) I2CM Interrupt Flag Status and Clear */ + +#define SERCOM_I2CM_INTFLAG_MB_Pos 0 /**< \brief (SERCOM_I2CM_INTFLAG) Master on Bus */ +#define SERCOM_I2CM_INTFLAG_MB (0x1u << SERCOM_I2CM_INTFLAG_MB_Pos) +#define SERCOM_I2CM_INTFLAG_SB_Pos 1 /**< \brief (SERCOM_I2CM_INTFLAG) Slave on Bus */ +#define SERCOM_I2CM_INTFLAG_SB (0x1u << SERCOM_I2CM_INTFLAG_SB_Pos) +#define SERCOM_I2CM_INTFLAG_MASK 0x03u /**< \brief (SERCOM_I2CM_INTFLAG) MASK Register */ + +/* -------- SERCOM_I2CS_INTFLAG : (SERCOM Offset: 0x0E) (R/W 8) I2CS I2CS Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PREC:1; /*!< bit: 0 Stop Received */ + uint8_t AMATCH:1; /*!< bit: 1 Address Match */ + uint8_t DRDY:1; /*!< bit: 2 Data Ready */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_INTFLAG_OFFSET 0x0E /**< \brief (SERCOM_I2CS_INTFLAG offset) I2CS Interrupt Flag Status and Clear */ +#define SERCOM_I2CS_INTFLAG_RESETVALUE 0x00 /**< \brief (SERCOM_I2CS_INTFLAG reset_value) I2CS Interrupt Flag Status and Clear */ + +#define SERCOM_I2CS_INTFLAG_PREC_Pos 0 /**< \brief (SERCOM_I2CS_INTFLAG) Stop Received */ +#define SERCOM_I2CS_INTFLAG_PREC (0x1u << SERCOM_I2CS_INTFLAG_PREC_Pos) +#define SERCOM_I2CS_INTFLAG_AMATCH_Pos 1 /**< \brief (SERCOM_I2CS_INTFLAG) Address Match */ +#define SERCOM_I2CS_INTFLAG_AMATCH (0x1u << SERCOM_I2CS_INTFLAG_AMATCH_Pos) +#define SERCOM_I2CS_INTFLAG_DRDY_Pos 2 /**< \brief (SERCOM_I2CS_INTFLAG) Data Ready */ +#define SERCOM_I2CS_INTFLAG_DRDY (0x1u << SERCOM_I2CS_INTFLAG_DRDY_Pos) +#define SERCOM_I2CS_INTFLAG_MASK 0x07u /**< \brief (SERCOM_I2CS_INTFLAG) MASK Register */ + +/* -------- SERCOM_SPI_INTFLAG : (SERCOM Offset: 0x0E) (R/W 8) SPI SPI Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_SPI_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_INTFLAG_OFFSET 0x0E /**< \brief (SERCOM_SPI_INTFLAG offset) SPI Interrupt Flag Status and Clear */ +#define SERCOM_SPI_INTFLAG_RESETVALUE 0x00 /**< \brief (SERCOM_SPI_INTFLAG reset_value) SPI Interrupt Flag Status and Clear */ + +#define SERCOM_SPI_INTFLAG_DRE_Pos 0 /**< \brief (SERCOM_SPI_INTFLAG) Data Register Empty */ +#define SERCOM_SPI_INTFLAG_DRE (0x1u << SERCOM_SPI_INTFLAG_DRE_Pos) +#define SERCOM_SPI_INTFLAG_TXC_Pos 1 /**< \brief (SERCOM_SPI_INTFLAG) Transmit Complete */ +#define SERCOM_SPI_INTFLAG_TXC (0x1u << SERCOM_SPI_INTFLAG_TXC_Pos) +#define SERCOM_SPI_INTFLAG_RXC_Pos 2 /**< \brief (SERCOM_SPI_INTFLAG) Receive Complete */ +#define SERCOM_SPI_INTFLAG_RXC (0x1u << SERCOM_SPI_INTFLAG_RXC_Pos) +#define SERCOM_SPI_INTFLAG_MASK 0x07u /**< \brief (SERCOM_SPI_INTFLAG) MASK Register */ + +/* -------- SERCOM_USART_INTFLAG : (SERCOM Offset: 0x0E) (R/W 8) USART USART Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DRE:1; /*!< bit: 0 Data Register Empty */ + uint8_t TXC:1; /*!< bit: 1 Transmit Complete */ + uint8_t RXC:1; /*!< bit: 2 Receive Complete */ + uint8_t RXS:1; /*!< bit: 3 Receive Start Interrupt */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_USART_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_INTFLAG_OFFSET 0x0E /**< \brief (SERCOM_USART_INTFLAG offset) USART Interrupt Flag Status and Clear */ +#define SERCOM_USART_INTFLAG_RESETVALUE 0x00 /**< \brief (SERCOM_USART_INTFLAG reset_value) USART Interrupt Flag Status and Clear */ + +#define SERCOM_USART_INTFLAG_DRE_Pos 0 /**< \brief (SERCOM_USART_INTFLAG) Data Register Empty */ +#define SERCOM_USART_INTFLAG_DRE (0x1u << SERCOM_USART_INTFLAG_DRE_Pos) +#define SERCOM_USART_INTFLAG_TXC_Pos 1 /**< \brief (SERCOM_USART_INTFLAG) Transmit Complete */ +#define SERCOM_USART_INTFLAG_TXC (0x1u << SERCOM_USART_INTFLAG_TXC_Pos) +#define SERCOM_USART_INTFLAG_RXC_Pos 2 /**< \brief (SERCOM_USART_INTFLAG) Receive Complete */ +#define SERCOM_USART_INTFLAG_RXC (0x1u << SERCOM_USART_INTFLAG_RXC_Pos) +#define SERCOM_USART_INTFLAG_RXS_Pos 3 /**< \brief (SERCOM_USART_INTFLAG) Receive Start Interrupt */ +#define SERCOM_USART_INTFLAG_RXS (0x1u << SERCOM_USART_INTFLAG_RXS_Pos) +#define SERCOM_USART_INTFLAG_MASK 0x0Fu /**< \brief (SERCOM_USART_INTFLAG) MASK Register */ + +/* -------- SERCOM_I2CM_STATUS : (SERCOM Offset: 0x10) (R/W 16) I2CM I2CM Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t BUSERR:1; /*!< bit: 0 Bus Error */ + uint16_t ARBLOST:1; /*!< bit: 1 Arbitration Lost */ + uint16_t RXNACK:1; /*!< bit: 2 Received Not Acknowledge */ + uint16_t :1; /*!< bit: 3 Reserved */ + uint16_t BUSSTATE:2; /*!< bit: 4.. 5 Bus State */ + uint16_t LOWTOUT:1; /*!< bit: 6 SCL Low Time-out */ + uint16_t CLKHOLD:1; /*!< bit: 7 Clock Hold */ + uint16_t :7; /*!< bit: 8..14 Reserved */ + uint16_t SYNCBUSY:1; /*!< bit: 15 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_STATUS_OFFSET 0x10 /**< \brief (SERCOM_I2CM_STATUS offset) I2CM Status */ +#define SERCOM_I2CM_STATUS_RESETVALUE 0x0000 /**< \brief (SERCOM_I2CM_STATUS reset_value) I2CM Status */ + +#define SERCOM_I2CM_STATUS_BUSERR_Pos 0 /**< \brief (SERCOM_I2CM_STATUS) Bus Error */ +#define SERCOM_I2CM_STATUS_BUSERR (0x1u << SERCOM_I2CM_STATUS_BUSERR_Pos) +#define SERCOM_I2CM_STATUS_ARBLOST_Pos 1 /**< \brief (SERCOM_I2CM_STATUS) Arbitration Lost */ +#define SERCOM_I2CM_STATUS_ARBLOST (0x1u << SERCOM_I2CM_STATUS_ARBLOST_Pos) +#define SERCOM_I2CM_STATUS_RXNACK_Pos 2 /**< \brief (SERCOM_I2CM_STATUS) Received Not Acknowledge */ +#define SERCOM_I2CM_STATUS_RXNACK (0x1u << SERCOM_I2CM_STATUS_RXNACK_Pos) +#define SERCOM_I2CM_STATUS_BUSSTATE_Pos 4 /**< \brief (SERCOM_I2CM_STATUS) Bus State */ +#define SERCOM_I2CM_STATUS_BUSSTATE_Msk (0x3u << SERCOM_I2CM_STATUS_BUSSTATE_Pos) +#define SERCOM_I2CM_STATUS_BUSSTATE(value) ((SERCOM_I2CM_STATUS_BUSSTATE_Msk & ((value) << SERCOM_I2CM_STATUS_BUSSTATE_Pos))) +#define SERCOM_I2CM_STATUS_LOWTOUT_Pos 6 /**< \brief (SERCOM_I2CM_STATUS) SCL Low Time-out */ +#define SERCOM_I2CM_STATUS_LOWTOUT (0x1u << SERCOM_I2CM_STATUS_LOWTOUT_Pos) +#define SERCOM_I2CM_STATUS_CLKHOLD_Pos 7 /**< \brief (SERCOM_I2CM_STATUS) Clock Hold */ +#define SERCOM_I2CM_STATUS_CLKHOLD (0x1u << SERCOM_I2CM_STATUS_CLKHOLD_Pos) +#define SERCOM_I2CM_STATUS_SYNCBUSY_Pos 15 /**< \brief (SERCOM_I2CM_STATUS) Synchronization Busy */ +#define SERCOM_I2CM_STATUS_SYNCBUSY (0x1u << SERCOM_I2CM_STATUS_SYNCBUSY_Pos) +#define SERCOM_I2CM_STATUS_MASK 0x80F7u /**< \brief (SERCOM_I2CM_STATUS) MASK Register */ + +/* -------- SERCOM_I2CS_STATUS : (SERCOM Offset: 0x10) (R/W 16) I2CS I2CS Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t BUSERR:1; /*!< bit: 0 Bus Error */ + uint16_t COLL:1; /*!< bit: 1 Transmit Collision */ + uint16_t RXNACK:1; /*!< bit: 2 Received Not Acknowledge */ + uint16_t DIR:1; /*!< bit: 3 Read / Write Direction */ + uint16_t SR:1; /*!< bit: 4 Repeated Start */ + uint16_t :1; /*!< bit: 5 Reserved */ + uint16_t LOWTOUT:1; /*!< bit: 6 SCL Low Time-out */ + uint16_t CLKHOLD:1; /*!< bit: 7 Clock Hold */ + uint16_t :7; /*!< bit: 8..14 Reserved */ + uint16_t SYNCBUSY:1; /*!< bit: 15 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_STATUS_OFFSET 0x10 /**< \brief (SERCOM_I2CS_STATUS offset) I2CS Status */ +#define SERCOM_I2CS_STATUS_RESETVALUE 0x0000 /**< \brief (SERCOM_I2CS_STATUS reset_value) I2CS Status */ + +#define SERCOM_I2CS_STATUS_BUSERR_Pos 0 /**< \brief (SERCOM_I2CS_STATUS) Bus Error */ +#define SERCOM_I2CS_STATUS_BUSERR (0x1u << SERCOM_I2CS_STATUS_BUSERR_Pos) +#define SERCOM_I2CS_STATUS_COLL_Pos 1 /**< \brief (SERCOM_I2CS_STATUS) Transmit Collision */ +#define SERCOM_I2CS_STATUS_COLL (0x1u << SERCOM_I2CS_STATUS_COLL_Pos) +#define SERCOM_I2CS_STATUS_RXNACK_Pos 2 /**< \brief (SERCOM_I2CS_STATUS) Received Not Acknowledge */ +#define SERCOM_I2CS_STATUS_RXNACK (0x1u << SERCOM_I2CS_STATUS_RXNACK_Pos) +#define SERCOM_I2CS_STATUS_DIR_Pos 3 /**< \brief (SERCOM_I2CS_STATUS) Read / Write Direction */ +#define SERCOM_I2CS_STATUS_DIR (0x1u << SERCOM_I2CS_STATUS_DIR_Pos) +#define SERCOM_I2CS_STATUS_SR_Pos 4 /**< \brief (SERCOM_I2CS_STATUS) Repeated Start */ +#define SERCOM_I2CS_STATUS_SR (0x1u << SERCOM_I2CS_STATUS_SR_Pos) +#define SERCOM_I2CS_STATUS_LOWTOUT_Pos 6 /**< \brief (SERCOM_I2CS_STATUS) SCL Low Time-out */ +#define SERCOM_I2CS_STATUS_LOWTOUT (0x1u << SERCOM_I2CS_STATUS_LOWTOUT_Pos) +#define SERCOM_I2CS_STATUS_CLKHOLD_Pos 7 /**< \brief (SERCOM_I2CS_STATUS) Clock Hold */ +#define SERCOM_I2CS_STATUS_CLKHOLD (0x1u << SERCOM_I2CS_STATUS_CLKHOLD_Pos) +#define SERCOM_I2CS_STATUS_SYNCBUSY_Pos 15 /**< \brief (SERCOM_I2CS_STATUS) Synchronization Busy */ +#define SERCOM_I2CS_STATUS_SYNCBUSY (0x1u << SERCOM_I2CS_STATUS_SYNCBUSY_Pos) +#define SERCOM_I2CS_STATUS_MASK 0x80DFu /**< \brief (SERCOM_I2CS_STATUS) MASK Register */ + +/* -------- SERCOM_SPI_STATUS : (SERCOM Offset: 0x10) (R/W 16) SPI SPI Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t :2; /*!< bit: 0.. 1 Reserved */ + uint16_t BUFOVF:1; /*!< bit: 2 Buffer Overflow */ + uint16_t :12; /*!< bit: 3..14 Reserved */ + uint16_t SYNCBUSY:1; /*!< bit: 15 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_SPI_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_STATUS_OFFSET 0x10 /**< \brief (SERCOM_SPI_STATUS offset) SPI Status */ +#define SERCOM_SPI_STATUS_RESETVALUE 0x0000 /**< \brief (SERCOM_SPI_STATUS reset_value) SPI Status */ + +#define SERCOM_SPI_STATUS_BUFOVF_Pos 2 /**< \brief (SERCOM_SPI_STATUS) Buffer Overflow */ +#define SERCOM_SPI_STATUS_BUFOVF (0x1u << SERCOM_SPI_STATUS_BUFOVF_Pos) +#define SERCOM_SPI_STATUS_SYNCBUSY_Pos 15 /**< \brief (SERCOM_SPI_STATUS) Synchronization Busy */ +#define SERCOM_SPI_STATUS_SYNCBUSY (0x1u << SERCOM_SPI_STATUS_SYNCBUSY_Pos) +#define SERCOM_SPI_STATUS_MASK 0x8004u /**< \brief (SERCOM_SPI_STATUS) MASK Register */ + +/* -------- SERCOM_USART_STATUS : (SERCOM Offset: 0x10) (R/W 16) USART USART Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t PERR:1; /*!< bit: 0 Parity Error */ + uint16_t FERR:1; /*!< bit: 1 Frame Error */ + uint16_t BUFOVF:1; /*!< bit: 2 Buffer Overflow */ + uint16_t :12; /*!< bit: 3..14 Reserved */ + uint16_t SYNCBUSY:1; /*!< bit: 15 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_USART_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_STATUS_OFFSET 0x10 /**< \brief (SERCOM_USART_STATUS offset) USART Status */ +#define SERCOM_USART_STATUS_RESETVALUE 0x0000 /**< \brief (SERCOM_USART_STATUS reset_value) USART Status */ + +#define SERCOM_USART_STATUS_PERR_Pos 0 /**< \brief (SERCOM_USART_STATUS) Parity Error */ +#define SERCOM_USART_STATUS_PERR (0x1u << SERCOM_USART_STATUS_PERR_Pos) +#define SERCOM_USART_STATUS_FERR_Pos 1 /**< \brief (SERCOM_USART_STATUS) Frame Error */ +#define SERCOM_USART_STATUS_FERR (0x1u << SERCOM_USART_STATUS_FERR_Pos) +#define SERCOM_USART_STATUS_BUFOVF_Pos 2 /**< \brief (SERCOM_USART_STATUS) Buffer Overflow */ +#define SERCOM_USART_STATUS_BUFOVF (0x1u << SERCOM_USART_STATUS_BUFOVF_Pos) +#define SERCOM_USART_STATUS_SYNCBUSY_Pos 15 /**< \brief (SERCOM_USART_STATUS) Synchronization Busy */ +#define SERCOM_USART_STATUS_SYNCBUSY (0x1u << SERCOM_USART_STATUS_SYNCBUSY_Pos) +#define SERCOM_USART_STATUS_MASK 0x8007u /**< \brief (SERCOM_USART_STATUS) MASK Register */ + +/* -------- SERCOM_I2CM_ADDR : (SERCOM Offset: 0x14) (R/W 8) I2CM I2CM Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t ADDR:8; /*!< bit: 0.. 7 Address */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_ADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_ADDR_OFFSET 0x14 /**< \brief (SERCOM_I2CM_ADDR offset) I2CM Address */ +#define SERCOM_I2CM_ADDR_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_ADDR reset_value) I2CM Address */ + +#define SERCOM_I2CM_ADDR_ADDR_Pos 0 /**< \brief (SERCOM_I2CM_ADDR) Address */ +#define SERCOM_I2CM_ADDR_ADDR_Msk (0xFFu << SERCOM_I2CM_ADDR_ADDR_Pos) +#define SERCOM_I2CM_ADDR_ADDR(value) ((SERCOM_I2CM_ADDR_ADDR_Msk & ((value) << SERCOM_I2CM_ADDR_ADDR_Pos))) +#define SERCOM_I2CM_ADDR_MASK 0xFFu /**< \brief (SERCOM_I2CM_ADDR) MASK Register */ + +/* -------- SERCOM_I2CS_ADDR : (SERCOM Offset: 0x14) (R/W 32) I2CS I2CS Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t GENCEN:1; /*!< bit: 0 General Call Address Enable */ + uint32_t ADDR:7; /*!< bit: 1.. 7 Address */ + uint32_t :9; /*!< bit: 8..16 Reserved */ + uint32_t ADDRMASK:7; /*!< bit: 17..23 Address Mask */ + uint32_t :8; /*!< bit: 24..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_ADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_ADDR_OFFSET 0x14 /**< \brief (SERCOM_I2CS_ADDR offset) I2CS Address */ +#define SERCOM_I2CS_ADDR_RESETVALUE 0x00000000 /**< \brief (SERCOM_I2CS_ADDR reset_value) I2CS Address */ + +#define SERCOM_I2CS_ADDR_GENCEN_Pos 0 /**< \brief (SERCOM_I2CS_ADDR) General Call Address Enable */ +#define SERCOM_I2CS_ADDR_GENCEN (0x1u << SERCOM_I2CS_ADDR_GENCEN_Pos) +#define SERCOM_I2CS_ADDR_ADDR_Pos 1 /**< \brief (SERCOM_I2CS_ADDR) Address */ +#define SERCOM_I2CS_ADDR_ADDR_Msk (0x7Fu << SERCOM_I2CS_ADDR_ADDR_Pos) +#define SERCOM_I2CS_ADDR_ADDR(value) ((SERCOM_I2CS_ADDR_ADDR_Msk & ((value) << SERCOM_I2CS_ADDR_ADDR_Pos))) +#define SERCOM_I2CS_ADDR_ADDRMASK_Pos 17 /**< \brief (SERCOM_I2CS_ADDR) Address Mask */ +#define SERCOM_I2CS_ADDR_ADDRMASK_Msk (0x7Fu << SERCOM_I2CS_ADDR_ADDRMASK_Pos) +#define SERCOM_I2CS_ADDR_ADDRMASK(value) ((SERCOM_I2CS_ADDR_ADDRMASK_Msk & ((value) << SERCOM_I2CS_ADDR_ADDRMASK_Pos))) +#define SERCOM_I2CS_ADDR_MASK 0x00FE00FFu /**< \brief (SERCOM_I2CS_ADDR) MASK Register */ + +/* -------- SERCOM_SPI_ADDR : (SERCOM Offset: 0x14) (R/W 32) SPI SPI Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ADDR:8; /*!< bit: 0.. 7 Address */ + uint32_t :8; /*!< bit: 8..15 Reserved */ + uint32_t ADDRMASK:8; /*!< bit: 16..23 Address Mask */ + uint32_t :8; /*!< bit: 24..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SERCOM_SPI_ADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_ADDR_OFFSET 0x14 /**< \brief (SERCOM_SPI_ADDR offset) SPI Address */ +#define SERCOM_SPI_ADDR_RESETVALUE 0x00000000 /**< \brief (SERCOM_SPI_ADDR reset_value) SPI Address */ + +#define SERCOM_SPI_ADDR_ADDR_Pos 0 /**< \brief (SERCOM_SPI_ADDR) Address */ +#define SERCOM_SPI_ADDR_ADDR_Msk (0xFFu << SERCOM_SPI_ADDR_ADDR_Pos) +#define SERCOM_SPI_ADDR_ADDR(value) ((SERCOM_SPI_ADDR_ADDR_Msk & ((value) << SERCOM_SPI_ADDR_ADDR_Pos))) +#define SERCOM_SPI_ADDR_ADDRMASK_Pos 16 /**< \brief (SERCOM_SPI_ADDR) Address Mask */ +#define SERCOM_SPI_ADDR_ADDRMASK_Msk (0xFFu << SERCOM_SPI_ADDR_ADDRMASK_Pos) +#define SERCOM_SPI_ADDR_ADDRMASK(value) ((SERCOM_SPI_ADDR_ADDRMASK_Msk & ((value) << SERCOM_SPI_ADDR_ADDRMASK_Pos))) +#define SERCOM_SPI_ADDR_MASK 0x00FF00FFu /**< \brief (SERCOM_SPI_ADDR) MASK Register */ + +/* -------- SERCOM_I2CM_DATA : (SERCOM Offset: 0x18) (R/W 8) I2CM I2CM Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DATA:8; /*!< bit: 0.. 7 Data */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CM_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CM_DATA_OFFSET 0x18 /**< \brief (SERCOM_I2CM_DATA offset) I2CM Data */ +#define SERCOM_I2CM_DATA_RESETVALUE 0x00 /**< \brief (SERCOM_I2CM_DATA reset_value) I2CM Data */ + +#define SERCOM_I2CM_DATA_DATA_Pos 0 /**< \brief (SERCOM_I2CM_DATA) Data */ +#define SERCOM_I2CM_DATA_DATA_Msk (0xFFu << SERCOM_I2CM_DATA_DATA_Pos) +#define SERCOM_I2CM_DATA_DATA(value) ((SERCOM_I2CM_DATA_DATA_Msk & ((value) << SERCOM_I2CM_DATA_DATA_Pos))) +#define SERCOM_I2CM_DATA_MASK 0xFFu /**< \brief (SERCOM_I2CM_DATA) MASK Register */ + +/* -------- SERCOM_I2CS_DATA : (SERCOM Offset: 0x18) (R/W 8) I2CS I2CS Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DATA:8; /*!< bit: 0.. 7 Data */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SERCOM_I2CS_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_I2CS_DATA_OFFSET 0x18 /**< \brief (SERCOM_I2CS_DATA offset) I2CS Data */ +#define SERCOM_I2CS_DATA_RESETVALUE 0x00 /**< \brief (SERCOM_I2CS_DATA reset_value) I2CS Data */ + +#define SERCOM_I2CS_DATA_DATA_Pos 0 /**< \brief (SERCOM_I2CS_DATA) Data */ +#define SERCOM_I2CS_DATA_DATA_Msk (0xFFu << SERCOM_I2CS_DATA_DATA_Pos) +#define SERCOM_I2CS_DATA_DATA(value) ((SERCOM_I2CS_DATA_DATA_Msk & ((value) << SERCOM_I2CS_DATA_DATA_Pos))) +#define SERCOM_I2CS_DATA_MASK 0xFFu /**< \brief (SERCOM_I2CS_DATA) MASK Register */ + +/* -------- SERCOM_SPI_DATA : (SERCOM Offset: 0x18) (R/W 16) SPI SPI Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATA:9; /*!< bit: 0.. 8 Data */ + uint16_t :7; /*!< bit: 9..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_SPI_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_SPI_DATA_OFFSET 0x18 /**< \brief (SERCOM_SPI_DATA offset) SPI Data */ +#define SERCOM_SPI_DATA_RESETVALUE 0x0000 /**< \brief (SERCOM_SPI_DATA reset_value) SPI Data */ + +#define SERCOM_SPI_DATA_DATA_Pos 0 /**< \brief (SERCOM_SPI_DATA) Data */ +#define SERCOM_SPI_DATA_DATA_Msk (0x1FFu << SERCOM_SPI_DATA_DATA_Pos) +#define SERCOM_SPI_DATA_DATA(value) ((SERCOM_SPI_DATA_DATA_Msk & ((value) << SERCOM_SPI_DATA_DATA_Pos))) +#define SERCOM_SPI_DATA_MASK 0x01FFu /**< \brief (SERCOM_SPI_DATA) MASK Register */ + +/* -------- SERCOM_USART_DATA : (SERCOM Offset: 0x18) (R/W 16) USART USART Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATA:9; /*!< bit: 0.. 8 Data */ + uint16_t :7; /*!< bit: 9..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_USART_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SERCOM_USART_DATA_OFFSET 0x18 /**< \brief (SERCOM_USART_DATA offset) USART Data */ +#define SERCOM_USART_DATA_RESETVALUE 0x0000 /**< \brief (SERCOM_USART_DATA reset_value) USART Data */ + +#define SERCOM_USART_DATA_DATA_Pos 0 /**< \brief (SERCOM_USART_DATA) Data */ +#define SERCOM_USART_DATA_DATA_Msk (0x1FFu << SERCOM_USART_DATA_DATA_Pos) +#define SERCOM_USART_DATA_DATA(value) ((SERCOM_USART_DATA_DATA_Msk & ((value) << SERCOM_USART_DATA_DATA_Pos))) +#define SERCOM_USART_DATA_MASK 0x01FFu /**< \brief (SERCOM_USART_DATA) MASK Register */ + +/** \brief SERCOM_I2CM hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* I2C Master Mode */ + __IO SERCOM_I2CM_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) I2CM Control A */ + __IO SERCOM_I2CM_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) I2CM Control B */ + __IO SERCOM_I2CM_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) I2CM Debug Control */ + RoReg8 Reserved1[0x1]; + __IO SERCOM_I2CM_BAUD_Type BAUD; /**< \brief Offset: 0x0A (R/W 16) I2CM Baud Rate */ + __IO SERCOM_I2CM_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) I2CM Interrupt Enable Clear */ + __IO SERCOM_I2CM_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) I2CM Interrupt Enable Set */ + __IO SERCOM_I2CM_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) I2CM Interrupt Flag Status and Clear */ + RoReg8 Reserved2[0x1]; + __IO SERCOM_I2CM_STATUS_Type STATUS; /**< \brief Offset: 0x10 (R/W 16) I2CM Status */ + RoReg8 Reserved3[0x2]; + __IO SERCOM_I2CM_ADDR_Type ADDR; /**< \brief Offset: 0x14 (R/W 8) I2CM Address */ + RoReg8 Reserved4[0x3]; + __IO SERCOM_I2CM_DATA_Type DATA; /**< \brief Offset: 0x18 (R/W 8) I2CM Data */ +} SercomI2cm; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief SERCOM_I2CS hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* I2C Slave Mode */ + __IO SERCOM_I2CS_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) I2CS Control A */ + __IO SERCOM_I2CS_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) I2CS Control B */ + RoReg8 Reserved1[0x4]; + __IO SERCOM_I2CS_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) I2CS Interrupt Enable Clear */ + __IO SERCOM_I2CS_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) I2CS Interrupt Enable Set */ + __IO SERCOM_I2CS_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) I2CS Interrupt Flag Status and Clear */ + RoReg8 Reserved2[0x1]; + __IO SERCOM_I2CS_STATUS_Type STATUS; /**< \brief Offset: 0x10 (R/W 16) I2CS Status */ + RoReg8 Reserved3[0x2]; + __IO SERCOM_I2CS_ADDR_Type ADDR; /**< \brief Offset: 0x14 (R/W 32) I2CS Address */ + __IO SERCOM_I2CS_DATA_Type DATA; /**< \brief Offset: 0x18 (R/W 8) I2CS Data */ +} SercomI2cs; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief SERCOM_SPI hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* SPI Mode */ + __IO SERCOM_SPI_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) SPI Control A */ + __IO SERCOM_SPI_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) SPI Control B */ + __IO SERCOM_SPI_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) SPI Debug Control */ + RoReg8 Reserved1[0x1]; + __IO SERCOM_SPI_BAUD_Type BAUD; /**< \brief Offset: 0x0A (R/W 8) SPI Baud Rate */ + RoReg8 Reserved2[0x1]; + __IO SERCOM_SPI_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) SPI Interrupt Enable Clear */ + __IO SERCOM_SPI_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) SPI Interrupt Enable Set */ + __IO SERCOM_SPI_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) SPI Interrupt Flag Status and Clear */ + RoReg8 Reserved3[0x1]; + __IO SERCOM_SPI_STATUS_Type STATUS; /**< \brief Offset: 0x10 (R/W 16) SPI Status */ + RoReg8 Reserved4[0x2]; + __IO SERCOM_SPI_ADDR_Type ADDR; /**< \brief Offset: 0x14 (R/W 32) SPI Address */ + __IO SERCOM_SPI_DATA_Type DATA; /**< \brief Offset: 0x18 (R/W 16) SPI Data */ +} SercomSpi; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief SERCOM_USART hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* USART Mode */ + __IO SERCOM_USART_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) USART Control A */ + __IO SERCOM_USART_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) USART Control B */ + __IO SERCOM_USART_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) USART Debug Control */ + RoReg8 Reserved1[0x1]; + __IO SERCOM_USART_BAUD_Type BAUD; /**< \brief Offset: 0x0A (R/W 16) USART Baud */ + __IO SERCOM_USART_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) USART Interrupt Enable Clear */ + __IO SERCOM_USART_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) USART Interrupt Enable Set */ + __IO SERCOM_USART_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) USART Interrupt Flag Status and Clear */ + RoReg8 Reserved2[0x1]; + __IO SERCOM_USART_STATUS_Type STATUS; /**< \brief Offset: 0x10 (R/W 16) USART Status */ + RoReg8 Reserved3[0x6]; + __IO SERCOM_USART_DATA_Type DATA; /**< \brief Offset: 0x18 (R/W 16) USART Data */ +} SercomUsart; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + SercomI2cm I2CM; /**< \brief Offset: 0x00 I2C Master Mode */ + SercomI2cs I2CS; /**< \brief Offset: 0x00 I2C Slave Mode */ + SercomSpi SPI; /**< \brief Offset: 0x00 SPI Mode */ + SercomUsart USART; /**< \brief Offset: 0x00 USART Mode */ +} Sercom; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_SERCOM_COMPONENT_ */ diff --git a/loader/samd20/component/sysctrl.h b/loader/samd20/component/sysctrl.h new file mode 100644 index 0000000..a6b4248 --- /dev/null +++ b/loader/samd20/component/sysctrl.h @@ -0,0 +1,688 @@ +/** + * \file + * + * \brief Component description for SYSCTRL + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_SYSCTRL_COMPONENT_ +#define _SAMD20_SYSCTRL_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR SYSCTRL */ +/* ========================================================================== */ +/** \addtogroup SAMD20_SYSCTRL System Control */ +/*@{*/ + +#define SYSCTRL_U2100 +#define REV_SYSCTRL 0x201 + +/* -------- SYSCTRL_INTENCLR : (SYSCTRL Offset: 0x00) (R/W 32) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t XOSCRDY:1; /*!< bit: 0 XOSC Ready */ + uint32_t XOSC32KRDY:1; /*!< bit: 1 XOSC32K Ready */ + uint32_t OSC32KRDY:1; /*!< bit: 2 OSC32K Ready */ + uint32_t OSC8MRDY:1; /*!< bit: 3 OSC8M Ready */ + uint32_t DFLLRDY:1; /*!< bit: 4 DFLL Ready */ + uint32_t DFLLOOB:1; /*!< bit: 5 DFLL Out Of Bounds */ + uint32_t DFLLLCKF:1; /*!< bit: 6 DFLL Lock Fine */ + uint32_t DFLLLCKC:1; /*!< bit: 7 DFLL Lock Coarse */ + uint32_t DFLLRCS:1; /*!< bit: 8 DFLL Reference Clock Stopped */ + uint32_t BOD33RDY:1; /*!< bit: 9 BOD33 Ready */ + uint32_t BOD33DET:1; /*!< bit: 10 BOD33 Detection */ + uint32_t B33SRDY:1; /*!< bit: 11 BOD33 Synchronization Ready */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_INTENCLR_OFFSET 0x00 /**< \brief (SYSCTRL_INTENCLR offset) Interrupt Enable Clear */ +#define SYSCTRL_INTENCLR_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_INTENCLR reset_value) Interrupt Enable Clear */ + +#define SYSCTRL_INTENCLR_XOSCRDY_Pos 0 /**< \brief (SYSCTRL_INTENCLR) XOSC Ready */ +#define SYSCTRL_INTENCLR_XOSCRDY (0x1u << SYSCTRL_INTENCLR_XOSCRDY_Pos) +#define SYSCTRL_INTENCLR_XOSC32KRDY_Pos 1 /**< \brief (SYSCTRL_INTENCLR) XOSC32K Ready */ +#define SYSCTRL_INTENCLR_XOSC32KRDY (0x1u << SYSCTRL_INTENCLR_XOSC32KRDY_Pos) +#define SYSCTRL_INTENCLR_OSC32KRDY_Pos 2 /**< \brief (SYSCTRL_INTENCLR) OSC32K Ready */ +#define SYSCTRL_INTENCLR_OSC32KRDY (0x1u << SYSCTRL_INTENCLR_OSC32KRDY_Pos) +#define SYSCTRL_INTENCLR_OSC8MRDY_Pos 3 /**< \brief (SYSCTRL_INTENCLR) OSC8M Ready */ +#define SYSCTRL_INTENCLR_OSC8MRDY (0x1u << SYSCTRL_INTENCLR_OSC8MRDY_Pos) +#define SYSCTRL_INTENCLR_DFLLRDY_Pos 4 /**< \brief (SYSCTRL_INTENCLR) DFLL Ready */ +#define SYSCTRL_INTENCLR_DFLLRDY (0x1u << SYSCTRL_INTENCLR_DFLLRDY_Pos) +#define SYSCTRL_INTENCLR_DFLLOOB_Pos 5 /**< \brief (SYSCTRL_INTENCLR) DFLL Out Of Bounds */ +#define SYSCTRL_INTENCLR_DFLLOOB (0x1u << SYSCTRL_INTENCLR_DFLLOOB_Pos) +#define SYSCTRL_INTENCLR_DFLLLCKF_Pos 6 /**< \brief (SYSCTRL_INTENCLR) DFLL Lock Fine */ +#define SYSCTRL_INTENCLR_DFLLLCKF (0x1u << SYSCTRL_INTENCLR_DFLLLCKF_Pos) +#define SYSCTRL_INTENCLR_DFLLLCKC_Pos 7 /**< \brief (SYSCTRL_INTENCLR) DFLL Lock Coarse */ +#define SYSCTRL_INTENCLR_DFLLLCKC (0x1u << SYSCTRL_INTENCLR_DFLLLCKC_Pos) +#define SYSCTRL_INTENCLR_DFLLRCS_Pos 8 /**< \brief (SYSCTRL_INTENCLR) DFLL Reference Clock Stopped */ +#define SYSCTRL_INTENCLR_DFLLRCS (0x1u << SYSCTRL_INTENCLR_DFLLRCS_Pos) +#define SYSCTRL_INTENCLR_BOD33RDY_Pos 9 /**< \brief (SYSCTRL_INTENCLR) BOD33 Ready */ +#define SYSCTRL_INTENCLR_BOD33RDY (0x1u << SYSCTRL_INTENCLR_BOD33RDY_Pos) +#define SYSCTRL_INTENCLR_BOD33DET_Pos 10 /**< \brief (SYSCTRL_INTENCLR) BOD33 Detection */ +#define SYSCTRL_INTENCLR_BOD33DET (0x1u << SYSCTRL_INTENCLR_BOD33DET_Pos) +#define SYSCTRL_INTENCLR_B33SRDY_Pos 11 /**< \brief (SYSCTRL_INTENCLR) BOD33 Synchronization Ready */ +#define SYSCTRL_INTENCLR_B33SRDY (0x1u << SYSCTRL_INTENCLR_B33SRDY_Pos) +#define SYSCTRL_INTENCLR_MASK 0x00000FFFu /**< \brief (SYSCTRL_INTENCLR) MASK Register */ + +/* -------- SYSCTRL_INTENSET : (SYSCTRL Offset: 0x04) (R/W 32) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t XOSCRDY:1; /*!< bit: 0 XOSC Ready */ + uint32_t XOSC32KRDY:1; /*!< bit: 1 XOSC32K Ready */ + uint32_t OSC32KRDY:1; /*!< bit: 2 OSC32K Ready */ + uint32_t OSC8MRDY:1; /*!< bit: 3 OSC8M Ready */ + uint32_t DFLLRDY:1; /*!< bit: 4 DFLL Ready */ + uint32_t DFLLOOB:1; /*!< bit: 5 DFLL Out Of Bounds */ + uint32_t DFLLLCKF:1; /*!< bit: 6 DFLL Lock Fine */ + uint32_t DFLLLCKC:1; /*!< bit: 7 DFLL Lock Coarse */ + uint32_t DFLLRCS:1; /*!< bit: 8 DFLL Reference Clock Stopped */ + uint32_t BOD33RDY:1; /*!< bit: 9 BOD33 Ready */ + uint32_t BOD33DET:1; /*!< bit: 10 BOD33 Detection */ + uint32_t B33SRDY:1; /*!< bit: 11 BOD33 Synchronization Ready */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_INTENSET_OFFSET 0x04 /**< \brief (SYSCTRL_INTENSET offset) Interrupt Enable Set */ +#define SYSCTRL_INTENSET_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_INTENSET reset_value) Interrupt Enable Set */ + +#define SYSCTRL_INTENSET_XOSCRDY_Pos 0 /**< \brief (SYSCTRL_INTENSET) XOSC Ready */ +#define SYSCTRL_INTENSET_XOSCRDY (0x1u << SYSCTRL_INTENSET_XOSCRDY_Pos) +#define SYSCTRL_INTENSET_XOSC32KRDY_Pos 1 /**< \brief (SYSCTRL_INTENSET) XOSC32K Ready */ +#define SYSCTRL_INTENSET_XOSC32KRDY (0x1u << SYSCTRL_INTENSET_XOSC32KRDY_Pos) +#define SYSCTRL_INTENSET_OSC32KRDY_Pos 2 /**< \brief (SYSCTRL_INTENSET) OSC32K Ready */ +#define SYSCTRL_INTENSET_OSC32KRDY (0x1u << SYSCTRL_INTENSET_OSC32KRDY_Pos) +#define SYSCTRL_INTENSET_OSC8MRDY_Pos 3 /**< \brief (SYSCTRL_INTENSET) OSC8M Ready */ +#define SYSCTRL_INTENSET_OSC8MRDY (0x1u << SYSCTRL_INTENSET_OSC8MRDY_Pos) +#define SYSCTRL_INTENSET_DFLLRDY_Pos 4 /**< \brief (SYSCTRL_INTENSET) DFLL Ready */ +#define SYSCTRL_INTENSET_DFLLRDY (0x1u << SYSCTRL_INTENSET_DFLLRDY_Pos) +#define SYSCTRL_INTENSET_DFLLOOB_Pos 5 /**< \brief (SYSCTRL_INTENSET) DFLL Out Of Bounds */ +#define SYSCTRL_INTENSET_DFLLOOB (0x1u << SYSCTRL_INTENSET_DFLLOOB_Pos) +#define SYSCTRL_INTENSET_DFLLLCKF_Pos 6 /**< \brief (SYSCTRL_INTENSET) DFLL Lock Fine */ +#define SYSCTRL_INTENSET_DFLLLCKF (0x1u << SYSCTRL_INTENSET_DFLLLCKF_Pos) +#define SYSCTRL_INTENSET_DFLLLCKC_Pos 7 /**< \brief (SYSCTRL_INTENSET) DFLL Lock Coarse */ +#define SYSCTRL_INTENSET_DFLLLCKC (0x1u << SYSCTRL_INTENSET_DFLLLCKC_Pos) +#define SYSCTRL_INTENSET_DFLLRCS_Pos 8 /**< \brief (SYSCTRL_INTENSET) DFLL Reference Clock Stopped */ +#define SYSCTRL_INTENSET_DFLLRCS (0x1u << SYSCTRL_INTENSET_DFLLRCS_Pos) +#define SYSCTRL_INTENSET_BOD33RDY_Pos 9 /**< \brief (SYSCTRL_INTENSET) BOD33 Ready */ +#define SYSCTRL_INTENSET_BOD33RDY (0x1u << SYSCTRL_INTENSET_BOD33RDY_Pos) +#define SYSCTRL_INTENSET_BOD33DET_Pos 10 /**< \brief (SYSCTRL_INTENSET) BOD33 Detection */ +#define SYSCTRL_INTENSET_BOD33DET (0x1u << SYSCTRL_INTENSET_BOD33DET_Pos) +#define SYSCTRL_INTENSET_B33SRDY_Pos 11 /**< \brief (SYSCTRL_INTENSET) BOD33 Synchronization Ready */ +#define SYSCTRL_INTENSET_B33SRDY (0x1u << SYSCTRL_INTENSET_B33SRDY_Pos) +#define SYSCTRL_INTENSET_MASK 0x00000FFFu /**< \brief (SYSCTRL_INTENSET) MASK Register */ + +/* -------- SYSCTRL_INTFLAG : (SYSCTRL Offset: 0x08) (R/W 32) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t XOSCRDY:1; /*!< bit: 0 XOSC Ready */ + uint32_t XOSC32KRDY:1; /*!< bit: 1 XOSC32K Ready */ + uint32_t OSC32KRDY:1; /*!< bit: 2 OSC32K Ready */ + uint32_t OSC8MRDY:1; /*!< bit: 3 OSC8M Ready */ + uint32_t DFLLRDY:1; /*!< bit: 4 DFLL Ready */ + uint32_t DFLLOOB:1; /*!< bit: 5 DFLL Out Of Bounds */ + uint32_t DFLLLCKF:1; /*!< bit: 6 DFLL Lock Fine */ + uint32_t DFLLLCKC:1; /*!< bit: 7 DFLL Lock Coarse */ + uint32_t DFLLRCS:1; /*!< bit: 8 DFLL Reference Clock Stopped */ + uint32_t BOD33RDY:1; /*!< bit: 9 BOD33 Ready */ + uint32_t BOD33DET:1; /*!< bit: 10 BOD33 Detection */ + uint32_t B33SRDY:1; /*!< bit: 11 BOD33 Synchronization Ready */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_INTFLAG_OFFSET 0x08 /**< \brief (SYSCTRL_INTFLAG offset) Interrupt Flag Status and Clear */ +#define SYSCTRL_INTFLAG_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define SYSCTRL_INTFLAG_XOSCRDY_Pos 0 /**< \brief (SYSCTRL_INTFLAG) XOSC Ready */ +#define SYSCTRL_INTFLAG_XOSCRDY (0x1u << SYSCTRL_INTFLAG_XOSCRDY_Pos) +#define SYSCTRL_INTFLAG_XOSC32KRDY_Pos 1 /**< \brief (SYSCTRL_INTFLAG) XOSC32K Ready */ +#define SYSCTRL_INTFLAG_XOSC32KRDY (0x1u << SYSCTRL_INTFLAG_XOSC32KRDY_Pos) +#define SYSCTRL_INTFLAG_OSC32KRDY_Pos 2 /**< \brief (SYSCTRL_INTFLAG) OSC32K Ready */ +#define SYSCTRL_INTFLAG_OSC32KRDY (0x1u << SYSCTRL_INTFLAG_OSC32KRDY_Pos) +#define SYSCTRL_INTFLAG_OSC8MRDY_Pos 3 /**< \brief (SYSCTRL_INTFLAG) OSC8M Ready */ +#define SYSCTRL_INTFLAG_OSC8MRDY (0x1u << SYSCTRL_INTFLAG_OSC8MRDY_Pos) +#define SYSCTRL_INTFLAG_DFLLRDY_Pos 4 /**< \brief (SYSCTRL_INTFLAG) DFLL Ready */ +#define SYSCTRL_INTFLAG_DFLLRDY (0x1u << SYSCTRL_INTFLAG_DFLLRDY_Pos) +#define SYSCTRL_INTFLAG_DFLLOOB_Pos 5 /**< \brief (SYSCTRL_INTFLAG) DFLL Out Of Bounds */ +#define SYSCTRL_INTFLAG_DFLLOOB (0x1u << SYSCTRL_INTFLAG_DFLLOOB_Pos) +#define SYSCTRL_INTFLAG_DFLLLCKF_Pos 6 /**< \brief (SYSCTRL_INTFLAG) DFLL Lock Fine */ +#define SYSCTRL_INTFLAG_DFLLLCKF (0x1u << SYSCTRL_INTFLAG_DFLLLCKF_Pos) +#define SYSCTRL_INTFLAG_DFLLLCKC_Pos 7 /**< \brief (SYSCTRL_INTFLAG) DFLL Lock Coarse */ +#define SYSCTRL_INTFLAG_DFLLLCKC (0x1u << SYSCTRL_INTFLAG_DFLLLCKC_Pos) +#define SYSCTRL_INTFLAG_DFLLRCS_Pos 8 /**< \brief (SYSCTRL_INTFLAG) DFLL Reference Clock Stopped */ +#define SYSCTRL_INTFLAG_DFLLRCS (0x1u << SYSCTRL_INTFLAG_DFLLRCS_Pos) +#define SYSCTRL_INTFLAG_BOD33RDY_Pos 9 /**< \brief (SYSCTRL_INTFLAG) BOD33 Ready */ +#define SYSCTRL_INTFLAG_BOD33RDY (0x1u << SYSCTRL_INTFLAG_BOD33RDY_Pos) +#define SYSCTRL_INTFLAG_BOD33DET_Pos 10 /**< \brief (SYSCTRL_INTFLAG) BOD33 Detection */ +#define SYSCTRL_INTFLAG_BOD33DET (0x1u << SYSCTRL_INTFLAG_BOD33DET_Pos) +#define SYSCTRL_INTFLAG_B33SRDY_Pos 11 /**< \brief (SYSCTRL_INTFLAG) BOD33 Synchronization Ready */ +#define SYSCTRL_INTFLAG_B33SRDY (0x1u << SYSCTRL_INTFLAG_B33SRDY_Pos) +#define SYSCTRL_INTFLAG_MASK 0x00000FFFu /**< \brief (SYSCTRL_INTFLAG) MASK Register */ + +/* -------- SYSCTRL_PCLKSR : (SYSCTRL Offset: 0x0C) (R/ 32) Power and Clocks Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t XOSCRDY:1; /*!< bit: 0 XOSC Ready */ + uint32_t XOSC32KRDY:1; /*!< bit: 1 XOSC32K Ready */ + uint32_t OSC32KRDY:1; /*!< bit: 2 OSC32K Ready */ + uint32_t OSC8MRDY:1; /*!< bit: 3 OSC8M Ready */ + uint32_t DFLLRDY:1; /*!< bit: 4 DFLL Ready */ + uint32_t DFLLOOB:1; /*!< bit: 5 DFLL Out Of Bounds */ + uint32_t DFLLLCKF:1; /*!< bit: 6 DFLL Lock Fine */ + uint32_t DFLLLCKC:1; /*!< bit: 7 DFLL Lock Coarse */ + uint32_t DFLLRCS:1; /*!< bit: 8 DFLL Reference Clock Stopped */ + uint32_t BOD33RDY:1; /*!< bit: 9 BOD33 Ready */ + uint32_t BOD33DET:1; /*!< bit: 10 BOD33 Detection */ + uint32_t B33SRDY:1; /*!< bit: 11 BOD33 Synchronization Ready */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_PCLKSR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_PCLKSR_OFFSET 0x0C /**< \brief (SYSCTRL_PCLKSR offset) Power and Clocks Status */ +#define SYSCTRL_PCLKSR_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_PCLKSR reset_value) Power and Clocks Status */ + +#define SYSCTRL_PCLKSR_XOSCRDY_Pos 0 /**< \brief (SYSCTRL_PCLKSR) XOSC Ready */ +#define SYSCTRL_PCLKSR_XOSCRDY (0x1u << SYSCTRL_PCLKSR_XOSCRDY_Pos) +#define SYSCTRL_PCLKSR_XOSC32KRDY_Pos 1 /**< \brief (SYSCTRL_PCLKSR) XOSC32K Ready */ +#define SYSCTRL_PCLKSR_XOSC32KRDY (0x1u << SYSCTRL_PCLKSR_XOSC32KRDY_Pos) +#define SYSCTRL_PCLKSR_OSC32KRDY_Pos 2 /**< \brief (SYSCTRL_PCLKSR) OSC32K Ready */ +#define SYSCTRL_PCLKSR_OSC32KRDY (0x1u << SYSCTRL_PCLKSR_OSC32KRDY_Pos) +#define SYSCTRL_PCLKSR_OSC8MRDY_Pos 3 /**< \brief (SYSCTRL_PCLKSR) OSC8M Ready */ +#define SYSCTRL_PCLKSR_OSC8MRDY (0x1u << SYSCTRL_PCLKSR_OSC8MRDY_Pos) +#define SYSCTRL_PCLKSR_DFLLRDY_Pos 4 /**< \brief (SYSCTRL_PCLKSR) DFLL Ready */ +#define SYSCTRL_PCLKSR_DFLLRDY (0x1u << SYSCTRL_PCLKSR_DFLLRDY_Pos) +#define SYSCTRL_PCLKSR_DFLLOOB_Pos 5 /**< \brief (SYSCTRL_PCLKSR) DFLL Out Of Bounds */ +#define SYSCTRL_PCLKSR_DFLLOOB (0x1u << SYSCTRL_PCLKSR_DFLLOOB_Pos) +#define SYSCTRL_PCLKSR_DFLLLCKF_Pos 6 /**< \brief (SYSCTRL_PCLKSR) DFLL Lock Fine */ +#define SYSCTRL_PCLKSR_DFLLLCKF (0x1u << SYSCTRL_PCLKSR_DFLLLCKF_Pos) +#define SYSCTRL_PCLKSR_DFLLLCKC_Pos 7 /**< \brief (SYSCTRL_PCLKSR) DFLL Lock Coarse */ +#define SYSCTRL_PCLKSR_DFLLLCKC (0x1u << SYSCTRL_PCLKSR_DFLLLCKC_Pos) +#define SYSCTRL_PCLKSR_DFLLRCS_Pos 8 /**< \brief (SYSCTRL_PCLKSR) DFLL Reference Clock Stopped */ +#define SYSCTRL_PCLKSR_DFLLRCS (0x1u << SYSCTRL_PCLKSR_DFLLRCS_Pos) +#define SYSCTRL_PCLKSR_BOD33RDY_Pos 9 /**< \brief (SYSCTRL_PCLKSR) BOD33 Ready */ +#define SYSCTRL_PCLKSR_BOD33RDY (0x1u << SYSCTRL_PCLKSR_BOD33RDY_Pos) +#define SYSCTRL_PCLKSR_BOD33DET_Pos 10 /**< \brief (SYSCTRL_PCLKSR) BOD33 Detection */ +#define SYSCTRL_PCLKSR_BOD33DET (0x1u << SYSCTRL_PCLKSR_BOD33DET_Pos) +#define SYSCTRL_PCLKSR_B33SRDY_Pos 11 /**< \brief (SYSCTRL_PCLKSR) BOD33 Synchronization Ready */ +#define SYSCTRL_PCLKSR_B33SRDY (0x1u << SYSCTRL_PCLKSR_B33SRDY_Pos) +#define SYSCTRL_PCLKSR_MASK 0x00000FFFu /**< \brief (SYSCTRL_PCLKSR) MASK Register */ + +/* -------- SYSCTRL_XOSC : (SYSCTRL Offset: 0x10) (R/W 16) XOSC Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t :1; /*!< bit: 0 Reserved */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t XTALEN:1; /*!< bit: 2 Crystal Oscillator Enable */ + uint16_t :3; /*!< bit: 3.. 5 Reserved */ + uint16_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint16_t ONDEMAND:1; /*!< bit: 7 Enable on Demand */ + uint16_t GAIN:3; /*!< bit: 8..10 Gain Value */ + uint16_t AMPGC:1; /*!< bit: 11 Automatic Amplitude Gain Control */ + uint16_t STARTUP:4; /*!< bit: 12..15 Start-Up Time */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SYSCTRL_XOSC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_XOSC_OFFSET 0x10 /**< \brief (SYSCTRL_XOSC offset) XOSC Control */ +#define SYSCTRL_XOSC_RESETVALUE 0x0080 /**< \brief (SYSCTRL_XOSC reset_value) XOSC Control */ + +#define SYSCTRL_XOSC_ENABLE_Pos 1 /**< \brief (SYSCTRL_XOSC) Enable */ +#define SYSCTRL_XOSC_ENABLE (0x1u << SYSCTRL_XOSC_ENABLE_Pos) +#define SYSCTRL_XOSC_XTALEN_Pos 2 /**< \brief (SYSCTRL_XOSC) Crystal Oscillator Enable */ +#define SYSCTRL_XOSC_XTALEN (0x1u << SYSCTRL_XOSC_XTALEN_Pos) +#define SYSCTRL_XOSC_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_XOSC) Run during Standby */ +#define SYSCTRL_XOSC_RUNSTDBY (0x1u << SYSCTRL_XOSC_RUNSTDBY_Pos) +#define SYSCTRL_XOSC_ONDEMAND_Pos 7 /**< \brief (SYSCTRL_XOSC) Enable on Demand */ +#define SYSCTRL_XOSC_ONDEMAND (0x1u << SYSCTRL_XOSC_ONDEMAND_Pos) +#define SYSCTRL_XOSC_GAIN_Pos 8 /**< \brief (SYSCTRL_XOSC) Gain Value */ +#define SYSCTRL_XOSC_GAIN_Msk (0x7u << SYSCTRL_XOSC_GAIN_Pos) +#define SYSCTRL_XOSC_GAIN(value) ((SYSCTRL_XOSC_GAIN_Msk & ((value) << SYSCTRL_XOSC_GAIN_Pos))) +#define SYSCTRL_XOSC_AMPGC_Pos 11 /**< \brief (SYSCTRL_XOSC) Automatic Amplitude Gain Control */ +#define SYSCTRL_XOSC_AMPGC (0x1u << SYSCTRL_XOSC_AMPGC_Pos) +#define SYSCTRL_XOSC_STARTUP_Pos 12 /**< \brief (SYSCTRL_XOSC) Start-Up Time */ +#define SYSCTRL_XOSC_STARTUP_Msk (0xFu << SYSCTRL_XOSC_STARTUP_Pos) +#define SYSCTRL_XOSC_STARTUP(value) ((SYSCTRL_XOSC_STARTUP_Msk & ((value) << SYSCTRL_XOSC_STARTUP_Pos))) +#define SYSCTRL_XOSC_MASK 0xFFC6u /**< \brief (SYSCTRL_XOSC) MASK Register */ + +/* -------- SYSCTRL_XOSC32K : (SYSCTRL Offset: 0x14) (R/W 16) XOSC32K Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t :1; /*!< bit: 0 Reserved */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t XTALEN:1; /*!< bit: 2 Crystal Oscillator Enable */ + uint16_t EN32K:1; /*!< bit: 3 32kHz Output Enable */ + uint16_t EN1K:1; /*!< bit: 4 1kHz Output Enable */ + uint16_t AAMPEN:1; /*!< bit: 5 Automatic Amplitude Control Enable */ + uint16_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint16_t ONDEMAND:1; /*!< bit: 7 Enable on Demand */ + uint16_t STARTUP:3; /*!< bit: 8..10 Start-Up Time */ + uint16_t :1; /*!< bit: 11 Reserved */ + uint16_t WRTLOCK:1; /*!< bit: 12 Write Lock */ + uint16_t :3; /*!< bit: 13..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SYSCTRL_XOSC32K_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_XOSC32K_OFFSET 0x14 /**< \brief (SYSCTRL_XOSC32K offset) XOSC32K Control */ +#define SYSCTRL_XOSC32K_RESETVALUE 0x0080 /**< \brief (SYSCTRL_XOSC32K reset_value) XOSC32K Control */ + +#define SYSCTRL_XOSC32K_ENABLE_Pos 1 /**< \brief (SYSCTRL_XOSC32K) Enable */ +#define SYSCTRL_XOSC32K_ENABLE (0x1u << SYSCTRL_XOSC32K_ENABLE_Pos) +#define SYSCTRL_XOSC32K_XTALEN_Pos 2 /**< \brief (SYSCTRL_XOSC32K) Crystal Oscillator Enable */ +#define SYSCTRL_XOSC32K_XTALEN (0x1u << SYSCTRL_XOSC32K_XTALEN_Pos) +#define SYSCTRL_XOSC32K_EN32K_Pos 3 /**< \brief (SYSCTRL_XOSC32K) 32kHz Output Enable */ +#define SYSCTRL_XOSC32K_EN32K (0x1u << SYSCTRL_XOSC32K_EN32K_Pos) +#define SYSCTRL_XOSC32K_EN1K_Pos 4 /**< \brief (SYSCTRL_XOSC32K) 1kHz Output Enable */ +#define SYSCTRL_XOSC32K_EN1K (0x1u << SYSCTRL_XOSC32K_EN1K_Pos) +#define SYSCTRL_XOSC32K_AAMPEN_Pos 5 /**< \brief (SYSCTRL_XOSC32K) Automatic Amplitude Control Enable */ +#define SYSCTRL_XOSC32K_AAMPEN (0x1u << SYSCTRL_XOSC32K_AAMPEN_Pos) +#define SYSCTRL_XOSC32K_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_XOSC32K) Run during Standby */ +#define SYSCTRL_XOSC32K_RUNSTDBY (0x1u << SYSCTRL_XOSC32K_RUNSTDBY_Pos) +#define SYSCTRL_XOSC32K_ONDEMAND_Pos 7 /**< \brief (SYSCTRL_XOSC32K) Enable on Demand */ +#define SYSCTRL_XOSC32K_ONDEMAND (0x1u << SYSCTRL_XOSC32K_ONDEMAND_Pos) +#define SYSCTRL_XOSC32K_STARTUP_Pos 8 /**< \brief (SYSCTRL_XOSC32K) Start-Up Time */ +#define SYSCTRL_XOSC32K_STARTUP_Msk (0x7u << SYSCTRL_XOSC32K_STARTUP_Pos) +#define SYSCTRL_XOSC32K_STARTUP(value) ((SYSCTRL_XOSC32K_STARTUP_Msk & ((value) << SYSCTRL_XOSC32K_STARTUP_Pos))) +#define SYSCTRL_XOSC32K_WRTLOCK_Pos 12 /**< \brief (SYSCTRL_XOSC32K) Write Lock */ +#define SYSCTRL_XOSC32K_WRTLOCK (0x1u << SYSCTRL_XOSC32K_WRTLOCK_Pos) +#define SYSCTRL_XOSC32K_MASK 0x17FEu /**< \brief (SYSCTRL_XOSC32K) MASK Register */ + +/* -------- SYSCTRL_OSC32K : (SYSCTRL Offset: 0x18) (R/W 32) OSC32K Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t EN32K:1; /*!< bit: 2 32kHz Output Enable */ + uint32_t EN1K:1; /*!< bit: 3 1kHz Output Enable */ + uint32_t :2; /*!< bit: 4.. 5 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint32_t ONDEMAND:1; /*!< bit: 7 Enable on Demand */ + uint32_t STARTUP:3; /*!< bit: 8..10 Start-Up Time */ + uint32_t :1; /*!< bit: 11 Reserved */ + uint32_t WRTLOCK:1; /*!< bit: 12 Write Lock */ + uint32_t :3; /*!< bit: 13..15 Reserved */ + uint32_t CALIB:7; /*!< bit: 16..22 Calibration Value */ + uint32_t :9; /*!< bit: 23..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_OSC32K_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_OSC32K_OFFSET 0x18 /**< \brief (SYSCTRL_OSC32K offset) OSC32K Control */ +#define SYSCTRL_OSC32K_RESETVALUE 0x003F0080 /**< \brief (SYSCTRL_OSC32K reset_value) OSC32K Control */ + +#define SYSCTRL_OSC32K_ENABLE_Pos 1 /**< \brief (SYSCTRL_OSC32K) Enable */ +#define SYSCTRL_OSC32K_ENABLE (0x1u << SYSCTRL_OSC32K_ENABLE_Pos) +#define SYSCTRL_OSC32K_EN32K_Pos 2 /**< \brief (SYSCTRL_OSC32K) 32kHz Output Enable */ +#define SYSCTRL_OSC32K_EN32K (0x1u << SYSCTRL_OSC32K_EN32K_Pos) +#define SYSCTRL_OSC32K_EN1K_Pos 3 /**< \brief (SYSCTRL_OSC32K) 1kHz Output Enable */ +#define SYSCTRL_OSC32K_EN1K (0x1u << SYSCTRL_OSC32K_EN1K_Pos) +#define SYSCTRL_OSC32K_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_OSC32K) Run during Standby */ +#define SYSCTRL_OSC32K_RUNSTDBY (0x1u << SYSCTRL_OSC32K_RUNSTDBY_Pos) +#define SYSCTRL_OSC32K_ONDEMAND_Pos 7 /**< \brief (SYSCTRL_OSC32K) Enable on Demand */ +#define SYSCTRL_OSC32K_ONDEMAND (0x1u << SYSCTRL_OSC32K_ONDEMAND_Pos) +#define SYSCTRL_OSC32K_STARTUP_Pos 8 /**< \brief (SYSCTRL_OSC32K) Start-Up Time */ +#define SYSCTRL_OSC32K_STARTUP_Msk (0x7u << SYSCTRL_OSC32K_STARTUP_Pos) +#define SYSCTRL_OSC32K_STARTUP(value) ((SYSCTRL_OSC32K_STARTUP_Msk & ((value) << SYSCTRL_OSC32K_STARTUP_Pos))) +#define SYSCTRL_OSC32K_WRTLOCK_Pos 12 /**< \brief (SYSCTRL_OSC32K) Write Lock */ +#define SYSCTRL_OSC32K_WRTLOCK (0x1u << SYSCTRL_OSC32K_WRTLOCK_Pos) +#define SYSCTRL_OSC32K_CALIB_Pos 16 /**< \brief (SYSCTRL_OSC32K) Calibration Value */ +#define SYSCTRL_OSC32K_CALIB_Msk (0x7Fu << SYSCTRL_OSC32K_CALIB_Pos) +#define SYSCTRL_OSC32K_CALIB(value) ((SYSCTRL_OSC32K_CALIB_Msk & ((value) << SYSCTRL_OSC32K_CALIB_Pos))) +#define SYSCTRL_OSC32K_MASK 0x007F17CEu /**< \brief (SYSCTRL_OSC32K) MASK Register */ + +/* -------- SYSCTRL_OSCULP32K : (SYSCTRL Offset: 0x1C) (R/W 8) OSCULP32K Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CALIB:5; /*!< bit: 0.. 4 Calibration Value */ + uint8_t :2; /*!< bit: 5.. 6 Reserved */ + uint8_t WRTLOCK:1; /*!< bit: 7 Write Lock */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SYSCTRL_OSCULP32K_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_OSCULP32K_OFFSET 0x1C /**< \brief (SYSCTRL_OSCULP32K offset) OSCULP32K Control */ +#define SYSCTRL_OSCULP32K_RESETVALUE 0x0F /**< \brief (SYSCTRL_OSCULP32K reset_value) OSCULP32K Control */ + +#define SYSCTRL_OSCULP32K_CALIB_Pos 0 /**< \brief (SYSCTRL_OSCULP32K) Calibration Value */ +#define SYSCTRL_OSCULP32K_CALIB_Msk (0x1Fu << SYSCTRL_OSCULP32K_CALIB_Pos) +#define SYSCTRL_OSCULP32K_CALIB(value) ((SYSCTRL_OSCULP32K_CALIB_Msk & ((value) << SYSCTRL_OSCULP32K_CALIB_Pos))) +#define SYSCTRL_OSCULP32K_WRTLOCK_Pos 7 /**< \brief (SYSCTRL_OSCULP32K) Write Lock */ +#define SYSCTRL_OSCULP32K_WRTLOCK (0x1u << SYSCTRL_OSCULP32K_WRTLOCK_Pos) +#define SYSCTRL_OSCULP32K_MASK 0x9Fu /**< \brief (SYSCTRL_OSCULP32K) MASK Register */ + +/* -------- SYSCTRL_OSC8M : (SYSCTRL Offset: 0x20) (R/W 32) OSC8M Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t :4; /*!< bit: 2.. 5 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint32_t ONDEMAND:1; /*!< bit: 7 Enable on Demand */ + uint32_t PRESC:2; /*!< bit: 8.. 9 Prescaler Select */ + uint32_t :6; /*!< bit: 10..15 Reserved */ + uint32_t CALIB:12; /*!< bit: 16..27 Calibration Value */ + uint32_t :2; /*!< bit: 28..29 Reserved */ + uint32_t FRANGE:2; /*!< bit: 30..31 Frequency Range */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_OSC8M_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_OSC8M_OFFSET 0x20 /**< \brief (SYSCTRL_OSC8M offset) OSC8M Control A */ +#define SYSCTRL_OSC8M_RESETVALUE 0x87070382 /**< \brief (SYSCTRL_OSC8M reset_value) OSC8M Control A */ + +#define SYSCTRL_OSC8M_ENABLE_Pos 1 /**< \brief (SYSCTRL_OSC8M) Enable */ +#define SYSCTRL_OSC8M_ENABLE (0x1u << SYSCTRL_OSC8M_ENABLE_Pos) +#define SYSCTRL_OSC8M_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_OSC8M) Run during Standby */ +#define SYSCTRL_OSC8M_RUNSTDBY (0x1u << SYSCTRL_OSC8M_RUNSTDBY_Pos) +#define SYSCTRL_OSC8M_ONDEMAND_Pos 7 /**< \brief (SYSCTRL_OSC8M) Enable on Demand */ +#define SYSCTRL_OSC8M_ONDEMAND (0x1u << SYSCTRL_OSC8M_ONDEMAND_Pos) +#define SYSCTRL_OSC8M_PRESC_Pos 8 /**< \brief (SYSCTRL_OSC8M) Prescaler Select */ +#define SYSCTRL_OSC8M_PRESC_Msk (0x3u << SYSCTRL_OSC8M_PRESC_Pos) +#define SYSCTRL_OSC8M_PRESC(value) ((SYSCTRL_OSC8M_PRESC_Msk & ((value) << SYSCTRL_OSC8M_PRESC_Pos))) +#define SYSCTRL_OSC8M_CALIB_Pos 16 /**< \brief (SYSCTRL_OSC8M) Calibration Value */ +#define SYSCTRL_OSC8M_CALIB_Msk (0xFFFu << SYSCTRL_OSC8M_CALIB_Pos) +#define SYSCTRL_OSC8M_CALIB(value) ((SYSCTRL_OSC8M_CALIB_Msk & ((value) << SYSCTRL_OSC8M_CALIB_Pos))) +#define SYSCTRL_OSC8M_FRANGE_Pos 30 /**< \brief (SYSCTRL_OSC8M) Frequency Range */ +#define SYSCTRL_OSC8M_FRANGE_Msk (0x3u << SYSCTRL_OSC8M_FRANGE_Pos) +#define SYSCTRL_OSC8M_FRANGE(value) ((SYSCTRL_OSC8M_FRANGE_Msk & ((value) << SYSCTRL_OSC8M_FRANGE_Pos))) +#define SYSCTRL_OSC8M_MASK 0xCFFF03C2u /**< \brief (SYSCTRL_OSC8M) MASK Register */ + +/* -------- SYSCTRL_DFLLCTRL : (SYSCTRL Offset: 0x24) (R/W 16) DFLL Config -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t :1; /*!< bit: 0 Reserved */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t MODE:1; /*!< bit: 2 Mode Selection */ + uint16_t STABLE:1; /*!< bit: 3 Stable Frequency */ + uint16_t LLAW:1; /*!< bit: 4 Lose Lock After Wake */ + uint16_t :1; /*!< bit: 5 Reserved */ + uint16_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint16_t ONDEMAND:1; /*!< bit: 7 Enable on Demand */ + uint16_t CCDIS:1; /*!< bit: 8 Chill Cycle Disable */ + uint16_t QLDIS:1; /*!< bit: 9 Quick Lock Disable */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SYSCTRL_DFLLCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_DFLLCTRL_OFFSET 0x24 /**< \brief (SYSCTRL_DFLLCTRL offset) DFLL Config */ +#define SYSCTRL_DFLLCTRL_RESETVALUE 0x0080 /**< \brief (SYSCTRL_DFLLCTRL reset_value) DFLL Config */ + +#define SYSCTRL_DFLLCTRL_ENABLE_Pos 1 /**< \brief (SYSCTRL_DFLLCTRL) Enable */ +#define SYSCTRL_DFLLCTRL_ENABLE (0x1u << SYSCTRL_DFLLCTRL_ENABLE_Pos) +#define SYSCTRL_DFLLCTRL_MODE_Pos 2 /**< \brief (SYSCTRL_DFLLCTRL) Mode Selection */ +#define SYSCTRL_DFLLCTRL_MODE (0x1u << SYSCTRL_DFLLCTRL_MODE_Pos) +#define SYSCTRL_DFLLCTRL_STABLE_Pos 3 /**< \brief (SYSCTRL_DFLLCTRL) Stable Frequency */ +#define SYSCTRL_DFLLCTRL_STABLE (0x1u << SYSCTRL_DFLLCTRL_STABLE_Pos) +#define SYSCTRL_DFLLCTRL_LLAW_Pos 4 /**< \brief (SYSCTRL_DFLLCTRL) Lose Lock After Wake */ +#define SYSCTRL_DFLLCTRL_LLAW (0x1u << SYSCTRL_DFLLCTRL_LLAW_Pos) +#define SYSCTRL_DFLLCTRL_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_DFLLCTRL) Run during Standby */ +#define SYSCTRL_DFLLCTRL_RUNSTDBY (0x1u << SYSCTRL_DFLLCTRL_RUNSTDBY_Pos) +#define SYSCTRL_DFLLCTRL_ONDEMAND_Pos 7 /**< \brief (SYSCTRL_DFLLCTRL) Enable on Demand */ +#define SYSCTRL_DFLLCTRL_ONDEMAND (0x1u << SYSCTRL_DFLLCTRL_ONDEMAND_Pos) +#define SYSCTRL_DFLLCTRL_CCDIS_Pos 8 /**< \brief (SYSCTRL_DFLLCTRL) Chill Cycle Disable */ +#define SYSCTRL_DFLLCTRL_CCDIS (0x1u << SYSCTRL_DFLLCTRL_CCDIS_Pos) +#define SYSCTRL_DFLLCTRL_QLDIS_Pos 9 /**< \brief (SYSCTRL_DFLLCTRL) Quick Lock Disable */ +#define SYSCTRL_DFLLCTRL_QLDIS (0x1u << SYSCTRL_DFLLCTRL_QLDIS_Pos) +#define SYSCTRL_DFLLCTRL_MASK 0x03DEu /**< \brief (SYSCTRL_DFLLCTRL) MASK Register */ + +/* -------- SYSCTRL_DFLLVAL : (SYSCTRL Offset: 0x28) (R/W 32) DFLL Calibration Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t FINE:10; /*!< bit: 0.. 9 Fine Calibration Value */ + uint32_t COARSE:6; /*!< bit: 10..15 Coarse Calibration Value */ + uint32_t DIFF:16; /*!< bit: 16..31 Multiplication Ratio Difference */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_DFLLVAL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_DFLLVAL_OFFSET 0x28 /**< \brief (SYSCTRL_DFLLVAL offset) DFLL Calibration Value */ +#define SYSCTRL_DFLLVAL_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_DFLLVAL reset_value) DFLL Calibration Value */ + +#define SYSCTRL_DFLLVAL_FINE_Pos 0 /**< \brief (SYSCTRL_DFLLVAL) Fine Calibration Value */ +#define SYSCTRL_DFLLVAL_FINE_Msk (0x3FFu << SYSCTRL_DFLLVAL_FINE_Pos) +#define SYSCTRL_DFLLVAL_FINE(value) ((SYSCTRL_DFLLVAL_FINE_Msk & ((value) << SYSCTRL_DFLLVAL_FINE_Pos))) +#define SYSCTRL_DFLLVAL_COARSE_Pos 10 /**< \brief (SYSCTRL_DFLLVAL) Coarse Calibration Value */ +#define SYSCTRL_DFLLVAL_COARSE_Msk (0x3Fu << SYSCTRL_DFLLVAL_COARSE_Pos) +#define SYSCTRL_DFLLVAL_COARSE(value) ((SYSCTRL_DFLLVAL_COARSE_Msk & ((value) << SYSCTRL_DFLLVAL_COARSE_Pos))) +#define SYSCTRL_DFLLVAL_DIFF_Pos 16 /**< \brief (SYSCTRL_DFLLVAL) Multiplication Ratio Difference */ +#define SYSCTRL_DFLLVAL_DIFF_Msk (0xFFFFu << SYSCTRL_DFLLVAL_DIFF_Pos) +#define SYSCTRL_DFLLVAL_DIFF(value) ((SYSCTRL_DFLLVAL_DIFF_Msk & ((value) << SYSCTRL_DFLLVAL_DIFF_Pos))) +#define SYSCTRL_DFLLVAL_MASK 0xFFFFFFFFu /**< \brief (SYSCTRL_DFLLVAL) MASK Register */ + +/* -------- SYSCTRL_DFLLMUL : (SYSCTRL Offset: 0x2C) (R/W 32) DFLL Multiplier -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t MUL:16; /*!< bit: 0..15 Multiplication Value */ + uint32_t FSTEP:10; /*!< bit: 16..25 Maximum Fine Step Size */ + uint32_t CSTEP:6; /*!< bit: 26..31 Maximum Coarse Step Size */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_DFLLMUL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_DFLLMUL_OFFSET 0x2C /**< \brief (SYSCTRL_DFLLMUL offset) DFLL Multiplier */ +#define SYSCTRL_DFLLMUL_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_DFLLMUL reset_value) DFLL Multiplier */ + +#define SYSCTRL_DFLLMUL_MUL_Pos 0 /**< \brief (SYSCTRL_DFLLMUL) Multiplication Value */ +#define SYSCTRL_DFLLMUL_MUL_Msk (0xFFFFu << SYSCTRL_DFLLMUL_MUL_Pos) +#define SYSCTRL_DFLLMUL_MUL(value) ((SYSCTRL_DFLLMUL_MUL_Msk & ((value) << SYSCTRL_DFLLMUL_MUL_Pos))) +#define SYSCTRL_DFLLMUL_FSTEP_Pos 16 /**< \brief (SYSCTRL_DFLLMUL) Maximum Fine Step Size */ +#define SYSCTRL_DFLLMUL_FSTEP_Msk (0x3FFu << SYSCTRL_DFLLMUL_FSTEP_Pos) +#define SYSCTRL_DFLLMUL_FSTEP(value) ((SYSCTRL_DFLLMUL_FSTEP_Msk & ((value) << SYSCTRL_DFLLMUL_FSTEP_Pos))) +#define SYSCTRL_DFLLMUL_CSTEP_Pos 26 /**< \brief (SYSCTRL_DFLLMUL) Maximum Coarse Step Size */ +#define SYSCTRL_DFLLMUL_CSTEP_Msk (0x3Fu << SYSCTRL_DFLLMUL_CSTEP_Pos) +#define SYSCTRL_DFLLMUL_CSTEP(value) ((SYSCTRL_DFLLMUL_CSTEP_Msk & ((value) << SYSCTRL_DFLLMUL_CSTEP_Pos))) +#define SYSCTRL_DFLLMUL_MASK 0xFFFFFFFFu /**< \brief (SYSCTRL_DFLLMUL) MASK Register */ + +/* -------- SYSCTRL_DFLLSYNC : (SYSCTRL Offset: 0x30) (R/W 8) DFLL Synchronization -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t READREQ:1; /*!< bit: 7 Read Request Synchronization */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} SYSCTRL_DFLLSYNC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_DFLLSYNC_OFFSET 0x30 /**< \brief (SYSCTRL_DFLLSYNC offset) DFLL Synchronization */ +#define SYSCTRL_DFLLSYNC_RESETVALUE 0x00 /**< \brief (SYSCTRL_DFLLSYNC reset_value) DFLL Synchronization */ + +#define SYSCTRL_DFLLSYNC_READREQ_Pos 7 /**< \brief (SYSCTRL_DFLLSYNC) Read Request Synchronization */ +#define SYSCTRL_DFLLSYNC_READREQ (0x1u << SYSCTRL_DFLLSYNC_READREQ_Pos) +#define SYSCTRL_DFLLSYNC_MASK 0x80u /**< \brief (SYSCTRL_DFLLSYNC) MASK Register */ + +/* -------- SYSCTRL_BOD33 : (SYSCTRL Offset: 0x34) (R/W 32) 3.3V Brown-Out Detector (BOD33) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t ENABLE:1; /*!< bit: 1 Enable */ + uint32_t HYST:1; /*!< bit: 2 Hysteresis Enable */ + uint32_t ACTION:2; /*!< bit: 3.. 4 Action when Threshold Crossed */ + uint32_t :1; /*!< bit: 5 Reserved */ + uint32_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint32_t :1; /*!< bit: 7 Reserved */ + uint32_t MODE:1; /*!< bit: 8 Operation Modes */ + uint32_t CEN:1; /*!< bit: 9 Clock Enable */ + uint32_t :2; /*!< bit: 10..11 Reserved */ + uint32_t PSEL:4; /*!< bit: 12..15 Prescaler Select */ + uint32_t LEVEL:6; /*!< bit: 16..21 Threshold Level */ + uint32_t :10; /*!< bit: 22..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_BOD33_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_BOD33_OFFSET 0x34 /**< \brief (SYSCTRL_BOD33 offset) 3.3V Brown-Out Detector (BOD33) Control */ +#define SYSCTRL_BOD33_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_BOD33 reset_value) 3.3V Brown-Out Detector (BOD33) Control */ + +#define SYSCTRL_BOD33_ENABLE_Pos 1 /**< \brief (SYSCTRL_BOD33) Enable */ +#define SYSCTRL_BOD33_ENABLE (0x1u << SYSCTRL_BOD33_ENABLE_Pos) +#define SYSCTRL_BOD33_HYST_Pos 2 /**< \brief (SYSCTRL_BOD33) Hysteresis Enable */ +#define SYSCTRL_BOD33_HYST (0x1u << SYSCTRL_BOD33_HYST_Pos) +#define SYSCTRL_BOD33_ACTION_Pos 3 /**< \brief (SYSCTRL_BOD33) Action when Threshold Crossed */ +#define SYSCTRL_BOD33_ACTION_Msk (0x3u << SYSCTRL_BOD33_ACTION_Pos) +#define SYSCTRL_BOD33_ACTION(value) ((SYSCTRL_BOD33_ACTION_Msk & ((value) << SYSCTRL_BOD33_ACTION_Pos))) +#define SYSCTRL_BOD33_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_BOD33) Run during Standby */ +#define SYSCTRL_BOD33_RUNSTDBY (0x1u << SYSCTRL_BOD33_RUNSTDBY_Pos) +#define SYSCTRL_BOD33_MODE_Pos 8 /**< \brief (SYSCTRL_BOD33) Operation Modes */ +#define SYSCTRL_BOD33_MODE (0x1u << SYSCTRL_BOD33_MODE_Pos) +#define SYSCTRL_BOD33_CEN_Pos 9 /**< \brief (SYSCTRL_BOD33) Clock Enable */ +#define SYSCTRL_BOD33_CEN (0x1u << SYSCTRL_BOD33_CEN_Pos) +#define SYSCTRL_BOD33_PSEL_Pos 12 /**< \brief (SYSCTRL_BOD33) Prescaler Select */ +#define SYSCTRL_BOD33_PSEL_Msk (0xFu << SYSCTRL_BOD33_PSEL_Pos) +#define SYSCTRL_BOD33_PSEL(value) ((SYSCTRL_BOD33_PSEL_Msk & ((value) << SYSCTRL_BOD33_PSEL_Pos))) +#define SYSCTRL_BOD33_LEVEL_Pos 16 /**< \brief (SYSCTRL_BOD33) Threshold Level */ +#define SYSCTRL_BOD33_LEVEL_Msk (0x3Fu << SYSCTRL_BOD33_LEVEL_Pos) +#define SYSCTRL_BOD33_LEVEL(value) ((SYSCTRL_BOD33_LEVEL_Msk & ((value) << SYSCTRL_BOD33_LEVEL_Pos))) +#define SYSCTRL_BOD33_MASK 0x003FF35Eu /**< \brief (SYSCTRL_BOD33) MASK Register */ + +/* -------- SYSCTRL_VREG : (SYSCTRL Offset: 0x3C) (R/W 16) VREG Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t :6; /*!< bit: 0.. 5 Reserved */ + uint16_t RUNSTDBY:1; /*!< bit: 6 Run during Standby */ + uint16_t :6; /*!< bit: 7..12 Reserved */ + uint16_t FORCELDO:1; /*!< bit: 13 Force LDO Voltage Regulator */ + uint16_t :2; /*!< bit: 14..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SYSCTRL_VREG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_VREG_OFFSET 0x3C /**< \brief (SYSCTRL_VREG offset) VREG Control */ +#define SYSCTRL_VREG_RESETVALUE 0x0402 /**< \brief (SYSCTRL_VREG reset_value) VREG Control */ + +#define SYSCTRL_VREG_RUNSTDBY_Pos 6 /**< \brief (SYSCTRL_VREG) Run during Standby */ +#define SYSCTRL_VREG_RUNSTDBY (0x1u << SYSCTRL_VREG_RUNSTDBY_Pos) +#define SYSCTRL_VREG_FORCELDO_Pos 13 /**< \brief (SYSCTRL_VREG) Force LDO Voltage Regulator */ +#define SYSCTRL_VREG_FORCELDO (0x1u << SYSCTRL_VREG_FORCELDO_Pos) +#define SYSCTRL_VREG_MASK 0x2040u /**< \brief (SYSCTRL_VREG) MASK Register */ + +/* -------- SYSCTRL_VREF : (SYSCTRL Offset: 0x40) (R/W 32) VREF Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t :1; /*!< bit: 0 Reserved */ + uint32_t TSEN:1; /*!< bit: 1 Temperature Sensor Output Enable */ + uint32_t BGOUTEN:1; /*!< bit: 2 Bandgap Output Enable */ + uint32_t :13; /*!< bit: 3..15 Reserved */ + uint32_t CALIB:11; /*!< bit: 16..26 Voltage Reference Calibration Value */ + uint32_t :5; /*!< bit: 27..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} SYSCTRL_VREF_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define SYSCTRL_VREF_OFFSET 0x40 /**< \brief (SYSCTRL_VREF offset) VREF Control A */ +#define SYSCTRL_VREF_RESETVALUE 0x00000000 /**< \brief (SYSCTRL_VREF reset_value) VREF Control A */ + +#define SYSCTRL_VREF_TSEN_Pos 1 /**< \brief (SYSCTRL_VREF) Temperature Sensor Output Enable */ +#define SYSCTRL_VREF_TSEN (0x1u << SYSCTRL_VREF_TSEN_Pos) +#define SYSCTRL_VREF_BGOUTEN_Pos 2 /**< \brief (SYSCTRL_VREF) Bandgap Output Enable */ +#define SYSCTRL_VREF_BGOUTEN (0x1u << SYSCTRL_VREF_BGOUTEN_Pos) +#define SYSCTRL_VREF_CALIB_Pos 16 /**< \brief (SYSCTRL_VREF) Voltage Reference Calibration Value */ +#define SYSCTRL_VREF_CALIB_Msk (0x7FFu << SYSCTRL_VREF_CALIB_Pos) +#define SYSCTRL_VREF_CALIB(value) ((SYSCTRL_VREF_CALIB_Msk & ((value) << SYSCTRL_VREF_CALIB_Pos))) +#define SYSCTRL_VREF_MASK 0x07FF0006u /**< \brief (SYSCTRL_VREF) MASK Register */ + +/** \brief SYSCTRL hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO SYSCTRL_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x00 (R/W 32) Interrupt Enable Clear */ + __IO SYSCTRL_INTENSET_Type INTENSET; /**< \brief Offset: 0x04 (R/W 32) Interrupt Enable Set */ + __IO SYSCTRL_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x08 (R/W 32) Interrupt Flag Status and Clear */ + __I SYSCTRL_PCLKSR_Type PCLKSR; /**< \brief Offset: 0x0C (R/ 32) Power and Clocks Status */ + __IO SYSCTRL_XOSC_Type XOSC; /**< \brief Offset: 0x10 (R/W 16) XOSC Control */ + RoReg8 Reserved1[0x2]; + __IO SYSCTRL_XOSC32K_Type XOSC32K; /**< \brief Offset: 0x14 (R/W 16) XOSC32K Control */ + RoReg8 Reserved2[0x2]; + __IO SYSCTRL_OSC32K_Type OSC32K; /**< \brief Offset: 0x18 (R/W 32) OSC32K Control */ + __IO SYSCTRL_OSCULP32K_Type OSCULP32K; /**< \brief Offset: 0x1C (R/W 8) OSCULP32K Control */ + RoReg8 Reserved3[0x3]; + __IO SYSCTRL_OSC8M_Type OSC8M; /**< \brief Offset: 0x20 (R/W 32) OSC8M Control A */ + __IO SYSCTRL_DFLLCTRL_Type DFLLCTRL; /**< \brief Offset: 0x24 (R/W 16) DFLL Config */ + RoReg8 Reserved4[0x2]; + __IO SYSCTRL_DFLLVAL_Type DFLLVAL; /**< \brief Offset: 0x28 (R/W 32) DFLL Calibration Value */ + __IO SYSCTRL_DFLLMUL_Type DFLLMUL; /**< \brief Offset: 0x2C (R/W 32) DFLL Multiplier */ + __IO SYSCTRL_DFLLSYNC_Type DFLLSYNC; /**< \brief Offset: 0x30 (R/W 8) DFLL Synchronization */ + RoReg8 Reserved5[0x3]; + __IO SYSCTRL_BOD33_Type BOD33; /**< \brief Offset: 0x34 (R/W 32) 3.3V Brown-Out Detector (BOD33) Control */ + RoReg8 Reserved6[0x4]; + __IO SYSCTRL_VREG_Type VREG; /**< \brief Offset: 0x3C (R/W 16) VREG Control */ + RoReg8 Reserved7[0x2]; + __IO SYSCTRL_VREF_Type VREF; /**< \brief Offset: 0x40 (R/W 32) VREF Control A */ +} Sysctrl; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_SYSCTRL_COMPONENT_ */ diff --git a/loader/samd20/component/tc.h b/loader/samd20/component/tc.h new file mode 100644 index 0000000..2e5a007 --- /dev/null +++ b/loader/samd20/component/tc.h @@ -0,0 +1,684 @@ +/** + * \file + * + * \brief Component description for TC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_TC_COMPONENT_ +#define _SAMD20_TC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR TC */ +/* ========================================================================== */ +/** \addtogroup SAMD20_TC Basic Timer Counter */ +/*@{*/ + +#define TC_U2212 +#define REV_TC 0x111 + +/* -------- TC_CTRLA : (TC Offset: 0x00) (R/W 16) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t SWRST:1; /*!< bit: 0 Software Reset */ + uint16_t ENABLE:1; /*!< bit: 1 Enable */ + uint16_t MODE:2; /*!< bit: 2.. 3 TC Mode */ + uint16_t :1; /*!< bit: 4 Reserved */ + uint16_t WAVEGEN:2; /*!< bit: 5.. 6 Waveform Generation Operation */ + uint16_t :1; /*!< bit: 7 Reserved */ + uint16_t PRESCALER:3; /*!< bit: 8..10 Prescaler */ + uint16_t RUNSTDBY:1; /*!< bit: 11 Run in Standby */ + uint16_t PRESCSYNC:2; /*!< bit: 12..13 Prescaler and Counter Synchronization */ + uint16_t :2; /*!< bit: 14..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} TC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_CTRLA_OFFSET 0x00 /**< \brief (TC_CTRLA offset) Control A */ +#define TC_CTRLA_RESETVALUE 0x0000 /**< \brief (TC_CTRLA reset_value) Control A */ + +#define TC_CTRLA_SWRST_Pos 0 /**< \brief (TC_CTRLA) Software Reset */ +#define TC_CTRLA_SWRST (0x1u << TC_CTRLA_SWRST_Pos) +#define TC_CTRLA_ENABLE_Pos 1 /**< \brief (TC_CTRLA) Enable */ +#define TC_CTRLA_ENABLE (0x1u << TC_CTRLA_ENABLE_Pos) +#define TC_CTRLA_MODE_Pos 2 /**< \brief (TC_CTRLA) TC Mode */ +#define TC_CTRLA_MODE_Msk (0x3u << TC_CTRLA_MODE_Pos) +#define TC_CTRLA_MODE(value) ((TC_CTRLA_MODE_Msk & ((value) << TC_CTRLA_MODE_Pos))) +#define TC_CTRLA_MODE_COUNT16_Val 0x0u /**< \brief (TC_CTRLA) Counter in 16-bit mode */ +#define TC_CTRLA_MODE_COUNT8_Val 0x1u /**< \brief (TC_CTRLA) Counter in 8-bit mode */ +#define TC_CTRLA_MODE_COUNT32_Val 0x2u /**< \brief (TC_CTRLA) Counter in 32-bit mode */ +#define TC_CTRLA_MODE_COUNT16 (TC_CTRLA_MODE_COUNT16_Val << TC_CTRLA_MODE_Pos) +#define TC_CTRLA_MODE_COUNT8 (TC_CTRLA_MODE_COUNT8_Val << TC_CTRLA_MODE_Pos) +#define TC_CTRLA_MODE_COUNT32 (TC_CTRLA_MODE_COUNT32_Val << TC_CTRLA_MODE_Pos) +#define TC_CTRLA_WAVEGEN_Pos 5 /**< \brief (TC_CTRLA) Waveform Generation Operation */ +#define TC_CTRLA_WAVEGEN_Msk (0x3u << TC_CTRLA_WAVEGEN_Pos) +#define TC_CTRLA_WAVEGEN(value) ((TC_CTRLA_WAVEGEN_Msk & ((value) << TC_CTRLA_WAVEGEN_Pos))) +#define TC_CTRLA_WAVEGEN_NFRQ_Val 0x0u /**< \brief (TC_CTRLA) */ +#define TC_CTRLA_WAVEGEN_MFRQ_Val 0x1u /**< \brief (TC_CTRLA) */ +#define TC_CTRLA_WAVEGEN_NPWM_Val 0x2u /**< \brief (TC_CTRLA) */ +#define TC_CTRLA_WAVEGEN_MPWM_Val 0x3u /**< \brief (TC_CTRLA) */ +#define TC_CTRLA_WAVEGEN_NFRQ (TC_CTRLA_WAVEGEN_NFRQ_Val << TC_CTRLA_WAVEGEN_Pos) +#define TC_CTRLA_WAVEGEN_MFRQ (TC_CTRLA_WAVEGEN_MFRQ_Val << TC_CTRLA_WAVEGEN_Pos) +#define TC_CTRLA_WAVEGEN_NPWM (TC_CTRLA_WAVEGEN_NPWM_Val << TC_CTRLA_WAVEGEN_Pos) +#define TC_CTRLA_WAVEGEN_MPWM (TC_CTRLA_WAVEGEN_MPWM_Val << TC_CTRLA_WAVEGEN_Pos) +#define TC_CTRLA_PRESCALER_Pos 8 /**< \brief (TC_CTRLA) Prescaler */ +#define TC_CTRLA_PRESCALER_Msk (0x7u << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER(value) ((TC_CTRLA_PRESCALER_Msk & ((value) << TC_CTRLA_PRESCALER_Pos))) +#define TC_CTRLA_PRESCALER_DIV1_Val 0x0u /**< \brief (TC_CTRLA) GCLK_TC */ +#define TC_CTRLA_PRESCALER_DIV2_Val 0x1u /**< \brief (TC_CTRLA) GCLK_TC/2 */ +#define TC_CTRLA_PRESCALER_DIV4_Val 0x2u /**< \brief (TC_CTRLA) GCLK_TC/4 */ +#define TC_CTRLA_PRESCALER_DIV8_Val 0x3u /**< \brief (TC_CTRLA) GCLK_TC/8 */ +#define TC_CTRLA_PRESCALER_DIV16_Val 0x4u /**< \brief (TC_CTRLA) GCLK_TC/16 */ +#define TC_CTRLA_PRESCALER_DIV64_Val 0x5u /**< \brief (TC_CTRLA) GCLK_TC/64 */ +#define TC_CTRLA_PRESCALER_DIV256_Val 0x6u /**< \brief (TC_CTRLA) GCLK_TC/256 */ +#define TC_CTRLA_PRESCALER_DIV1024_Val 0x7u /**< \brief (TC_CTRLA) GCLK_TC/1024 */ +#define TC_CTRLA_PRESCALER_DIV1 (TC_CTRLA_PRESCALER_DIV1_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV2 (TC_CTRLA_PRESCALER_DIV2_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV4 (TC_CTRLA_PRESCALER_DIV4_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV8 (TC_CTRLA_PRESCALER_DIV8_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV16 (TC_CTRLA_PRESCALER_DIV16_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV64 (TC_CTRLA_PRESCALER_DIV64_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV256 (TC_CTRLA_PRESCALER_DIV256_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_PRESCALER_DIV1024 (TC_CTRLA_PRESCALER_DIV1024_Val << TC_CTRLA_PRESCALER_Pos) +#define TC_CTRLA_RUNSTDBY_Pos 11 /**< \brief (TC_CTRLA) Run in Standby */ +#define TC_CTRLA_RUNSTDBY (0x1u << TC_CTRLA_RUNSTDBY_Pos) +#define TC_CTRLA_PRESCSYNC_Pos 12 /**< \brief (TC_CTRLA) Prescaler and Counter Synchronization */ +#define TC_CTRLA_PRESCSYNC_Msk (0x3u << TC_CTRLA_PRESCSYNC_Pos) +#define TC_CTRLA_PRESCSYNC(value) ((TC_CTRLA_PRESCSYNC_Msk & ((value) << TC_CTRLA_PRESCSYNC_Pos))) +#define TC_CTRLA_PRESCSYNC_GCLK_Val 0x0u /**< \brief (TC_CTRLA) Reload or reset Counter on next GCLK */ +#define TC_CTRLA_PRESCSYNC_PRESC_Val 0x1u /**< \brief (TC_CTRLA) Reload or reset Counter on next prescaler clock */ +#define TC_CTRLA_PRESCSYNC_RESYNC_Val 0x2u /**< \brief (TC_CTRLA) Reload or reset Counter on next GCLK. Reset prescaler counter */ +#define TC_CTRLA_PRESCSYNC_GCLK (TC_CTRLA_PRESCSYNC_GCLK_Val << TC_CTRLA_PRESCSYNC_Pos) +#define TC_CTRLA_PRESCSYNC_PRESC (TC_CTRLA_PRESCSYNC_PRESC_Val << TC_CTRLA_PRESCSYNC_Pos) +#define TC_CTRLA_PRESCSYNC_RESYNC (TC_CTRLA_PRESCSYNC_RESYNC_Val << TC_CTRLA_PRESCSYNC_Pos) +#define TC_CTRLA_MASK 0x3F6Fu /**< \brief (TC_CTRLA) MASK Register */ + +/* -------- TC_READREQ : (TC Offset: 0x02) (R/W 16) Read Request -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t ADDR:5; /*!< bit: 0.. 4 Address */ + uint16_t :9; /*!< bit: 5..13 Reserved */ + uint16_t RCONT:1; /*!< bit: 14 Read Continuously */ + uint16_t RREQ:1; /*!< bit: 15 Read Request */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} TC_READREQ_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_READREQ_OFFSET 0x02 /**< \brief (TC_READREQ offset) Read Request */ +#define TC_READREQ_RESETVALUE 0x0000 /**< \brief (TC_READREQ reset_value) Read Request */ + +#define TC_READREQ_ADDR_Pos 0 /**< \brief (TC_READREQ) Address */ +#define TC_READREQ_ADDR_Msk (0x1Fu << TC_READREQ_ADDR_Pos) +#define TC_READREQ_ADDR(value) ((TC_READREQ_ADDR_Msk & ((value) << TC_READREQ_ADDR_Pos))) +#define TC_READREQ_RCONT_Pos 14 /**< \brief (TC_READREQ) Read Continuously */ +#define TC_READREQ_RCONT (0x1u << TC_READREQ_RCONT_Pos) +#define TC_READREQ_RREQ_Pos 15 /**< \brief (TC_READREQ) Read Request */ +#define TC_READREQ_RREQ (0x1u << TC_READREQ_RREQ_Pos) +#define TC_READREQ_MASK 0xC01Fu /**< \brief (TC_READREQ) MASK Register */ + +/* -------- TC_CTRLBCLR : (TC Offset: 0x04) (R/W 8) Control B Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DIR:1; /*!< bit: 0 Counter Direction */ + uint8_t :1; /*!< bit: 1 Reserved */ + uint8_t ONESHOT:1; /*!< bit: 2 One-Shot */ + uint8_t :3; /*!< bit: 3.. 5 Reserved */ + uint8_t CMD:2; /*!< bit: 6.. 7 Command */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_CTRLBCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_CTRLBCLR_OFFSET 0x04 /**< \brief (TC_CTRLBCLR offset) Control B Clear */ +#define TC_CTRLBCLR_RESETVALUE 0x02 /**< \brief (TC_CTRLBCLR reset_value) Control B Clear */ + +#define TC_CTRLBCLR_DIR_Pos 0 /**< \brief (TC_CTRLBCLR) Counter Direction */ +#define TC_CTRLBCLR_DIR (0x1u << TC_CTRLBCLR_DIR_Pos) +#define TC_CTRLBCLR_ONESHOT_Pos 2 /**< \brief (TC_CTRLBCLR) One-Shot */ +#define TC_CTRLBCLR_ONESHOT (0x1u << TC_CTRLBCLR_ONESHOT_Pos) +#define TC_CTRLBCLR_CMD_Pos 6 /**< \brief (TC_CTRLBCLR) Command */ +#define TC_CTRLBCLR_CMD_Msk (0x3u << TC_CTRLBCLR_CMD_Pos) +#define TC_CTRLBCLR_CMD(value) ((TC_CTRLBCLR_CMD_Msk & ((value) << TC_CTRLBCLR_CMD_Pos))) +#define TC_CTRLBCLR_CMD_NONE_Val 0x0u /**< \brief (TC_CTRLBCLR) No action */ +#define TC_CTRLBCLR_CMD_RETRIGGER_Val 0x1u /**< \brief (TC_CTRLBCLR) Force start, restart or retrigger */ +#define TC_CTRLBCLR_CMD_STOP_Val 0x2u /**< \brief (TC_CTRLBCLR) Force stop */ +#define TC_CTRLBCLR_CMD_NONE (TC_CTRLBCLR_CMD_NONE_Val << TC_CTRLBCLR_CMD_Pos) +#define TC_CTRLBCLR_CMD_RETRIGGER (TC_CTRLBCLR_CMD_RETRIGGER_Val << TC_CTRLBCLR_CMD_Pos) +#define TC_CTRLBCLR_CMD_STOP (TC_CTRLBCLR_CMD_STOP_Val << TC_CTRLBCLR_CMD_Pos) +#define TC_CTRLBCLR_MASK 0xC5u /**< \brief (TC_CTRLBCLR) MASK Register */ + +/* -------- TC_CTRLBSET : (TC Offset: 0x05) (R/W 8) Control B Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DIR:1; /*!< bit: 0 Counter Direction */ + uint8_t :1; /*!< bit: 1 Reserved */ + uint8_t ONESHOT:1; /*!< bit: 2 One-shot */ + uint8_t :3; /*!< bit: 3.. 5 Reserved */ + uint8_t CMD:2; /*!< bit: 6.. 7 Command */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_CTRLBSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_CTRLBSET_OFFSET 0x05 /**< \brief (TC_CTRLBSET offset) Control B Set */ +#define TC_CTRLBSET_RESETVALUE 0x00 /**< \brief (TC_CTRLBSET reset_value) Control B Set */ + +#define TC_CTRLBSET_DIR_Pos 0 /**< \brief (TC_CTRLBSET) Counter Direction */ +#define TC_CTRLBSET_DIR (0x1u << TC_CTRLBSET_DIR_Pos) +#define TC_CTRLBSET_ONESHOT_Pos 2 /**< \brief (TC_CTRLBSET) One-shot */ +#define TC_CTRLBSET_ONESHOT (0x1u << TC_CTRLBSET_ONESHOT_Pos) +#define TC_CTRLBSET_CMD_Pos 6 /**< \brief (TC_CTRLBSET) Command */ +#define TC_CTRLBSET_CMD_Msk (0x3u << TC_CTRLBSET_CMD_Pos) +#define TC_CTRLBSET_CMD(value) ((TC_CTRLBSET_CMD_Msk & ((value) << TC_CTRLBSET_CMD_Pos))) +#define TC_CTRLBSET_CMD_NONE_Val 0x0u /**< \brief (TC_CTRLBSET) No action */ +#define TC_CTRLBSET_CMD_RETRIGGER_Val 0x1u /**< \brief (TC_CTRLBSET) Force start, restart or retrigger */ +#define TC_CTRLBSET_CMD_STOP_Val 0x2u /**< \brief (TC_CTRLBSET) Force stop */ +#define TC_CTRLBSET_CMD_NONE (TC_CTRLBSET_CMD_NONE_Val << TC_CTRLBSET_CMD_Pos) +#define TC_CTRLBSET_CMD_RETRIGGER (TC_CTRLBSET_CMD_RETRIGGER_Val << TC_CTRLBSET_CMD_Pos) +#define TC_CTRLBSET_CMD_STOP (TC_CTRLBSET_CMD_STOP_Val << TC_CTRLBSET_CMD_Pos) +#define TC_CTRLBSET_MASK 0xC5u /**< \brief (TC_CTRLBSET) MASK Register */ + +/* -------- TC_CTRLC : (TC Offset: 0x06) (R/W 8) Control C -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t INVEN0:1; /*!< bit: 0 Output Waveform 0 Invert Enable */ + uint8_t INVEN1:1; /*!< bit: 1 Output Waveform 1 Invert Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t CPTEN0:1; /*!< bit: 4 Capture Channel 0 Enable */ + uint8_t CPTEN1:1; /*!< bit: 5 Capture Channel 1 Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t INVEN:2; /*!< bit: 0.. 1 Output Waveform x Invert Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t CPTEN:2; /*!< bit: 4.. 5 Capture Channel x Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} TC_CTRLC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_CTRLC_OFFSET 0x06 /**< \brief (TC_CTRLC offset) Control C */ +#define TC_CTRLC_RESETVALUE 0x00 /**< \brief (TC_CTRLC reset_value) Control C */ + +#define TC_CTRLC_INVEN0_Pos 0 /**< \brief (TC_CTRLC) Output Waveform 0 Invert Enable */ +#define TC_CTRLC_INVEN0 (1 << TC_CTRLC_INVEN0_Pos) +#define TC_CTRLC_INVEN1_Pos 1 /**< \brief (TC_CTRLC) Output Waveform 1 Invert Enable */ +#define TC_CTRLC_INVEN1 (1 << TC_CTRLC_INVEN1_Pos) +#define TC_CTRLC_INVEN_Pos 0 /**< \brief (TC_CTRLC) Output Waveform x Invert Enable */ +#define TC_CTRLC_INVEN_Msk (0x3u << TC_CTRLC_INVEN_Pos) +#define TC_CTRLC_INVEN(value) ((TC_CTRLC_INVEN_Msk & ((value) << TC_CTRLC_INVEN_Pos))) +#define TC_CTRLC_CPTEN0_Pos 4 /**< \brief (TC_CTRLC) Capture Channel 0 Enable */ +#define TC_CTRLC_CPTEN0 (1 << TC_CTRLC_CPTEN0_Pos) +#define TC_CTRLC_CPTEN1_Pos 5 /**< \brief (TC_CTRLC) Capture Channel 1 Enable */ +#define TC_CTRLC_CPTEN1 (1 << TC_CTRLC_CPTEN1_Pos) +#define TC_CTRLC_CPTEN_Pos 4 /**< \brief (TC_CTRLC) Capture Channel x Enable */ +#define TC_CTRLC_CPTEN_Msk (0x3u << TC_CTRLC_CPTEN_Pos) +#define TC_CTRLC_CPTEN(value) ((TC_CTRLC_CPTEN_Msk & ((value) << TC_CTRLC_CPTEN_Pos))) +#define TC_CTRLC_MASK 0x33u /**< \brief (TC_CTRLC) MASK Register */ + +/* -------- TC_DBGCTRL : (TC Offset: 0x08) (R/W 8) Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGRUN:1; /*!< bit: 0 Debug Run Mode */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_DBGCTRL_OFFSET 0x08 /**< \brief (TC_DBGCTRL offset) Debug Control */ +#define TC_DBGCTRL_RESETVALUE 0x00 /**< \brief (TC_DBGCTRL reset_value) Debug Control */ + +#define TC_DBGCTRL_DBGRUN_Pos 0 /**< \brief (TC_DBGCTRL) Debug Run Mode */ +#define TC_DBGCTRL_DBGRUN (0x1u << TC_DBGCTRL_DBGRUN_Pos) +#define TC_DBGCTRL_MASK 0x01u /**< \brief (TC_DBGCTRL) MASK Register */ + +/* -------- TC_EVCTRL : (TC Offset: 0x0A) (R/W 16) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t EVACT:3; /*!< bit: 0.. 2 Event Action */ + uint16_t :1; /*!< bit: 3 Reserved */ + uint16_t TCINV:1; /*!< bit: 4 TC Inverted Event Input */ + uint16_t TCEI:1; /*!< bit: 5 TC Event Input */ + uint16_t :2; /*!< bit: 6.. 7 Reserved */ + uint16_t OVFEO:1; /*!< bit: 8 Overflow/Underflow Event Output Enable */ + uint16_t :3; /*!< bit: 9..11 Reserved */ + uint16_t MCEO0:1; /*!< bit: 12 Match or Capture Channel 0 Event Output Enable */ + uint16_t MCEO1:1; /*!< bit: 13 Match or Capture Channel 1 Event Output Enable */ + uint16_t :2; /*!< bit: 14..15 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t :12; /*!< bit: 0..11 Reserved */ + uint16_t MCEO:2; /*!< bit: 12..13 Match or Capture Channel x Event Output Enable */ + uint16_t :2; /*!< bit: 14..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} TC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_EVCTRL_OFFSET 0x0A /**< \brief (TC_EVCTRL offset) Event Control */ +#define TC_EVCTRL_RESETVALUE 0x0000 /**< \brief (TC_EVCTRL reset_value) Event Control */ + +#define TC_EVCTRL_EVACT_Pos 0 /**< \brief (TC_EVCTRL) Event Action */ +#define TC_EVCTRL_EVACT_Msk (0x7u << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT(value) ((TC_EVCTRL_EVACT_Msk & ((value) << TC_EVCTRL_EVACT_Pos))) +#define TC_EVCTRL_EVACT_OFF_Val 0x0u /**< \brief (TC_EVCTRL) Event action disabled */ +#define TC_EVCTRL_EVACT_RETRIGGER_Val 0x1u /**< \brief (TC_EVCTRL) Start, restart or retrigger TC on event */ +#define TC_EVCTRL_EVACT_COUNT_Val 0x2u /**< \brief (TC_EVCTRL) Count on event */ +#define TC_EVCTRL_EVACT_START_Val 0x3u /**< \brief (TC_EVCTRL) Start TC on event */ +#define TC_EVCTRL_EVACT_PPW_Val 0x5u /**< \brief (TC_EVCTRL) Period captured into CC0 Pulse Width in CC1 */ +#define TC_EVCTRL_EVACT_PWP_Val 0x6u /**< \brief (TC_EVCTRL) Period captured into CC1 Pulse Width on CC0 */ +#define TC_EVCTRL_EVACT_OFF (TC_EVCTRL_EVACT_OFF_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT_RETRIGGER (TC_EVCTRL_EVACT_RETRIGGER_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT_COUNT (TC_EVCTRL_EVACT_COUNT_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT_START (TC_EVCTRL_EVACT_START_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT_PPW (TC_EVCTRL_EVACT_PPW_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_EVACT_PWP (TC_EVCTRL_EVACT_PWP_Val << TC_EVCTRL_EVACT_Pos) +#define TC_EVCTRL_TCINV_Pos 4 /**< \brief (TC_EVCTRL) TC Inverted Event Input */ +#define TC_EVCTRL_TCINV (0x1u << TC_EVCTRL_TCINV_Pos) +#define TC_EVCTRL_TCEI_Pos 5 /**< \brief (TC_EVCTRL) TC Event Input */ +#define TC_EVCTRL_TCEI (0x1u << TC_EVCTRL_TCEI_Pos) +#define TC_EVCTRL_OVFEO_Pos 8 /**< \brief (TC_EVCTRL) Overflow/Underflow Event Output Enable */ +#define TC_EVCTRL_OVFEO (0x1u << TC_EVCTRL_OVFEO_Pos) +#define TC_EVCTRL_MCEO0_Pos 12 /**< \brief (TC_EVCTRL) Match or Capture Channel 0 Event Output Enable */ +#define TC_EVCTRL_MCEO0 (1 << TC_EVCTRL_MCEO0_Pos) +#define TC_EVCTRL_MCEO1_Pos 13 /**< \brief (TC_EVCTRL) Match or Capture Channel 1 Event Output Enable */ +#define TC_EVCTRL_MCEO1 (1 << TC_EVCTRL_MCEO1_Pos) +#define TC_EVCTRL_MCEO_Pos 12 /**< \brief (TC_EVCTRL) Match or Capture Channel x Event Output Enable */ +#define TC_EVCTRL_MCEO_Msk (0x3u << TC_EVCTRL_MCEO_Pos) +#define TC_EVCTRL_MCEO(value) ((TC_EVCTRL_MCEO_Msk & ((value) << TC_EVCTRL_MCEO_Pos))) +#define TC_EVCTRL_MASK 0x3137u /**< \brief (TC_EVCTRL) MASK Register */ + +/* -------- TC_INTENCLR : (TC Offset: 0x0C) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t OVF:1; /*!< bit: 0 Overflow Interrupt Enable */ + uint8_t ERR:1; /*!< bit: 1 Error Interrupt Enable */ + uint8_t :1; /*!< bit: 2 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t MC0:1; /*!< bit: 4 Match or Capture Channel 0 Interrupt Enable */ + uint8_t MC1:1; /*!< bit: 5 Match or Capture Channel 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t :4; /*!< bit: 0.. 3 Reserved */ + uint8_t MC:2; /*!< bit: 4.. 5 Match or Capture Channel x Interrupt Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} TC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_INTENCLR_OFFSET 0x0C /**< \brief (TC_INTENCLR offset) Interrupt Enable Clear */ +#define TC_INTENCLR_RESETVALUE 0x00 /**< \brief (TC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define TC_INTENCLR_OVF_Pos 0 /**< \brief (TC_INTENCLR) Overflow Interrupt Enable */ +#define TC_INTENCLR_OVF (0x1u << TC_INTENCLR_OVF_Pos) +#define TC_INTENCLR_ERR_Pos 1 /**< \brief (TC_INTENCLR) Error Interrupt Enable */ +#define TC_INTENCLR_ERR (0x1u << TC_INTENCLR_ERR_Pos) +#define TC_INTENCLR_SYNCRDY_Pos 3 /**< \brief (TC_INTENCLR) Synchronization Ready Interrupt Enable */ +#define TC_INTENCLR_SYNCRDY (0x1u << TC_INTENCLR_SYNCRDY_Pos) +#define TC_INTENCLR_MC0_Pos 4 /**< \brief (TC_INTENCLR) Match or Capture Channel 0 Interrupt Enable */ +#define TC_INTENCLR_MC0 (1 << TC_INTENCLR_MC0_Pos) +#define TC_INTENCLR_MC1_Pos 5 /**< \brief (TC_INTENCLR) Match or Capture Channel 1 Interrupt Enable */ +#define TC_INTENCLR_MC1 (1 << TC_INTENCLR_MC1_Pos) +#define TC_INTENCLR_MC_Pos 4 /**< \brief (TC_INTENCLR) Match or Capture Channel x Interrupt Enable */ +#define TC_INTENCLR_MC_Msk (0x3u << TC_INTENCLR_MC_Pos) +#define TC_INTENCLR_MC(value) ((TC_INTENCLR_MC_Msk & ((value) << TC_INTENCLR_MC_Pos))) +#define TC_INTENCLR_MASK 0x3Bu /**< \brief (TC_INTENCLR) MASK Register */ + +/* -------- TC_INTENSET : (TC Offset: 0x0D) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t OVF:1; /*!< bit: 0 Overflow Interrupt Enable */ + uint8_t ERR:1; /*!< bit: 1 Error Interrupt Enable */ + uint8_t :1; /*!< bit: 2 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t MC0:1; /*!< bit: 4 Match or Capture Channel 0 Interrupt Enable */ + uint8_t MC1:1; /*!< bit: 5 Match or Capture Channel 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t :4; /*!< bit: 0.. 3 Reserved */ + uint8_t MC:2; /*!< bit: 4.. 5 Match or Capture Channel x Interrupt Enable */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} TC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_INTENSET_OFFSET 0x0D /**< \brief (TC_INTENSET offset) Interrupt Enable Set */ +#define TC_INTENSET_RESETVALUE 0x00 /**< \brief (TC_INTENSET reset_value) Interrupt Enable Set */ + +#define TC_INTENSET_OVF_Pos 0 /**< \brief (TC_INTENSET) Overflow Interrupt Enable */ +#define TC_INTENSET_OVF (0x1u << TC_INTENSET_OVF_Pos) +#define TC_INTENSET_ERR_Pos 1 /**< \brief (TC_INTENSET) Error Interrupt Enable */ +#define TC_INTENSET_ERR (0x1u << TC_INTENSET_ERR_Pos) +#define TC_INTENSET_SYNCRDY_Pos 3 /**< \brief (TC_INTENSET) Synchronization Ready Interrupt Enable */ +#define TC_INTENSET_SYNCRDY (0x1u << TC_INTENSET_SYNCRDY_Pos) +#define TC_INTENSET_MC0_Pos 4 /**< \brief (TC_INTENSET) Match or Capture Channel 0 Interrupt Enable */ +#define TC_INTENSET_MC0 (1 << TC_INTENSET_MC0_Pos) +#define TC_INTENSET_MC1_Pos 5 /**< \brief (TC_INTENSET) Match or Capture Channel 1 Interrupt Enable */ +#define TC_INTENSET_MC1 (1 << TC_INTENSET_MC1_Pos) +#define TC_INTENSET_MC_Pos 4 /**< \brief (TC_INTENSET) Match or Capture Channel x Interrupt Enable */ +#define TC_INTENSET_MC_Msk (0x3u << TC_INTENSET_MC_Pos) +#define TC_INTENSET_MC(value) ((TC_INTENSET_MC_Msk & ((value) << TC_INTENSET_MC_Pos))) +#define TC_INTENSET_MASK 0x3Bu /**< \brief (TC_INTENSET) MASK Register */ + +/* -------- TC_INTFLAG : (TC Offset: 0x0E) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t OVF:1; /*!< bit: 0 Overflow */ + uint8_t ERR:1; /*!< bit: 1 Error */ + uint8_t :1; /*!< bit: 2 Reserved */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready */ + uint8_t MC0:1; /*!< bit: 4 Match or Capture Channel 0 */ + uint8_t MC1:1; /*!< bit: 5 Match or Capture Channel 1 */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t :4; /*!< bit: 0.. 3 Reserved */ + uint8_t MC:2; /*!< bit: 4.. 5 Match or Capture Channel x */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} TC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_INTFLAG_OFFSET 0x0E /**< \brief (TC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define TC_INTFLAG_RESETVALUE 0x00 /**< \brief (TC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define TC_INTFLAG_OVF_Pos 0 /**< \brief (TC_INTFLAG) Overflow */ +#define TC_INTFLAG_OVF (0x1u << TC_INTFLAG_OVF_Pos) +#define TC_INTFLAG_ERR_Pos 1 /**< \brief (TC_INTFLAG) Error */ +#define TC_INTFLAG_ERR (0x1u << TC_INTFLAG_ERR_Pos) +#define TC_INTFLAG_SYNCRDY_Pos 3 /**< \brief (TC_INTFLAG) Synchronization Ready */ +#define TC_INTFLAG_SYNCRDY (0x1u << TC_INTFLAG_SYNCRDY_Pos) +#define TC_INTFLAG_MC0_Pos 4 /**< \brief (TC_INTFLAG) Match or Capture Channel 0 */ +#define TC_INTFLAG_MC0 (1 << TC_INTFLAG_MC0_Pos) +#define TC_INTFLAG_MC1_Pos 5 /**< \brief (TC_INTFLAG) Match or Capture Channel 1 */ +#define TC_INTFLAG_MC1 (1 << TC_INTFLAG_MC1_Pos) +#define TC_INTFLAG_MC_Pos 4 /**< \brief (TC_INTFLAG) Match or Capture Channel x */ +#define TC_INTFLAG_MC_Msk (0x3u << TC_INTFLAG_MC_Pos) +#define TC_INTFLAG_MC(value) ((TC_INTFLAG_MC_Msk & ((value) << TC_INTFLAG_MC_Pos))) +#define TC_INTFLAG_MASK 0x3Bu /**< \brief (TC_INTFLAG) MASK Register */ + +/* -------- TC_STATUS : (TC Offset: 0x0F) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :3; /*!< bit: 0.. 2 Reserved */ + uint8_t STOP:1; /*!< bit: 3 Stop */ + uint8_t SLAVE:1; /*!< bit: 4 Slave */ + uint8_t :2; /*!< bit: 5.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_STATUS_OFFSET 0x0F /**< \brief (TC_STATUS offset) Status */ +#define TC_STATUS_RESETVALUE 0x08 /**< \brief (TC_STATUS reset_value) Status */ + +#define TC_STATUS_STOP_Pos 3 /**< \brief (TC_STATUS) Stop */ +#define TC_STATUS_STOP (0x1u << TC_STATUS_STOP_Pos) +#define TC_STATUS_SLAVE_Pos 4 /**< \brief (TC_STATUS) Slave */ +#define TC_STATUS_SLAVE (0x1u << TC_STATUS_SLAVE_Pos) +#define TC_STATUS_SYNCBUSY_Pos 7 /**< \brief (TC_STATUS) Synchronization Busy */ +#define TC_STATUS_SYNCBUSY (0x1u << TC_STATUS_SYNCBUSY_Pos) +#define TC_STATUS_MASK 0x98u /**< \brief (TC_STATUS) MASK Register */ + +/* -------- TC_COUNT16_COUNT : (TC Offset: 0x10) (R/W 16) COUNT16 COUNT16 Counter Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t COUNT:16; /*!< bit: 0..15 Counter Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} TC_COUNT16_COUNT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT16_COUNT_OFFSET 0x10 /**< \brief (TC_COUNT16_COUNT offset) COUNT16 Counter Value */ +#define TC_COUNT16_COUNT_RESETVALUE 0x0000 /**< \brief (TC_COUNT16_COUNT reset_value) COUNT16 Counter Value */ + +#define TC_COUNT16_COUNT_COUNT_Pos 0 /**< \brief (TC_COUNT16_COUNT) Counter Value */ +#define TC_COUNT16_COUNT_COUNT_Msk (0xFFFFu << TC_COUNT16_COUNT_COUNT_Pos) +#define TC_COUNT16_COUNT_COUNT(value) ((TC_COUNT16_COUNT_COUNT_Msk & ((value) << TC_COUNT16_COUNT_COUNT_Pos))) +#define TC_COUNT16_COUNT_MASK 0xFFFFu /**< \brief (TC_COUNT16_COUNT) MASK Register */ + +/* -------- TC_COUNT32_COUNT : (TC Offset: 0x10) (R/W 32) COUNT32 COUNT32 Counter Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t COUNT:32; /*!< bit: 0..31 Counter Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} TC_COUNT32_COUNT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT32_COUNT_OFFSET 0x10 /**< \brief (TC_COUNT32_COUNT offset) COUNT32 Counter Value */ +#define TC_COUNT32_COUNT_RESETVALUE 0x00000000 /**< \brief (TC_COUNT32_COUNT reset_value) COUNT32 Counter Value */ + +#define TC_COUNT32_COUNT_COUNT_Pos 0 /**< \brief (TC_COUNT32_COUNT) Counter Value */ +#define TC_COUNT32_COUNT_COUNT_Msk (0xFFFFFFFFu << TC_COUNT32_COUNT_COUNT_Pos) +#define TC_COUNT32_COUNT_COUNT(value) ((TC_COUNT32_COUNT_COUNT_Msk & ((value) << TC_COUNT32_COUNT_COUNT_Pos))) +#define TC_COUNT32_COUNT_MASK 0xFFFFFFFFu /**< \brief (TC_COUNT32_COUNT) MASK Register */ + +/* -------- TC_COUNT8_COUNT : (TC Offset: 0x10) (R/W 8) COUNT8 COUNT8 Counter Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COUNT:8; /*!< bit: 0.. 7 Counter Value */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_COUNT8_COUNT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT8_COUNT_OFFSET 0x10 /**< \brief (TC_COUNT8_COUNT offset) COUNT8 Counter Value */ +#define TC_COUNT8_COUNT_RESETVALUE 0x00 /**< \brief (TC_COUNT8_COUNT reset_value) COUNT8 Counter Value */ + +#define TC_COUNT8_COUNT_COUNT_Pos 0 /**< \brief (TC_COUNT8_COUNT) Counter Value */ +#define TC_COUNT8_COUNT_COUNT_Msk (0xFFu << TC_COUNT8_COUNT_COUNT_Pos) +#define TC_COUNT8_COUNT_COUNT(value) ((TC_COUNT8_COUNT_COUNT_Msk & ((value) << TC_COUNT8_COUNT_COUNT_Pos))) +#define TC_COUNT8_COUNT_MASK 0xFFu /**< \brief (TC_COUNT8_COUNT) MASK Register */ + +/* -------- TC_COUNT8_PER : (TC Offset: 0x14) (R/W 8) COUNT8 COUNT8 Period Value -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PER:8; /*!< bit: 0.. 7 Period Value */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_COUNT8_PER_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT8_PER_OFFSET 0x14 /**< \brief (TC_COUNT8_PER offset) COUNT8 Period Value */ +#define TC_COUNT8_PER_RESETVALUE 0xFF /**< \brief (TC_COUNT8_PER reset_value) COUNT8 Period Value */ + +#define TC_COUNT8_PER_PER_Pos 0 /**< \brief (TC_COUNT8_PER) Period Value */ +#define TC_COUNT8_PER_PER_Msk (0xFFu << TC_COUNT8_PER_PER_Pos) +#define TC_COUNT8_PER_PER(value) ((TC_COUNT8_PER_PER_Msk & ((value) << TC_COUNT8_PER_PER_Pos))) +#define TC_COUNT8_PER_MASK 0xFFu /**< \brief (TC_COUNT8_PER) MASK Register */ + +/* -------- TC_COUNT16_CC : (TC Offset: 0x18) (R/W 16) COUNT16 COUNT16 Compare/Capture -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t CC:16; /*!< bit: 0..15 Compare/Capture Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} TC_COUNT16_CC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT16_CC_OFFSET 0x18 /**< \brief (TC_COUNT16_CC offset) COUNT16 Compare/Capture */ +#define TC_COUNT16_CC_RESETVALUE 0x0000 /**< \brief (TC_COUNT16_CC reset_value) COUNT16 Compare/Capture */ + +#define TC_COUNT16_CC_CC_Pos 0 /**< \brief (TC_COUNT16_CC) Compare/Capture Value */ +#define TC_COUNT16_CC_CC_Msk (0xFFFFu << TC_COUNT16_CC_CC_Pos) +#define TC_COUNT16_CC_CC(value) ((TC_COUNT16_CC_CC_Msk & ((value) << TC_COUNT16_CC_CC_Pos))) +#define TC_COUNT16_CC_MASK 0xFFFFu /**< \brief (TC_COUNT16_CC) MASK Register */ + +/* -------- TC_COUNT32_CC : (TC Offset: 0x18) (R/W 32) COUNT32 COUNT32 Compare/Capture -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CC:32; /*!< bit: 0..31 Compare/Capture Value */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} TC_COUNT32_CC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT32_CC_OFFSET 0x18 /**< \brief (TC_COUNT32_CC offset) COUNT32 Compare/Capture */ +#define TC_COUNT32_CC_RESETVALUE 0x00000000 /**< \brief (TC_COUNT32_CC reset_value) COUNT32 Compare/Capture */ + +#define TC_COUNT32_CC_CC_Pos 0 /**< \brief (TC_COUNT32_CC) Compare/Capture Value */ +#define TC_COUNT32_CC_CC_Msk (0xFFFFFFFFu << TC_COUNT32_CC_CC_Pos) +#define TC_COUNT32_CC_CC(value) ((TC_COUNT32_CC_CC_Msk & ((value) << TC_COUNT32_CC_CC_Pos))) +#define TC_COUNT32_CC_MASK 0xFFFFFFFFu /**< \brief (TC_COUNT32_CC) MASK Register */ + +/* -------- TC_COUNT8_CC : (TC Offset: 0x18) (R/W 8) COUNT8 COUNT8 Compare/Capture -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CC:8; /*!< bit: 0.. 7 Compare/Capture Value */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} TC_COUNT8_CC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define TC_COUNT8_CC_OFFSET 0x18 /**< \brief (TC_COUNT8_CC offset) COUNT8 Compare/Capture */ +#define TC_COUNT8_CC_RESETVALUE 0x00 /**< \brief (TC_COUNT8_CC reset_value) COUNT8 Compare/Capture */ + +#define TC_COUNT8_CC_CC_Pos 0 /**< \brief (TC_COUNT8_CC) Compare/Capture Value */ +#define TC_COUNT8_CC_CC_Msk (0xFFu << TC_COUNT8_CC_CC_Pos) +#define TC_COUNT8_CC_CC(value) ((TC_COUNT8_CC_CC_Msk & ((value) << TC_COUNT8_CC_CC_Pos))) +#define TC_COUNT8_CC_MASK 0xFFu /**< \brief (TC_COUNT8_CC) MASK Register */ + +/** \brief TC_COUNT8 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* 8-bit Counter Mode */ + __IO TC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 16) Control A */ + __IO TC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO TC_CTRLBCLR_Type CTRLBCLR; /**< \brief Offset: 0x04 (R/W 8) Control B Clear */ + __IO TC_CTRLBSET_Type CTRLBSET; /**< \brief Offset: 0x05 (R/W 8) Control B Set */ + __IO TC_CTRLC_Type CTRLC; /**< \brief Offset: 0x06 (R/W 8) Control C */ + RoReg8 Reserved1[0x1]; + __IO TC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) Debug Control */ + RoReg8 Reserved2[0x1]; + __IO TC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x0A (R/W 16) Event Control */ + __IO TC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) Interrupt Enable Clear */ + __IO TC_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) Interrupt Enable Set */ + __IO TC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) Interrupt Flag Status and Clear */ + __I TC_STATUS_Type STATUS; /**< \brief Offset: 0x0F (R/ 8) Status */ + __IO TC_COUNT8_COUNT_Type COUNT; /**< \brief Offset: 0x10 (R/W 8) COUNT8 Counter Value */ + RoReg8 Reserved3[0x3]; + __IO TC_COUNT8_PER_Type PER; /**< \brief Offset: 0x14 (R/W 8) COUNT8 Period Value */ + RoReg8 Reserved4[0x3]; + __IO TC_COUNT8_CC_Type CC[2]; /**< \brief Offset: 0x18 (R/W 8) COUNT8 Compare/Capture */ +} TcCount8; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief TC_COUNT16 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* 16-bit Counter Mode */ + __IO TC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 16) Control A */ + __IO TC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO TC_CTRLBCLR_Type CTRLBCLR; /**< \brief Offset: 0x04 (R/W 8) Control B Clear */ + __IO TC_CTRLBSET_Type CTRLBSET; /**< \brief Offset: 0x05 (R/W 8) Control B Set */ + __IO TC_CTRLC_Type CTRLC; /**< \brief Offset: 0x06 (R/W 8) Control C */ + RoReg8 Reserved1[0x1]; + __IO TC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) Debug Control */ + RoReg8 Reserved2[0x1]; + __IO TC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x0A (R/W 16) Event Control */ + __IO TC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) Interrupt Enable Clear */ + __IO TC_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) Interrupt Enable Set */ + __IO TC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) Interrupt Flag Status and Clear */ + __I TC_STATUS_Type STATUS; /**< \brief Offset: 0x0F (R/ 8) Status */ + __IO TC_COUNT16_COUNT_Type COUNT; /**< \brief Offset: 0x10 (R/W 16) COUNT16 Counter Value */ + RoReg8 Reserved3[0x6]; + __IO TC_COUNT16_CC_Type CC[2]; /**< \brief Offset: 0x18 (R/W 16) COUNT16 Compare/Capture */ +} TcCount16; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/** \brief TC_COUNT32 hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { /* 32-bit Counter Mode */ + __IO TC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 16) Control A */ + __IO TC_READREQ_Type READREQ; /**< \brief Offset: 0x02 (R/W 16) Read Request */ + __IO TC_CTRLBCLR_Type CTRLBCLR; /**< \brief Offset: 0x04 (R/W 8) Control B Clear */ + __IO TC_CTRLBSET_Type CTRLBSET; /**< \brief Offset: 0x05 (R/W 8) Control B Set */ + __IO TC_CTRLC_Type CTRLC; /**< \brief Offset: 0x06 (R/W 8) Control C */ + RoReg8 Reserved1[0x1]; + __IO TC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x08 (R/W 8) Debug Control */ + RoReg8 Reserved2[0x1]; + __IO TC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x0A (R/W 16) Event Control */ + __IO TC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x0C (R/W 8) Interrupt Enable Clear */ + __IO TC_INTENSET_Type INTENSET; /**< \brief Offset: 0x0D (R/W 8) Interrupt Enable Set */ + __IO TC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x0E (R/W 8) Interrupt Flag Status and Clear */ + __I TC_STATUS_Type STATUS; /**< \brief Offset: 0x0F (R/ 8) Status */ + __IO TC_COUNT32_COUNT_Type COUNT; /**< \brief Offset: 0x10 (R/W 32) COUNT32 Counter Value */ + RoReg8 Reserved3[0x4]; + __IO TC_COUNT32_CC_Type CC[2]; /**< \brief Offset: 0x18 (R/W 32) COUNT32 Compare/Capture */ +} TcCount32; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + TcCount8 COUNT8; /**< \brief Offset: 0x00 8-bit Counter Mode */ + TcCount16 COUNT16; /**< \brief Offset: 0x00 16-bit Counter Mode */ + TcCount32 COUNT32; /**< \brief Offset: 0x00 32-bit Counter Mode */ +} Tc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_TC_COMPONENT_ */ diff --git a/loader/samd20/component/wdt.h b/loader/samd20/component/wdt.h new file mode 100644 index 0000000..4fd1cdb --- /dev/null +++ b/loader/samd20/component/wdt.h @@ -0,0 +1,303 @@ +/** + * \file + * + * \brief Component description for WDT + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_WDT_COMPONENT_ +#define _SAMD20_WDT_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR WDT */ +/* ========================================================================== */ +/** \addtogroup SAMD20_WDT Watchdog Timer */ +/*@{*/ + +#define WDT_U2203 +#define REV_WDT 0x200 + +/* -------- WDT_CTRL : (WDT Offset: 0x0) (R/W 8) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :1; /*!< bit: 0 Reserved */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t WEN:1; /*!< bit: 2 Watchdog Timer Window Mode Enable */ + uint8_t :4; /*!< bit: 3.. 6 Reserved */ + uint8_t ALWAYSON:1; /*!< bit: 7 Always-On */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_CTRL_OFFSET 0x0 /**< \brief (WDT_CTRL offset) Control */ +#define WDT_CTRL_RESETVALUE 0x00 /**< \brief (WDT_CTRL reset_value) Control */ + +#define WDT_CTRL_ENABLE_Pos 1 /**< \brief (WDT_CTRL) Enable */ +#define WDT_CTRL_ENABLE (0x1u << WDT_CTRL_ENABLE_Pos) +#define WDT_CTRL_WEN_Pos 2 /**< \brief (WDT_CTRL) Watchdog Timer Window Mode Enable */ +#define WDT_CTRL_WEN (0x1u << WDT_CTRL_WEN_Pos) +#define WDT_CTRL_ALWAYSON_Pos 7 /**< \brief (WDT_CTRL) Always-On */ +#define WDT_CTRL_ALWAYSON (0x1u << WDT_CTRL_ALWAYSON_Pos) +#define WDT_CTRL_MASK 0x86u /**< \brief (WDT_CTRL) MASK Register */ + +/* -------- WDT_CONFIG : (WDT Offset: 0x1) (R/W 8) Configuration -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PER:4; /*!< bit: 0.. 3 Time-Out Period */ + uint8_t WINDOW:4; /*!< bit: 4.. 7 Window Mode Time-Out Period */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_CONFIG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_CONFIG_OFFSET 0x1 /**< \brief (WDT_CONFIG offset) Configuration */ +#define WDT_CONFIG_RESETVALUE 0xBB /**< \brief (WDT_CONFIG reset_value) Configuration */ + +#define WDT_CONFIG_PER_Pos 0 /**< \brief (WDT_CONFIG) Time-Out Period */ +#define WDT_CONFIG_PER_Msk (0xFu << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER(value) ((WDT_CONFIG_PER_Msk & ((value) << WDT_CONFIG_PER_Pos))) +#define WDT_CONFIG_PER_0_Val 0x0u /**< \brief (WDT_CONFIG) 8 clock cycles */ +#define WDT_CONFIG_PER_1_Val 0x1u /**< \brief (WDT_CONFIG) 16 clock cycles */ +#define WDT_CONFIG_PER_2_Val 0x2u /**< \brief (WDT_CONFIG) 32 clock cycles */ +#define WDT_CONFIG_PER_3_Val 0x3u /**< \brief (WDT_CONFIG) 64 clock cycles */ +#define WDT_CONFIG_PER_4_Val 0x4u /**< \brief (WDT_CONFIG) 128 clock cycles */ +#define WDT_CONFIG_PER_5_Val 0x5u /**< \brief (WDT_CONFIG) 256 clock cycles */ +#define WDT_CONFIG_PER_6_Val 0x6u /**< \brief (WDT_CONFIG) 512 clock cycles */ +#define WDT_CONFIG_PER_7_Val 0x7u /**< \brief (WDT_CONFIG) 1024 clock cycles */ +#define WDT_CONFIG_PER_8_Val 0x8u /**< \brief (WDT_CONFIG) 2048 clock cycles */ +#define WDT_CONFIG_PER_9_Val 0x9u /**< \brief (WDT_CONFIG) 4096 clock cycles */ +#define WDT_CONFIG_PER_10_Val 0xAu /**< \brief (WDT_CONFIG) 8192 clock cycles */ +#define WDT_CONFIG_PER_11_Val 0xBu /**< \brief (WDT_CONFIG) 16384 clock cycles */ +#define WDT_CONFIG_PER_0 (WDT_CONFIG_PER_0_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_1 (WDT_CONFIG_PER_1_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_2 (WDT_CONFIG_PER_2_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_3 (WDT_CONFIG_PER_3_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_4 (WDT_CONFIG_PER_4_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_5 (WDT_CONFIG_PER_5_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_6 (WDT_CONFIG_PER_6_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_7 (WDT_CONFIG_PER_7_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_8 (WDT_CONFIG_PER_8_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_9 (WDT_CONFIG_PER_9_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_10 (WDT_CONFIG_PER_10_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_PER_11 (WDT_CONFIG_PER_11_Val << WDT_CONFIG_PER_Pos) +#define WDT_CONFIG_WINDOW_Pos 4 /**< \brief (WDT_CONFIG) Window Mode Time-Out Period */ +#define WDT_CONFIG_WINDOW_Msk (0xFu << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW(value) ((WDT_CONFIG_WINDOW_Msk & ((value) << WDT_CONFIG_WINDOW_Pos))) +#define WDT_CONFIG_WINDOW_0_Val 0x0u /**< \brief (WDT_CONFIG) 8 clock cycles */ +#define WDT_CONFIG_WINDOW_1_Val 0x1u /**< \brief (WDT_CONFIG) 16 clock cycles */ +#define WDT_CONFIG_WINDOW_2_Val 0x2u /**< \brief (WDT_CONFIG) 32 clock cycles */ +#define WDT_CONFIG_WINDOW_3_Val 0x3u /**< \brief (WDT_CONFIG) 64 clock cycles */ +#define WDT_CONFIG_WINDOW_4_Val 0x4u /**< \brief (WDT_CONFIG) 128 clock cycles */ +#define WDT_CONFIG_WINDOW_5_Val 0x5u /**< \brief (WDT_CONFIG) 256 clock cycles */ +#define WDT_CONFIG_WINDOW_6_Val 0x6u /**< \brief (WDT_CONFIG) 512 clock cycles */ +#define WDT_CONFIG_WINDOW_7_Val 0x7u /**< \brief (WDT_CONFIG) 1024 clock cycles */ +#define WDT_CONFIG_WINDOW_8_Val 0x8u /**< \brief (WDT_CONFIG) 2048 clock cycles */ +#define WDT_CONFIG_WINDOW_9_Val 0x9u /**< \brief (WDT_CONFIG) 4096 clock cycles */ +#define WDT_CONFIG_WINDOW_10_Val 0xAu /**< \brief (WDT_CONFIG) 8192 clock cycles */ +#define WDT_CONFIG_WINDOW_11_Val 0xBu /**< \brief (WDT_CONFIG) 16384 clock cycles */ +#define WDT_CONFIG_WINDOW_0 (WDT_CONFIG_WINDOW_0_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_1 (WDT_CONFIG_WINDOW_1_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_2 (WDT_CONFIG_WINDOW_2_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_3 (WDT_CONFIG_WINDOW_3_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_4 (WDT_CONFIG_WINDOW_4_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_5 (WDT_CONFIG_WINDOW_5_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_6 (WDT_CONFIG_WINDOW_6_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_7 (WDT_CONFIG_WINDOW_7_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_8 (WDT_CONFIG_WINDOW_8_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_9 (WDT_CONFIG_WINDOW_9_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_10 (WDT_CONFIG_WINDOW_10_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_WINDOW_11 (WDT_CONFIG_WINDOW_11_Val << WDT_CONFIG_WINDOW_Pos) +#define WDT_CONFIG_MASK 0xFFu /**< \brief (WDT_CONFIG) MASK Register */ + +/* -------- WDT_EWCTRL : (WDT Offset: 0x2) (R/W 8) Early Warning Interrupt Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EWOFFSET:4; /*!< bit: 0.. 3 Early Warning Interrupt Time Offset */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_EWCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_EWCTRL_OFFSET 0x2 /**< \brief (WDT_EWCTRL offset) Early Warning Interrupt Control */ +#define WDT_EWCTRL_RESETVALUE 0x0B /**< \brief (WDT_EWCTRL reset_value) Early Warning Interrupt Control */ + +#define WDT_EWCTRL_EWOFFSET_Pos 0 /**< \brief (WDT_EWCTRL) Early Warning Interrupt Time Offset */ +#define WDT_EWCTRL_EWOFFSET_Msk (0xFu << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET(value) ((WDT_EWCTRL_EWOFFSET_Msk & ((value) << WDT_EWCTRL_EWOFFSET_Pos))) +#define WDT_EWCTRL_EWOFFSET_0_Val 0x0u /**< \brief (WDT_EWCTRL) 8 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_1_Val 0x1u /**< \brief (WDT_EWCTRL) 16 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_2_Val 0x2u /**< \brief (WDT_EWCTRL) 32 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_3_Val 0x3u /**< \brief (WDT_EWCTRL) 64 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_4_Val 0x4u /**< \brief (WDT_EWCTRL) 128 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_5_Val 0x5u /**< \brief (WDT_EWCTRL) 256 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_6_Val 0x6u /**< \brief (WDT_EWCTRL) 512 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_7_Val 0x7u /**< \brief (WDT_EWCTRL) 1024 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_8_Val 0x8u /**< \brief (WDT_EWCTRL) 2048 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_9_Val 0x9u /**< \brief (WDT_EWCTRL) 4096 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_10_Val 0xAu /**< \brief (WDT_EWCTRL) 8192 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_11_Val 0xBu /**< \brief (WDT_EWCTRL) 16384 clock cycles */ +#define WDT_EWCTRL_EWOFFSET_0 (WDT_EWCTRL_EWOFFSET_0_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_1 (WDT_EWCTRL_EWOFFSET_1_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_2 (WDT_EWCTRL_EWOFFSET_2_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_3 (WDT_EWCTRL_EWOFFSET_3_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_4 (WDT_EWCTRL_EWOFFSET_4_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_5 (WDT_EWCTRL_EWOFFSET_5_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_6 (WDT_EWCTRL_EWOFFSET_6_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_7 (WDT_EWCTRL_EWOFFSET_7_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_8 (WDT_EWCTRL_EWOFFSET_8_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_9 (WDT_EWCTRL_EWOFFSET_9_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_10 (WDT_EWCTRL_EWOFFSET_10_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_EWOFFSET_11 (WDT_EWCTRL_EWOFFSET_11_Val << WDT_EWCTRL_EWOFFSET_Pos) +#define WDT_EWCTRL_MASK 0x0Fu /**< \brief (WDT_EWCTRL) MASK Register */ + +/* -------- WDT_INTENCLR : (WDT Offset: 0x4) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EW:1; /*!< bit: 0 Early Warning Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_INTENCLR_OFFSET 0x4 /**< \brief (WDT_INTENCLR offset) Interrupt Enable Clear */ +#define WDT_INTENCLR_RESETVALUE 0x00 /**< \brief (WDT_INTENCLR reset_value) Interrupt Enable Clear */ + +#define WDT_INTENCLR_EW_Pos 0 /**< \brief (WDT_INTENCLR) Early Warning Interrupt Enable */ +#define WDT_INTENCLR_EW (0x1u << WDT_INTENCLR_EW_Pos) +#define WDT_INTENCLR_MASK 0x01u /**< \brief (WDT_INTENCLR) MASK Register */ + +/* -------- WDT_INTENSET : (WDT Offset: 0x5) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EW:1; /*!< bit: 0 Early Warning Interrupt Enable */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_INTENSET_OFFSET 0x5 /**< \brief (WDT_INTENSET offset) Interrupt Enable Set */ +#define WDT_INTENSET_RESETVALUE 0x00 /**< \brief (WDT_INTENSET reset_value) Interrupt Enable Set */ + +#define WDT_INTENSET_EW_Pos 0 /**< \brief (WDT_INTENSET) Early Warning Interrupt Enable */ +#define WDT_INTENSET_EW (0x1u << WDT_INTENSET_EW_Pos) +#define WDT_INTENSET_MASK 0x01u /**< \brief (WDT_INTENSET) MASK Register */ + +/* -------- WDT_INTFLAG : (WDT Offset: 0x6) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EW:1; /*!< bit: 0 Early Warning */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_INTFLAG_OFFSET 0x6 /**< \brief (WDT_INTFLAG offset) Interrupt Flag Status and Clear */ +#define WDT_INTFLAG_RESETVALUE 0x00 /**< \brief (WDT_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define WDT_INTFLAG_EW_Pos 0 /**< \brief (WDT_INTFLAG) Early Warning */ +#define WDT_INTFLAG_EW (0x1u << WDT_INTFLAG_EW_Pos) +#define WDT_INTFLAG_MASK 0x01u /**< \brief (WDT_INTFLAG) MASK Register */ + +/* -------- WDT_STATUS : (WDT Offset: 0x7) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_STATUS_OFFSET 0x7 /**< \brief (WDT_STATUS offset) Status */ +#define WDT_STATUS_RESETVALUE 0x00 /**< \brief (WDT_STATUS reset_value) Status */ + +#define WDT_STATUS_SYNCBUSY_Pos 7 /**< \brief (WDT_STATUS) Synchronization Busy */ +#define WDT_STATUS_SYNCBUSY (0x1u << WDT_STATUS_SYNCBUSY_Pos) +#define WDT_STATUS_MASK 0x80u /**< \brief (WDT_STATUS) MASK Register */ + +/* -------- WDT_CLEAR : (WDT Offset: 0x8) ( /W 8) Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CLEAR:8; /*!< bit: 0.. 7 Watchdog Clear */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} WDT_CLEAR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define WDT_CLEAR_OFFSET 0x8 /**< \brief (WDT_CLEAR offset) Clear */ +#define WDT_CLEAR_RESETVALUE 0x00 /**< \brief (WDT_CLEAR reset_value) Clear */ + +#define WDT_CLEAR_CLEAR_Pos 0 /**< \brief (WDT_CLEAR) Watchdog Clear */ +#define WDT_CLEAR_CLEAR_Msk (0xFFu << WDT_CLEAR_CLEAR_Pos) +#define WDT_CLEAR_CLEAR(value) ((WDT_CLEAR_CLEAR_Msk & ((value) << WDT_CLEAR_CLEAR_Pos))) +#define WDT_CLEAR_CLEAR_KEY_Val 0xA5u /**< \brief (WDT_CLEAR) Clear Key */ +#define WDT_CLEAR_CLEAR_KEY (WDT_CLEAR_CLEAR_KEY_Val << WDT_CLEAR_CLEAR_Pos) +#define WDT_CLEAR_MASK 0xFFu /**< \brief (WDT_CLEAR) MASK Register */ + +/** \brief WDT hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO WDT_CTRL_Type CTRL; /**< \brief Offset: 0x0 (R/W 8) Control */ + __IO WDT_CONFIG_Type CONFIG; /**< \brief Offset: 0x1 (R/W 8) Configuration */ + __IO WDT_EWCTRL_Type EWCTRL; /**< \brief Offset: 0x2 (R/W 8) Early Warning Interrupt Control */ + RoReg8 Reserved1[0x1]; + __IO WDT_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x4 (R/W 8) Interrupt Enable Clear */ + __IO WDT_INTENSET_Type INTENSET; /**< \brief Offset: 0x5 (R/W 8) Interrupt Enable Set */ + __IO WDT_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x6 (R/W 8) Interrupt Flag Status and Clear */ + __I WDT_STATUS_Type STATUS; /**< \brief Offset: 0x7 (R/ 8) Status */ + __O WDT_CLEAR_Type CLEAR; /**< \brief Offset: 0x8 ( /W 8) Clear */ +} Wdt; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD20_WDT_COMPONENT_ */ diff --git a/loader/samd20/instance/ac.h b/loader/samd20/instance/ac.h new file mode 100644 index 0000000..ec37809 --- /dev/null +++ b/loader/samd20/instance/ac.h @@ -0,0 +1,87 @@ +/** + * \file + * + * \brief Instance description for AC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_AC_INSTANCE_ +#define _SAMD20_AC_INSTANCE_ + +/* ========== Register definition for AC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_AC_CTRLA (0x42004400U) /**< \brief (AC) Control A */ +#define REG_AC_CTRLB (0x42004401U) /**< \brief (AC) Control B */ +#define REG_AC_EVCTRL (0x42004402U) /**< \brief (AC) Event Control */ +#define REG_AC_INTENCLR (0x42004404U) /**< \brief (AC) Interrupt Enable Clear */ +#define REG_AC_INTENSET (0x42004405U) /**< \brief (AC) Interrupt Enable Set */ +#define REG_AC_INTFLAG (0x42004406U) /**< \brief (AC) Interrupt Flag Status and Clear */ +#define REG_AC_STATUSA (0x42004408U) /**< \brief (AC) Status A */ +#define REG_AC_STATUSB (0x42004409U) /**< \brief (AC) Status B */ +#define REG_AC_STATUSC (0x4200440AU) /**< \brief (AC) Status C */ +#define REG_AC_WINCTRL (0x4200440CU) /**< \brief (AC) Window Control */ +#define REG_AC_COMPCTRL0 (0x42004410U) /**< \brief (AC) Comparator Control 0 */ +#define REG_AC_COMPCTRL1 (0x42004414U) /**< \brief (AC) Comparator Control 1 */ +#define REG_AC_SCALER0 (0x42004420U) /**< \brief (AC) Scaler 0 */ +#define REG_AC_SCALER1 (0x42004421U) /**< \brief (AC) Scaler 1 */ +#else +#define REG_AC_CTRLA (*(RwReg8 *)0x42004400U) /**< \brief (AC) Control A */ +#define REG_AC_CTRLB (*(WoReg8 *)0x42004401U) /**< \brief (AC) Control B */ +#define REG_AC_EVCTRL (*(RwReg16*)0x42004402U) /**< \brief (AC) Event Control */ +#define REG_AC_INTENCLR (*(RwReg8 *)0x42004404U) /**< \brief (AC) Interrupt Enable Clear */ +#define REG_AC_INTENSET (*(RwReg8 *)0x42004405U) /**< \brief (AC) Interrupt Enable Set */ +#define REG_AC_INTFLAG (*(RwReg8 *)0x42004406U) /**< \brief (AC) Interrupt Flag Status and Clear */ +#define REG_AC_STATUSA (*(RoReg8 *)0x42004408U) /**< \brief (AC) Status A */ +#define REG_AC_STATUSB (*(RoReg8 *)0x42004409U) /**< \brief (AC) Status B */ +#define REG_AC_STATUSC (*(RoReg8 *)0x4200440AU) /**< \brief (AC) Status C */ +#define REG_AC_WINCTRL (*(RwReg8 *)0x4200440CU) /**< \brief (AC) Window Control */ +#define REG_AC_COMPCTRL0 (*(RwReg *)0x42004410U) /**< \brief (AC) Comparator Control 0 */ +#define REG_AC_COMPCTRL1 (*(RwReg *)0x42004414U) /**< \brief (AC) Comparator Control 1 */ +#define REG_AC_SCALER0 (*(RwReg8 *)0x42004420U) /**< \brief (AC) Scaler 0 */ +#define REG_AC_SCALER1 (*(RwReg8 *)0x42004421U) /**< \brief (AC) Scaler 1 */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for AC peripheral ========== */ +#define AC_CMP_NUM 2 +#define AC_GCLK_ID_ANA 25 +#define AC_GCLK_ID_DIG 24 +#define AC_NUM_CMP AC_CMP_NUM +#define AC_PAIRS 1 + +#endif /* _SAMD20_AC_INSTANCE_ */ diff --git a/loader/samd20/instance/adc.h b/loader/samd20/instance/adc.h new file mode 100644 index 0000000..315dace --- /dev/null +++ b/loader/samd20/instance/adc.h @@ -0,0 +1,98 @@ +/** + * \file + * + * \brief Instance description for ADC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_ADC_INSTANCE_ +#define _SAMD20_ADC_INSTANCE_ + +/* ========== Register definition for ADC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_ADC_CTRLA (0x42004000U) /**< \brief (ADC) Control A */ +#define REG_ADC_REFCTRL (0x42004001U) /**< \brief (ADC) Reference Control */ +#define REG_ADC_AVGCTRL (0x42004002U) /**< \brief (ADC) Average Control */ +#define REG_ADC_SAMPCTRL (0x42004003U) /**< \brief (ADC) Sampling Time Control */ +#define REG_ADC_CTRLB (0x42004004U) /**< \brief (ADC) Control B */ +#define REG_ADC_WINCTRL (0x42004008U) /**< \brief (ADC) Window Monitor Control */ +#define REG_ADC_SWTRIG (0x4200400CU) /**< \brief (ADC) Software Trigger */ +#define REG_ADC_INPUTCTRL (0x42004010U) /**< \brief (ADC) Inputs Control */ +#define REG_ADC_EVCTRL (0x42004014U) /**< \brief (ADC) Event Control */ +#define REG_ADC_INTENCLR (0x42004016U) /**< \brief (ADC) Interrupt Enable Clear */ +#define REG_ADC_INTENSET (0x42004017U) /**< \brief (ADC) Interrupt Enable Set */ +#define REG_ADC_INTFLAG (0x42004018U) /**< \brief (ADC) Interrupt Flag Status and Clear */ +#define REG_ADC_STATUS (0x42004019U) /**< \brief (ADC) Status */ +#define REG_ADC_RESULT (0x4200401AU) /**< \brief (ADC) Result */ +#define REG_ADC_WINLT (0x4200401CU) /**< \brief (ADC) Window Monitor Lower Threshold */ +#define REG_ADC_WINUT (0x42004020U) /**< \brief (ADC) Window Monitor Upper Threshold */ +#define REG_ADC_GAINCORR (0x42004024U) /**< \brief (ADC) Gain Correction */ +#define REG_ADC_OFFSETCORR (0x42004026U) /**< \brief (ADC) Offset Correction */ +#define REG_ADC_CALIB (0x42004028U) /**< \brief (ADC) Calibration */ +#define REG_ADC_DBGCTRL (0x4200402AU) /**< \brief (ADC) Debug Control */ +#else +#define REG_ADC_CTRLA (*(RwReg8 *)0x42004000U) /**< \brief (ADC) Control A */ +#define REG_ADC_REFCTRL (*(RwReg8 *)0x42004001U) /**< \brief (ADC) Reference Control */ +#define REG_ADC_AVGCTRL (*(RwReg8 *)0x42004002U) /**< \brief (ADC) Average Control */ +#define REG_ADC_SAMPCTRL (*(RwReg8 *)0x42004003U) /**< \brief (ADC) Sampling Time Control */ +#define REG_ADC_CTRLB (*(RwReg16*)0x42004004U) /**< \brief (ADC) Control B */ +#define REG_ADC_WINCTRL (*(RwReg8 *)0x42004008U) /**< \brief (ADC) Window Monitor Control */ +#define REG_ADC_SWTRIG (*(RwReg8 *)0x4200400CU) /**< \brief (ADC) Software Trigger */ +#define REG_ADC_INPUTCTRL (*(RwReg *)0x42004010U) /**< \brief (ADC) Inputs Control */ +#define REG_ADC_EVCTRL (*(RwReg8 *)0x42004014U) /**< \brief (ADC) Event Control */ +#define REG_ADC_INTENCLR (*(RwReg8 *)0x42004016U) /**< \brief (ADC) Interrupt Enable Clear */ +#define REG_ADC_INTENSET (*(RwReg8 *)0x42004017U) /**< \brief (ADC) Interrupt Enable Set */ +#define REG_ADC_INTFLAG (*(RwReg8 *)0x42004018U) /**< \brief (ADC) Interrupt Flag Status and Clear */ +#define REG_ADC_STATUS (*(RoReg8 *)0x42004019U) /**< \brief (ADC) Status */ +#define REG_ADC_RESULT (*(RoReg16*)0x4200401AU) /**< \brief (ADC) Result */ +#define REG_ADC_WINLT (*(RwReg16*)0x4200401CU) /**< \brief (ADC) Window Monitor Lower Threshold */ +#define REG_ADC_WINUT (*(RwReg16*)0x42004020U) /**< \brief (ADC) Window Monitor Upper Threshold */ +#define REG_ADC_GAINCORR (*(RwReg16*)0x42004024U) /**< \brief (ADC) Gain Correction */ +#define REG_ADC_OFFSETCORR (*(RwReg16*)0x42004026U) /**< \brief (ADC) Offset Correction */ +#define REG_ADC_CALIB (*(RwReg16*)0x42004028U) /**< \brief (ADC) Calibration */ +#define REG_ADC_DBGCTRL (*(RwReg8 *)0x4200402AU) /**< \brief (ADC) Debug Control */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for ADC peripheral ========== */ +#define ADC_EXTCHANNEL_MSB 19 +#define ADC_GCLK_ID 23 +#define ADC_RESULT_BITS 16 +#define ADC_RESULT_MSB (ADC_RESULT_BITS-1) + +#endif /* _SAMD20_ADC_INSTANCE_ */ diff --git a/loader/samd20/instance/dac.h b/loader/samd20/instance/dac.h new file mode 100644 index 0000000..34ee220 --- /dev/null +++ b/loader/samd20/instance/dac.h @@ -0,0 +1,73 @@ +/** + * \file + * + * \brief Instance description for DAC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_DAC_INSTANCE_ +#define _SAMD20_DAC_INSTANCE_ + +/* ========== Register definition for DAC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_DAC_CTRLA (0x42004800U) /**< \brief (DAC) Control A */ +#define REG_DAC_CTRLB (0x42004801U) /**< \brief (DAC) Control B */ +#define REG_DAC_EVCTRL (0x42004802U) /**< \brief (DAC) Event Control */ +#define REG_DAC_INTENCLR (0x42004804U) /**< \brief (DAC) Interrupt Enable Clear */ +#define REG_DAC_INTENSET (0x42004805U) /**< \brief (DAC) Interrupt Enable Set */ +#define REG_DAC_INTFLAG (0x42004806U) /**< \brief (DAC) Interrupt Flag Status and Clear */ +#define REG_DAC_STATUS (0x42004807U) /**< \brief (DAC) Status */ +#define REG_DAC_DATA (0x42004808U) /**< \brief (DAC) Data */ +#define REG_DAC_DATABUF (0x4200480CU) /**< \brief (DAC) Data Buffer */ +#else +#define REG_DAC_CTRLA (*(RwReg8 *)0x42004800U) /**< \brief (DAC) Control A */ +#define REG_DAC_CTRLB (*(RwReg8 *)0x42004801U) /**< \brief (DAC) Control B */ +#define REG_DAC_EVCTRL (*(RwReg8 *)0x42004802U) /**< \brief (DAC) Event Control */ +#define REG_DAC_INTENCLR (*(RwReg8 *)0x42004804U) /**< \brief (DAC) Interrupt Enable Clear */ +#define REG_DAC_INTENSET (*(RwReg8 *)0x42004805U) /**< \brief (DAC) Interrupt Enable Set */ +#define REG_DAC_INTFLAG (*(RwReg8 *)0x42004806U) /**< \brief (DAC) Interrupt Flag Status and Clear */ +#define REG_DAC_STATUS (*(RoReg8 *)0x42004807U) /**< \brief (DAC) Status */ +#define REG_DAC_DATA (*(RwReg16*)0x42004808U) /**< \brief (DAC) Data */ +#define REG_DAC_DATABUF (*(RwReg16*)0x4200480CU) /**< \brief (DAC) Data Buffer */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for DAC peripheral ========== */ +#define DAC_GCLK_ID 26 + +#endif /* _SAMD20_DAC_INSTANCE_ */ diff --git a/loader/samd20/instance/dsu.h b/loader/samd20/instance/dsu.h new file mode 100644 index 0000000..293c816 --- /dev/null +++ b/loader/samd20/instance/dsu.h @@ -0,0 +1,109 @@ +/** + * \file + * + * \brief Instance description for DSU + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_DSU_INSTANCE_ +#define _SAMD20_DSU_INSTANCE_ + +/* ========== Register definition for DSU peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_DSU_CTRL (0x41002000U) /**< \brief (DSU) Control */ +#define REG_DSU_STATUSA (0x41002001U) /**< \brief (DSU) Status A */ +#define REG_DSU_STATUSB (0x41002002U) /**< \brief (DSU) Status B */ +#define REG_DSU_ADDR (0x41002004U) /**< \brief (DSU) Address */ +#define REG_DSU_LENGTH (0x41002008U) /**< \brief (DSU) Length */ +#define REG_DSU_DATA (0x4100200CU) /**< \brief (DSU) Data */ +#define REG_DSU_DCC0 (0x41002010U) /**< \brief (DSU) Debug Communication Channel 0 */ +#define REG_DSU_DCC1 (0x41002014U) /**< \brief (DSU) Debug Communication Channel 1 */ +#define REG_DSU_DID (0x41002018U) /**< \brief (DSU) Device Identification */ +#define REG_DSU_DCFG0 (0x410020F0U) /**< \brief (DSU) Device Configuration 0 */ +#define REG_DSU_DCFG1 (0x410020F4U) /**< \brief (DSU) Device Configuration 1 */ +#define REG_DSU_ENTRY0 (0x41003000U) /**< \brief (DSU) Coresight ROM Table Entry 0 */ +#define REG_DSU_ENTRY1 (0x41003004U) /**< \brief (DSU) Coresight ROM Table Entry 1 */ +#define REG_DSU_END (0x41003008U) /**< \brief (DSU) Coresight ROM Table End */ +#define REG_DSU_MEMTYPE (0x41003FCCU) /**< \brief (DSU) Coresight ROM Table Memory Type */ +#define REG_DSU_PID4 (0x41003FD0U) /**< \brief (DSU) Peripheral Identification 4 */ +#define REG_DSU_PID5 (0x41003FD4U) /**< \brief (DSU) Peripheral Identification 5 */ +#define REG_DSU_PID6 (0x41003FD8U) /**< \brief (DSU) Peripheral Identification 6 */ +#define REG_DSU_PID7 (0x41003FDCU) /**< \brief (DSU) Peripheral Identification 7 */ +#define REG_DSU_PID0 (0x41003FE0U) /**< \brief (DSU) Peripheral Identification 0 */ +#define REG_DSU_PID1 (0x41003FE4U) /**< \brief (DSU) Peripheral Identification 1 */ +#define REG_DSU_PID2 (0x41003FE8U) /**< \brief (DSU) Peripheral Identification 2 */ +#define REG_DSU_PID3 (0x41003FECU) /**< \brief (DSU) Peripheral Identification 3 */ +#define REG_DSU_CID0 (0x41003FF0U) /**< \brief (DSU) Component Identification 0 */ +#define REG_DSU_CID1 (0x41003FF4U) /**< \brief (DSU) Component Identification 1 */ +#define REG_DSU_CID2 (0x41003FF8U) /**< \brief (DSU) Component Identification 2 */ +#define REG_DSU_CID3 (0x41003FFCU) /**< \brief (DSU) Component Identification 3 */ +#else +#define REG_DSU_CTRL (*(WoReg8 *)0x41002000U) /**< \brief (DSU) Control */ +#define REG_DSU_STATUSA (*(RwReg8 *)0x41002001U) /**< \brief (DSU) Status A */ +#define REG_DSU_STATUSB (*(RoReg8 *)0x41002002U) /**< \brief (DSU) Status B */ +#define REG_DSU_ADDR (*(RwReg *)0x41002004U) /**< \brief (DSU) Address */ +#define REG_DSU_LENGTH (*(RwReg *)0x41002008U) /**< \brief (DSU) Length */ +#define REG_DSU_DATA (*(RwReg *)0x4100200CU) /**< \brief (DSU) Data */ +#define REG_DSU_DCC0 (*(RwReg *)0x41002010U) /**< \brief (DSU) Debug Communication Channel 0 */ +#define REG_DSU_DCC1 (*(RwReg *)0x41002014U) /**< \brief (DSU) Debug Communication Channel 1 */ +#define REG_DSU_DID (*(RoReg *)0x41002018U) /**< \brief (DSU) Device Identification */ +#define REG_DSU_DCFG0 (*(RwReg *)0x410020F0U) /**< \brief (DSU) Device Configuration 0 */ +#define REG_DSU_DCFG1 (*(RwReg *)0x410020F4U) /**< \brief (DSU) Device Configuration 1 */ +#define REG_DSU_ENTRY0 (*(RoReg *)0x41003000U) /**< \brief (DSU) Coresight ROM Table Entry 0 */ +#define REG_DSU_ENTRY1 (*(RoReg *)0x41003004U) /**< \brief (DSU) Coresight ROM Table Entry 1 */ +#define REG_DSU_END (*(RoReg *)0x41003008U) /**< \brief (DSU) Coresight ROM Table End */ +#define REG_DSU_MEMTYPE (*(RoReg *)0x41003FCCU) /**< \brief (DSU) Coresight ROM Table Memory Type */ +#define REG_DSU_PID4 (*(RoReg *)0x41003FD0U) /**< \brief (DSU) Peripheral Identification 4 */ +#define REG_DSU_PID5 (*(RoReg *)0x41003FD4U) /**< \brief (DSU) Peripheral Identification 5 */ +#define REG_DSU_PID6 (*(RoReg *)0x41003FD8U) /**< \brief (DSU) Peripheral Identification 6 */ +#define REG_DSU_PID7 (*(RoReg *)0x41003FDCU) /**< \brief (DSU) Peripheral Identification 7 */ +#define REG_DSU_PID0 (*(RoReg *)0x41003FE0U) /**< \brief (DSU) Peripheral Identification 0 */ +#define REG_DSU_PID1 (*(RoReg *)0x41003FE4U) /**< \brief (DSU) Peripheral Identification 1 */ +#define REG_DSU_PID2 (*(RoReg *)0x41003FE8U) /**< \brief (DSU) Peripheral Identification 2 */ +#define REG_DSU_PID3 (*(RoReg *)0x41003FECU) /**< \brief (DSU) Peripheral Identification 3 */ +#define REG_DSU_CID0 (*(RoReg *)0x41003FF0U) /**< \brief (DSU) Component Identification 0 */ +#define REG_DSU_CID1 (*(RoReg *)0x41003FF4U) /**< \brief (DSU) Component Identification 1 */ +#define REG_DSU_CID2 (*(RoReg *)0x41003FF8U) /**< \brief (DSU) Component Identification 2 */ +#define REG_DSU_CID3 (*(RoReg *)0x41003FFCU) /**< \brief (DSU) Component Identification 3 */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for DSU peripheral ========== */ +#define DSU_CLK_HSB_ID 3 + +#endif /* _SAMD20_DSU_INSTANCE_ */ diff --git a/loader/samd20/instance/eic.h b/loader/samd20/instance/eic.h new file mode 100644 index 0000000..0ef9379 --- /dev/null +++ b/loader/samd20/instance/eic.h @@ -0,0 +1,81 @@ +/** + * \file + * + * \brief Instance description for EIC + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_EIC_INSTANCE_ +#define _SAMD20_EIC_INSTANCE_ + +/* ========== Register definition for EIC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_EIC_CTRL (0x40001800U) /**< \brief (EIC) Control */ +#define REG_EIC_STATUS (0x40001801U) /**< \brief (EIC) Status */ +#define REG_EIC_NMICTRL (0x40001802U) /**< \brief (EIC) Non-Maskable Interrupt Control */ +#define REG_EIC_NMIFLAG (0x40001803U) /**< \brief (EIC) Non-Maskable Interrupt Flag Status and Clear */ +#define REG_EIC_EVCTRL (0x40001804U) /**< \brief (EIC) Event Control */ +#define REG_EIC_INTENCLR (0x40001808U) /**< \brief (EIC) Interrupt Enable Clear */ +#define REG_EIC_INTENSET (0x4000180CU) /**< \brief (EIC) Interrupt Enable Set */ +#define REG_EIC_INTFLAG (0x40001810U) /**< \brief (EIC) Interrupt Flag Status and Clear */ +#define REG_EIC_WAKEUP (0x40001814U) /**< \brief (EIC) Wake-Up Enable */ +#define REG_EIC_CONFIG0 (0x40001818U) /**< \brief (EIC) Configuration 0 */ +#define REG_EIC_CONFIG1 (0x4000181CU) /**< \brief (EIC) Configuration 1 */ +#else +#define REG_EIC_CTRL (*(RwReg8 *)0x40001800U) /**< \brief (EIC) Control */ +#define REG_EIC_STATUS (*(RoReg8 *)0x40001801U) /**< \brief (EIC) Status */ +#define REG_EIC_NMICTRL (*(RwReg8 *)0x40001802U) /**< \brief (EIC) Non-Maskable Interrupt Control */ +#define REG_EIC_NMIFLAG (*(RwReg8 *)0x40001803U) /**< \brief (EIC) Non-Maskable Interrupt Flag Status and Clear */ +#define REG_EIC_EVCTRL (*(RwReg *)0x40001804U) /**< \brief (EIC) Event Control */ +#define REG_EIC_INTENCLR (*(RwReg *)0x40001808U) /**< \brief (EIC) Interrupt Enable Clear */ +#define REG_EIC_INTENSET (*(RwReg *)0x4000180CU) /**< \brief (EIC) Interrupt Enable Set */ +#define REG_EIC_INTFLAG (*(RwReg *)0x40001810U) /**< \brief (EIC) Interrupt Flag Status and Clear */ +#define REG_EIC_WAKEUP (*(RwReg *)0x40001814U) /**< \brief (EIC) Wake-Up Enable */ +#define REG_EIC_CONFIG0 (*(RwReg *)0x40001818U) /**< \brief (EIC) Configuration 0 */ +#define REG_EIC_CONFIG1 (*(RwReg *)0x4000181CU) /**< \brief (EIC) Configuration 1 */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for EIC peripheral ========== */ +#define EIC_CONFIG_NUM ((EIC_EXTINT_NUM+7)/8) +#define EIC_EXTINT_NUM 16 +#define EIC_GCLK_ID 3 +#define EIC_NUMBER_OF_CONFIG_REGS EIC_CONFIG_NUM +#define EIC_NUMBER_OF_INTERRUPTS EIC_EXTINT_NUM + +#endif /* _SAMD20_EIC_INSTANCE_ */ diff --git a/loader/samd20/instance/evsys.h b/loader/samd20/instance/evsys.h new file mode 100644 index 0000000..c2523a2 --- /dev/null +++ b/loader/samd20/instance/evsys.h @@ -0,0 +1,165 @@ +/** + * \file + * + * \brief Instance description for EVSYS + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_EVSYS_INSTANCE_ +#define _SAMD20_EVSYS_INSTANCE_ + +/* ========== Register definition for EVSYS peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_EVSYS_CTRL (0x42000400U) /**< \brief (EVSYS) Control */ +#define REG_EVSYS_CHANNEL (0x42000404U) /**< \brief (EVSYS) Channel */ +#define REG_EVSYS_USER (0x42000408U) /**< \brief (EVSYS) User Multiplexer */ +#define REG_EVSYS_CHSTATUS (0x4200040CU) /**< \brief (EVSYS) Channel Status */ +#define REG_EVSYS_INTENCLR (0x42000410U) /**< \brief (EVSYS) Interrupt Enable Clear */ +#define REG_EVSYS_INTENSET (0x42000414U) /**< \brief (EVSYS) Interrupt Enable Set */ +#define REG_EVSYS_INTFLAG (0x42000418U) /**< \brief (EVSYS) Interrupt Flag Status and Clear */ +#else +#define REG_EVSYS_CTRL (*(WoReg8 *)0x42000400U) /**< \brief (EVSYS) Control */ +#define REG_EVSYS_CHANNEL (*(RwReg *)0x42000404U) /**< \brief (EVSYS) Channel */ +#define REG_EVSYS_USER (*(RwReg16*)0x42000408U) /**< \brief (EVSYS) User Multiplexer */ +#define REG_EVSYS_CHSTATUS (*(RoReg *)0x4200040CU) /**< \brief (EVSYS) Channel Status */ +#define REG_EVSYS_INTENCLR (*(RwReg *)0x42000410U) /**< \brief (EVSYS) Interrupt Enable Clear */ +#define REG_EVSYS_INTENSET (*(RwReg *)0x42000414U) /**< \brief (EVSYS) Interrupt Enable Set */ +#define REG_EVSYS_INTFLAG (*(RwReg *)0x42000418U) /**< \brief (EVSYS) Interrupt Flag Status and Clear */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for EVSYS peripheral ========== */ +#define EVSYS_CHANNELS 8 +#define EVSYS_CHANNELS_BITS (len(bin(EVSYS_CHANNELS-1))-2) +#define EVSYS_CHANNELS_MSB 7 +#define EVSYS_EXTEVT_NUM +#define EVSYS_EXT_EVT_MSB 0 +#define EVSYS_GCLK_ID_0 4 +#define EVSYS_GCLK_ID_1 5 +#define EVSYS_GCLK_ID_2 6 +#define EVSYS_GCLK_ID_3 7 +#define EVSYS_GCLK_ID_4 8 +#define EVSYS_GCLK_ID_5 9 +#define EVSYS_GCLK_ID_6 10 +#define EVSYS_GCLK_ID_7 11 +#define EVSYS_GCLK_ID_LSB 4 +#define EVSYS_GCLK_ID_MSB 11 +#define EVSYS_GCLK_ID_SIZE 8 +#define EVSYS_GENERATORS 59 +#define EVSYS_GENERATORS_BITS (len(bin(EVSYS_GENERATORS-1))-2) +#define EVSYS_USERS 14 +#define EVSYS_USERS_BITS (len(bin(EVSYS_USERS-1))-2) + +// GENERATORS +#define EVSYS_ID_GEN_RTC_CMP_0 1 +#define EVSYS_ID_GEN_RTC_CMP_1 2 +#define EVSYS_ID_GEN_RTC_OVF 3 +#define EVSYS_ID_GEN_RTC_PER_0 4 +#define EVSYS_ID_GEN_RTC_PER_1 5 +#define EVSYS_ID_GEN_RTC_PER_2 6 +#define EVSYS_ID_GEN_RTC_PER_3 7 +#define EVSYS_ID_GEN_RTC_PER_4 8 +#define EVSYS_ID_GEN_RTC_PER_5 9 +#define EVSYS_ID_GEN_RTC_PER_6 10 +#define EVSYS_ID_GEN_RTC_PER_7 11 +#define EVSYS_ID_GEN_EIC_EXTINT_0 12 +#define EVSYS_ID_GEN_EIC_EXTINT_1 13 +#define EVSYS_ID_GEN_EIC_EXTINT_2 14 +#define EVSYS_ID_GEN_EIC_EXTINT_3 15 +#define EVSYS_ID_GEN_EIC_EXTINT_4 16 +#define EVSYS_ID_GEN_EIC_EXTINT_5 17 +#define EVSYS_ID_GEN_EIC_EXTINT_6 18 +#define EVSYS_ID_GEN_EIC_EXTINT_7 19 +#define EVSYS_ID_GEN_EIC_EXTINT_8 20 +#define EVSYS_ID_GEN_EIC_EXTINT_9 21 +#define EVSYS_ID_GEN_EIC_EXTINT_10 22 +#define EVSYS_ID_GEN_EIC_EXTINT_11 23 +#define EVSYS_ID_GEN_EIC_EXTINT_12 24 +#define EVSYS_ID_GEN_EIC_EXTINT_13 25 +#define EVSYS_ID_GEN_EIC_EXTINT_14 26 +#define EVSYS_ID_GEN_EIC_EXTINT_15 27 +#define EVSYS_ID_GEN_TC0_OVF 28 +#define EVSYS_ID_GEN_TC0_MCX_0 29 +#define EVSYS_ID_GEN_TC0_MCX_1 30 +#define EVSYS_ID_GEN_TC1_OVF 31 +#define EVSYS_ID_GEN_TC1_MCX_0 32 +#define EVSYS_ID_GEN_TC1_MCX_1 33 +#define EVSYS_ID_GEN_TC2_OVF 34 +#define EVSYS_ID_GEN_TC2_MCX_0 35 +#define EVSYS_ID_GEN_TC2_MCX_1 36 +#define EVSYS_ID_GEN_TC3_OVF 37 +#define EVSYS_ID_GEN_TC3_MCX_0 38 +#define EVSYS_ID_GEN_TC3_MCX_1 39 +#define EVSYS_ID_GEN_TC4_OVF 40 +#define EVSYS_ID_GEN_TC4_MCX_0 41 +#define EVSYS_ID_GEN_TC4_MCX_1 42 +#define EVSYS_ID_GEN_TC5_OVF 43 +#define EVSYS_ID_GEN_TC5_MCX_0 44 +#define EVSYS_ID_GEN_TC5_MCX_1 45 +#define EVSYS_ID_GEN_TC6_OVF 46 +#define EVSYS_ID_GEN_TC6_MCX_0 47 +#define EVSYS_ID_GEN_TC6_MCX_1 48 +#define EVSYS_ID_GEN_TC7_OVF 49 +#define EVSYS_ID_GEN_TC7_MCX_0 50 +#define EVSYS_ID_GEN_TC7_MCX_1 51 +#define EVSYS_ID_GEN_ADC_RESRDY 52 +#define EVSYS_ID_GEN_ADC_WINMON 53 +#define EVSYS_ID_GEN_AC_COMP_0 54 +#define EVSYS_ID_GEN_AC_COMP_1 55 +#define EVSYS_ID_GEN_AC_WIN_0 56 +#define EVSYS_ID_GEN_DAC_EMPTY 57 +#define EVSYS_ID_GEN_PTC_EOC 58 +#define EVSYS_ID_GEN_PTC_WCOMP 59 + +// USERS +#define EVSYS_ID_USER_TC0_EVU 0 +#define EVSYS_ID_USER_TC1_EVU 1 +#define EVSYS_ID_USER_TC2_EVU 2 +#define EVSYS_ID_USER_TC3_EVU 3 +#define EVSYS_ID_USER_TC4_EVU 4 +#define EVSYS_ID_USER_TC5_EVU 5 +#define EVSYS_ID_USER_TC6_EVU 6 +#define EVSYS_ID_USER_TC7_EVU 7 +#define EVSYS_ID_USER_ADC_START 8 +#define EVSYS_ID_USER_ADC_SYNC 9 +#define EVSYS_ID_USER_AC_SOC_0 10 +#define EVSYS_ID_USER_AC_SOC_1 11 +#define EVSYS_ID_USER_DAC_START 12 +#define EVSYS_ID_USER_PTC_STCONV 13 + +#endif /* _SAMD20_EVSYS_INSTANCE_ */ diff --git a/loader/samd20/instance/gclk.h b/loader/samd20/instance/gclk.h new file mode 100644 index 0000000..ae7055f --- /dev/null +++ b/loader/samd20/instance/gclk.h @@ -0,0 +1,79 @@ +/** + * \file + * + * \brief Instance description for GCLK + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_GCLK_INSTANCE_ +#define _SAMD20_GCLK_INSTANCE_ + +/* ========== Register definition for GCLK peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_GCLK_CTRL (0x40000C00U) /**< \brief (GCLK) Control */ +#define REG_GCLK_STATUS (0x40000C01U) /**< \brief (GCLK) Status */ +#define REG_GCLK_CLKCTRL (0x40000C02U) /**< \brief (GCLK) Generic Clock Control */ +#define REG_GCLK_GENCTRL (0x40000C04U) /**< \brief (GCLK) Generic Clock Generator Control */ +#define REG_GCLK_GENDIV (0x40000C08U) /**< \brief (GCLK) Generic Clock Generator Division */ +#else +#define REG_GCLK_CTRL (*(RwReg8 *)0x40000C00U) /**< \brief (GCLK) Control */ +#define REG_GCLK_STATUS (*(RoReg8 *)0x40000C01U) /**< \brief (GCLK) Status */ +#define REG_GCLK_CLKCTRL (*(RwReg16*)0x40000C02U) /**< \brief (GCLK) Generic Clock Control */ +#define REG_GCLK_GENCTRL (*(RwReg *)0x40000C04U) /**< \brief (GCLK) Generic Clock Generator Control */ +#define REG_GCLK_GENDIV (*(RwReg *)0x40000C08U) /**< \brief (GCLK) Generic Clock Generator Division */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for GCLK peripheral ========== */ +#define GCLK_GENDIV_BITS 16 +#define GCLK_GEN_NUM 8 +#define GCLK_GEN_NUM_MSB 7 +#define GCLK_GEN_SOURCE_NUM_MSB 7 +#define GCLK_NUM 28 +#define GCLK_SOURCE_DFLL48M 7 +#define GCLK_SOURCE_FDPLL +#define GCLK_SOURCE_GCLKGEN1 2 +#define GCLK_SOURCE_GCLKIN 1 +#define GCLK_SOURCE_NUM 8 +#define GCLK_SOURCE_OSCULP32K 3 +#define GCLK_SOURCE_OSC8M 6 +#define GCLK_SOURCE_OSC32K 4 +#define GCLK_SOURCE_XOSC 0 +#define GCLK_SOURCE_XOSC32K 5 + +#endif /* _SAMD20_GCLK_INSTANCE_ */ diff --git a/loader/samd20/instance/nvmctrl.h b/loader/samd20/instance/nvmctrl.h new file mode 100644 index 0000000..05ae54e --- /dev/null +++ b/loader/samd20/instance/nvmctrl.h @@ -0,0 +1,92 @@ +/** + * \file + * + * \brief Instance description for NVMCTRL + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20_NVMCTRL_INSTANCE_ +#define _SAMD20_NVMCTRL_INSTANCE_ + +/* ========== Register definition for NVMCTRL peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define REG_NVMCTRL_CTRLA (0x41004000U) /**< \brief (NVMCTRL) Control A */ +#define REG_NVMCTRL_CTRLB (0x41004004U) /**< \brief (NVMCTRL) Control B */ +#define REG_NVMCTRL_PARAM (0x41004008U) /**< \brief (NVMCTRL) NVM Parameter */ +#define REG_NVMCTRL_INTENCLR (0x4100400CU) /**< \brief (NVMCTRL) Interrupt Enable Clear */ +#define REG_NVMCTRL_INTENSET (0x41004010U) /**< \brief (NVMCTRL) Interrupt Enable Set */ +#define REG_NVMCTRL_INTFLAG (0x41004014U) /**< \brief (NVMCTRL) Interrupt Flag Status and Clear */ +#define REG_NVMCTRL_STATUS (0x41004018U) /**< \brief (NVMCTRL) Status */ +#define REG_NVMCTRL_ADDR (0x4100401CU) /**< \brief (NVMCTRL) Address */ +#define REG_NVMCTRL_LOCK (0x41004020U) /**< \brief (NVMCTRL) Lock Section */ +#else +#define REG_NVMCTRL_CTRLA (*(RwReg16*)0x41004000U) /**< \brief (NVMCTRL) Control A */ +#define REG_NVMCTRL_CTRLB (*(RwReg *)0x41004004U) /**< \brief (NVMCTRL) Control B */ +#define REG_NVMCTRL_PARAM (*(RwReg *)0x41004008U) /**< \brief (NVMCTRL) NVM Parameter */ +#define REG_NVMCTRL_INTENCLR (*(RwReg8 *)0x4100400CU) /**< \brief (NVMCTRL) Interrupt Enable Clear */ +#define REG_NVMCTRL_INTENSET (*(RwReg8 *)0x41004010U) /**< \brief (NVMCTRL) Interrupt Enable Set */ +#define REG_NVMCTRL_INTFLAG (*(RwReg8 *)0x41004014U) /**< \brief (NVMCTRL) Interrupt Flag Status and Clear */ +#define REG_NVMCTRL_STATUS (*(RwReg16*)0x41004018U) /**< \brief (NVMCTRL) Status */ +#define REG_NVMCTRL_ADDR (*(RwReg *)0x4100401CU) /**< \brief (NVMCTRL) Address */ +#define REG_NVMCTRL_LOCK (*(RwReg16*)0x41004020U) /**< \brief (NVMCTRL) Lock Section */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* ========== Instance parameters for NVMCTRL peripheral ========== */ +#define NVMCTRL_AUX0_ADDRESS (NVMCTRL_USER_PAGE_ADDRESS + 0x00004000) +#define NVMCTRL_AUX1_ADDRESS (NVMCTRL_USER_PAGE_ADDRESS + 0x00006000) +#define NVMCTRL_AUX2_ADDRESS (NVMCTRL_USER_PAGE_ADDRESS + 0x00008000) +#define NVMCTRL_AUX3_ADDRESS (NVMCTRL_USER_PAGE_ADDRESS + 0x0000A000) +#define NVMCTRL_CLK_AHB_ID 4 +#define NVMCTRL_FACTORY_WORD_IMPLEMENTED_MASK 0xC0000007FFFFFFFF +#define NVMCTRL_FLASH_SIZE (NVMCTRL_PAGES*NVMCTRL_PAGE_SIZE) +#define NVMCTRL_LOCKBIT_ADDRESS (NVMCTRL_USER_PAGE_ADDRESS + 0x00002000) +#define NVMCTRL_PAGES 4096 +#define NVMCTRL_PAGE_HW (NVMCTRL_PAGE_SIZE/2) +#define NVMCTRL_PAGE_SIZE (1< +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20E14-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20E14 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20E14 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20E14 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20E14 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20E14 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20E14 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20E14 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20E14 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20E14 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20E14 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20E14 Serial Communication Interface 3 (SERCOM3) */ + TC0_IRQn = 13, /**< 13 SAMD20E14 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20E14 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20E14 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20E14 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20E14 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20E14 Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 21, /**< 21 SAMD20E14 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20E14 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20E14 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20E14 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnReserved11; + void* pfnReserved12; + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnReserved19; + void* pfnReserved20; + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 6 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E14_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20e14.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x4000 /* 16 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 256 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x800 /* 2 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x1000130E +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20E14 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20E14_H */ diff --git a/loader/samd20/samd20e15.h b/loader/samd20/samd20e15.h new file mode 100644 index 0000000..2da6c83 --- /dev/null +++ b/loader/samd20/samd20e15.h @@ -0,0 +1,500 @@ +/** + * \file + * + * \brief Header file for SAMD20E15 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20E15_ +#define _SAMD20E15_ + +#define SAMD20 +#define SAMD20E + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20E15_definitions SAMD20E15 definitions + * This file defines all structures and symbols for SAMD20E15: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20E15-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20E15 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20E15 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20E15 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20E15 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20E15 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20E15 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20E15 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20E15 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20E15 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20E15 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20E15 Serial Communication Interface 3 (SERCOM3) */ + TC0_IRQn = 13, /**< 13 SAMD20E15 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20E15 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20E15 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20E15 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20E15 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20E15 Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 21, /**< 21 SAMD20E15 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20E15 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20E15 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20E15 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnReserved11; + void* pfnReserved12; + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnReserved19; + void* pfnReserved20; + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 6 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E15_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20e15.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x8000 /* 32 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 512 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x1000 /* 4 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x1000130D +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20E15 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20E15_H */ diff --git a/loader/samd20/samd20e16.h b/loader/samd20/samd20e16.h new file mode 100644 index 0000000..f7e64e6 --- /dev/null +++ b/loader/samd20/samd20e16.h @@ -0,0 +1,500 @@ +/** + * \file + * + * \brief Header file for SAMD20E16 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20E16_ +#define _SAMD20E16_ + +#define SAMD20 +#define SAMD20E + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20E16_definitions SAMD20E16 definitions + * This file defines all structures and symbols for SAMD20E16: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20E16-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20E16 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20E16 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20E16 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20E16 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20E16 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20E16 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20E16 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20E16 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20E16 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20E16 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20E16 Serial Communication Interface 3 (SERCOM3) */ + TC0_IRQn = 13, /**< 13 SAMD20E16 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20E16 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20E16 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20E16 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20E16 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20E16 Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 21, /**< 21 SAMD20E16 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20E16 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20E16 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20E16 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnReserved11; + void* pfnReserved12; + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnReserved19; + void* pfnReserved20; + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 6 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E16_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20e16.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x10000 /* 64 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 1024 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x2000 /* 8 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x1000130C +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20E16 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20E16_H */ diff --git a/loader/samd20/samd20e17.h b/loader/samd20/samd20e17.h new file mode 100644 index 0000000..229bae2 --- /dev/null +++ b/loader/samd20/samd20e17.h @@ -0,0 +1,500 @@ +/** + * \file + * + * \brief Header file for SAMD20E17 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20E17_ +#define _SAMD20E17_ + +#define SAMD20 +#define SAMD20E + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20E17_definitions SAMD20E17 definitions + * This file defines all structures and symbols for SAMD20E17: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20E17-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20E17 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20E17 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20E17 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20E17 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20E17 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20E17 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20E17 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20E17 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20E17 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20E17 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20E17 Serial Communication Interface 3 (SERCOM3) */ + TC0_IRQn = 13, /**< 13 SAMD20E17 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20E17 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20E17 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20E17 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20E17 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20E17 Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 21, /**< 21 SAMD20E17 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20E17 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20E17 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20E17 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnReserved11; + void* pfnReserved12; + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnReserved19; + void* pfnReserved20; + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 6 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E17_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20e17.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x20000 /* 128 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 2048 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x4000 /* 16 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x1000130B +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20E17 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20E17_H */ diff --git a/loader/samd20/samd20e18.h b/loader/samd20/samd20e18.h new file mode 100644 index 0000000..8ef4038 --- /dev/null +++ b/loader/samd20/samd20e18.h @@ -0,0 +1,500 @@ +/** + * \file + * + * \brief Header file for SAMD20E18 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20E18_ +#define _SAMD20E18_ + +#define SAMD20 +#define SAMD20E + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20E18_definitions SAMD20E18 definitions + * This file defines all structures and symbols for SAMD20E18: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20E18-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20E18 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20E18 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20E18 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20E18 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20E18 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20E18 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20E18 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20E18 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20E18 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20E18 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20E18 Serial Communication Interface 3 (SERCOM3) */ + TC0_IRQn = 13, /**< 13 SAMD20E18 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20E18 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20E18 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20E18 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20E18 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20E18 Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 21, /**< 21 SAMD20E18 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20E18 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20E18 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20E18 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnReserved11; + void* pfnReserved12; + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnReserved19; + void* pfnReserved20; + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 6 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20E18_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20e18.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x40000 /* 256 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 4096 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x8000 /* 32 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x1000130A +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20E18 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20E18_H */ diff --git a/loader/samd20/samd20g14.h b/loader/samd20/samd20g14.h new file mode 100644 index 0000000..bed4e52 --- /dev/null +++ b/loader/samd20/samd20g14.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20G14 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20G14_ +#define _SAMD20G14_ + +#define SAMD20 +#define SAMD20G + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20G14_definitions SAMD20G14 definitions + * This file defines all structures and symbols for SAMD20G14: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20G14-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20G14 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20G14 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20G14 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20G14 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20G14 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20G14 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20G14 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20G14 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20G14 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20G14 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20G14 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20G14 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20G14 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20G14 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20G14 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20G14 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20G14 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20G14 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20G14 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20G14 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20G14 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20G14 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20G14 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20G14 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20G14 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G14_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20g14.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x4000 /* 16 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 256 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x800 /* 2 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001309 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20G14 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20G14_H */ diff --git a/loader/samd20/samd20g15.h b/loader/samd20/samd20g15.h new file mode 100644 index 0000000..c607528 --- /dev/null +++ b/loader/samd20/samd20g15.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20G15 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20G15_ +#define _SAMD20G15_ + +#define SAMD20 +#define SAMD20G + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20G15_definitions SAMD20G15 definitions + * This file defines all structures and symbols for SAMD20G15: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20G15-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20G15 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20G15 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20G15 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20G15 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20G15 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20G15 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20G15 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20G15 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20G15 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20G15 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20G15 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20G15 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20G15 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20G15 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20G15 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20G15 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20G15 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20G15 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20G15 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20G15 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20G15 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20G15 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20G15 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20G15 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20G15 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G15_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20g15.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x8000 /* 32 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 512 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x1000 /* 4 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001308 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20G15 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20G15_H */ diff --git a/loader/samd20/samd20g16.h b/loader/samd20/samd20g16.h new file mode 100644 index 0000000..bfc3b28 --- /dev/null +++ b/loader/samd20/samd20g16.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20G16 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20G16_ +#define _SAMD20G16_ + +#define SAMD20 +#define SAMD20G + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20G16_definitions SAMD20G16 definitions + * This file defines all structures and symbols for SAMD20G16: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20G16-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20G16 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20G16 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20G16 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20G16 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20G16 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20G16 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20G16 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20G16 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20G16 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20G16 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20G16 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20G16 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20G16 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20G16 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20G16 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20G16 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20G16 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20G16 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20G16 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20G16 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20G16 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20G16 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20G16 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20G16 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20G16 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G16_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20g16.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x10000 /* 64 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 1024 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x2000 /* 8 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001307 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20G16 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20G16_H */ diff --git a/loader/samd20/samd20g17.h b/loader/samd20/samd20g17.h new file mode 100644 index 0000000..99e60dd --- /dev/null +++ b/loader/samd20/samd20g17.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20G17 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20G17_ +#define _SAMD20G17_ + +#define SAMD20 +#define SAMD20G + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20G17_definitions SAMD20G17 definitions + * This file defines all structures and symbols for SAMD20G17: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20G17-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20G17 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20G17 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20G17 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20G17 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20G17 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20G17 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20G17 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20G17 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20G17 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20G17 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20G17 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20G17 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20G17 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20G17 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20G17 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20G17 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20G17 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20G17 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20G17 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20G17 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20G17 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20G17 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20G17 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20G17 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20G17 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G17_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20g17.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x20000 /* 128 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 2048 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x4000 /* 16 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001306 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20G17 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20G17_H */ diff --git a/loader/samd20/samd20g18.h b/loader/samd20/samd20g18.h new file mode 100644 index 0000000..fb3bf29 --- /dev/null +++ b/loader/samd20/samd20g18.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20G18 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20G18_ +#define _SAMD20G18_ + +#define SAMD20 +#define SAMD20G + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20G18_definitions SAMD20G18 definitions + * This file defines all structures and symbols for SAMD20G18: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20G18-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20G18 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20G18 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20G18 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20G18 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20G18 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20G18 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20G18 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20G18 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20G18 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20G18 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20G18 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20G18 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20G18 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20G18 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20G18 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20G18 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20G18 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20G18 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20G18 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20G18 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20G18 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20G18 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20G18 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20G18 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20G18 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20G18_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20g18.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x40000 /* 256 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 4096 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x8000 /* 32 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001305 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20G18 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20G18_H */ diff --git a/loader/samd20/samd20j14.h b/loader/samd20/samd20j14.h new file mode 100644 index 0000000..c10a29d --- /dev/null +++ b/loader/samd20/samd20j14.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20J14 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20J14_ +#define _SAMD20J14_ + +#define SAMD20 +#define SAMD20J + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20J14_definitions SAMD20J14 definitions + * This file defines all structures and symbols for SAMD20J14: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20J14-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20J14 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20J14 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20J14 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20J14 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20J14 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20J14 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20J14 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20J14 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20J14 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20J14 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20J14 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20J14 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20J14 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20J14 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20J14 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20J14 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20J14 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20J14 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20J14 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20J14 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20J14 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20J14 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20J14 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20J14 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20J14 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J14_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20j14.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x4000 /* 16 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 256 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x800 /* 2 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001304 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20J14 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20J14_H */ diff --git a/loader/samd20/samd20j15.h b/loader/samd20/samd20j15.h new file mode 100644 index 0000000..28e0a14 --- /dev/null +++ b/loader/samd20/samd20j15.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20J15 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20J15_ +#define _SAMD20J15_ + +#define SAMD20 +#define SAMD20J + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20J15_definitions SAMD20J15 definitions + * This file defines all structures and symbols for SAMD20J15: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20J15-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20J15 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20J15 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20J15 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20J15 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20J15 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20J15 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20J15 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20J15 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20J15 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20J15 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20J15 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20J15 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20J15 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20J15 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20J15 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20J15 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20J15 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20J15 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20J15 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20J15 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20J15 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20J15 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20J15 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20J15 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20J15 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J15_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20j15.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x8000 /* 32 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 512 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x1000 /* 4 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001303 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20J15 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20J15_H */ diff --git a/loader/samd20/samd20j16.h b/loader/samd20/samd20j16.h new file mode 100644 index 0000000..b41b55d --- /dev/null +++ b/loader/samd20/samd20j16.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20J16 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20J16_ +#define _SAMD20J16_ + +#define SAMD20 +#define SAMD20J + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20J16_definitions SAMD20J16 definitions + * This file defines all structures and symbols for SAMD20J16: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20J16-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20J16 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20J16 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20J16 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20J16 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20J16 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20J16 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20J16 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20J16 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20J16 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20J16 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20J16 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20J16 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20J16 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20J16 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20J16 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20J16 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20J16 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20J16 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20J16 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20J16 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20J16 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20J16 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20J16 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20J16 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20J16 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J16_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20j16.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x10000 /* 64 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 1024 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x2000 /* 8 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001302 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20J16 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20J16_H */ diff --git a/loader/samd20/samd20j17.h b/loader/samd20/samd20j17.h new file mode 100644 index 0000000..7de38e4 --- /dev/null +++ b/loader/samd20/samd20j17.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20J17 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20J17_ +#define _SAMD20J17_ + +#define SAMD20 +#define SAMD20J + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20J17_definitions SAMD20J17 definitions + * This file defines all structures and symbols for SAMD20J17: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20J17-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20J17 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20J17 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20J17 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20J17 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20J17 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20J17 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20J17 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20J17 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20J17 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20J17 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20J17 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20J17 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20J17 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20J17 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20J17 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20J17 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20J17 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20J17 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20J17 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20J17 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20J17 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20J17 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20J17 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20J17 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20J17 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J17_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20j17.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x20000 /* 128 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 2048 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x4000 /* 16 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001301 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20J17 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20J17_H */ diff --git a/loader/samd20/samd20j18.h b/loader/samd20/samd20j18.h new file mode 100644 index 0000000..359f247 --- /dev/null +++ b/loader/samd20/samd20j18.h @@ -0,0 +1,524 @@ +/** + * \file + * + * \brief Header file for SAMD20J18 + * + * Copyright (c) 2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD20J18_ +#define _SAMD20J18_ + +#define SAMD20 +#define SAMD20J + +/** + * \ingroup SAMD20_definitions + * \addtogroup SAMD20J18_definitions SAMD20J18 definitions + * This file defines all structures and symbols for SAMD20J18: + * - registers and bitfields + * - peripheral base address + * - peripheral ID + * - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint32_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#define CAST(type, value) ((type *)(value)) +#define REG_ACCESS(type, address) (*(type*)(address)) /**< C code: Register value */ +#else +#define CAST(type, value) (value) +#define REG_ACCESS(type, address) (address) /**< Assembly code: Register address */ +#endif + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13, /**< 3 Cortex-M0+ Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M0+ SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M0+ Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M0+ System Tick Interrupt */ + /****** SAMD20J18-specific Interrupt Numbers ***********************/ + PM_IRQn = 0, /**< 0 SAMD20J18 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD20J18 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD20J18 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD20J18 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD20J18 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD20J18 Non-Volatile Memory Controller (NVMCTRL) */ + EVSYS_IRQn = 6, /**< 6 SAMD20J18 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 7, /**< 7 SAMD20J18 Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 8, /**< 8 SAMD20J18 Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 9, /**< 9 SAMD20J18 Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 10, /**< 10 SAMD20J18 Serial Communication Interface 3 (SERCOM3) */ + SERCOM4_IRQn = 11, /**< 11 SAMD20J18 Serial Communication Interface 4 (SERCOM4) */ + SERCOM5_IRQn = 12, /**< 12 SAMD20J18 Serial Communication Interface 5 (SERCOM5) */ + TC0_IRQn = 13, /**< 13 SAMD20J18 Basic Timer Counter 0 (TC0) */ + TC1_IRQn = 14, /**< 14 SAMD20J18 Basic Timer Counter 1 (TC1) */ + TC2_IRQn = 15, /**< 15 SAMD20J18 Basic Timer Counter 2 (TC2) */ + TC3_IRQn = 16, /**< 16 SAMD20J18 Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 17, /**< 17 SAMD20J18 Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 18, /**< 18 SAMD20J18 Basic Timer Counter 5 (TC5) */ + TC6_IRQn = 19, /**< 19 SAMD20J18 Basic Timer Counter 6 (TC6) */ + TC7_IRQn = 20, /**< 20 SAMD20J18 Basic Timer Counter 7 (TC7) */ + ADC_IRQn = 21, /**< 21 SAMD20J18 Analog Digital Converter (ADC) */ + AC_IRQn = 22, /**< 22 SAMD20J18 Analog Comparators (AC) */ + DAC_IRQn = 23, /**< 23 SAMD20J18 Digital Analog Converter (DAC) */ + PTC_IRQn = 24, /**< 24 SAMD20J18 Peripheral Touch Controller (PTC) */ + + PERIPH_COUNT_IRQn = 25 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNMI_Handler; + void* pfnHardFault_Handler; + void* pfnReservedM12; + void* pfnReservedM11; + void* pfnReservedM10; + void* pfnReservedM9; + void* pfnReservedM8; + void* pfnReservedM7; + void* pfnReservedM6; + void* pfnSVC_Handler; + void* pfnReservedM4; + void* pfnReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnEVSYS_Handler; /* 6 Event System Interface */ + void* pfnSERCOM0_Handler; /* 7 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 8 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 9 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 10 Serial Communication Interface 3 */ + void* pfnSERCOM4_Handler; /* 11 Serial Communication Interface 4 */ + void* pfnSERCOM5_Handler; /* 12 Serial Communication Interface 5 */ + void* pfnTC0_Handler; /* 13 Basic Timer Counter 0 */ + void* pfnTC1_Handler; /* 14 Basic Timer Counter 1 */ + void* pfnTC2_Handler; /* 15 Basic Timer Counter 2 */ + void* pfnTC3_Handler; /* 16 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 17 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 18 Basic Timer Counter 5 */ + void* pfnTC6_Handler; /* 19 Basic Timer Counter 6 */ + void* pfnTC7_Handler; /* 20 Basic Timer Counter 7 */ + void* pfnADC_Handler; /* 21 Analog Digital Converter */ + void* pfnAC_Handler; /* 22 Analog Comparators */ + void* pfnDAC_Handler; /* 23 Digital Analog Converter */ + void* pfnPTC_Handler; /* 24 Peripheral Touch Controller */ +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void SVC_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void SERCOM4_Handler ( void ); +void SERCOM5_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void TC6_Handler ( void ); +void TC7_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define LITTLE_ENDIAN 1 +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd20.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sercom4.h" +#include "instance/sercom5.h" +#include "instance/sysctrl.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tc6.h" +#include "instance/tc7.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller PAC (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller PAC (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller PAC (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface SERCOM (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface SERCOM (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface SERCOM (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface SERCOM (SERCOM3) */ +#define ID_SERCOM4 70 /**< \brief Serial Communication Interface SERCOM (SERCOM4) */ +#define ID_SERCOM5 71 /**< \brief Serial Communication Interface SERCOM (SERCOM5) */ +#define ID_TC0 72 /**< \brief Basic Timer Counter TC (TC0) */ +#define ID_TC1 73 /**< \brief Basic Timer Counter TC (TC1) */ +#define ID_TC2 74 /**< \brief Basic Timer Counter TC (TC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter TC (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter TC (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter TC (TC5) */ +#define ID_TC6 78 /**< \brief Basic Timer Counter TC (TC6) */ +#define ID_TC7 79 /**< \brief Basic Timer Counter TC (TC7) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ + +#define ID_PERIPH_COUNT 84 /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400U) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000U) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DSU (0x41002000U) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define NVMCTRL (0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400U) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define RTC (0x40001400U) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 (0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 (0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SYSCTRL (0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define TC0 (0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 (0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 (0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 (0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 (0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 (0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define WDT (0x40001000U) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400U) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000U) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800U) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DSU ((Dsu *)0x41002000U) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800U) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400U) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00U) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000U) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000U) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000U) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000U) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008U) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020U) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030U) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000U) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000U) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000U) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000U) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400U) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400U) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000U) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ + +#define PTC_GCLK_ID 27 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400U) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800U) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00U) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000U) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400U) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM4 ((Sercom *)0x42001800U) /**< \brief (SERCOM4) APB Base Address */ +#define SERCOM5 ((Sercom *)0x42001C00U) /**< \brief (SERCOM5) APB Base Address */ +#define SERCOM_INST_NUM 6 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3, SERCOM4, SERCOM5 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800U) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC0 ((Tc *)0x42002000U) /**< \brief (TC0) APB Base Address */ +#define TC1 ((Tc *)0x42002400U) /**< \brief (TC1) APB Base Address */ +#define TC2 ((Tc *)0x42002800U) /**< \brief (TC2) APB Base Address */ +#define TC3 ((Tc *)0x42002C00U) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000U) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400U) /**< \brief (TC5) APB Base Address */ +#define TC6 ((Tc *)0x42003800U) /**< \brief (TC6) APB Base Address */ +#define TC7 ((Tc *)0x42003C00U) /**< \brief (TC7) APB Base Address */ +#define TC_INST_NUM 8 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC0, TC1, TC2, TC3, TC4, TC5, TC6, TC7 } /**< \brief (TC) Instances List */ + +#define WDT ((Wdt *)0x40001000U) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ +/** \defgroup SAMD20J18_port PORT Definitions */ +/*@{*/ + +#include "pio/samd20j18.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ + +#define FLASH_SIZE 0x40000 /* 256 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 4096 +#define FLASH_USER_PAGE_SIZE 64 +#define HRAMC0_SIZE 0x8000 /* 32 kB */ +#define FLASH_ADDR (0x00000000U) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR (0x00800000U) /**< FLASH_USER_PAGE base address */ +#define HRAMC0_ADDR (0x20000000U) /**< HRAMC0 base address */ + +#define DSU_DID_RESETVALUE 0x10001300 +#define PORT_GROUPS 2 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD20J18 */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD20J18_H */ diff --git a/loader/src/adc/adc.c b/loader/src/adc/adc.c new file mode 100644 index 0000000..db67d46 --- /dev/null +++ b/loader/src/adc/adc.c @@ -0,0 +1,674 @@ +/** + * \file + * + * \brief SAM D20/D21/R21 Peripheral Analog-to-Digital Converter Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "samd20.h" +#include +#include "system/clock.h" +#include "system/gclk.h" +#include "system/system.h" +#include "system/pinmux.h" +#include "adc/adc.h" +#include "watchdog.h" + +#define Assert assert + +#ifdef SAMD20 +/* The Die revision D number */ +#define REVISON_D_NUM 3 +#endif + +/** + * \internal Configure MUX settings for the analog pins + * + * This function will set the given ADC input pins + * to the analog function in the pin mux, giving + * the ADC access to the analog signal + * + * \param [in] pin AINxx pin to configure + */ +static inline void _adc_configure_ain_pin(uint32_t pin) +{ +#define PIN_INVALID_ADC_AIN 0xFFFFUL + + /* Pinmapping table for AINxx -> GPIO pin number */ + const uint32_t pinmapping[] = { +//#if (SAMD20E | SAMD21E) + PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1, + PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, + PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5, + PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7, + PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, + PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, + PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, + PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, + PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17, + PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19, +/* #elif (SAMD20G | SAMD21G) */ +/* PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1, */ +/* PIN_PB08B_ADC_AIN2, PIN_PB09B_ADC_AIN3, */ +/* PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5, */ +/* PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17, */ +/* PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19, */ +/* #elif (SAMD20J | SAMD21J) */ +/* PIN_PA02B_ADC_AIN0, PIN_PA03B_ADC_AIN1, */ +/* PIN_PB08B_ADC_AIN2, PIN_PB09B_ADC_AIN3, */ +/* PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5, */ +/* PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7, */ +/* PIN_PB00B_ADC_AIN8, PIN_PB01B_ADC_AIN9, */ +/* PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11, */ +/* PIN_PB04B_ADC_AIN12, PIN_PB05B_ADC_AIN13, */ +/* PIN_PB06B_ADC_AIN14, PIN_PB07B_ADC_AIN15, */ +/* PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17, */ +/* PIN_PA10B_ADC_AIN18, PIN_PA11B_ADC_AIN19, */ +/* #elif SAMR21E */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* #elif SAMR21G */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PA04B_ADC_AIN4, PIN_PA05B_ADC_AIN5, */ +/* PIN_PA06B_ADC_AIN6, PIN_PA07B_ADC_AIN7, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PB02B_ADC_AIN10, PIN_PB03B_ADC_AIN11, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* PIN_PA08B_ADC_AIN16, PIN_PA09B_ADC_AIN17, */ +/* PIN_INVALID_ADC_AIN, PIN_INVALID_ADC_AIN, */ +/* #else */ +/* # error ADC pin mappings are not defined for this device. */ +/* #endif */ + }; + + uint32_t pin_map_result = PIN_INVALID_ADC_AIN; + + if (pin <= ADC_EXTCHANNEL_MSB) { + pin_map_result = pinmapping[pin >> ADC_INPUTCTRL_MUXPOS_Pos]; + + + + system_pinmux_pin_set_config(pin_map_result, + 1, // B + SYSTEM_PINMUX_PIN_DIR_INPUT, + SYSTEM_PINMUX_PIN_PULL_NONE, + false); + } +} + +/** + * \internal Writes an ADC configuration to the hardware module + * + * Writes out a given ADC module configuration to the hardware module. + * + * \param[out] module_inst Pointer to the ADC software instance struct + * \param[in] config Pointer to configuration struct + * + * \return Status of the configuration procedure + * \retval ADC_STATUS_OK The configuration was successful + * \retval ADC_STATUS_ERR_INVALID_ARG Invalid argument(s) were provided + */ +static enum adc_status_code _adc_set_config(struct adc_config *const config) +{ + uint8_t adjres = 0; + uint32_t resolution = ADC_RESOLUTION_16BIT; + enum adc_accumulate_samples accumulate = ADC_ACCUMULATE_DISABLE; +#ifdef SAMD20 + uint8_t revision_num = ((REG_DSU_DID & DSU_DID_DIE_Msk) >> DSU_DID_DIE_Pos); +#endif + + /* Get the hardware module pointer */ + Adc *const adc_module = module_inst.hw; + + /* Configure GCLK channel and enable clock */ + system_gclk_chan_set_config(ADC_GCLK_ID, config->clock_source); + system_gclk_chan_enable(ADC_GCLK_ID); + + /* Setup pinmuxing for analog inputs */ + if (config->pin_scan.inputs_to_scan != 0) { + uint8_t offset = config->pin_scan.offset_start_scan; + uint8_t start_pin = + offset +(uint8_t)config->positive_input; + uint8_t end_pin = + start_pin + config->pin_scan.inputs_to_scan; + + while (start_pin < end_pin) { + _adc_configure_ain_pin((offset % 16)+(uint8_t)config->positive_input); + start_pin++; + offset++; + } + _adc_configure_ain_pin(config->negative_input); + } else { + _adc_configure_ain_pin(config->positive_input); + _adc_configure_ain_pin(config->negative_input); + } + + /* Configure run in standby */ + adc_module->CTRLA.reg = (config->run_in_standby << ADC_CTRLA_RUNSTDBY_Pos); + + /* Configure reference */ + adc_module->REFCTRL.reg = + (config->reference_compensation_enable << ADC_REFCTRL_REFCOMP_Pos) | + (config->reference); + + /* Set adjusting result and number of samples */ + switch (config->resolution) { + + case ADC_RESOLUTION_CUSTOM: + adjres = config->divide_result; + accumulate = config->accumulate_samples; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; + + case ADC_RESOLUTION_13BIT: + /* Increase resolution by 1 bit */ + adjres = ADC_DIVIDE_RESULT_2; + accumulate = ADC_ACCUMULATE_SAMPLES_4; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; + + case ADC_RESOLUTION_14BIT: + /* Increase resolution by 2 bit */ + adjres = ADC_DIVIDE_RESULT_4; + accumulate = ADC_ACCUMULATE_SAMPLES_16; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; +#ifdef SAMD20 + /* Please see $35.1.8 for ADC errata of SAM D20. + The revisions before D have this issue.*/ + case ADC_RESOLUTION_15BIT: + /* Increase resolution by 3 bit */ + if(revision_num < REVISON_D_NUM) { + adjres = ADC_DIVIDE_RESULT_8; + } else { + adjres = ADC_DIVIDE_RESULT_2; + } + accumulate = ADC_ACCUMULATE_SAMPLES_64; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; + + case ADC_RESOLUTION_16BIT: + if(revision_num < REVISON_D_NUM) { + /* Increase resolution by 4 bit */ + adjres = ADC_DIVIDE_RESULT_16; + } else { + adjres = ADC_DIVIDE_RESULT_DISABLE; + } + accumulate = ADC_ACCUMULATE_SAMPLES_256; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; +#else + case ADC_RESOLUTION_15BIT: + /* Increase resolution by 3 bit */ + adjres = ADC_DIVIDE_RESULT_2; + accumulate = ADC_ACCUMULATE_SAMPLES_64; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; + + case ADC_RESOLUTION_16BIT: + /* Increase resolution by 4 bit */ + adjres = ADC_DIVIDE_RESULT_DISABLE; + accumulate = ADC_ACCUMULATE_SAMPLES_256; + /* 16-bit result register */ + resolution = ADC_RESOLUTION_16BIT; + break; +#endif + case ADC_RESOLUTION_8BIT: + /* 8-bit result register */ + resolution = ADC_RESOLUTION_8BIT; + break; + case ADC_RESOLUTION_10BIT: + /* 10-bit result register */ + resolution = ADC_RESOLUTION_10BIT; + break; + case ADC_RESOLUTION_12BIT: + /* 12-bit result register */ + resolution = ADC_RESOLUTION_12BIT; + break; + + default: + /* Unknown. Abort. */ + return ADC_STATUS_ERR_INVALID_ARG; + } + + adc_module->AVGCTRL.reg = ADC_AVGCTRL_ADJRES(adjres) | accumulate; + + /* Check validity of sample length value */ + if (config->sample_length > 63) { + return ADC_STATUS_ERR_INVALID_ARG; + } else { + /* Configure sample length */ + adc_module->SAMPCTRL.reg = + (config->sample_length << ADC_SAMPCTRL_SAMPLEN_Pos); + } + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Configure CTRLB */ + adc_module->CTRLB.reg = + config->clock_prescaler | + resolution | + (config->correction.correction_enable << ADC_CTRLB_CORREN_Pos) | + (config->freerunning << ADC_CTRLB_FREERUN_Pos) | + (config->left_adjust << ADC_CTRLB_LEFTADJ_Pos) | + (config->differential_mode << ADC_CTRLB_DIFFMODE_Pos); + + /* Check validity of window thresholds */ + if (config->window.window_mode != ADC_WINDOW_MODE_DISABLE) { + switch (resolution) { + case ADC_RESOLUTION_8BIT: + if (config->differential_mode && + (config->window.window_lower_value > 127 || + config->window.window_lower_value < -128 || + config->window.window_upper_value > 127 || + config->window.window_upper_value < -128)) { + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } else if (config->window.window_lower_value > 255 || + config->window.window_upper_value > 255){ + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } + break; + case ADC_RESOLUTION_10BIT: + if (config->differential_mode && + (config->window.window_lower_value > 511 || + config->window.window_lower_value < -512 || + config->window.window_upper_value > 511 || + config->window.window_upper_value > -512)) { + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } else if (config->window.window_lower_value > 1023 || + config->window.window_upper_value > 1023){ + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } + break; + case ADC_RESOLUTION_12BIT: + if (config->differential_mode && + (config->window.window_lower_value > 2047 || + config->window.window_lower_value < -2048 || + config->window.window_upper_value > 2047 || + config->window.window_upper_value < -2048)) { + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } else if (config->window.window_lower_value > 4095 || + config->window.window_upper_value > 4095){ + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } + break; + case ADC_RESOLUTION_16BIT: + if (config->differential_mode && + (config->window.window_lower_value > 32767 || + config->window.window_lower_value < -32768 || + config->window.window_upper_value > 32767 || + config->window.window_upper_value < -32768)) { + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } else if (config->window.window_lower_value > 65535 || + config->window.window_upper_value > 65535){ + /* Invalid value */ + return ADC_STATUS_ERR_INVALID_ARG; + } + break; + } + } + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Configure window mode */ + adc_module->WINCTRL.reg = config->window.window_mode; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Configure lower threshold */ + adc_module->WINLT.reg = + config->window.window_lower_value << ADC_WINLT_WINLT_Pos; + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Configure lower threshold */ + adc_module->WINUT.reg = config->window.window_upper_value << + ADC_WINUT_WINUT_Pos; + + uint8_t inputs_to_scan = config->pin_scan.inputs_to_scan; + if (inputs_to_scan > 0) { + /* + * Number of input sources included is the value written to INPUTSCAN + * plus 1. + */ + inputs_to_scan--; + } + + if (inputs_to_scan > (ADC_INPUTCTRL_INPUTSCAN_Msk >> ADC_INPUTCTRL_INPUTSCAN_Pos) || + config->pin_scan.offset_start_scan > (ADC_INPUTCTRL_INPUTOFFSET_Msk >> ADC_INPUTCTRL_INPUTOFFSET_Pos)) { + /* Invalid number of input pins or input offset */ + return ADC_STATUS_ERR_INVALID_ARG; + } + + while (adc_is_syncing()) { + /* Wait for synchronization */ + } + + /* Configure pin scan mode and positive and negative input pins */ + adc_module->INPUTCTRL.reg = + config->gain_factor | + (config->pin_scan.offset_start_scan << + ADC_INPUTCTRL_INPUTOFFSET_Pos) | + (inputs_to_scan << ADC_INPUTCTRL_INPUTSCAN_Pos) | + config->negative_input | + config->positive_input; + + /* Configure events */ + adc_module->EVCTRL.reg = config->event_action; + + /* Disable all interrupts */ + adc_module->INTENCLR.reg = + (1 << ADC_INTENCLR_SYNCRDY_Pos) | (1 << ADC_INTENCLR_WINMON_Pos) | + (1 << ADC_INTENCLR_OVERRUN_Pos) | (1 << ADC_INTENCLR_RESRDY_Pos); + + if (config->correction.correction_enable){ + /* Make sure gain_correction value is valid */ + if (config->correction.gain_correction > ADC_GAINCORR_GAINCORR_Msk) { + return ADC_STATUS_ERR_INVALID_ARG; + } else { + /* Set gain correction value */ + adc_module->GAINCORR.reg = config->correction.gain_correction << + ADC_GAINCORR_GAINCORR_Pos; + } + + /* Make sure offset correction value is valid */ + if (config->correction.offset_correction > 2047 || + config->correction.offset_correction < -2048) { + return ADC_STATUS_ERR_INVALID_ARG; + } else { + /* Set offset correction value */ + adc_module->OFFSETCORR.reg = config->correction.offset_correction << + ADC_OFFSETCORR_OFFSETCORR_Pos; + } + } + + /* Load in the fixed device ADC calibration constants */ + adc_module->CALIB.reg = + ADC_CALIB_BIAS_CAL( + (*(uint32_t *)ADC_FUSES_BIASCAL_ADDR >> ADC_FUSES_BIASCAL_Pos) + ) | + ADC_CALIB_LINEARITY_CAL( + (*(uint64_t *)ADC_FUSES_LINEARITY_0_ADDR >> ADC_FUSES_LINEARITY_0_Pos) + ); + + return ADC_STATUS_OK; +} + +/** + * \brief Initializes the ADC + * + * Initializes the ADC device struct and the hardware module based on the + * given configuration struct values. + * + * \param[out] module_inst Pointer to the ADC software instance struct + * \param[in] hw Pointer to the ADC module instance + * \param[in] config Pointer to the configuration struct + * + * \return Status of the initialization procedure + * \retval ADC_STATUS_OK The initialization was successful + * \retval ADC_STATUS_ERR_INVALID_ARG Invalid argument(s) were provided + * \retval ADC_STATUS_BUSY The module is busy with a reset operation + * \retval ADC_STATUS_ERR_DENIED The module is enabled + */ +enum adc_status_code adc_init(Adc *hw, + struct adc_config *config) +{ + /* Sanity check arguments */ + + + + + /* Associate the software module instance with the hardware module */ + module_inst.hw = hw; + + /* Turn on the digital interface clock */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_ADC); + + if (hw->CTRLA.reg & ADC_CTRLA_SWRST) { + /* We are in the middle of a reset. Abort. */ + return ADC_STATUS_BUSY; + } + + if (hw->CTRLA.reg & ADC_CTRLA_ENABLE) { + /* Module must be disabled before initialization. Abort. */ + return ADC_STATUS_ERR_DENIED; + } + + /* Store the selected reference for later use */ + module_inst.reference = config->reference; + + for (uint8_t i = 0; i < ADC_CALLBACK_N; i++) { + module_inst.callback[i] = NULL; + }; + + module_inst.registered_callback_mask = 0; + module_inst.enabled_callback_mask = 0; + module_inst.remaining_conversions = 0; + module_inst.job_status = ADC_STATUS_OK; + + if (config->event_action == ADC_EVENT_ACTION_DISABLED && + !config->freerunning) { + module_inst.software_trigger = true; + } else { + module_inst.software_trigger = false; + } + + /* Write configuration to module */ + return _adc_set_config(config); +} + +/** Interrupt handler for the ADC module. */ +void ADC_Handler(void) +{ + awake_do_watchdog(); + + /* get interrupt flags and mask out enabled callbacks */ + uint32_t flags = module_inst.hw->INTFLAG.reg; + + if (flags & ADC_INTFLAG_RESRDY) { + /* job is complete. update status,disable interrupt + * and call callback */ + module_inst.job_status = ADC_STATUS_OK; + adc_disable_interrupt(ADC_INTERRUPT_RESULT_READY); + + (module_inst.callback[ADC_CALLBACK_READ_BUFFER])(); + } + + if (flags & ADC_INTFLAG_WINMON) { + module_inst.hw->INTFLAG.reg = ADC_INTFLAG_WINMON; + if ((module_inst.enabled_callback_mask & (1 << ADC_CALLBACK_WINDOW)) && + (module_inst.registered_callback_mask & (1 << ADC_CALLBACK_WINDOW))) { + (module_inst.callback[ADC_CALLBACK_WINDOW])(); + } + + } + + if (flags & ADC_INTFLAG_OVERRUN) { + module_inst.hw->INTFLAG.reg = ADC_INTFLAG_OVERRUN; + if ((module_inst.enabled_callback_mask & (1 << ADC_CALLBACK_ERROR)) && + (module_inst.registered_callback_mask & (1 << ADC_CALLBACK_ERROR))) { + (module_inst.callback[ADC_CALLBACK_ERROR])(); + } + } +} + +/** + * \brief Registers a callback + * + * Registers a callback function which is implemented by the user. + * + * \note The callback must be enabled by for the interrupt handler to call it + * when the condition for the callback is met. + * + * \param[in] module Pointer to ADC software instance struct + * \param[in] callback_func Pointer to callback function + * \param[in] callback_type Callback type given by an enum + * + */ +void adc_register_callback( + adc_callback_t callback_func, + enum adc_callback callback_type) +{ + /* Sanity check arguments */ + + + /* Register callback function */ + module_inst.callback[callback_type] = callback_func; + + /* Set the bit corresponding to the callback_type */ + module_inst.registered_callback_mask |= (1 << callback_type); +} + +/** + * \brief Unregisters a callback + * + * Unregisters a callback function which is implemented by the user. + * + * \param[in] module Pointer to ADC software instance struct + * \param[in] callback_type Callback type given by an enum + * + */ +void adc_unregister_callback( + enum adc_callback callback_type) +{ + /* Unregister callback function */ + module_inst.callback[callback_type] = NULL; + + /* Clear the bit corresponding to the callback_type */ + module_inst.registered_callback_mask &= ~(1 << callback_type); +} + +/** + * \brief Read multiple samples from ADC + * + * Read \c samples samples from the ADC into the buffer \c buffer. + * If there is no hardware trigger defined (event action) the + * driver will retrigger the ADC conversion whenever a conversion + * is complete until \c samples samples has been acquired. To avoid + * jitter in the sampling frequency using an event trigger is advised. + * + * \param[in] module_inst Pointer to the ADC software instance struct + * \param[in] samples Number of samples to acquire + * \param[out] buffer Buffer to store the ADC samples + * + * \return Status of the job start + * \retval STATUS_OK The conversion job was started successfully and is + * in progress + * \retval STATUS_BUSY The ADC is already busy with another job + */ +enum adc_status_code adc_read_buffer_job( + uint16_t *buffer, + uint16_t samples) +{ + + + + if(module_inst.remaining_conversions != 0 || + module_inst.job_status == ADC_STATUS_BUSY){ + return ADC_STATUS_BUSY; + } + + module_inst.job_status = ADC_STATUS_BUSY; + module_inst.remaining_conversions = samples; + module_inst.job_buffer = buffer; + + adc_enable_interrupt(ADC_INTERRUPT_RESULT_READY); + + if(module_inst.software_trigger == true) { + adc_start_conversion(); + } + + return ADC_STATUS_OK; +} + +/** + * \brief Gets the status of a job + * + * Gets the status of an ongoing or the last job. + * + * \param [in] module_inst Pointer to the ADC software instance struct + * \param [in] type Type of job to abort + * + * \return Status of the job + */ +enum adc_status_code adc_get_job_status( + enum adc_job_type type) +{ + if (type == ADC_JOB_READ_BUFFER ) { + return module_inst.job_status; + } else { + return ADC_STATUS_ERR_INVALID_ARG; + } +} diff --git a/loader/src/analogue.c b/loader/src/analogue.c new file mode 100644 index 0000000..99bd774 --- /dev/null +++ b/loader/src/analogue.c @@ -0,0 +1,202 @@ +/* + * Functions for analogue sensors + * Copyright (C) 2014 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "samd20.h" +#include "adc/adc.h" +#include "system/interrupt.h" +#include "hw_config.h" + +float battery_v = 0.0, thermistor_ratio = 0.0, solar_v = 0.0; + +#define ADC_GAINF ADC_GAIN_FACTOR_DIV2 +#define ADC_GAINF_VAL 0.5 +#define ADC_RESOLUTION ADC_RESOLUTION_12BIT +#define ADC_RESOLUTION_VAL 4096 + +enum adc_phase_t { + ADC_PHASE_NONE, + ADC_PHASE_START, +#if BATTERY_ADC + ADC_PHASE_CONVERT_BATTERY, +#endif +#if THERMISTOR_ADC + ADC_PHASE_CONVERT_THERMISTOR, +#endif +#if SOLAR_ADC + ADC_PHASE_CONVERT_SOLAR, +#endif + ADC_PHASE_DONE, +} adc_phase = ADC_PHASE_NONE; + +void adc_complete_callback(void); + +/** + * Configures ADC for a given channel + */ +void configure_adc(enum adc_positive_input input, enum adc_reference reference) +{ + struct adc_config config_adc; + adc_get_config_defaults(&config_adc); + + config_adc.clock_source = GCLK_GENERATOR_0; + config_adc.reference = reference; + config_adc.clock_prescaler = ADC_CLOCK_PRESCALER_DIV64; + config_adc.resolution = ADC_RESOLUTION; + config_adc.gain_factor = ADC_GAINF; + config_adc.positive_input = input; + config_adc.sample_length = 15; /* len = 15+1 = 16 */ + config_adc.accumulate_samples = ADC_ACCUMULATE_DISABLE; + config_adc.run_in_standby = true; + + adc_init(ADC, &config_adc); + adc_enable(); + + adc_register_callback(adc_complete_callback, ADC_CALLBACK_READ_BUFFER); + adc_enable_interrupt(ADC_INTERRUPT_RESULT_READY); + + irq_register_handler(ADC_IRQn, ADC_INT_PRIO); +} + + +/** + * Gets the channel to sample in the current phase + */ +enum adc_positive_input adc_get_channel(enum adc_phase_t phase) +{ + switch (phase) { +#if BATTERY_ADC + case ADC_PHASE_CONVERT_BATTERY: return BATTERY_ADC_CHANNEL; +#endif +#if THERMISTOR_ADC + case ADC_PHASE_CONVERT_THERMISTOR: return THERMISTOR_ADC_CHANNEL; +#endif +#if SOLAR_ADC + case ADC_PHASE_CONVERT_SOLAR: return SOLAR_ADC_CHANNEL; +#endif + default: return SOLAR_ADC_CHANNEL; + } +} +/** + * Gets the reference to use in the current phase + */ +enum adc_reference adc_get_reference(enum adc_phase_t phase) +{ + switch (phase) { +#if BATTERY_ADC + case ADC_PHASE_CONVERT_BATTERY: return BATTERY_ADC_REFERENCE; +#endif +#if THERMISTOR_ADC + case ADC_PHASE_CONVERT_THERMISTOR: return THERMISTOR_ADC_REFERENCE; +#endif +#if SOLAR_ADC + case ADC_PHASE_CONVERT_SOLAR: return SOLAR_ADC_REFERENCE; +#endif + default: return SOLAR_ADC_CHANNEL; + } +} +/** + * Assigns the value for the current phase + */ +void assign_adc_value(enum adc_phase_t phase, float pin_v) +{ + switch (phase) { +#if BATTERY_ADC + case ADC_PHASE_CONVERT_BATTERY: + battery_v = pin_v / BATTERY_ADC_CHANNEL_DIV; + break; +#endif +#if THERMISTOR_ADC + case ADC_PHASE_CONVERT_THERMISTOR: + thermistor_ratio = pin_v / THERMISTOR_ADC_CHANNEL_DIV; + break; +#endif +#if SOLAR_ADC + case ADC_PHASE_CONVERT_SOLAR: + solar_v = pin_v / SOLAR_ADC_CHANNEL_DIV; + break; +#endif + default: + break; + } +} +/** + * Is the ADC sequence done? + */ +uint8_t is_adc_sequence_done(void) { + return (adc_phase == ADC_PHASE_DONE); +} + +/** + * Called on a ADC result ready event + */ +void adc_complete_callback(void) { + uint16_t result = 0; + float pin_v; + + adc_read(&result); + adc_disable(); + + pin_v = (float)result / (ADC_GAINF_VAL * ADC_RESOLUTION_VAL); + + /* Assign this value to the correct channel */ + assign_adc_value(adc_phase, pin_v); + + adc_phase++; + if (!is_adc_sequence_done()) { /* Another channel still to do.. */ + + /* Start conversion on this channel */ + configure_adc(adc_get_channel(adc_phase), adc_get_reference(adc_phase)); + adc_start_conversion(); + } +} + +/** + * Called to start the ADC sequence + */ +void start_adc_sequence(void) +{ + /* Move to the first sampling phase */ + adc_phase = ADC_PHASE_START; + adc_phase++; + + /* Start conversion on this channel */ + configure_adc(adc_get_channel(adc_phase), adc_get_reference(adc_phase)); + adc_start_conversion(); +} + +/** + * Getters + */ +float get_battery(void) +{ + return battery_v; +} +float get_thermistor(void) +{ + return thermistor_ratio; +} +float get_solar(void) +{ + return solar_v; +} diff --git a/loader/src/flash.c b/loader/src/flash.c new file mode 100644 index 0000000..b03f647 --- /dev/null +++ b/loader/src/flash.c @@ -0,0 +1,116 @@ +/* + * Function related to the flash memory + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "samd20.h" +#include "memory.h" +#include "flash.h" + +/** + * we put our checksum at the last address in flash + */ +volatile unsigned int* flash_checksum = + (unsigned int*)(FLASH_ADDR + FLASH_SIZE - 4); + + +// ---------------------------- crc32cx -------------------------------- + +/* This is crc32b modified to load the message a fullword at a time. + It assumes the message is word aligned and consists of an integral + number of words before the 0-byte that marks the end of the message. + This works only on a little-endian machine. + Not counting the table setup (which would probably be a separate + function), this function should be doable in 3 + 22w instructions, where + w is the number of fullwords in the input message. This is equivalent to + 3 + 5.5n instructions, where n is the number of bytes. 1.25 of those 5.5 + instructions are loads. + This is Exercise 1 in the text. C.f. Christopher Dannemiller, + who got it from Linux Source base, + www.gelato.unsw.edu.au/lxr/source/lib/crc32.c, lines 105-111. */ + +unsigned int crc32cx(unsigned int *ptr, size_t length) +{ + int j; + unsigned int byte, crc, mask; + unsigned int table[256]; + + length &= ~0x3; /* must be mutiple of 4 */ + + /* Set up the table */ + for (byte = 0; byte <= 255; byte++) { + crc = byte; + for (j = 7; j >= 0; j--) { // Do eight times. + mask = -(crc & 1); + crc = (crc >> 1) ^ (0xEDB88320 & mask); + } + table[byte] = crc; + } + + /* Through with table setup, now calculate the CRC. */ + crc = 0xFFFFFFFF; + while (length != 0) { + crc = crc ^ *ptr; + crc = (crc >> 8) ^ table[crc & 0xFF]; + crc = (crc >> 8) ^ table[crc & 0xFF]; + crc = (crc >> 8) ^ table[crc & 0xFF]; + crc = (crc >> 8) ^ table[crc & 0xFF]; + + ptr++; length -= 4; + } + return ~crc; +} + +/** + * 32 bit checksum for the whole memory space + */ +unsigned int checksum_memory(void) +{ + /* do crc */ + return crc32cx((unsigned int)FLASH_ADDR, /* start */ + FLASH_SIZE - 4); /* length */ +} + +/** + * checks if memory checksum is good + */ +enum flash_state check_flash_state(void) +{ + unsigned int calculated = checksum_memory(); + + if (*flash_checksum == 0xFFFFFFFF) { /* not written */ + /* write it */ + mem_write_word((uint32_t)flash_checksum, calculated); + + return FLASH_GOOD; + + } else { /* written */ + /* check it */ + if (calculated == *flash_checksum) { + return FLASH_GOOD; + } else { + return FLASH_BAD_CSUM; + } + } +} diff --git a/loader/src/init.c b/loader/src/init.c new file mode 100644 index 0000000..b2d0d14 --- /dev/null +++ b/loader/src/init.c @@ -0,0 +1,159 @@ +/* + * Board init functions + * Copyright (C) 201 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "samd20.h" +#include "hw_config.h" +#include "system/system.h" +#include "system/port.h" +#include "system/events.h" +#include "system/extint.h" +#include "watchdog.h" +#include "xosc.h" +#include "init.h" +#include "rtc.h" + +/** + * Initialises the status LED. SHOULD TURN ON THE LED + */ +static inline void led_reset(void) +{ + port_pin_set_config(LED0_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + port_pin_set_output_level(LED0_PIN, 0); /* LED is active low */ +} + + +/** + * Radio + * ============================================================================= + */ + +/** + * Shutdown. Active High (High = Shutdown, Low = Run) + */ +#define _si_trx_sdn_enable() \ + port_pin_set_output_level(SI4xxx_SDN_PIN, 1) +#define _si_trx_sdn_disable() \ + port_pin_set_output_level(SI4xxx_SDN_PIN, 0) +/** + * Resets the radio + */ +void si_trx_shutdown(void) +{ + /* Configure the SDN pin */ + port_pin_set_config(SI4xxx_SDN_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + + /* Put the transciever in shutdown */ + _si_trx_sdn_enable(); +} + +/** + * GPS + * ============================================================================= + */ + +/** + * Reset. Places the GPS in a RESET state + */ +void gps_reset(void) +{ +#ifdef GPS_RESET_PIN + port_pin_set_config(GPS_RESET_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + port_pin_set_output_level(GPS_RESET_PIN, 0); /* active low */ +#endif +} + +/** + * Internal initialisation + * ============================================================================= + */ +void init(enum init_type init_t) +{ + /** + * Make the external watchdog safely armed, ready to trigger if we don't call watchdog_init. + * (hw v0.987.3 adds an external resistor for this, this call can be removed then) + */ + external_watchdog_safe(); + + /** + * OSC8M should be considered unstable due to the temperature range. Therefore + * we need to switch to a stable low frequency clock right away. + * -------------------------------------------------------------------------- + */ + lf_clock_startup(); /* 100-200ms startup */ + gclk0_to_lf_clock(); /* switch, clocking at 32kHz now */ + system_clock_source_disable(SYSTEM_CLOCK_SOURCE_OSC8M); + + /** + * Reset to get the system in a safe state + * -------------------------------------------------------------------------- + */ + led_reset(); + gps_reset(); + si_trx_shutdown(); + + /** + * Watchdog bringup, includes first kick + * -------------------------------------------------------------------------- + */ + if (init_t != INIT_TESTCASE) { + watchdog_init(); + } + + /** + * Internal initialisation + * --------------------------------------------------------------------------- + */ + + /* Switch to high frequency clock */ + hf_clock_init(); /* TCXO powered on */ + hf_clock_enable(); /* TCXO startup time.. */ + gclk0_to_hf_clock(); /* and switch, clock at 8MHz */ + gclk1_init(); + gclk2_init(); + + /* Clock up to 14MHz with 0 wait states */ + system_flash_set_waitstates(SYSTEM_WAIT_STATE_1_8V_14MHZ); + + /* Restart the GCLK Module */ + system_events_init(); + system_extint_init(); + + /* Configure Sleep Mode */ + system_set_sleepmode(SYSTEM_SLEEPMODE_IDLE_2); /* Lowest power */ + + /* Start rtc */ + rtc_init(); + + /* We've done good things, kick wdt */ + kick_the_watchdog(); +} diff --git a/loader/src/loader.c b/loader/src/loader.c new file mode 100644 index 0000000..148b0fe --- /dev/null +++ b/loader/src/loader.c @@ -0,0 +1,45 @@ +/* + * bootloader functions + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "samd20.h" + +#define APPLICATION_BASE (0x00004000) /* 16K */ + +/** + * transfers control to application + */ +void transfer_to_application(void) +{ + void (*application_ptr)(void); + + /* new stack pointer */ + __set_MSP(*(uint32_t *)APPLICATION_BASE); + + /* new vector table */ + SCB->VTOR = ((uint32_t)APPLICATION_BASE & SCB_VTOR_TBLOFF_Msk); + + /* Jump to application reset handler */ + application_ptr = (void (*)(void))(unsigned *)(*(unsigned *)(APPLICATION_BASE + 4)); + application_ptr(); +} diff --git a/loader/src/main.c b/loader/src/main.c new file mode 100644 index 0000000..b383a53 --- /dev/null +++ b/loader/src/main.c @@ -0,0 +1,72 @@ +/* + * Bristol SEDS pico-tracker + * Copyright (C) 2014 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include + +#include "samd20.h" +#include "hw_config.h" +#include "init.h" +#include "watchdog.h" +#include "analogue.h" +#include "xosc.h" +#include "loader.h" + +/** + * MAIN + * ============================================================================= + */ +int main(void) +{ + /* Init */ + init(INIT_NORMAL); + + /* Stay in low power mode until power/temperature are high enough */ + do { + led_off(); + idle(IDLE_LOADER); + led_on(); + + /* Read sensors */ + start_adc_sequence(); + while (is_adc_sequence_done() == 0) { + idle(IDLE_LOADER); + } + + /* Check battery */ + } while (get_battery() < 4.0); + + + /* Check and repair memory */ + + + /* Transfer control to application */ + transfer_to_application(); + + /* Should never get here */ + while (1) { + idle(IDLE_LOADER); + } +} diff --git a/loader/src/memory.c b/loader/src/memory.c new file mode 100644 index 0000000..492cafd --- /dev/null +++ b/loader/src/memory.c @@ -0,0 +1,200 @@ +/* + * Provides functions for using the external flash memory + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "samd20.h" +#include "memory.h" +#include "sercom/spi.h" +#include "hw_config.h" + +/** + * See Errata 10804 for more details, d/s §35.3.16 + * Silicon Revision C + */ +#define FIX_ERRATA_REV_C_FLASH_10804 + +#define MEM_SIZE 16384 /* 16 KB */ +/** + * Allocate a 16KB section of flash memory, aligned to an NVM row + */ +const uint8_t nvm_section[MEM_SIZE] + __attribute__ ((aligned (256))) + __attribute__ ((section (".eeprom"))) + = { 0xFF }; + +/** + * Poll the status register until the busy bit is cleared + */ +void _mem_wait_for_done(void) +{ + while ((NVMCTRL->INTFLAG.reg & NVMCTRL_INTFLAG_READY) == 0); +} + + +/** + * ============================================================================= + * Public Methods ============================================================== + * ============================================================================= + */ + +/** + * Simple Commands + */ +void mem_chip_erase(void) +{ +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* save CTRLB and disable cache */ + uint32_t temp = NVMCTRL->CTRLB.reg; + NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_CACHEDIS; +#endif + + /* erase each row */ + for (int n = 0; n < TOTAL_ROWS; n++) { + /* write address */ + NVMCTRL->ADDR.reg = (uint32_t)(nvm_section + (n*ROW_SIZE)) >> 1; + /* unlock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_UR; + /* erase */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER; + _mem_wait_for_done(); + /* lock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_LR; + } + +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* restore CTRLB */ + NVMCTRL->CTRLB.reg = temp; +#endif +} + +/** + * Read memory + */ +void mem_read_memory(uint32_t address, uint8_t* buffer, uint32_t length) +{ + memcpy(buffer, nvm_section + address, length); +} +/** + * Write single word + */ +void mem_write_word(uint32_t address, uint32_t word) +{ +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* save CTRLB and disable cache */ + uint32_t temp = NVMCTRL->CTRLB.reg; + NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_CACHEDIS; +#endif + + /* write address */ + NVMCTRL->ADDR.reg = (uint32_t)(address) >> 1; + /* write data. length must be multiple of two */ + *(uint32_t*)address = word; + /* unlock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_UR; + /* write page */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP; + _mem_wait_for_done(); + /* lock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_LR; + +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* restore CTRLB */ + NVMCTRL->CTRLB.reg = temp; +#endif +} +/** + * Write 64-byte page. Address should be page aligned + */ +void mem_write_page(uint32_t address, uint8_t* buffer, uint16_t length) +{ +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* save CTRLB and disable cache */ + uint32_t temp = NVMCTRL->CTRLB.reg; + NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_CACHEDIS; +#endif + + if ((address < MEM_SIZE) && (length <= PAGE_SIZE)) { + /* write address */ + NVMCTRL->ADDR.reg = (uint32_t)(nvm_section + address) >> 1; + /* write data. length must be multiple of two */ + memcpy((void*)(nvm_section + address), buffer, length & ~0x1); + /* unlock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_UR; + /* write page */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_WP; + _mem_wait_for_done(); + /* lock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_LR; + } + +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* restore CTRLB */ + NVMCTRL->CTRLB.reg = temp; +#endif +} +/** + * Erase 256-byte sector. + */ +void mem_erase_sector(uint32_t address) +{ +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* save CTRLB and disable cache */ + uint32_t temp = NVMCTRL->CTRLB.reg; + NVMCTRL->CTRLB.reg |= NVMCTRL_CTRLB_CACHEDIS; +#endif + + if (address < MEM_SIZE) { + /* write address */ + NVMCTRL->ADDR.reg = (uint32_t)(nvm_section + address) >> 1; + /* unlock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_UR; + _mem_wait_for_done(); + /* erase row */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_ER; + _mem_wait_for_done(); + /* lock */ + NVMCTRL->CTRLA.reg = NVMCTRL_CTRLA_CMDEX_KEY | NVMCTRL_CTRLA_CMD_LR; + } + +#ifdef FIX_ERRATA_REV_C_FLASH_10804 + /* restore CTRLB */ + NVMCTRL->CTRLB.reg = temp; +#endif +} + +/** + * Initialise and Power on Memory Interface + * + * Returns 1 on success, 0 on failure + */ +uint8_t mem_power_on(void) +{ + /* NVMCTRL is enabled by default */ + return 1; +} +/** + * Return memory to lowest power state + */ +void mem_power_off(void) +{ +} diff --git a/loader/src/rtc.c b/loader/src/rtc.c new file mode 100644 index 0000000..7167813 --- /dev/null +++ b/loader/src/rtc.c @@ -0,0 +1,77 @@ +/* + * Initialised RTC to provide 1Hz event and interrupt + * Copyright (C) 2016 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "samd20.h" +#include "hw_config.h" +#include "system/interrupt.h" +#include "system/rtc_count.h" +#include "system/events.h" + +/** + * Initialises RTC to provide 1Hz event and interrupt + */ +void rtc_init(void) +{ + /* 16 bit, 1024Hz clock in on GCLK2 */ + struct rtc_count_config config_rtc_count; + rtc_count_get_config_defaults(&config_rtc_count); + config_rtc_count.prescaler = RTC_COUNT_PRESCALER_DIV_1024; + config_rtc_count.mode = RTC_COUNT_MODE_16BIT; + rtc_count_init(&config_rtc_count); + + /* Enable event generation for PER7 only */ + struct rtc_count_events config_events; + config_events.generate_event_on_overflow = false; + for (uint8_t i = 0; i < RTC_NUM_OF_COMP16; i++) { + config_events.generate_event_on_compare[i] = false; + } + for (uint8_t i = 0; i < 8; i++) { + config_events.generate_event_on_periodic[i] = false; + } + config_events.generate_event_on_periodic[7] = true; + rtc_count_enable_events(&config_events); + + /* Enable interrupts */ + RTC->MODE1.INTENSET.reg |= RTC_MODE1_INTENSET_OVF; /* Overflow interrupt */ + irq_register_handler(RTC_IRQn, RTC_INT_PRIO); /* Lowest Priority */ + + /* Enable */ + rtc_count_enable(); + rtc_count_set_period(0); /* overflow on every tick */ +} + +/** + * Tick functions + * ============================================================================= + */ + +/** + * Interrupt for RTC, called at 1Hz + */ +void RTC_Handler(void) +{ + if (RTC->MODE1.INTFLAG.reg & RTC_MODE1_INTFLAG_OVF) { + RTC->MODE1.INTFLAG.reg |= RTC_MODE1_INTFLAG_OVF; /* Clear flag */ + } +} diff --git a/loader/src/sercom/i2c.c b/loader/src/sercom/i2c.c new file mode 100644 index 0000000..d63ded2 --- /dev/null +++ b/loader/src/sercom/i2c.c @@ -0,0 +1,105 @@ +/* + * A wrapper around the samd20 i2c functions. Single master only + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include "sercom/i2c_master.h" + +/** + * We just declare our single instance here because. Very naughty + */ +struct i2c_master_module i2c_master_instance; + +/** + * I2C Write. + * + * address is the full write address like 0xEE + */ +void i2c_master_write(uint8_t address, uint8_t* data, uint16_t data_length) +{ + uint32_t timeout = 0; + struct i2c_master_packet packet = { + .address = address >> 1, + .data_length = data_length, + .data = data, + .ten_bit_address = false, + .high_speed = false, + .hs_master_code = 0x0, + }; + + while (i2c_master_write_packet_wait(&i2c_master_instance, &packet) != + STATUS_OK) { + /* Increment timeout counter and check if timed out. */ + if (timeout++ > 20) { + break; + } + } +} + + +/** + * I2C Read. + * + * address is the full write address like 0xEE + */ +void i2c_master_read(uint8_t address, uint8_t* data, uint16_t data_length) +{ + uint32_t timeout = 0; + struct i2c_master_packet packet = { + .address = address >> 1, + .data_length = data_length, + .data = data, + .ten_bit_address = false, + .high_speed = false, + .hs_master_code = 0x0, + }; + + while (i2c_master_read_packet_wait(&i2c_master_instance, &packet) != + STATUS_OK) { + /* Increment timeout counter and check if timed out. */ + if (timeout++ > 20) { + break; + } + } +} + + +/** + * I2C bus master. + */ +void i2c_init(SercomI2cm*const sercom, uint32_t pad0_pinmux, uint32_t pad1_pinmux) +{ + struct i2c_master_config config_i2c_master; + i2c_master_get_config_defaults(&config_i2c_master); + + /* Config */ + config_i2c_master.buffer_timeout = 10000; + config_i2c_master.baud_rate = 100; /* 100 kBaud */ + + /* Pinmux */ + config_i2c_master.pinmux_pad0 = pad0_pinmux; + config_i2c_master.pinmux_pad1 = pad1_pinmux; + + /* Initialize and enable device with config. */ + i2c_master_init(&i2c_master_instance, (Sercom*)sercom, &config_i2c_master); + i2c_master_enable(&i2c_master_instance); +} diff --git a/loader/src/sercom/i2c_master.c b/loader/src/sercom/i2c_master.c new file mode 100644 index 0000000..ff8dbdd --- /dev/null +++ b/loader/src/sercom/i2c_master.c @@ -0,0 +1,739 @@ +/** + * \file + * + * \brief SAM D20 I2C Master Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "sercom/i2c_master.h" +#include "system/pinmux.h" + +#if I2C_MASTER_CALLBACK_MODE == true +# include "i2c_master_interrupt.h" +#endif + +#if !defined(__DOXYGEN__) + +/** + * \internal Sets configurations to module + * + * \param[out] module Pointer to software module structure. + * \param[in] config Configuration structure with configurations to set. + * + * \return Status of setting configuration. + * \retval STATUS_OK If module was configured correctly + * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than + * previously set + * \retval STATUS_ERR_BAUDRATE_UNAVAILABLE If given baud rate is not compatible + * with set GCLK frequency + */ +static enum status_code _i2c_master_set_config( + struct i2c_master_module *const module, + const struct i2c_master_config *const config) +{ + /* Sanity check arguments. */ + Assert(module); + Assert(module->hw); + Assert(config); + + /* Temporary variables. */ + uint32_t tmp_ctrla; + int32_t tmp_baud; + enum status_code tmp_status_code = STATUS_OK; + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + Sercom *const sercom_hw = module->hw; + + uint8_t sercom_index = _sercom_get_sercom_inst_index(sercom_hw); + + /* Pin configuration */ + + uint32_t pad0 = config->pinmux_pad0; + uint32_t pad1 = config->pinmux_pad1; + + /* SERCOM PAD0 - SDA */ + if (pad0 == PINMUX_DEFAULT) { + pad0 = _sercom_get_default_pad(sercom_hw, 0); + } + system_pinmux_pin_set_config(pad0 >> 16, + pad0 & 0xFFFF, + SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK, + SYSTEM_PINMUX_PIN_PULL_UP, + false); + + /* SERCOM PAD1 - SCL */ + if (pad1 == PINMUX_DEFAULT) { + pad1 = _sercom_get_default_pad(sercom_hw, 1); + } + system_pinmux_pin_set_config(pad1 >> 16, + pad1 & 0xFFFF, + SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK, + SYSTEM_PINMUX_PIN_PULL_UP, + false); + + + /* Save timeout on unknown bus state in software module. */ + module->unknown_bus_state_timeout = config->unknown_bus_state_timeout; + + /* Save timeout on buffer write. */ + module->buffer_timeout = config->buffer_timeout; + + /* Set whether module should run in standby. */ + if (config->run_in_standby || system_is_debugger_present()) { + tmp_ctrla = SERCOM_I2CM_CTRLA_RUNSTDBY; + } else { + tmp_ctrla = 0; + } + + /* Check and set start data hold timeout. */ + if (config->start_hold_time != I2C_MASTER_START_HOLD_TIME_DISABLED) { + tmp_ctrla |= config->start_hold_time; + } + + /* Check and set SCL low timeout. */ + if (config->scl_low_timeout) { + tmp_ctrla |= SERCOM_I2CM_CTRLA_LOWTOUT; + } + + /* Check and set inactive bus timeout. */ + if (config->inactive_timeout != I2C_MASTER_INACTIVE_TIMEOUT_DISABLED) { + tmp_ctrla |= config->inactive_timeout; + } + + /* Write config to register CTRLA. */ + i2c_module->CTRLA.reg |= tmp_ctrla; + + /* Set configurations in CTRLB. */ + i2c_module->CTRLB.reg = SERCOM_I2CM_CTRLB_SMEN; + + /* Find and set baudrate. */ + tmp_baud = (int32_t)(system_gclk_chan_get_hz(SERCOM0_GCLK_ID_CORE + sercom_index) / + (2000*(config->baud_rate)) - 5); + + /* Check that baud rate is supported at current speed. */ + if (tmp_baud > 255 || tmp_baud < 0) { + /* Baud rate not supported. */ + tmp_status_code = STATUS_ERR_BAUDRATE_UNAVAILABLE; + } else { + /* Baud rate acceptable. */ + i2c_module->BAUD.reg = (uint8_t)tmp_baud; + } + + return tmp_status_code; +} +#endif /* __DOXYGEN__ */ + +/** + * \brief Initializes the requested I2C hardware module + * + * Initializes the SERCOM I2C master device requested and sets the provided + * software module struct. Run this function before any further use of + * the driver. + * + * \param[out] module Pointer to software module struct + * \param[in] hw Pointer to the hardware instance + * \param[in] config Pointer to the configuration struct + * + * \return Status of initialization. + * \retval STATUS_OK Module initiated correctly + * \retval STATUS_ERR_DENIED If module is enabled + * \retval STATUS_BUSY If module is busy resetting + * \retval STATUS_ERR_ALREADY_INITIALIZED If setting other GCLK generator than + * previously set + * \retval STATUS_ERR_BAUDRATE_UNAVAILABLE If given baudrate is not compatible + * with set GCLK frequency + * + */ +enum status_code i2c_master_init( + struct i2c_master_module *const module, + Sercom *const hw, + const struct i2c_master_config *const config) +{ + /* Sanity check arguments. */ + Assert(module); + Assert(hw); + Assert(config); + + /* Initialize software module */ + module->hw = hw; + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + uint32_t sercom_index = _sercom_get_sercom_inst_index(module->hw); + uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos; + uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; + + /* Turn on module in PM */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index); + + /* Set up the GCLK for the module */ + + + + system_gclk_chan_set_config(gclk_index, config->generator_source); + system_gclk_chan_enable(gclk_index); + _sercom_set_gclk_generator(config->generator_source); + + /* Check if module is enabled. */ + if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_ENABLE) { + return STATUS_ERR_DENIED; + } + + /* Check if reset is in progress. */ + if (i2c_module->CTRLA.reg & SERCOM_I2CM_CTRLA_SWRST) { + return STATUS_BUSY; + } + +#if I2C_MASTER_CALLBACK_MODE == true + /* Get sercom instance index and register callback. */ + uint8_t instance_index = _sercom_get_sercom_inst_index(module->hw); + _sercom_set_handler(instance_index, _i2c_master_interrupt_handler); + _sercom_instances[instance_index] = module; + + /* Initialize values in module. */ + module->registered_callback = 0; + module->enabled_callback = 0; + module->buffer_length = 0; + module->buffer_remaining = 0; + + module->status = STATUS_OK; + module->buffer = NULL; +#endif + + /* Set sercom module to operate in I2C master mode. */ + i2c_module->CTRLA.reg = SERCOM_I2CM_CTRLA_MODE_I2C_MASTER; + + /* Set config and return status. */ + return _i2c_master_set_config(module, config); +} + +/** + * \brief Resets the hardware module + * + * Reset the module to hardware defaults. + * + * \param[in,out] module Pointer to software module structure + */ +void i2c_master_reset(struct i2c_master_module *const module) +{ + /* Sanity check arguments */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Wait for sync */ + _i2c_master_wait_for_sync(module); + + /* Disable module */ + i2c_master_disable(module); + +#if I2C_MASTER_CALLBACK_MODE == true + /* Clear all pending interrupts */ + system_interrupt_enter_critical_section(); + system_interrupt_clear_pending(_sercom_get_interrupt_vector(module->hw)); + system_interrupt_leave_critical_section(); +#endif + + /* Wait for sync */ + _i2c_master_wait_for_sync(module); + + /* Reset module */ + i2c_module->CTRLA.reg = SERCOM_I2CM_CTRLA_SWRST; +} + +#if !defined(__DOXYGEN__) +/** + * \internal + * Address response. Called when address is answered or timed out. + * + * \param[in,out] module Pointer to software module structure + * + * \return Status of address response. + * \retval STATUS_OK No error has occurred + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + */ +static enum status_code _i2c_master_address_response( + struct i2c_master_module *const module) +{ + /* Sanity check arguments */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Check for error and ignore bus-error; workaround for BUSSTATE stuck in + * BUSY */ + if (i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_SB) { + + /* Clear write interrupt flag */ + i2c_module->INTFLAG.reg = SERCOM_I2CM_INTFLAG_SB; + + /* Check arbitration. */ + if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_ARBLOST) { + /* Return packet collision. */ + return STATUS_ERR_PACKET_COLLISION; + } + /* Check that slave responded with ack. */ + } else if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) { + /* Slave busy. Issue ack and stop command. */ + i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3); + + /* Return bad address value. */ + return STATUS_ERR_BAD_ADDRESS; + } + + return STATUS_OK; +} + +/** + * \internal + * Waits for answer on bus. + * + * \param[in,out] module Pointer to software module structure + * + * \return Status of bus. + * \retval STATUS_OK If given response from slave device + * \retval STATUS_ERR_TIMEOUT If no response was given within specified timeout + * period + */ +static enum status_code _i2c_master_wait_for_bus( + struct i2c_master_module *const module) +{ + /* Sanity check arguments */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Wait for reply. */ + uint16_t timeout_counter = 0; + while (!(i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_MB) && + !(i2c_module->INTFLAG.reg & SERCOM_I2CM_INTFLAG_SB)) { + + /* Check timeout condition. */ + if (++timeout_counter >= module->buffer_timeout) { + return STATUS_ERR_TIMEOUT; + } + } + return STATUS_OK; +} +#endif /* __DOXYGEN__ */ + +/** + * \internal + * Starts blocking read operation. + * + * \param[in,out] module Pointer to software module struct. + * \param[in,out] packet Pointer to I2C packet to transfer. + * + * \return Status of reading packet. + * \retval STATUS_OK The packet was read successfully + * \retval STATUS_ERR_TIMEOUT If no response was given within + * specified timeout period + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + * + */ +static enum status_code _i2c_master_read_packet( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + /* Sanity check arguments */ + Assert(module); + Assert(module->hw); + Assert(packet); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Return value. */ + enum status_code tmp_status; + uint16_t tmp_data_length = packet->data_length; + + /* Written buffer counter. */ + uint16_t counter = 0; + + /* Set address and direction bit. Will send start command on bus. */ + i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_READ; + + /* Wait for response on bus. */ + tmp_status = _i2c_master_wait_for_bus(module); + + /* Set action to ack. */ + i2c_module->CTRLB.reg &= ~SERCOM_I2CM_CTRLB_ACKACT; + + /* Check for address response error unless previous error is + * detected. */ + if (tmp_status == STATUS_OK) { + tmp_status = _i2c_master_address_response(module); + } + + /* Check that no error has occurred. */ + if (tmp_status == STATUS_OK) { + /* Read data buffer. */ + while (tmp_data_length--) { + /* Check that bus ownership is not lost. */ + if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) { + return STATUS_ERR_PACKET_COLLISION; + } + + if (tmp_data_length == 0) { + /* Set action to NACK */ + i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_ACKACT; + } else { + /* Save data to buffer. */ + _i2c_master_wait_for_sync(module); + packet->data[counter++] = i2c_module->DATA.reg; + /* Wait for response. */ + tmp_status = _i2c_master_wait_for_bus(module); + } + + /* Check for error. */ + if (tmp_status != STATUS_OK) { + break; + } + } + + if (module->send_stop) { + /* Send stop command unless arbitration is lost. */ + _i2c_master_wait_for_sync(module); + i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3); + } + + /* Save last data to buffer. */ + _i2c_master_wait_for_sync(module); + packet->data[counter] = i2c_module->DATA.reg; + } + + return tmp_status; +} + +/** + * \brief Reads data packet from slave + * + * Reads a data packet from the specified slave address on the I2C + * bus and sends a stop condition when finished. + * + * \note This will stall the device from any other operation. For + * interrupt-driven operation, see \ref i2c_master_read_packet_job. + * + * \param[in,out] module Pointer to software module struct + * \param[in,out] packet Pointer to I2C packet to transfer + * + * \return Status of reading packet. + * \retval STATUS_OK The packet was read successfully + * \retval STATUS_ERR_TIMEOUT If no response was given within + * specified timeout period + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + */ +enum status_code i2c_master_read_packet_wait( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + Assert(packet); + +#if I2C_MASTER_CALLBACK_MODE == true + /* Check if the I2C module is busy with a job. */ + if (module->buffer_remaining > 0) { + return STATUS_BUSY; + } +#endif + + module->send_stop = true; + + return _i2c_master_read_packet(module, packet); +} + +/** + * \brief Reads data packet from slave without sending a stop condition when done + * + * Reads a data packet from the specified slave address on the I2C + * bus without sending a stop condition when done, thus retaining ownership of + * the bus when done. To end the transaction, a + * \ref i2c_master_read_packet_wait "read" or + * \ref i2c_master_write_packet_wait "write" with stop condition must be + * performed. + * + * \note This will stall the device from any other operation. For + * interrupt-driven operation, see \ref i2c_master_read_packet_job. + * + * \param[in,out] module Pointer to software module struct + * \param[in,out] packet Pointer to I2C packet to transfer + * + * \return Status of reading packet. + * \retval STATUS_OK The packet was read successfully + * \retval STATUS_ERR_TIMEOUT If no response was given within + * specified timeout period + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + */ +enum status_code i2c_master_read_packet_wait_no_stop( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + Assert(packet); + +#if I2C_MASTER_CALLBACK_MODE == true + /* Check if the I2C module is busy with a job. */ + if (module->buffer_remaining > 0) { + return STATUS_BUSY; + } +#endif + + module->send_stop = false; + + return _i2c_master_read_packet(module, packet); +} + +/** + * \internal + * Starts blocking write operation. + * + * \param[in,out] module Pointer to software module struct. + * \param[in,out] packet Pointer to I2C packet to transfer. + * + * \return Status of reading packet. + * \retval STATUS_OK The packet was read successfully + * \retval STATUS_ERR_TIMEOUT If no response was given within + * specified timeout period + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + */ +static enum status_code _i2c_master_write_packet( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Return value. */ + enum status_code tmp_status; + uint16_t tmp_data_length = packet->data_length; + + _i2c_master_wait_for_sync(module); + + /* Set address and direction bit. Will send start command on bus. */ + i2c_module->ADDR.reg = (packet->address << 1) | I2C_TRANSFER_WRITE; + + /* Wait for response on bus. */ + tmp_status = _i2c_master_wait_for_bus(module); + + /* Check for address response error unless previous error is + * detected. */ + if (tmp_status == STATUS_OK) { + tmp_status = _i2c_master_address_response(module); + } + + /* Check that no error has occurred. */ + if (tmp_status == STATUS_OK) { + /* Buffer counter. */ + uint16_t buffer_counter = 0; + + /* Write data buffer. */ + while (tmp_data_length--) { + /* Check that bus ownership is not lost. */ + if (!(i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_BUSSTATE(2))) { + return STATUS_ERR_PACKET_COLLISION; + } + + /* Write byte to slave. */ + _i2c_master_wait_for_sync(module); + i2c_module->DATA.reg = packet->data[buffer_counter++]; + + /* Wait for response. */ + tmp_status = _i2c_master_wait_for_bus(module); + + /* Check for error. */ + if (tmp_status != STATUS_OK) { + break; + } + + /* Check for NACK from slave. */ + if (i2c_module->STATUS.reg & SERCOM_I2CM_STATUS_RXNACK) { + /* Return bad data value. */ + tmp_status = STATUS_ERR_OVERFLOW; + break; + } + } + + if (module->send_stop) { + /* Stop command */ + _i2c_master_wait_for_sync(module); + i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3); + } + } + + return tmp_status; +} + +/** + * \brief Writes data packet to slave + * + * Writes a data packet to the specified slave address on the I2C bus + * and sends a stop condition when finished. + * + * \note This will stall the device from any other operation. For + * interrupt-driven operation, see \ref i2c_master_read_packet_job. + * + * \param[in,out] module Pointer to software module struct + * \param[in,out] packet Pointer to I2C packet to transfer + * + * \return Status of reading packet. + * \retval STATUS_OK If packet was read + * \retval STATUS_BUSY If master module is busy with a job + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + * \retval STATUS_ERR_TIMEOUT If timeout occurred + * \retval STATUS_ERR_OVERFLOW If slave did not acknowledge last sent + * data, indicating that slave does not + * want more data and was not able to read + * last data sent + */ +enum status_code i2c_master_write_packet_wait( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + Assert(packet); + +#if I2C_MASTER_CALLBACK_MODE == true + /* Check if the I2C module is busy with a job */ + if (module->buffer_remaining > 0) { + return STATUS_BUSY; + } +#endif + + module->send_stop = true; + + return _i2c_master_write_packet(module, packet); +} + +/** + * \brief Writes data packet to slave without sending a stop condition when done + * + * Writes a data packet to the specified slave address on the I2C bus + * without sending a stop condition, thus retaining ownership of the bus when + * done. To end the transaction, a \ref i2c_master_read_packet_wait "read" or + * \ref i2c_master_write_packet_wait "write" with stop condition or sending a + * stop with the \ref i2c_master_send_stop function must be performed. + * + * \note This will stall the device from any other operation. For + * interrupt-driven operation, see \ref i2c_master_read_packet_job. + * + * \param[in,out] module Pointer to software module struct + * \param[in,out] packet Pointer to I2C packet to transfer + * + * \return Status of reading packet. + * \retval STATUS_OK If packet was read + * \retval STATUS_BUSY If master module is busy + * \retval STATUS_ERR_DENIED If error on bus + * \retval STATUS_ERR_PACKET_COLLISION If arbitration is lost + * \retval STATUS_ERR_BAD_ADDRESS If slave is busy, or no slave + * acknowledged the address + * \retval STATUS_ERR_TIMEOUT If timeout occurred + * \retval STATUS_ERR_OVERFLOW If slave did not acknowledge last sent + * data, indicating that slave do not want + * more data + */ +enum status_code i2c_master_write_packet_wait_no_stop( + struct i2c_master_module *const module, + struct i2c_master_packet *const packet) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + Assert(packet); + +#if I2C_MASTER_CALLBACK_MODE == true + /* Check if the I2C module is busy with a job */ + if (module->buffer_remaining > 0) { + return STATUS_BUSY; + } +#endif + + module->send_stop = false; + + return _i2c_master_write_packet(module, packet); +} + +/** + * \brief Sends stop condition on bus + * + * Sends a stop condition on bus. + * + * \note This function can only be used after the + * \ref i2c_master_write_packet_wait_no_stop function. If a stop condition + * is to be sent after a read, the \ref i2c_master_read_packet_wait + * function must be used. + * + * \param[in] module Pointer to the software instance struct + */ +void i2c_master_send_stop(struct i2c_master_module *const module) +{ + /* Sanity check */ + Assert(module); + Assert(module->hw); + + SercomI2cm *const i2c_module = &(module->hw->I2CM); + + /* Send stop command */ + _i2c_master_wait_for_sync(module); + i2c_module->CTRLB.reg |= SERCOM_I2CM_CTRLB_CMD(3); +} diff --git a/loader/src/sercom/sercom.c b/loader/src/sercom/sercom.c new file mode 100644 index 0000000..c3f12c0 --- /dev/null +++ b/loader/src/sercom/sercom.c @@ -0,0 +1,304 @@ +/** + * SAM D20/D21/R21 Serial Peripheral Interface Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "samd20.h" + +#include "sercom/sercom.h" +#include "util/mrecursion.h" +#include "hw_config.h" + +/** + * Sercom Configuration + */ +#define SHIFT 32 +#define BAUD_INT_MAX 8192 +#define BAUD_FP_MAX 8 + +/** + * Find index of given instance. + */ +uint8_t _sercom_get_sercom_inst_index(Sercom *const sercom_instance) +{ + /* Save all available SERCOM instances for compare. */ + Sercom *sercom_instances[SERCOM_INST_NUM] = SERCOM_INSTS; + + /* Find index for sercom instance. */ + for (uint32_t i = 0; i < SERCOM_INST_NUM; i++) { + if ((uintptr_t)sercom_instance == (uintptr_t)sercom_instances[i]) { + return i; + } + } + + /* Invalid data given. */ + while (1); + return 0; +} + +/** Error callback for unregistered sercom interrupt handlers */ +void sercom_unregistered_handler(Sercom* const sercom_instance, uint8_t instance_index) { + (void)sercom_instance; + (void)instance_index; + + /* Unregisted Handler for Sercom %d called! HALT */ + + while (1); +} + +/** Void pointers for sercom interrupt handlers */ +static void (*_sercom_interrupt_handlers[SERCOM_INST_NUM])(Sercom* const sercom_instance, + uint8_t instance_index) = { +#if SERCOM_INST_NUM > 0 + sercom_unregistered_handler, +#endif +#if SERCOM_INST_NUM > 1 + sercom_unregistered_handler, +#endif +#if SERCOM_INST_NUM > 2 + sercom_unregistered_handler, +#endif +#if SERCOM_INST_NUM > 3 + sercom_unregistered_handler, +#endif +#if SERCOM_INST_NUM > 4 + sercom_unregistered_handler, +#endif +#if SERCOM_INST_NUM > 5 + sercom_unregistered_handler, +#endif +}; + +/** Sercom interrupt handlers */ +#define SERCOM_INTERRUPT_HANDLER(n) \ + void SERCOM##n##_Handler(void) \ + { \ + _sercom_interrupt_handlers[n](SERCOM##n, n); \ + } +#if SERCOM_INST_NUM > 0 +SERCOM_INTERRUPT_HANDLER(0) +#endif +#if SERCOM_INST_NUM > 1 +SERCOM_INTERRUPT_HANDLER(1) +#endif +#if SERCOM_INST_NUM > 2 +SERCOM_INTERRUPT_HANDLER(2) +#endif +#if SERCOM_INST_NUM > 3 +SERCOM_INTERRUPT_HANDLER(3) +#endif +#if SERCOM_INST_NUM > 4 +SERCOM_INTERRUPT_HANDLER(4) +#endif +#if SERCOM_INST_NUM > 5 +SERCOM_INTERRUPT_HANDLER(5) +#endif + +/** + * Sets an interrupt handler + */ +void _sercom_set_handler(Sercom* const sercom_instance, + const sercom_handler_t interrupt_handler) +{ + /* Retrieve the index of the SERCOM being requested */ + uint8_t instance_index = _sercom_get_sercom_inst_index(sercom_instance); + + /* Set the interrupt handler */ + _sercom_interrupt_handlers[instance_index] = interrupt_handler; +} + +/** + * Calculate synchronous baudrate value (SPI/UART) + */ +enum sercom_status_t _sercom_get_sync_baud_val(const uint32_t baudrate, + const uint32_t external_clock, + uint16_t *const baudvalue) +{ + /* Baud value variable */ + uint16_t baud_calculated = 0; + + /* Check if baudrate is outside of valid range. */ + if (baudrate > (external_clock / 2)) { + /* Return with error code */ + return SERCOM_STATUS_BAUDRATE_UNAVAILABLE; + } + + /* Calculate BAUD value from clock frequency and baudrate */ + baud_calculated = (external_clock / (2 * baudrate)) - 1; + + /* Check if BAUD value is more than 255, which is maximum + * for synchronous mode */ + if (baud_calculated > 0xFF) { + /* Return with an error code */ + return SERCOM_STATUS_BAUDRATE_UNAVAILABLE; + } else { + *baudvalue = baud_calculated; + return SERCOM_STATUS_OK; + } +} + +/** + * Calculate asynchronous baudrate value (UART) + */ +enum sercom_status_t _sercom_get_async_baud_val(uint32_t baudrate, + uint32_t peripheral_clock, + uint16_t *const baudval, + enum sercom_asynchronous_operation_mode mode, + enum sercom_asynchronous_sample_num sample_num) +{ + /* Force variable */ + baudrate = GPS_BAUD_RATE; + peripheral_clock = (XOSC_FREQUENCY/XOSC_GCLK_DIVIDE); + mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; + + /* Temporary variables */ + uint64_t ratio = 0; + uint64_t scale = 0; + uint64_t baud_calculated = 0; + uint8_t baud_fp; + uint32_t baud_int; + + /* Check if the baudrate is outside of valid range */ + if ((baudrate * sample_num) >= peripheral_clock) { + /* Return with error code */ + return SERCOM_STATUS_BAUDRATE_UNAVAILABLE; + } + + if(mode == SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC) { + /* Calculate the BAUD value */ + ratio = ((sample_num * (uint64_t)baudrate) << SHIFT) / peripheral_clock; + scale = ((uint64_t)1 << SHIFT) - ratio; + baud_calculated = (65536 * scale) >> SHIFT; + + } else if(mode == SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL) { + + for(baud_fp = 0; baud_fp < BAUD_FP_MAX; baud_fp++) { + baud_int = BAUD_FP_MAX * + (uint64_t)peripheral_clock / ((uint64_t)baudrate * sample_num) + - baud_fp; + baud_int = baud_int / BAUD_FP_MAX; + + if(baud_int < BAUD_INT_MAX) { + break; + } + } + + if(baud_fp == BAUD_FP_MAX) { + return SERCOM_STATUS_BAUDRATE_UNAVAILABLE; + } + baud_calculated = baud_int | (baud_fp << 13); + } + + *baudval = baud_calculated; + return SERCOM_STATUS_OK; +} + +/** + * Set GCLK channel to generator. + * + * This will set the appropriate GCLK channel to the requested GCLK generator. + * + * \param[in] generator_source The generator to use for SERCOM. + */ +void _sercom_set_gclk_generator(const enum gclk_generator generator_source) +{ + system_gclk_chan_set_config(SERCOM_GCLK_ID, generator_source); + system_gclk_chan_enable(SERCOM_GCLK_ID); +} + +/** + * Convert a SERCOM instance and pad index to the default SERCOM pad + * MUX setting. + */ +#define SERCOM_PAD_DEFAULT(n, pad) \ + switch (pad) { \ + case 0: \ + return SERCOM##n##_PAD0_DEFAULT; \ + case 1: \ + return SERCOM##n##_PAD1_DEFAULT; \ + case 2: \ + return SERCOM##n##_PAD2_DEFAULT; \ + case 3: \ + return SERCOM##n##_PAD3_DEFAULT; \ + } + +/** + * Returns the PINMUX settings for the given SERCOM and pad. This is used + * for default configuration of pins. + * + * \param[in] sercom_module Pointer to the SERCOM module + * \param[in] pad PAD to get default pinout for + * + * \returns The default PINMUX for the given SERCOM instance and PAD + * + */ +uint32_t _sercom_get_default_pad(Sercom* const sercom_module, + const uint8_t pad) +{ + switch((uintptr_t)sercom_module) { +#if SERCOM_INST_NUM > 0 + case (uintptr_t)SERCOM0: + SERCOM_PAD_DEFAULT(0, pad); break; +#endif +#if SERCOM_INST_NUM > 1 + case (uintptr_t)SERCOM1: + SERCOM_PAD_DEFAULT(1, pad); break; +#endif +#if SERCOM_INST_NUM > 2 + case (uintptr_t)SERCOM2: + SERCOM_PAD_DEFAULT(2, pad); break; +#endif +#if SERCOM_INST_NUM > 3 + case (uintptr_t)SERCOM3: + SERCOM_PAD_DEFAULT(3, pad); break; +#endif +#if SERCOM_INST_NUM > 4 + case (uintptr_t)SERCOM4: + SERCOM_PAD_DEFAULT(4, pad); break; +#endif +#if SERCOM_INST_NUM > 5 + case (uintptr_t)SERCOM5: + SERCOM_PAD_DEFAULT(5, pad); break; +#endif + } + + while(1); + return 0; +} diff --git a/loader/src/sercom/spi.c b/loader/src/sercom/spi.c new file mode 100644 index 0000000..a39de21 --- /dev/null +++ b/loader/src/sercom/spi.c @@ -0,0 +1,1076 @@ +/** + * SAM D20/D21/R21 Serial Peripheral Interface Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "sercom/sercom.h" +#include "sercom/spi.h" +#include "samd20.h" + + +#define SPI_MODE_MASTER(hw) ((hw->CTRLA.reg & SERCOM_SPI_CTRLA_MODE_Msk) \ + == SERCOM_SPI_CTRLA_MODE_SPI_MASTER) +#define SPI_MODE_SLAVE(hw) ((hw->CTRLA.reg & SERCOM_SPI_CTRLA_MODE_Msk) \ + == SERCOM_SPI_CTRLA_MODE_SPI_SLAVE) +/** + * Resets the SPI module + * + * This function will reset the SPI module to its power on default values and + * disable it. + * + * \param[in,out] module Pointer to the software instance struct + */ +void spi_reset(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + /* Disable the module */ + spi_disable(hw); + + SPI_WAIT_FOR_SYNC(hw); + + /* Software reset the module */ + hw->CTRLA.reg |= SERCOM_SPI_CTRLA_SWRST; +} + +/** + * Set the baudrate of the SPI module + * + * This function will set the baudrate of the SPI module. + * + * \param[in] module Pointer to the software instance struct + * \param[in] baudrate The baudrate wanted + * + * \return The status of the configuration + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_OK If the configuration was written + */ +enum sercom_status_t spi_set_baudrate(SercomSpi* const hw, + uint32_t baudrate) +{ + /* Sanity check arguments */ + + + /* Value to write to BAUD register */ + uint16_t baud = 0; + + /* Disable the module */ + spi_disable(hw); + + SPI_WAIT_FOR_SYNC(hw); + + /* Find frequency of the internal SERCOMi_GCLK_ID_CORE */ + uint32_t sercom_index = _sercom_get_sercom_inst_index((Sercom*)hw); + uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; + uint32_t internal_clock = system_gclk_chan_get_hz(gclk_index); + + /* Get baud value, based on baudrate and the internal clock frequency */ + enum sercom_status_t error_code = _sercom_get_sync_baud_val( + baudrate, internal_clock, &baud); + + if (error_code != SERCOM_STATUS_OK) { + /* Baud rate calculation error, return status code */ + return SERCOM_STATUS_INVALID_ARG; + } + + hw->BAUD.reg = (uint8_t)baud; + + SPI_WAIT_FOR_SYNC(hw); + + /* Enable the module */ + spi_enable(hw); + + SPI_WAIT_FOR_SYNC(hw); + + return SERCOM_STATUS_OK; +} + +/** + * Clears the Transmit Complete interrupt flag. + * + * \param[in] module Pointer to the software instance struct + */ +static void _spi_clear_tx_complete_flag(SercomSpi* const hw) +{ + /* Sanity check arguments */ + + + /* Clear interrupt flag */ + hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE; +} + +/** + * This function will initialize the SERCOM SPI module + * + * \param[out] module Pointer to the software instance struct + * \param[in] hw Pointer to hardware instance + * \param[in] config Pointer to the config struct + * + * \return Status of the initialization + * \retval STATUS_OK Module initiated correctly. + * \retval STATUS_ERR_DENIED If module is enabled. + * \retval STATUS_BUSY If module is busy resetting. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + */ +enum sercom_status_t spi_init(SercomSpi *const hw, + enum spi_mode mode, + enum spi_data_order data_order, + enum spi_transfer_mode transfer_mode, + enum spi_signal_mux_setting mux_setting, + enum spi_character_size character_size, + bool run_in_standby, + bool receiver_enable, + uint32_t master_baudrate, + enum spi_frame_format slave_frame_format, + enum spi_addr_mode slave_address_mode, + uint8_t slave_address, + uint8_t slave_address_mask, + bool slave_preload_enable, +# ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT + bool select_slave_low_detect_enable, +# endif +# ifdef FEATURE_SPI_HARDWARE_SLAVE_SELECT + bool master_slave_select_enable, +# endif + enum gclk_generator generator_source, + uint32_t pinmux_pad0, + uint32_t pinmux_pad1, + uint32_t pinmux_pad2, + uint32_t pinmux_pad3) +{ + + /* Sanity check arguments */ + + + /* Check if module is enabled. */ + if (hw->CTRLA.reg & SERCOM_SPI_CTRLA_ENABLE) { + return SERCOM_STATUS_DENIED; + } + + /* Check if reset is in progress. */ + if (hw->CTRLA.reg & SERCOM_SPI_CTRLA_SWRST){ + return SERCOM_STATUS_BUSY; + } + + uint32_t sercom_index = _sercom_get_sercom_inst_index((Sercom*)hw); + uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos; + uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; + + /* Turn on module in PM */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index); + + /* Set up the GCLK for the module */ + system_gclk_chan_set_config(gclk_index, generator_source); + system_gclk_chan_enable(gclk_index); + _sercom_set_gclk_generator(generator_source); + + if (mode == SPI_MODE_MASTER) { + /* Set the SERCOM in SPI master mode */ + hw->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_MASTER; + } else if (mode == SPI_MODE_SLAVE) { + /* Set the SERCOM in SPI slave mode */ + hw->CTRLA.reg |= SERCOM_SPI_CTRLA_MODE_SPI_SLAVE; + } + + uint32_t pad_pinmuxes[] = { + pinmux_pad0, pinmux_pad1, + pinmux_pad2, pinmux_pad3 + }; + + /* Configure the SERCOM pins according to the user configuration */ + for (uint8_t pad = 0; pad < 4; pad++) { + uint32_t current_pinmux = pad_pinmuxes[pad]; + + if (current_pinmux == PINMUX_DEFAULT) { + current_pinmux = _sercom_get_default_pad((Sercom*)hw, pad); + } + + if (current_pinmux != PINMUX_UNUSED) { + system_pinmux_pin_set_config(current_pinmux >> 16, + current_pinmux & 0xFFFF, + SYSTEM_PINMUX_PIN_DIR_INPUT, /* Direction */ + SYSTEM_PINMUX_PIN_PULL_UP, /* Pull */ + false); /* Powersave */ + } + } + + /* Value to write to BAUD register */ + uint16_t baud = 0; + /* Value to write to CTRLA register */ + uint32_t ctrla = 0; + /* Value to write to CTRLB register */ + uint32_t ctrlb = 0; + + /* Find baud value and write it */ + if (mode == SPI_MODE_MASTER) { + /* Find frequency of the internal SERCOMi_GCLK_ID_CORE */ + uint32_t sercom_index = _sercom_get_sercom_inst_index((Sercom*)hw); + uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; + uint32_t internal_clock = system_gclk_chan_get_hz(gclk_index); + + /* Get baud value, based on baudrate and the internal clock frequency */ + enum sercom_status_t error_code = _sercom_get_sync_baud_val( + master_baudrate, internal_clock, &baud); + + if (error_code != SERCOM_STATUS_OK) { + /* Baud rate calculation error, return status code */ + return SERCOM_STATUS_INVALID_ARG; + } + + hw->BAUD.reg = (uint8_t)baud; + } else if (mode == SPI_MODE_SLAVE) { + /* Set frame format */ + ctrla = slave_frame_format; + + /* Set address mode */ + ctrlb = slave_address_mode; + + /* Set address and address mask*/ + hw->ADDR.reg |= + (slave_address << SERCOM_SPI_ADDR_ADDR_Pos) | + (slave_address_mask << SERCOM_SPI_ADDR_ADDRMASK_Pos); + + if (slave_preload_enable) { + /* Enable pre-loading of shift register */ + ctrlb |= SERCOM_SPI_CTRLB_PLOADEN; + } + } + + /* Set data order */ + ctrla |= data_order; + + /* Set clock polarity and clock phase */ + ctrla |= transfer_mode; + + /* Set mux setting */ + ctrla |= mux_setting; + + /* Set SPI character size */ + ctrlb |= character_size; + + /* Set whether module should run in standby. */ + if (run_in_standby || system_is_debugger_present()) { + ctrla |= SERCOM_SPI_CTRLA_RUNSTDBY; + } + + if (receiver_enable) { + /* Enable receiver */ + ctrlb |= SERCOM_SPI_CTRLB_RXEN; + } +# ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT + if (select_slave_low_detect_enable) { + /* Enable Slave Select Low Detect */ + ctrlb |= SERCOM_SPI_CTRLB_SSDE; + } +# endif +# ifdef FEATURE_SPI_HARDWARE_SLAVE_SELECT + if (master_slave_select_enable) { + /* Enable Master Slave Select */ + ctrlb |= SERCOM_SPI_CTRLB_MSSEN; + } +# endif + /* Write CTRLA register */ + hw->CTRLA.reg |= ctrla; + + /* Write CTRLB register */ + hw->CTRLB.reg |= ctrlb; + + return SERCOM_STATUS_OK; +} + +/** + * This function will initialize the SERCOM SPI module with the + * default values. + * + * + * The default configuration is as follows: + * - Master mode enabled + * - MSB of the data is transmitted first + * - Transfer mode 0 + * - MUX Setting D + * - Character size 8 bit + * - Not enabled in sleep mode + * - Receiver enabled + * - Baudrate 100000 + * - Default pinmux settings for all pads + * - GCLK generator 0 + * + */ +enum sercom_status_t spi_init_default(SercomSpi *const hw) +{ + return spi_init(hw, + SPI_MODE_MASTER, /** SPI mode */ + SPI_DATA_ORDER_MSB, /** Data order */ + SPI_TRANSFER_MODE_0, /** Transfer mode */ + SPI_SIGNAL_MUX_SETTING_D, /** Mux setting */ + SPI_CHARACTER_SIZE_8BIT, /** SPI character size */ + false, /** Enabled in sleep */ + true, /** Enable receiver */ + 100000, /** Master - Baud rate */ + 0, /** Slave - Frame format */ + 0, /** Slave - Address mode */ + 0, /** Slave - Address */ + 0, /** Slave - Address mask */ + false, /** Slave - Preload data */ +# ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT + true, /** Enable Slave Select Low Detect */ +# endif +# ifdef FEATURE_SPI_HARDWARE_SLAVE_SELECT + false, /** Enable Master Slave Select */ +# endif + GCLK_GENERATOR_0, /** GCLK generator to use */ + PINMUX_DEFAULT, /** PAD0 pinmux */ + PINMUX_DEFAULT, /** PAD1 pinmux */ + PINMUX_DEFAULT, /** PAD2 pinmux */ + PINMUX_DEFAULT); /** PAD3 pinmux */ +} + +/** + * Reads buffer of \c length SPI characters + * + * This function will read a buffer of data from an SPI peripheral by sending + * dummy SPI character if in master mode, or by waiting for data in slave mode. + * + * \note If address matching is enabled for the slave, the first character + * received and placed in the buffer will be the address. + * + * \param[in] module Pointer to the software instance struct + * \param[out] rx_data Data buffer for received data + * \param[in] length Length of data to receive + * \param[in] dummy 8- or 9-bit dummy byte to shift out in master mode + * + * \return Status of the read operation + * \retval STATUS_OK If the read was completed + * \retval STATUS_ABORTED If transaction was ended by master before + * entire buffer was transferred + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_ERR_TIMEOUT If the operation was not completed within the + * timeout in slave mode. + * \retval STATUS_ERR_DENIED If the receiver is not enabled + * \retval STATUS_ERR_OVERFLOW If the data is overflown + */ +enum sercom_status_t spi_read_buffer_wait(SercomSpi* const hw, + uint8_t *rx_data, + uint16_t length, + uint16_t dummy) +{ + /* Sanity check arguments */ + + + /* Sanity check arguments */ + if (length == 0) { + return SERCOM_STATUS_INVALID_ARG; + } + + uint16_t rx_pos = 0; + + while (length--) { + + /* Wait until the module is ready to write a character */ + while (!spi_is_ready_to_write(hw)); + + /* Send dummy SPI character to read in master mode */ + spi_write(hw, dummy); + + /* Wait until the module is ready to read a character */ + while (!spi_is_ready_to_read(hw)); + + uint16_t received_data = 0; + enum sercom_status_t retval = spi_read(hw, &received_data); + + if (retval != SERCOM_STATUS_OK) { + /* Overflow, abort */ + return retval; + } + + /* Read value will be at least 8-bits long */ + rx_data[rx_pos++] = received_data; + } + + return SERCOM_STATUS_OK; +} + +/** + * Sends and reads a single SPI character + * + * This function will transfer a single SPI character via SPI and return the + * SPI character that is shifted into the shift register. + * + * In master mode the SPI character will be sent immediately and the received + * SPI character will be read as soon as the shifting of the data is + * complete. + * + * In slave mode this function will place the data to be sent into the transmit + * buffer. It will then block until an SPI master has shifted a complete + * SPI character, and the received data is available. + * + * \note The data to be sent might not be sent before the next transfer, as + * loading of the shift register is dependent on SCK. + * \note If address matching is enabled for the slave, the first character + * received and placed in the buffer will be the address. + * + * \param[in] module Pointer to the software instance struct + * \param[in] tx_data SPI character to transmit + * \param[out] rx_data Pointer to store the received SPI character + * + * \return Status of the operation. + * \retval STATUS_OK If the operation was completed + * \retval STATUS_ERR_TIMEOUT If the operation was not completed within the + * timeout in slave mode + * \retval STATUS_ERR_DENIED If the receiver is not enabled + * \retval STATUS_ERR_OVERFLOW If the incoming data is overflown + */ +enum sercom_status_t spi_transceive_wait(SercomSpi* const hw, + uint16_t tx_data, + uint16_t *rx_data) +{ + /* Sanity check arguments */ + + + uint16_t j; + enum sercom_status_t retval = SERCOM_STATUS_OK; + + /* Start timeout period for slave */ + if (SPI_MODE_SLAVE(hw)) { + for (j = 0; j <= SPI_TIMEOUT; j++) { + if (spi_is_ready_to_write(hw)) { + break; + } else if (j == SPI_TIMEOUT) { + /* Not ready to write data within timeout period */ + return SERCOM_STATUS_TIMEOUT; + } + } + } + + /* Wait until the module is ready to write the character */ + while (!spi_is_ready_to_write(hw)) { + } + + /* Write data */ + spi_write(hw, tx_data); + + /* Start timeout period for slave */ + if (SPI_MODE_SLAVE(hw)) { + for (j = 0; j <= SPI_TIMEOUT; j++) { + if (spi_is_ready_to_read(hw)) { + break; + } else if (j == SPI_TIMEOUT) { + /* Not ready to read data within timeout period */ + return SERCOM_STATUS_TIMEOUT; + } + } + } + + /* Wait until the module is ready to read the character */ + while (!spi_is_ready_to_read(hw)) { + } + + /* Read data */ + retval = spi_read(hw, rx_data); + + return retval; +} + +/** + * Selects slave device + * + * This function will drive the slave select pin of the selected device low or + * high depending on the select boolean. + * If slave address recognition is enabled, the address will be sent to the + * slave when selecting it. + * + * \param[in] module Pointer to the software module struct + * \param[in] slave Pointer to the attached slave + * \param[in] select Boolean stating if the slave should be selected or + * deselected + * + * \return Status of the operation + * \retval STATUS_OK If the slave device was selected + * \retval STATUS_ERR_UNSUPPORTED_DEV If the SPI module is operating in slave + * mode + * \retval STATUS_BUSY If the SPI module is not ready to write + * the slave address + */ +enum sercom_status_t spi_select_slave(SercomSpi* const hw, + uint8_t ss_pin, + bool address_enabled, + uint8_t address, + const bool select) +{ + /* Sanity check arguments */ + + + /* Check that the SPI module is operating in master mode */ + if (!SPI_MODE_MASTER(hw)) { + return SERCOM_STATUS_UNSUPPORTED_DEV; + } +# ifdef FEATURE_SPI_HARDWARE_SLAVE_SELECT + if(!(master_slave_select_enable)) +# endif + { + if (select) { + /* Check if address recognition is enabled */ + if (address_enabled) { + /* Check if the module is ready to write the address */ + if (!spi_is_ready_to_write(hw)) { + /* Not ready, do not select slave and return */ + port_pin_set_output_level(ss_pin, true); + return SERCOM_STATUS_BUSY; + } + + /* Drive Slave Select low */ + port_pin_set_output_level(ss_pin, false); + + /* Write address to slave */ + spi_write(hw, address); + +// if (!(hw->receiver_enabled)) { + /* Flush contents of shift register shifted back from slave */ +// while (!spi_is_ready_to_read(hw)) { +// } +// uint16_t flush = 0; +// spi_read(hw, &flush); +// } + } else { + /* Drive Slave Select low */ + port_pin_set_output_level(ss_pin, false); + } + } else { + /* Drive Slave Select high */ + port_pin_set_output_level(ss_pin, true); + } + } + return SERCOM_STATUS_OK; +} + +/** + * Sends a buffer of \c length SPI characters + * + * This function will send a buffer of SPI characters via the SPI + * and discard any data that is received. To both send and receive a buffer of + * data, use the \ref spi_transceive_buffer_wait function. + * + * Note that this function does not handle the _SS (slave select) pin(s) in + * master mode; this must be handled by the user application. + * + * \param[in] module Pointer to the software instance struct + * \param[in] tx_data Pointer to the buffer to transmit + * \param[in] length Number of SPI characters to transfer + * + * \return Status of the write operation + * \retval STATUS_OK If the write was completed + * \retval STATUS_ABORTED If transaction was ended by master before + * entire buffer was transferred + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided + * \retval STATUS_ERR_TIMEOUT If the operation was not completed within the + * timeout in slave mode + */ +enum sercom_status_t spi_write_buffer_wait(SercomSpi* const hw, + const uint8_t *tx_data, + uint16_t length) +{ + /* Sanity check arguments */ + + + if (length == 0) { + return SERCOM_STATUS_INVALID_ARG; + } + + if (SPI_MODE_SLAVE(hw) && (spi_is_write_complete(hw))) { + /* Clear TX complete flag */ + _spi_clear_tx_complete_flag(hw); + } + + uint16_t tx_pos = 0; + uint16_t flush_length = length; + + /* Write block */ + while (length--) { + + /* Write value will be at least 8-bits long */ + uint16_t data_to_send = tx_data[tx_pos++]; + + /* Wait until the module is ready to write a character */ + while (!spi_is_ready_to_write(hw)); + + /* Write the data to send */ + spi_write(hw, data_to_send); + + while (!spi_is_ready_to_read(hw)); + + /* Flush read buffer */ + uint16_t flush; + spi_read(hw, &flush); + flush_length--; + } + + /* Wait for last byte to be transferred */ + while (!spi_is_write_complete(hw)); + + return SERCOM_STATUS_OK; +} + +/** + * Sends and receives a buffer of \c length SPI characters + * + * This function will send and receive a buffer of data via the SPI. + * + * In master mode the SPI characters will be sent immediately and the + * received SPI character will be read as soon as the shifting of the SPI + * character is complete. + * + * In slave mode this function will place the data to be sent into the transmit + * buffer. It will then block until an SPI master has shifted the complete + * buffer and the received data is available. + * + * \param[in] module Pointer to the software instance struct + * \param[in] tx_data Pointer to the buffer to transmit + * \param[out] rx_data Pointer to the buffer where received data will be stored + * \param[in] length Number of SPI characters to transfer + * + * \return Status of the operation + * \retval STATUS_OK If the operation was completed + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_ERR_TIMEOUT If the operation was not completed within the + * timeout in slave mode. + * \retval STATUS_ERR_DENIED If the receiver is not enabled + * \retval STATUS_ERR_OVERFLOW If the data is overflown + */ +enum sercom_status_t spi_transceive_buffer_wait(SercomSpi* const hw, + uint8_t *tx_data, + uint8_t *rx_data, + uint16_t length) +{ + /* Sanity check arguments */ + + + /* Sanity check arguments */ + if (length == 0) { + return SERCOM_STATUS_INVALID_ARG; + } + + if (SPI_MODE_SLAVE(hw) && (spi_is_write_complete(hw))) { + /* Clear TX complete flag */ + _spi_clear_tx_complete_flag(hw); + } + + uint16_t tx_pos = 0; + uint16_t rx_pos = 0; + uint16_t rx_length = length; + + /* Send and receive buffer */ + while (length--) { + /* Start timeout period for slave */ + if (SPI_MODE_SLAVE(hw)) { + for (uint32_t i = 0; i <= SPI_TIMEOUT; i++) { + if (spi_is_ready_to_write(hw)) { + break; + } + } + /* Check if master has ended the transaction */ + if (spi_is_write_complete(hw)) { + _spi_clear_tx_complete_flag(hw); + return SERCOM_STATUS_ABORTED; + } + + if (!spi_is_ready_to_write(hw)) { + /* Not ready to write data within timeout period */ + return SERCOM_STATUS_TIMEOUT; + } + } + + /* Wait until the module is ready to write a character */ + while (!spi_is_ready_to_write(hw)) { + } + + /* Write value will be at least 8-bits long */ + uint16_t data_to_send = tx_data[tx_pos++]; + + /* If 9-bit data, get next byte to send from the buffer */ +// if (module->character_size == SPI_CHARACTER_SIZE_9BIT) { +// data_to_send |= (tx_data[tx_pos++] << 8); +// } + + /* Write the data to send */ + spi_write(hw, data_to_send); + + /* Start timeout period for slave */ + if (SPI_MODE_SLAVE(hw)) { + for (uint32_t i = 0; i <= SPI_TIMEOUT; i++) { + if (spi_is_ready_to_write(hw)) { + data_to_send = tx_data[tx_pos++]; + /* If 9-bit data, get next byte to send from the buffer */ +// if (module->character_size == SPI_CHARACTER_SIZE_9BIT) { +// data_to_send |= (tx_data[tx_pos++] << 8); +// } + + /* Write the data to send */ + spi_write(hw, data_to_send); + length--; + } + if (spi_is_ready_to_read(hw)) { + break; + } + } + /* Check if master has ended the transaction */ + if (spi_is_write_complete(hw)) { + _spi_clear_tx_complete_flag(hw); + return SERCOM_STATUS_ABORTED; + } + + if (!spi_is_ready_to_read(hw)) { + /* Not ready to read data within timeout period */ + return SERCOM_STATUS_TIMEOUT; + } + } + + /* Wait until the module is ready to read a character */ + while (!spi_is_ready_to_read(hw)) { + } + + enum sercom_status_t retval; + uint16_t received_data = 0; + rx_length--; + + retval = spi_read(hw, &received_data); + + if (retval != SERCOM_STATUS_OK) { + /* Overflow, abort */ + return retval; + } + + /* Read value will be at least 8-bits long */ + rx_data[rx_pos++] = received_data; + + /* If 9-bit data, write next received byte to the buffer */ +// if (module->character_size == SPI_CHARACTER_SIZE_9BIT) { +// rx_data[rx_pos++] = (received_data >> 8); +// } + } + + if (SPI_MODE_MASTER(hw)) { + /* Wait for last byte to be transferred */ + while (!spi_is_write_complete(hw)) { + } + } else if (SPI_MODE_SLAVE(hw)) { + while (rx_length) { + /* Start timeout period for slave */ + for (uint32_t i = 0; i <= SPI_TIMEOUT; i++) { + if (spi_is_ready_to_read(hw)) { + break; + } + } + if (!spi_is_ready_to_read(hw)) { + /* Not ready to read data within timeout period */ + return SERCOM_STATUS_TIMEOUT; + } + enum sercom_status_t retval; + uint16_t received_data = 0; + rx_length--; + + retval = spi_read(hw, &received_data); + + if (retval != SERCOM_STATUS_OK) { + /* Overflow, abort */ + return retval; + } + /* Read value will be at least 8-bits long */ + rx_data[rx_pos++] = received_data; + + /* If 9-bit data, write next received byte to the buffer */ +// if (module->character_size == SPI_CHARACTER_SIZE_9BIT) { +// rx_data[rx_pos++] = (received_data >> 8); +// } + } + } else { + // ERROR + } + return SERCOM_STATUS_OK; +} + + + +static void _spi_transceive_buffer(SercomSpi* const hw) +{ + /* Enable the Data Register Empty and RX Complete Interrupt */ + hw->INTENSET.reg = (SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY | + SPI_INTERRUPT_FLAG_RX_COMPLETE); + + if (SPI_MODE_SLAVE(hw)) { + /* Clear TXC flag if set */ + hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE; + /* Enable transmit complete interrupt for slave */ + hw->INTENSET.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE; + } +} + + +/* # if CONF_SPI_MASTER_ENABLE == true */ +/* if (module->mode == SPI_MODE_MASTER && module->dir == SPI_DIRECTION_READ) { */ +/* /\* Enable Data Register Empty interrupt for master *\/ */ +/* tmp_intenset |= SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY; */ +/* } */ +/* # endif */ +/* # if CONF_SPI_SLAVE_ENABLE == true */ +/* if (module->mode == SPI_MODE_SLAVE) { */ +/* /\* Clear TXC flag if set *\/ */ +/* hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE; */ +/* /\* Enable transmit complete interrupt for slave *\/ */ +/* tmp_intenset |= SPI_INTERRUPT_FLAG_TX_COMPLETE; */ +/* } */ +/* # endif */ + +/* /\* Enable all interrupts simultaneously *\/ */ +/* hw->INTENSET.reg = tmp_intenset; */ +/* } */ + +/** + * Reads a character from the Data register to the RX buffer. + * + * \param[in,out] module Pointer to SPI software instance struct + */ +static void _spi_read(SercomSpi* const hw) +{ + uint16_t received_data = (hw->DATA.reg & SERCOM_SPI_DATA_MASK); + (void)received_data; + + /* Read value will be at least 8-bits long */ + /* *(module->rx_buffer_ptr) = received_data; */ + /* /\* Increment 8-bit pointer *\/ */ + /* module->rx_buffer_ptr += 1; */ + + /* if(module->character_size == SPI_CHARACTER_SIZE_9BIT) { */ + /* /\* 9-bit data, write next received byte to the buffer *\/ */ + /* *(module->rx_buffer_ptr) = (received_data >> 8); */ + /* /\* Increment 8-bit pointer *\/ */ + /* module->rx_buffer_ptr += 1; */ + /* } */ +} + +/** + * Handles interrupts as they occur, and it will run callback functions + * which are registered and enabled. + * + * \note This function will be called by the Sercom_Handler, and should + * not be called directly from any application code. + * + * \param[in] instance ID of the SERCOM instance calling the interrupt + * handler. + */ +void _spi_interrupt_handler(SercomSpi* const hw) +{ + /* Combine callback registered and enabled masks. */ +// uint8_t callback_mask = +// module->enabled_callback & module->registered_callback; + + /* Read and mask interrupt flag register */ + uint16_t interrupt_status = hw->INTFLAG.reg; + interrupt_status &= hw->INTENSET.reg; + + /* Data register empty interrupt */ +/* if (interrupt_status & SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY) { */ +/* # if CONF_SPI_MASTER_ENABLE == true */ +/* if ((module->mode == SPI_MODE_MASTER) && */ +/* (module->dir == SPI_DIRECTION_READ)) { */ +/* /\* Send dummy byte when reading in master mode *\/ */ +/* _spi_write_dummy(module); */ +/* if (module->remaining_dummy_buffer_length == 0) { */ +/* /\* Disable the Data Register Empty Interrupt *\/ */ +/* hw->INTENCLR.reg */ +/* = SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY; */ +/* } */ +/* } */ +/* # endif */ + +/* if (0 */ +/* # if CONF_SPI_MASTER_ENABLE == true */ +/* || ((module->mode == SPI_MODE_MASTER) && */ +/* (module->dir != SPI_DIRECTION_READ)) */ +/* # endif */ +/* # if CONF_SPI_SLAVE_ENABLE == true */ +/* || ((module->mode == SPI_MODE_SLAVE) && */ +/* (module->dir != SPI_DIRECTION_READ)) */ +/* # endif */ +/* ) { */ +/* /\* Write next byte from buffer *\/ */ +/* _spi_write(module); */ +/* if (module->remaining_tx_buffer_length == 0) { */ +/* /\* Disable the Data Register Empty Interrupt *\/ */ +/* hw->INTENCLR.reg */ +/* = SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY; */ + +/* if (module->dir == SPI_DIRECTION_WRITE && */ +/* !(module->receiver_enabled)) { */ +/* /\* Buffer sent with receiver disabled *\/ */ +/* module->dir = SPI_DIRECTION_IDLE; */ +/* module->status = STATUS_OK; */ +/* /\* Run callback if registered and enabled *\/ */ +/* if (callback_mask & (1 << SPI_CALLBACK_BUFFER_TRANSMITTED)){ */ +/* (module->callback[SPI_CALLBACK_BUFFER_TRANSMITTED]) */ +/* (module); */ +/* } */ +/* } */ +/* } */ +/* } */ +/* } */ + +/* /\* Receive complete interrupt*\/ */ +/* if (interrupt_status & SPI_INTERRUPT_FLAG_RX_COMPLETE) { */ +/* /\* Check for overflow *\/ */ +/* if (hw->STATUS.reg & SERCOM_SPI_STATUS_BUFOVF) { */ +/* if (module->dir != SPI_DIRECTION_WRITE) { */ +/* /\* Store the error code *\/ */ +/* module->status = STATUS_ERR_OVERFLOW; */ + +/* /\* End transaction *\/ */ +/* module->dir = SPI_DIRECTION_IDLE; */ + +/* hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE | */ +/* SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY; */ +/* /\* Run callback if registered and enabled *\/ */ +/* if (callback_mask & (1 << SPI_CALLBACK_ERROR)) { */ +/* (module->callback[SPI_CALLBACK_ERROR])(module); */ +/* } */ +/* } */ +/* /\* Flush *\/ */ +/* uint16_t flush = hw->DATA.reg; */ +/* UNUSED(flush); */ +/* /\* Clear overflow flag *\/ */ +/* hw->STATUS.reg |= SERCOM_SPI_STATUS_BUFOVF; */ +/* } else { */ +/* if (module->dir == SPI_DIRECTION_WRITE) { */ +/* /\* Flush receive buffer when writing *\/ */ +/* _spi_read_dummy(module); */ +/* if (module->remaining_dummy_buffer_length == 0) { */ +/* hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE; */ +/* module->status = STATUS_OK; */ +/* module->dir = SPI_DIRECTION_IDLE; */ +/* /\* Run callback if registered and enabled *\/ */ +/* if (callback_mask & */ +/* (1 << SPI_CALLBACK_BUFFER_TRANSMITTED)){ */ +/* (module->callback[SPI_CALLBACK_BUFFER_TRANSMITTED])(module); */ +/* } */ +/* } */ +/* } else { */ +/* /\* Read data register *\/ */ +/* _spi_read(module); */ + +/* /\* Check if the last character have been received *\/ */ +/* if (module->remaining_rx_buffer_length == 0) { */ +/* module->status = STATUS_OK; */ +/* /\* Disable RX Complete Interrupt and set status *\/ */ +/* hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_RX_COMPLETE; */ +/* if(module->dir == SPI_DIRECTION_BOTH) { */ +/* if (callback_mask & (1 << SPI_CALLBACK_BUFFER_TRANSCEIVED)) { */ +/* (module->callback[SPI_CALLBACK_BUFFER_TRANSCEIVED])(module); */ +/* } */ +/* } else if (module->dir == SPI_DIRECTION_READ) { */ +/* if (callback_mask & (1 << SPI_CALLBACK_BUFFER_RECEIVED)) { */ +/* (module->callback[SPI_CALLBACK_BUFFER_RECEIVED])(module); */ +/* } */ +/* } */ +/* } */ +/* } */ +/* } */ +/* } */ + +/* /\* Transmit complete *\/ */ +/* if (interrupt_status & SPI_INTERRUPT_FLAG_TX_COMPLETE) { */ +/* # if CONF_SPI_SLAVE_ENABLE == true */ +/* if (module->mode == SPI_MODE_SLAVE) { */ +/* /\* Transaction ended by master *\/ */ + +/* /\* Disable interrupts *\/ */ +/* hw->INTENCLR.reg = */ +/* SPI_INTERRUPT_FLAG_TX_COMPLETE | */ +/* SPI_INTERRUPT_FLAG_RX_COMPLETE | */ +/* SPI_INTERRUPT_FLAG_DATA_REGISTER_EMPTY; */ +/* /\* Clear interrupt flag *\/ */ +/* hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_TX_COMPLETE; */ + + +/* /\* Reset all status information *\/ */ +/* module->dir = SPI_DIRECTION_IDLE; */ +/* module->remaining_tx_buffer_length = 0; */ +/* module->remaining_rx_buffer_length = 0; */ +/* module->status = STATUS_OK; */ + +/* if (callback_mask & */ +/* (1 << SPI_CALLBACK_SLAVE_TRANSMISSION_COMPLETE)) { */ +/* (module->callback[SPI_CALLBACK_SLAVE_TRANSMISSION_COMPLETE]) */ +/* (module); */ +/* } */ + +/* } */ +/* # endif */ +/* } */ + +/* # ifdef FEATURE_SPI_SLAVE_SELECT_LOW_DETECT */ +/* # if CONF_SPI_SLAVE_ENABLE == true */ +/* /\* When a high to low transition is detected on the _SS pin in slave mode *\/ */ +/* if (interrupt_status & SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW) { */ +/* if (module->mode == SPI_MODE_SLAVE) { */ +/* /\* Disable interrupts *\/ */ +/* hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW; */ +/* /\* Clear interrupt flag *\/ */ +/* hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_SLAVE_SELECT_LOW; */ + +/* if (callback_mask & (1 << SPI_CALLBACK_SLAVE_SELECT_LOW)) { */ +/* (module->callback[SPI_CALLBACK_SLAVE_SELECT_LOW])(module); */ +/* } */ +/* } */ +/* } */ +/* # endif */ +/* # endif */ + +/* # ifdef FEATURE_SPI_ERROR_INTERRUPT */ +/* /\* When combined error happen *\/ */ +/* if (interrupt_status & SPI_INTERRUPT_FLAG_COMBINED_ERROR) { */ +/* /\* Disable interrupts *\/ */ +/* hw->INTENCLR.reg = SPI_INTERRUPT_FLAG_COMBINED_ERROR; */ +/* /\* Clear interrupt flag *\/ */ +/* hw->INTFLAG.reg = SPI_INTERRUPT_FLAG_COMBINED_ERROR; */ + +/* if (callback_mask & (1 << SPI_CALLBACK_COMBINED_ERROR)) { */ +/* (module->callback[SPI_CALLBACK_COMBINED_ERROR])(module); */ +/* } */ +/* } */ +/* # endif */ +} diff --git a/loader/src/sercom/usart.c b/loader/src/sercom/usart.c new file mode 100644 index 0000000..2685f2d --- /dev/null +++ b/loader/src/sercom/usart.c @@ -0,0 +1,777 @@ +/** + * SAM D20/D21/R21 SERCOM USART Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "sercom/sercom.h" +#include "sercom/usart.h" +#include "system/pinmux.h" +#include "system/interrupt.h" + +/** + * Initializes the USART device. + * + * \param[in] hw Pointer to USART hardware instance + * + * \return Status of the initialization + * + * \retval STATUS_OK The initialization was successful + * \retval STATUS_BUSY The USART module is busy + * resetting + * \retval STATUS_ERR_DENIED The USART have not been disabled in + * advance of initialization + * \retval STATUS_ERR_INVALID_ARG The configuration struct contains + * invalid configuration + * \retval STATUS_ERR_ALREADY_INITIALIZED The SERCOM instance has already been + * initialized with different clock + * configuration + * \retval STATUS_ERR_BAUD_UNAVAILABLE The BAUD rate given by the + * configuration + * struct cannot be reached with + * the current clock configuration + */ +enum sercom_status_t usart_init(SercomUsart* const hw, + enum usart_dataorder data_order, + enum usart_transfer_mode transfer_mode, + enum usart_parity parity, + enum usart_stopbits stopbits, + enum usart_character_size character_size, + enum usart_signal_mux_settings mux_setting, +#ifdef FEATURE_USART_OVER_SAMPLE + enum usart_sample_rate sample_rate, + enum usart_sample_adjustment sample_adjustment, +#endif + bool immediate_buffer_overflow_notification, + bool encoding_format_enable, + uint8_t receive_pulse_length, + bool lin_slave_enable, + bool start_frame_detection_enable, + bool collision_detection_enable, + uint32_t baudrate, + bool receiver_enable, + bool transmitter_enable, + bool clock_polarity_inverted, + bool use_external_clock, + uint32_t ext_clock_freq, + bool run_in_standby, + enum gclk_generator generator_source, + uint32_t pinmux_pad0, + uint32_t pinmux_pad1, + uint32_t pinmux_pad2, + uint32_t pinmux_pad3) + +{ + /* This function is deliberately broken to save space!!!! */ + + /* Unused */ + (void)encoding_format_enable; + (void)receive_pulse_length; + (void)collision_detection_enable; + (void)ext_clock_freq; + + enum sercom_status_t status_code = SERCOM_STATUS_OK; + + uint32_t sercom_index = _sercom_get_sercom_inst_index((Sercom*)hw); + uint32_t pm_index = sercom_index + PM_APBCMASK_SERCOM0_Pos; + uint32_t gclk_index = sercom_index + SERCOM0_GCLK_ID_CORE; + + /* Cache new register values to minimize the number of register writes */ + uint32_t ctrla = 0; + uint32_t ctrlb = 0; + uint16_t baud = 0; + + enum sercom_asynchronous_operation_mode mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; + enum sercom_asynchronous_sample_num sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; + + if (hw->CTRLA.reg & SERCOM_USART_CTRLA_SWRST) { + /* The module is busy resetting itself */ + return SERCOM_STATUS_BUSY; + } + + if (hw->CTRLA.reg & SERCOM_USART_CTRLA_ENABLE) { + /* Check the module is enabled */ + return SERCOM_STATUS_DENIED; + } + + /* Turn on module in PM */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, 1 << pm_index); + + /* Set up the GCLK for the module */ + system_gclk_chan_set_config(gclk_index, generator_source); + system_gclk_chan_enable(gclk_index); + _sercom_set_gclk_generator(generator_source); + +#ifdef FEATURE_USART_OVER_SAMPLE + switch (sample_rate) { + case USART_SAMPLE_RATE_16X_ARITHMETIC: + mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; + break; + case USART_SAMPLE_RATE_8X_ARITHMETIC: + mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_8; + break; + case USART_SAMPLE_RATE_3X_ARITHMETIC: + mode = SERCOM_ASYNC_OPERATION_MODE_ARITHMETIC; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_3; + break; + case USART_SAMPLE_RATE_16X_FRACTIONAL: + mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_16; + break; + case USART_SAMPLE_RATE_8X_FRACTIONAL: + mode = SERCOM_ASYNC_OPERATION_MODE_FRACTIONAL; + sample_num = SERCOM_ASYNC_SAMPLE_NUM_8; + break; + } +#endif + + /* Set data order, internal muxing, and clock polarity */ + ctrla = + (uint32_t)data_order | + (uint32_t)mux_setting | +#ifdef FEATURE_USART_OVER_SAMPLE + sample_adjustment | + sample_rate | +#endif + (immediate_buffer_overflow_notification << SERCOM_USART_CTRLA_IBON_Pos) | + (clock_polarity_inverted << SERCOM_USART_CTRLA_CPOL_Pos); + + /* calculate baud rate */ + status_code = + _sercom_get_async_baud_val(baudrate, + 0, &baud, mode, sample_num); + + /* Check if calculating the baud rate failed */ + if (status_code != SERCOM_STATUS_OK) { + /* Abort */ + return SERCOM_STATUS_BAUDRATE_UNAVAILABLE; + } + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Set baud val */ + hw->BAUD.reg = baud; + + /* Set sample mode */ + ctrla |= transfer_mode; + + if (use_external_clock == false) { + ctrla |= SERCOM_USART_CTRLA_MODE_USART_INT_CLK; + } + else { + ctrla |= SERCOM_USART_CTRLA_MODE_USART_EXT_CLK; + } + + /* Set stopbits, character size and enable transceivers */ + ctrlb = (uint32_t)stopbits | (uint32_t)character_size | + (start_frame_detection_enable << SERCOM_USART_CTRLB_SFDE_Pos) | + (receiver_enable << SERCOM_USART_CTRLB_RXEN_Pos) | + (transmitter_enable << SERCOM_USART_CTRLB_TXEN_Pos); + + /* Check parity mode bits */ + if (parity != USART_PARITY_NONE) { + if(lin_slave_enable) { + ctrla |= SERCOM_USART_CTRLA_FORM(0x5); + } + ctrla |= SERCOM_USART_CTRLA_FORM(1); + ctrlb |= parity; + } else { + if(lin_slave_enable) { + ctrla |= SERCOM_USART_CTRLA_FORM(0x4); + } + ctrla |= SERCOM_USART_CTRLA_FORM(0); + } + + /* Set whether module should run in standby. */ + if (run_in_standby || system_is_debugger_present()) { + ctrla |= SERCOM_USART_CTRLA_RUNSTDBY; + } + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Write configuration to CTRLB */ + hw->CTRLB.reg = ctrlb; + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Write configuration to CTRLA */ + hw->CTRLA.reg = ctrla; + + uint32_t pad_pinmuxes[] = { pinmux_pad0, pinmux_pad1, + pinmux_pad2, pinmux_pad3 }; + + /* Configure the SERCOM pins according to the user configuration */ + for (uint8_t pad = 0; pad < 4; pad++) { + uint32_t current_pinmux = pad_pinmuxes[pad]; + + if (current_pinmux == PINMUX_DEFAULT) { + current_pinmux = _sercom_get_default_pad((Sercom* const)hw, pad); + } + + if (current_pinmux != PINMUX_UNUSED) { + system_pinmux_pin_set_config(current_pinmux >> 16, /* GPIO Pin */ + current_pinmux & 0xFFFF, /* Mux Position */ + SYSTEM_PINMUX_PIN_DIR_INPUT, /* Direction */ + SYSTEM_PINMUX_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + } + } + + return status_code; +} + +/** + * Initialize the USART device to predefined defaults: + * - 8-bit asynchronous USART + * - No parity + * - 1 stop bit + * - 9600 baud + * - Transmitter enabled + * - Receiver enabled + * - GCLK generator 0 as clock source + * - Default pin configuration + */ +enum sercom_status_t usart_init_default(SercomUsart* const hw) +{ + return usart_init(hw, + USART_DATAORDER_LSB, /** Bit order (MSB or LSB first) */ + USART_TRANSFER_ASYNCHRONOUSLY, /** Asynchronous or synchronous mode */ + USART_PARITY_NONE, /** USART parity */ + USART_STOPBITS_1, /** Number of stop bits */ + USART_CHARACTER_SIZE_8BIT, /** USART character size */ + USART_RX_1_TX_2_XCK_3, /** USART pin out */ +#ifdef FEATURE_USART_OVER_SAMPLE + USART_SAMPLE_RATE_16X_ARITHMETIC, /** USART sample rate */ + USART_SAMPLE_ADJUSTMENT_7_8_9, /** USART sample adjustment */ +#endif + false, /** Immediate buffer overflow notification */ + false, /** Enable IrDA encoding format */ + 19, /** Minimum pulse length required for IrDA rx */ + false, /** Enable LIN Slave Support */ + false, /** Enable start of frame dection */ + false, /** Enable collision dection */ + 9600, /** USART Baud rate */ + true, /** Enable receiver */ + true, /** Enable transmitter */ + false, /** Sample on the rising edge of XLCK */ + false, /** Use the external clock applied to the XCK pin. */ + 0, /** External clock frequency in synchronous mode. */ + false, /** Run in standby */ + GCLK_GENERATOR_0, /** GCLK generator source */ + PINMUX_DEFAULT, /** PAD0 pinmux */ + PINMUX_DEFAULT, /** PAD1 pinmux */ + PINMUX_DEFAULT, /** PAD2 pinmux */ + PINMUX_DEFAULT); /** PAD3 pinmux */ +} + + + +/** + * This blocking function will transmit a single character via the + * USART. + * + * \param[in] module Pointer to the software instance struct + * \param[in] tx_data Data to transfer + * + * \return Status of the operation + * \retval STATUS_OK If the operation was completed + * \retval STATUS_BUSY If the operation was not completed, due to the USART + * module being busy. + * \retval STATUS_ERR_DENIED If the transmitter is not enabled + */ +enum sercom_status_t usart_write_wait(SercomUsart* const hw, + const uint16_t tx_data) +{ + /* Sanity check arguments */ + + + /* Check if USART is ready for new data */ + if (!(hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE)) { + /* Return error code */ + return SERCOM_STATUS_BUSY; + } + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Write data to USART module */ + hw->DATA.reg = tx_data; + + while (!(hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC)) { + /* Wait until data is sent */ + } + + return SERCOM_STATUS_OK; +} + +/** + * Receive a character via the USART + * + * This blocking function will receive a character via the USART. + * + * \param[in] module Pointer to the software instance struct + * \param[out] rx_data Pointer to received data + * + * \return Status of the operation + * \retval STATUS_OK If the operation was completed + * \retval STATUS_BUSY If the operation was not completed, + * due to the USART module being busy + * \retval STATUS_ERR_BAD_FORMAT If the operation was not completed, + * due to configuration mismatch between USART + * and the sender + * \retval STATUS_ERR_BAD_OVERFLOW If the operation was not completed, + * due to the baud rate being too low or the + * system frequency being too high + * \retval STATUS_ERR_BAD_DATA If the operation was not completed, due to + * data being corrupted + * \retval STATUS_ERR_DENIED If the receiver is not enabled + */ +enum sercom_status_t usart_read_wait(SercomUsart* const hw, + uint16_t *const rx_data) +{ + /* Sanity check arguments */ + + + /* Error variable */ + uint8_t error_code; + + /* If USART has no new data, abort */ + if (!(hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC)) { + /* Return error code */ + return SERCOM_STATUS_BUSY; + } + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Read out the status code and mask away all but the 3 LSBs*/ + error_code = (uint8_t)(hw->STATUS.reg & SERCOM_USART_STATUS_MASK); + + /* Check if an error has occurred during the receiving */ + if (error_code) { + /* Check which error occurred */ + if (error_code & SERCOM_USART_STATUS_FERR) { + /* Clear flag by writing a 1 to it and + * return with an error code */ + hw->STATUS.reg = SERCOM_USART_STATUS_FERR; + + return SERCOM_STATUS_BAD_FORMAT; + } else if (error_code & SERCOM_USART_STATUS_BUFOVF) { + /* Clear flag by writing a 1 to it and + * return with an error code */ + hw->STATUS.reg = SERCOM_USART_STATUS_BUFOVF; + + return SERCOM_STATUS_OVERFLOW; + } else if (error_code & SERCOM_USART_STATUS_PERR) { + /* Clear flag by writing a 1 to it and + * return with an error code */ + hw->STATUS.reg = SERCOM_USART_STATUS_PERR; + + return SERCOM_STATUS_BAD_DATA; +// } else if (error_code & SERCOM_USART_STATUS_ISF) { + /* Clear flag by writing 1 to it and + * return with an error code */ +// hw->STATUS.reg |= SERCOM_USART_STATUS_ISF; + +// return STATUS_ERR_PROTOCOL; +// } else if (error_code & SERCOM_USART_STATUS_COLL) { + /* Clear flag by writing 1 to it + * return with an error code */ +// hw->STATUS.reg |= SERCOM_USART_STATUS_COLL; + +// return SERCOM_STATUS_PACKET_COLLISION; + } + } + + /* Read data from USART module */ + *rx_data = hw->DATA.reg; + + return SERCOM_STATUS_OK; +} + +/** + * Transmit a buffer of characters via the USART + * + * This blocking function will transmit a block of \c length characters + * via the USART + * + * \note Using this function in combination with the interrupt (\c _job) functions is + * not recommended as it has no functionality to check if there is an + * ongoing interrupt driven operation running or not. + * + * \param[in] module Pointer to USART software instance struct + * \param[in] tx_data Pointer to data to transmit + * \param[in] length Number of characters to transmit + * + * \return Status of the operation + * \retval STATUS_OK If operation was completed + * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to invalid + * arguments + * \retval STATUS_ERR_TIMEOUT If operation was not completed, due to USART + * module timing out + * \retval STATUS_ERR_DENIED If the transmitter is not enabled + */ +enum sercom_status_t usart_write_buffer_wait(SercomUsart* const hw, + const uint8_t *tx_data, + uint16_t length) +{ + /* Sanity check arguments */ + + + /* Wait until synchronization is complete */ + USART_WAIT_FOR_SYNC(hw); + + uint16_t tx_pos = 0; + + /* Blocks while buffer is being transferred */ + while (length--) { + /* Wait for the USART to be ready for new data and abort + * operation if it doesn't get ready within the timeout*/ + for (uint32_t i = 0; i <= USART_TIMEOUT; i++) { + if (hw->INTFLAG.reg & SERCOM_USART_INTFLAG_DRE) { + break; + } else if (i == USART_TIMEOUT) { + return SERCOM_STATUS_TIMEOUT; + } + } + + /* Data to send is at least 8 bits long */ + uint16_t data_to_send = tx_data[tx_pos++]; + + /* Check if the character size exceeds 8 bit */ +// if (module->character_size == USART_CHARACTER_SIZE_9BIT) { +// data_to_send |= (tx_data[tx_pos++] << 8); +// } + + /* Send the data through the USART module */ + usart_write_wait(hw, data_to_send); + } + + /* Wait until Transmit is complete or timeout */ + for (uint32_t i = 0; i <= USART_TIMEOUT; i++) { + if (hw->INTFLAG.reg & SERCOM_USART_INTFLAG_TXC) { + break; + } else if (i == USART_TIMEOUT) { + return SERCOM_STATUS_TIMEOUT; + } + } + + return SERCOM_STATUS_OK; +} + +/** + * Receive a buffer of \c length characters via the USART + * + * This blocking function will receive a block of \c length characters + * via the USART. + * + * \note Using this function in combination with the interrupt (\c *_job) + * functions is not recommended as it has no functionality to check if + * there is an ongoing interrupt driven operation running or not. + * + * \param[in] module Pointer to USART software instance struct + * \param[out] rx_data Pointer to receive buffer + * \param[in] length Number of characters to receive + * + * \return Status of the operation. + * \retval STATUS_OK If operation was completed + * \retval STATUS_ERR_INVALID_ARG If operation was not completed, due to an + * invalid argument being supplied + * \retval STATUS_ERR_TIMEOUT If operation was not completed, due + * to USART module timing out + * \retval STATUS_ERR_BAD_FORMAT If the operation was not completed, + * due to a configuration mismatch + * between USART and the sender + * \retval STATUS_ERR_BAD_OVERFLOW If the operation was not completed, + * due to the baud rate being too low or the + * system frequency being too high + * \retval STATUS_ERR_BAD_DATA If the operation was not completed, due + * to data being corrupted + * \retval STATUS_ERR_DENIED If the receiver is not enabled + */ +enum sercom_status_t usart_read_buffer_wait(SercomUsart* hw, + uint8_t *rx_data, + uint16_t length) +{ + /* Sanity check arguments */ + + + uint16_t rx_pos = 0; + + /* Blocks while buffer is being received */ + while (length--) { + /* Wait for the USART to have new data and abort operation if it + * doesn't get ready within the timeout*/ + for (uint32_t i = 0; i <= USART_TIMEOUT; i++) { + if (hw->INTFLAG.reg & SERCOM_USART_INTFLAG_RXC) { + break; + } else if (i == USART_TIMEOUT) { + return SERCOM_STATUS_TIMEOUT; + } + } + + enum sercom_status_t retval; + uint16_t received_data = 0; + + retval = usart_read_wait(hw, &received_data); + + if (retval != SERCOM_STATUS_OK) { + /* Overflow, abort */ + return retval; + } + + /* Read value will be at least 8-bits long */ + rx_data[rx_pos++] = received_data; + + /* If 9-bit data, write next received byte to the buffer */ +// if (module->character_size == USART_CHARACTER_SIZE_9BIT) { +// rx_data[rx_pos++] = (received_data >> 8); +// } + } + + return SERCOM_STATUS_OK; +} + +/** + * -------------------------------- Interrupts ------------------------------- + */ + +/** + * Rx Callbacks for all instances + */ +static usart_rx_callback_t _usart_rx_callbacks[SERCOM_INST_NUM] = { +#if SERCOM_INST_NUM > 0 + NULL, +#endif +#if SERCOM_INST_NUM > 1 + NULL, +#endif +#if SERCOM_INST_NUM > 2 + NULL, +#endif +#if SERCOM_INST_NUM > 3 + NULL, +#endif +#if SERCOM_INST_NUM > 4 + NULL, +#endif +#if SERCOM_INST_NUM > 5 + NULL, +#endif +}; + +/** + * Handles interrupts as they occur, and it will run registered + * callback functions + */ +void _usart_interrupt_handler(Sercom* const sercom_instance, uint8_t instance_index) +{ + /* Hardware instance */ + SercomUsart* const hw = (SercomUsart*)sercom_instance; + + /* Temporary variables */ + uint16_t interrupt_status; + uint8_t error_code; + + /* Wait for the synchronization to complete */ + USART_WAIT_FOR_SYNC(hw); + + /* Read and mask interrupt flag register */ + interrupt_status = hw->INTFLAG.reg; + interrupt_status &= hw->INTENSET.reg; + + /* Check if a DATA READY interrupt has occurred, + * and if there is more to transfer */ + if (interrupt_status & SERCOM_USART_INTFLAG_DRE) { + + /* if (module->remaining_tx_buffer_length) { */ + /* /\* Write value will be at least 8-bits long *\/ */ + /* uint16_t data_to_send = *(module->tx_buffer_ptr); */ + /* /\* Increment 8-bit pointer *\/ */ + /* (module->tx_buffer_ptr)++; */ + + /* if (module->character_size == USART_CHARACTER_SIZE_9BIT) { */ + /* data_to_send |= (*(module->tx_buffer_ptr) << 8); */ + /* /\* Increment 8-bit pointer *\/ */ + /* (module->tx_buffer_ptr)++; */ + /* } */ + /* /\* Write the data to send *\/ */ + /* hw->DATA.reg = (data_to_send & SERCOM_USART_DATA_MASK); */ + + /* if (--(module->remaining_tx_buffer_length) == 0) { */ + /* /\* Disable the Data Register Empty Interrupt *\/ */ + /* hw->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE; */ + /* /\* Enable Transmission Complete interrupt *\/ */ + /* hw->INTENSET.reg = SERCOM_USART_INTFLAG_TXC; */ + + /* TODO: Turn off data ready interrupt */ + hw->INTENCLR.reg = SERCOM_USART_INTFLAG_DRE; + } + + /* Check if the Transmission Complete interrupt has occurred and + * that the transmit buffer is empty */ + if (interrupt_status & SERCOM_USART_INTFLAG_TXC) { + + /* Disable TX Complete Interrupt, and set STATUS_OK */ + hw->INTENCLR.reg = SERCOM_USART_INTFLAG_TXC; + + /* TODO: Callback */ + } + + /* Check if the Receive Complete interrupt has occurred, and that + * there's more data to receive */ + while ((hw->INTFLAG.reg & hw->INTENSET.reg) & SERCOM_USART_INTFLAG_RXC) { + + /* Read out the status code and mask away all but the 4 LSBs */ + error_code = (uint8_t)(hw->STATUS.reg & SERCOM_USART_STATUS_MASK); +#ifndef SAMD20 + /* CTS status should not be considered as an error */ + if(error_code & SERCOM_USART_STATUS_CTS) { + error_code &= ~SERCOM_USART_STATUS_CTS; + } +#endif + /* Check if an error has occurred during the receiving */ + if (error_code) { + /* Check which error occurred */ + if (error_code & SERCOM_USART_STATUS_FERR) { + /* Store the error code and clear flag by writing 1 to it */ + //module->rx_status = STATUS_ERR_BAD_FORMAT; + hw->STATUS.reg |= SERCOM_USART_STATUS_FERR; + } else if (error_code & SERCOM_USART_STATUS_BUFOVF) { + /* Store the error code and clear flag by writing 1 to it */ + //module->rx_status = STATUS_ERR_OVERFLOW; + hw->STATUS.reg |= SERCOM_USART_STATUS_BUFOVF; + } else if (error_code & SERCOM_USART_STATUS_PERR) { + /* Store the error code and clear flag by writing 1 to it */ + //module->rx_status = STATUS_ERR_BAD_DATA; + hw->STATUS.reg |= SERCOM_USART_STATUS_PERR; + } +#ifdef FEATURE_USART_LIN_SLAVE + else if (error_code & SERCOM_USART_STATUS_ISF) { + /* Store the error code and clear flag by writing 1 to it */ + //module->rx_status = STATUS_ERR_PROTOCOL; + hw->STATUS.reg |= SERCOM_USART_STATUS_ISF; + } +#endif +#ifdef FEATURE_USART_COLLISION_DECTION + else if (error_code & SERCOM_USART_STATUS_COLL) { + /* Store the error code and clear flag by writing 1 to it */ + // module->rx_status = STATUS_ERR_PACKET_COLLISION; + hw->STATUS.reg |= SERCOM_USART_STATUS_COLL; + } +#endif + + /* TODO: Error callback */ + + } else { /* No Error code occoured */ + + /* Read current packet from DATA register, + * increment buffer pointer and decrement buffer length */ + uint16_t received_data = (hw->DATA.reg & SERCOM_USART_DATA_MASK); + + /* Rx Callback */ + if (_usart_rx_callbacks[instance_index]) { + _usart_rx_callbacks[instance_index](hw, received_data); + } + + /* TODO: Disable this Rx interrupt at some point */ + //hw->INTENCLR.reg = SERCOM_USART_INTFLAG_RXC; + } + } + +#ifdef FEATURE_USART_HARDWARE_FLOW_CONTROL + if (interrupt_status & SERCOM_USART_INTFLAG_CTSIC) { + /* Disable interrupts */ + hw->INTENCLR.reg = SERCOM_USART_INTENCLR_CTSIC; + /* Clear interrupt flag */ + hw->INTFLAG.reg = SERCOM_USART_INTFLAG_CTSIC; + + /* TODO: Callback here */ + } +#endif + +#ifdef FEATURE_USART_LIN_SLAVE + if (interrupt_status & SERCOM_USART_INTFLAG_RXBRK) { + /* Disable interrupts */ + hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXBRK; + /* Clear interrupt flag */ + hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXBRK; + + /* TODO: Callback here */ + } +#endif + +#ifdef FEATURE_USART_START_FRAME_DECTION + if (interrupt_status & SERCOM_USART_INTFLAG_RXS) { + /* Disable interrupts */ + hw->INTENCLR.reg = SERCOM_USART_INTENCLR_RXS; + /* Clear interrupt flag */ + hw->INTFLAG.reg = SERCOM_USART_INTFLAG_RXS; + + /* TODO: Callback here */ + } +#endif +} + +/** + * Register a callback for received bytes + */ +void usart_register_rx_callback(SercomUsart* const hw, + usart_rx_callback_t callback, + uint32_t priority) +{ + /* Get instance index */ + uint8_t instance_index = _sercom_get_sercom_inst_index((Sercom*)hw); + + /* Enable the Rx interrupt */ + hw->INTENSET.reg = SERCOM_USART_INTFLAG_RXC; + + /* Set the rx handler */ + _usart_rx_callbacks[instance_index] = callback; + + /* Set our out interrupt handler with the main sercom module */ + _sercom_set_handler((Sercom*)hw, _usart_interrupt_handler); + + /* And enable this interrupt in the NVIC */ + irq_register_handler(SERCOM0_IRQn + instance_index, priority); +} diff --git a/loader/src/system/clock.c b/loader/src/system/clock.c new file mode 100644 index 0000000..c9143fc --- /dev/null +++ b/loader/src/system/clock.c @@ -0,0 +1,857 @@ +/** + * SAM D20 Clock Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ +#include "system/clock.h" +#include "system/conf_clocks.h" +#include "system/system.h" +#include "samd20.h" +#include "hw_config.h" + +/* Syncronisation Macros */ +#define DFLL_WAIT_FOR_SYNC() \ + while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_DFLLRDY)) +#define OSC32K_WAIT_FOR_SYNC() \ + while (!(SYSCTRL->PCLKSR.reg & SYSCTRL_PCLKSR_OSC32KRDY)) + +/** + * Determines the current operating frequency of a given clock source. + * + * \param[in] clock_source Clock source to get the frequency of + * + * \returns Frequency of the given clock source, in Hz + */ +uint32_t system_clock_source_get_hz(const enum system_clock_source clock_source) +{ + switch (clock_source) { + case SYSTEM_CLOCK_SOURCE_XOSC: + return XOSC_FREQUENCY; + + case SYSTEM_CLOCK_SOURCE_OSC8M: + return 8000000UL >> SYSCTRL->OSC8M.bit.PRESC; + + case SYSTEM_CLOCK_SOURCE_OSC32K: + return 32768UL; + + case SYSTEM_CLOCK_SOURCE_ULP32K: + return 32768UL; + + case SYSTEM_CLOCK_SOURCE_XOSC32K: + return 0;//TODO _system_clock_inst.xosc32k.frequency; + + case SYSTEM_CLOCK_SOURCE_DFLL: + + /* Check if the DFLL has been configured */ + if (!(SYSCTRL->DFLLCTRL.reg & SYSCTRL_DFLLCTRL_ENABLE)) { + return 0; /* Not configured */ + } + + /* Make sure that the DFLL module is ready */ + DFLL_WAIT_FOR_SYNC(); + + /* Check if operating in closed loop mode */ + if (SYSCTRL->DFLLCTRL.reg & SYSCTRL_DFLLCTRL_MODE) { + return system_gclk_chan_get_hz(SYSCTRL_GCLK_ID_DFLL48) * + (SYSCTRL->DFLLMUL.reg & 0xffff); + } + + return 48000000UL; + + default: + return 0; + } +} + +/** + * Configures the 8MHz (nominal) internal RC oscillator with the given + * configuration settings. + * + * \param[in] config OSC8M configuration structure containing the new config + */ +void system_clock_source_osc8m_set_config(enum system_osc8m_div prescaler, + bool run_in_standby, + bool on_demand) +{ + SYSCTRL_OSC8M_Type temp = SYSCTRL->OSC8M; + + /* Use temporary struct to reduce register access */ + temp.bit.PRESC = prescaler; + temp.bit.ONDEMAND = on_demand; + temp.bit.RUNSTDBY = run_in_standby; + + SYSCTRL->OSC8M = temp; +} +/** + * Configures the 8MHz (nominal) internal RC oscillator with the + * default configuation settings. + * + * - Clock output frequency divided by a factor of 8 + * - Don't run in STANDBY sleep mode + * - Run only when requested by peripheral (on demand) + */ +void system_clock_source_osc8m_set_config_default(void) +{ + system_clock_source_osc8m_set_config(SYSTEM_OSC8M_DIV_8, /* Prescaler */ + false, /* Run in Standby */ + false); /* Run on Demand */ +} + +/** + * Configures the 32KHz (nominal) internal RC oscillator with the given + * configuration settings. + * + * \param[in] config OSC32K configuration structure containing the new config + */ +void system_clock_source_osc32k_set_config(enum system_osc32k_startup startup_time, + bool enable_1khz_output, + bool enable_32khz_output, + bool run_in_standby, + bool on_demand, + bool write_once) +{ + SYSCTRL_OSC32K_Type temp = SYSCTRL->OSC32K; + + /* Update settings via a temporary struct to reduce register access */ + temp.bit.EN1K = enable_1khz_output; + temp.bit.EN32K = enable_32khz_output; + temp.bit.STARTUP = startup_time; + temp.bit.ONDEMAND = on_demand; + temp.bit.RUNSTDBY = run_in_standby; + temp.bit.WRTLOCK = write_once; + + SYSCTRL->OSC32K = temp; +} +/** + * Configures the 32KHz (nominal) internal RC oscillator with the + * default configuration settings. + * + * - 1KHz clock output enabled + * - 32KHz clock output enabled + * - Don't run in STANDBY sleep mode + * - Run only when requested by peripheral (on demand) + * - Set startup time to 130 cycles + * - Don't lock registers after configuration has been written + */ +void system_clock_source_osc32k_set_config_default(void) +{ + system_clock_source_osc32k_set_config(SYSTEM_OSC32K_STARTUP_130, /* Startup Cyles */ + true, /* 1KHz output enable */ + true, /* 32KHz output enable */ + false, /* Run in Standby */ + true, /* Run on demand */ + false); /* Lock registers */ +} + + +/** + * Configures the external oscillator clock source with the given configuration + * settings. + * + * \param[in] config External oscillator configuration structure containing + * the new config + */ +void system_clock_source_xosc_set_config(enum system_clock_external external_clock, + enum system_xosc_startup startup_time, + bool auto_gain_control, + uint32_t frequency, + bool run_in_standby, + bool on_demand) +{ + SYSCTRL_XOSC_Type temp = SYSCTRL->XOSC; + + /* Update settings via a temporary struct to reduce register access */ + temp.bit.STARTUP = startup_time; + + if (external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) { + temp.bit.XTALEN = 1; + } else { + temp.bit.XTALEN = 0; + } + + temp.bit.AMPGC = auto_gain_control; + + /* Set gain if automatic gain control is not selected */ + if (!auto_gain_control) { + if (frequency <= 2000000) { + temp.bit.GAIN = 0; + } else if (frequency <= 4000000) { + temp.bit.GAIN = 1; + } else if (frequency <= 8000000) { + temp.bit.GAIN = 2; + } else if (frequency <= 16000000) { + temp.bit.GAIN = 3; + } else if (frequency <= 30000000) { + temp.bit.GAIN = 4; + } + + } + + temp.bit.ONDEMAND = on_demand; + temp.bit.RUNSTDBY = run_in_standby; + + SYSCTRL->XOSC = temp; +} +/** + * Configures the external oscillator clock source with the default + * configuration settings. + * + * - External Crystal + * - Start-up time of 16384 external clock cycles + * - Automatic crystal gain control mode enabled + * - Frequency of 12MHz + * - Don't run in STANDBY sleep mode + * - Run only when requested by peripheral (on demand) + */ +void system_clock_source_xosc_set_config_default(void) +{ + /* void system_clock_source_xosc_set_config(SYSTEM_CLOCK_EXTERNAL_CRYSTAL, */ + /* SYSTEM_XOSC_STARTUP_16384, */ + /* true, /\* Auto gain control *\/ */ + /* 12000000UL, /\* Frequency *\/ */ + /* false, /\* Run in Standby *\/ */ + /* true); /\* Run on demand *\/ */ +} + + +/** + * Configures the external 32KHz oscillator clock source with the given + * configuration settings. + * + * \param[in] config XOSC32K configuration structure containing the new config + */ +void system_clock_source_xosc32k_set_config(enum system_clock_external external_clock, + enum system_xosc32k_startup startup_time, + bool auto_gain_control, + bool enable_1khz_output, + bool enable_32khz_output, + bool run_in_standby, + bool on_demand, + bool write_once) +{ + SYSCTRL_XOSC32K_Type temp = SYSCTRL->XOSC32K; + + /* Update settings via a temporary struct to reduce register access */ + temp.bit.STARTUP = startup_time; + + if (external_clock == SYSTEM_CLOCK_EXTERNAL_CRYSTAL) { + temp.bit.XTALEN = 1; + } else { + temp.bit.XTALEN = 0; + } + + temp.bit.AAMPEN = auto_gain_control; + temp.bit.EN1K = enable_1khz_output; + temp.bit.EN32K = enable_32khz_output; + + temp.bit.ONDEMAND = on_demand; + temp.bit.RUNSTDBY = run_in_standby; + temp.bit.WRTLOCK = write_once; + + SYSCTRL->XOSC32K = temp; +} +/** + * Configures the external 32KHz oscillator clock source with the + * default configuration settings. + * + * - External Crystal + * - Start-up time of 16384 external clock cycles + * - Automatic crystal gain control mode disabled + * - 1KHz clock output disabled + * - 32KHz clock output enabled + * - Don't run in STANDBY sleep mode + * - Run only when requested by peripheral (on demand) + * - Don't lock registers after configuration has been written + */ +void system_clock_source_xosc32k_set_config_default(void) +{ + system_clock_source_xosc32k_set_config(SYSTEM_CLOCK_EXTERNAL_CRYSTAL, + SYSTEM_XOSC32K_STARTUP_16384, + false, /* Auto gain control */ + false, /* Enable 1KHz output */ + false, /* Enable 32KHz output */ + false, /* Run in standby */ + true, /* Run on demand */ + false); /* Write once */ +} + +/** + * Header file macro copies for runtime support of different revisions + * + * These macros are copied from the header file to be able to support + * both new and old register layout runtime. + */ +#define _SYSTEM_OLD_DFLLVAL_FINE_Pos 0 +#define _SYSTEM_OLD_DFLLVAL_FINE_Msk (0xFFu << _SYSTEM_OLD_DFLLVAL_FINE_Pos) +#define _SYSTEM_OLD_DFLLVAL_FINE(value) ((_SYSTEM_OLD_DFLLVAL_FINE_Msk & ((value) << _SYSTEM_OLD_DFLLVAL_FINE_Pos))) + +#define _SYSTEM_OLD_DFLLVAL_COARSE_Pos 8 +#define _SYSTEM_OLD_DFLLVAL_COARSE_Msk (0x1Fu << _SYSTEM_OLD_DFLLVAL_COARSE_Pos) +#define _SYSTEM_OLD_DFLLVAL_COARSE(value) ((_SYSTEM_OLD_DFLLVAL_COARSE_Msk & ((value) << _SYSTEM_OLD_DFLLVAL_COARSE_Pos))) + +#define _SYSTEM_NEW_DFLLVAL_FINE_Pos 0 +#define _SYSTEM_NEW_DFLLVAL_FINE_Msk (0x3FFu << _SYSTEM_NEW_DFLLVAL_FINE_Pos) +#define _SYSTEM_NEW_DFLLVAL_FINE(value) ((_SYSTEM_NEW_DFLLVAL_FINE_Msk & ((value) << _SYSTEM_NEW_DFLLVAL_FINE_Pos))) + +#define _SYSTEM_NEW_DFLLVAL_COARSE_Pos 10 +#define _SYSTEM_NEW_DFLLVAL_COARSE_Msk (0x3Fu << _SYSTEM_NEW_DFLLVAL_COARSE_Pos) +#define _SYSTEM_NEW_DFLLVAL_COARSE(value) ((_SYSTEM_NEW_DFLLVAL_COARSE_Msk & ((value) << _SYSTEM_NEW_DFLLVAL_COARSE_Pos))) + +#define _SYSTEM_OLD_DFLLMUL_FSTEP_Pos 16 +#define _SYSTEM_OLD_DFLLMUL_FSTEP_Msk (0xFFu << _SYSTEM_OLD_DFLLMUL_FSTEP_Pos) +#define _SYSTEM_OLD_DFLLMUL_FSTEP(value) ((_SYSTEM_OLD_DFLLMUL_FSTEP_Msk & ((value) << _SYSTEM_OLD_DFLLMUL_FSTEP_Pos))) + +#define _SYSTEM_OLD_DFLLMUL_CSTEP_Pos 24 +#define _SYSTEM_OLD_DFLLMUL_CSTEP_Msk (0x1Fu << _SYSTEM_OLD_DFLLMUL_CSTEP_Pos) +#define _SYSTEM_OLD_DFLLMUL_CSTEP(value) ((_SYSTEM_OLD_DFLLMUL_CSTEP_Msk & ((value) << _SYSTEM_OLD_DFLLMUL_CSTEP_Pos))) + +#define _SYSTEM_NEW_DFLLMUL_FSTEP_Pos 16 +#define _SYSTEM_NEW_DFLLMUL_FSTEP_Msk (0x3FFu << _SYSTEM_NEW_DFLLMUL_FSTEP_Pos) +#define _SYSTEM_NEW_DFLLMUL_FSTEP(value) ((_SYSTEM_NEW_DFLLMUL_FSTEP_Msk & ((value) << _SYSTEM_NEW_DFLLMUL_FSTEP_Pos))) + +#define _SYSTEM_NEW_DFLLMUL_CSTEP_Pos 26 +#define _SYSTEM_NEW_DFLLMUL_CSTEP_Msk (0x3Fu << _SYSTEM_NEW_DFLLMUL_CSTEP_Pos) +#define _SYSTEM_NEW_DFLLMUL_CSTEP(value) ((_SYSTEM_NEW_DFLLMUL_CSTEP_Msk & ((value) << _SYSTEM_NEW_DFLLMUL_CSTEP_Pos))) + +#define _SYSTEM_MCU_REVISION_D 3 + + +/** + * Configures the Digital Frequency Locked Loop clock source with the given + * configuration settings. + * + * \note The DFLL will be running when this function returns, as the DFLL module + * needs to be enabled in order to perform the module configuration. + * + * \param[in] config DFLL configuration structure containing the new config + */ +void system_clock_source_dfll_set_config( + enum system_clock_dfll_loop_mode loop_mode, + bool on_demand, + enum system_clock_dfll_quick_lock quick_lock, + enum system_clock_dfll_chill_cycle chill_cycle, + enum system_clock_dfll_wakeup_lock wakeup_lock, + enum system_clock_dfll_stable_tracking stable_tracking, + uint8_t coarse_value, + uint16_t fine_value, + uint8_t coarse_max_step, + uint16_t fine_max_step, + uint16_t multiply_factor) +{ + uint32_t control, val, mul; + + /* Get MCU revision */ + uint32_t rev = system_get_device_id(); + rev &= DSU_DID_REVISION_Msk; + rev = rev >> DSU_DID_REVISION_Pos; + + /* Calculate the Value register */ + if (rev < _SYSTEM_MCU_REVISION_D) { + val = + _SYSTEM_OLD_DFLLVAL_COARSE(coarse_value) | + _SYSTEM_OLD_DFLLVAL_FINE(fine_value); + } else { + val = + _SYSTEM_NEW_DFLLVAL_COARSE(coarse_value) | + _SYSTEM_NEW_DFLLVAL_FINE(fine_value); + } + + /* Calculate the Control register */ + control = + (uint32_t)wakeup_lock | + (uint32_t)stable_tracking | + (uint32_t)quick_lock | + (uint32_t)chill_cycle | + ((uint32_t)on_demand << SYSCTRL_DFLLCTRL_ONDEMAND_Pos); + + /* Set the Multiplication register for closed loop mode */ + if (loop_mode == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) { + if(rev < _SYSTEM_MCU_REVISION_D) { + mul = + _SYSTEM_OLD_DFLLMUL_CSTEP(coarse_max_step) | + _SYSTEM_OLD_DFLLMUL_FSTEP(fine_max_step) | + SYSCTRL_DFLLMUL_MUL(multiply_factor); + } else { + mul = + _SYSTEM_NEW_DFLLMUL_CSTEP(coarse_max_step) | + _SYSTEM_NEW_DFLLMUL_FSTEP(fine_max_step) | + SYSCTRL_DFLLMUL_MUL(multiply_factor); + } + + /* Enable the closed loop mode */ + control |= loop_mode; + } + + /* Workaround for errata 9905 */ + SYSCTRL->DFLLCTRL.reg = control & ~SYSCTRL_DFLLCTRL_ONDEMAND; + DFLL_WAIT_FOR_SYNC(); + + SYSCTRL->DFLLMUL.reg = mul; + SYSCTRL->DFLLVAL.reg = val; + + /* Write full configuration to DFLL control register */ + SYSCTRL->DFLLCTRL.reg = control; +} + +/** + * Configures the Digital Frequency Locked Loop clock source with the + * default configuration settings. + * + * - Open loop mode + * - QuickLock mode enabled + * - Chill cycle enabled + * - Output frequency lock maintained during device wake-up + * - Continuous tracking of the output frequency + * - Default tracking values at the mid-points for both coarse and fine + * tracking parameters + * - Don't run in STANDBY sleep mode + * - Run only when requested by peripheral (on demand) + */ +void system_clock_source_dfll_set_config_default(void) +{ + system_clock_source_dfll_set_config( + SYSTEM_CLOCK_DFLL_LOOP_MODE_OPEN, /* Loop Mode */ + true, /* On demand */ + SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE, /* Quick Lock */ + SYSTEM_CLOCK_DFLL_CHILL_CYCLE_ENABLE, /* Chill Cycle */ + SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP, /* Lock during wakeup */ + SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK, + 0x1f / 4, /* Open Loop - Coarse calibration value */ + 0xff / 4, /* Open Loop - Fine calibration value */ + 1, /* Closed Loop - Coarse Maximum step */ + 1, /* Closed Loop - Fine Maximum step */ + 6); /* Frequency Multiplication Factor */ +} + +/** + * Writes an oscillator calibration value to the given oscillator control + * registers. The acceptable ranges are: + * + * For OSC32K: + * - 7 bits (max value 128) + * For OSC8MHZ: + * - 8 bits (Max value 255) + * For OSCULP: + * - 5 bits (Max value 32) + * + * \note The frequency range parameter applies only when configuring the 8MHz + * oscillator and will be ignored for the other oscillators. + * + * \param[in] clock_source Clock source to calibrate + * \param[in] calibration_value Calibration value to write + * \param[in] freq_range Frequency range (8MHz oscillator only) + * + * \retval STATUS_OK The calibration value was written + * successfully. + * \retval STATUS_ERR_INVALID_ARG The setting is not valid for selected clock + * source. + */ +enum clock_status_t system_clock_source_write_calibration( + const enum system_clock_source clock_source, + const uint16_t calibration_value, + const uint8_t freq_range) +{ + switch (clock_source) { + case SYSTEM_CLOCK_SOURCE_OSC8M: + + if (calibration_value > 0xfff || freq_range > 4) { + return CLOCK_STATUS_INVALID_ARG; + } + + SYSCTRL->OSC8M.bit.CALIB = calibration_value; + SYSCTRL->OSC8M.bit.FRANGE = freq_range; + break; + + case SYSTEM_CLOCK_SOURCE_OSC32K: + + if (calibration_value > 128) { + return CLOCK_STATUS_INVALID_ARG; + } + + OSC32K_WAIT_FOR_SYNC(); + SYSCTRL->OSC32K.bit.CALIB = calibration_value; + break; + + case SYSTEM_CLOCK_SOURCE_ULP32K: + + if (calibration_value > 32) { + return CLOCK_STATUS_INVALID_ARG; + } + + SYSCTRL->OSCULP32K.bit.CALIB = calibration_value; + break; + + default: + assert(false); + return CLOCK_STATUS_INVALID_ARG; + break; + } + + return CLOCK_STATUS_OK; +} + +/** + * Enables a clock source which has been previously configured. + * + * \param[in] clock_source Clock source to enable + * + * \retval STATUS_OK Clock source was enabled successfully and + * is ready + * \retval STATUS_ERR_INVALID_ARG The clock source is not available on this + * device + */ +enum clock_status_t system_clock_source_enable( + const enum system_clock_source clock_source) +{ + switch (clock_source) { + case SYSTEM_CLOCK_SOURCE_OSC8M: + SYSCTRL->OSC8M.reg |= SYSCTRL_OSC8M_ENABLE; + return CLOCK_STATUS_OK; + + case SYSTEM_CLOCK_SOURCE_OSC32K: + SYSCTRL->OSC32K.reg |= SYSCTRL_OSC32K_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC: + SYSCTRL->XOSC.reg |= SYSCTRL_XOSC_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC32K: + SYSCTRL->XOSC32K.reg |= SYSCTRL_XOSC32K_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_DFLL: + SYSCTRL->DFLLCTRL.reg |= SYSCTRL_DFLLCTRL_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_ULP32K: + /* Always enabled */ + return CLOCK_STATUS_OK; + + default: + while(1); + return CLOCK_STATUS_INVALID_ARG; + } + + return CLOCK_STATUS_OK; +} + +/** + * Disables a clock source that was previously enabled. + * + * \param[in] clock_source Clock source to disable + * + * \retval STATUS_OK Clock source was disabled successfully + * \retval STATUS_ERR_INVALID_ARG An invalid or unavailable clock source was + * given + */ +enum clock_status_t system_clock_source_disable( + const enum system_clock_source clock_source) +{ + switch (clock_source) { + case SYSTEM_CLOCK_SOURCE_OSC8M: + SYSCTRL->OSC8M.reg &= ~SYSCTRL_OSC8M_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_OSC32K: + SYSCTRL->OSC32K.reg &= ~SYSCTRL_OSC32K_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC: + SYSCTRL->XOSC.reg &= ~SYSCTRL_XOSC_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC32K: + SYSCTRL->XOSC32K.reg &= ~SYSCTRL_XOSC32K_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_DFLL: + SYSCTRL->DFLLCTRL.reg &= +SYSCTRL_DFLLCTRL_ENABLE; + break; + + case SYSTEM_CLOCK_SOURCE_ULP32K: + /* Not possible to disable */ + + default: + while(1); + return CLOCK_STATUS_INVALID_ARG; + + } + + return CLOCK_STATUS_OK; +} + +/** + * Checks if a given clock source is ready to be used. + * + * \param[in] clock_source Clock source to check if ready + * + * \returns Ready state of the given clock source. + * + * \retval true Clock source is enabled and ready + * \retval false Clock source is disabled or not yet ready + */ +bool system_clock_source_is_ready( + const enum system_clock_source clock_source) +{ + uint32_t mask = 0; + + switch (clock_source) { + case SYSTEM_CLOCK_SOURCE_OSC8M: + mask = SYSCTRL_PCLKSR_OSC8MRDY; + break; + + case SYSTEM_CLOCK_SOURCE_OSC32K: + mask = SYSCTRL_PCLKSR_OSC32KRDY; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC: + mask = SYSCTRL_PCLKSR_XOSCRDY; + break; + + case SYSTEM_CLOCK_SOURCE_XOSC32K: + mask = SYSCTRL_PCLKSR_XOSC32KRDY; + break; + + case SYSTEM_CLOCK_SOURCE_DFLL: + if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) { + mask = (SYSCTRL_PCLKSR_DFLLRDY | + SYSCTRL_PCLKSR_DFLLLCKF | SYSCTRL_PCLKSR_DFLLLCKC); + } else { + mask = SYSCTRL_PCLKSR_DFLLRDY; + } + break; + + case SYSTEM_CLOCK_SOURCE_ULP32K: + /* Not possible to disable */ + return true; + + default: + return false; + } + + return ((SYSCTRL->PCLKSR.reg & mask) == mask); +} + +/* Include some checks for conf_clocks.h validation */ +#include "system/clock_config_check.h" + +/** + * Configures a Generic Clock Generator with the configuration from \c conf_clocks.h. + */ + +#define _CONF_CLOCK_GCLK_CONFIG(n) \ + if (CONF_CLOCK_GCLK_##n##_ENABLE == true) { \ + system_gclk_gen_set_config( \ + GCLK_GENERATOR_##n, \ + CONF_CLOCK_GCLK_##n##_CLOCK_SOURCE, /* Source Clock */ \ + false, /* High When Disabled*/ \ + CONF_CLOCK_GCLK_##n##_PRESCALER, /* Division Factor */ \ + CONF_CLOCK_GCLK_##n##_RUN_IN_STANDBY, /* Run in standby */ \ + CONF_CLOCK_GCLK_##n##_OUTPUT_ENABLE); /* Output Pin Enable */ \ + \ + system_gclk_gen_enable(GCLK_GENERATOR_##n); \ + } + +/** + * Initialize clock system based on the configuration in conf_clocks.h + * + * This function will apply the settings in conf_clocks.h when run from the user + * application. All clock sources and GCLK generators are running when this function + * returns. + */ +void system_clock_init(void) +{ + /* Various bits in the INTFLAG register can be set to one at startup. + This will ensure that these bits are cleared */ + SYSCTRL->INTFLAG.reg = SYSCTRL_INTFLAG_BOD33RDY | SYSCTRL_INTFLAG_BOD33DET | + SYSCTRL_INTFLAG_DFLLRDY; + + system_flash_set_waitstates(CONF_CLOCK_FLASH_WAIT_STATES); + + /* XOSC */ +#if CONF_CLOCK_XOSC_ENABLE == true + struct system_clock_source_xosc_config xosc_conf; + system_clock_source_xosc_get_config_defaults(&xosc_conf); + + xosc_conf.external_clock = CONF_CLOCK_XOSC_EXTERNAL_CRYSTAL; + xosc_conf.startup_time = CONF_CLOCK_XOSC_STARTUP_TIME; + xosc_conf.auto_gain_control = CONF_CLOCK_XOSC_AUTO_GAIN_CONTROL; + xosc_conf.frequency = CONF_CLOCK_XOSC_EXTERNAL_FREQUENCY; + xosc_conf.on_demand = CONF_CLOCK_XOSC_ON_DEMAND; + xosc_conf.run_in_standby = CONF_CLOCK_XOSC_RUN_IN_STANDBY; + + system_clock_source_xosc_set_config(&xosc_conf); + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC); +#endif + + + /* XOSC32K */ +#if CONF_CLOCK_XOSC32K_ENABLE == true + struct system_clock_source_xosc32k_config xosc32k_conf; + system_clock_source_xosc32k_get_config_defaults(&xosc32k_conf); + + xosc32k_conf.frequency = 32768UL; + xosc32k_conf.external_clock = CONF_CLOCK_XOSC32K_EXTERNAL_CRYSTAL; + xosc32k_conf.startup_time = CONF_CLOCK_XOSC32K_STARTUP_TIME; + xosc32k_conf.auto_gain_control = CONF_CLOCK_XOSC32K_AUTO_AMPLITUDE_CONTROL; + xosc32k_conf.enable_1khz_output = CONF_CLOCK_XOSC32K_ENABLE_1KHZ_OUPUT; + xosc32k_conf.enable_32khz_output = CONF_CLOCK_XOSC32K_ENABLE_32KHZ_OUTPUT; + xosc32k_conf.on_demand = false; + xosc32k_conf.run_in_standby = CONF_CLOCK_XOSC32K_RUN_IN_STANDBY; + + system_clock_source_xosc32k_set_config(&xosc32k_conf); + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K); + while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC32K)); + if (CONF_CLOCK_XOSC32K_ON_DEMAND) { + SYSCTRL->XOSC32K.bit.ONDEMAND = 1; + } +#endif + + + /* OSCK32K */ +#if CONF_CLOCK_OSC32K_ENABLE == true + SYSCTRL->OSC32K.bit.CALIB = + (*(uint32_t *)SYSCTRL_FUSES_OSC32KCAL_ADDR >> SYSCTRL_FUSES_OSC32KCAL_Pos); + + struct system_clock_source_osc32k_config osc32k_conf; + system_clock_source_osc32k_get_config_defaults(&osc32k_conf); + + osc32k_conf.startup_time = CONF_CLOCK_OSC32K_STARTUP_TIME; + osc32k_conf.enable_1khz_output = CONF_CLOCK_OSC32K_ENABLE_1KHZ_OUTPUT; + osc32k_conf.enable_32khz_output = CONF_CLOCK_OSC32K_ENABLE_32KHZ_OUTPUT; + osc32k_conf.on_demand = CONF_CLOCK_OSC32K_ON_DEMAND; + osc32k_conf.run_in_standby = CONF_CLOCK_OSC32K_RUN_IN_STANDBY; + + system_clock_source_osc32k_set_config(&osc32k_conf); + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC32K); +#endif + + + /* DFLL Config (Open and Closed Loop) */ +#if CONF_CLOCK_DFLL_ENABLE == true + + system_clock_source_dfll_set_config( + CONF_CLOCK_DFLL_LOOP_MODE, /* Loop Mode */ + CONF_CLOCK_DFLL_ON_DEMAND, /* On demand */ +# if CONF_CLOCK_DFLL_QUICK_LOCK == true + SYSTEM_CLOCK_DFLL_QUICK_LOCK_ENABLE, /* Quick Lock */ +# else + SYSTEM_CLOCK_DFLL_QUICK_LOCK_DISABLE, /* Quick Lock */ +# endif +# if CONF_CLOCK_DFLL_ENABLE_CHILL_CYCLE == true + SYSTEM_CLOCK_DFLL_CHILL_CYCLE_ENABLE, /* Chill Cycle */ +# else + SYSTEM_CLOCK_DFLL_CHILL_CYCLE_DISABLE, /* Chill Cycle */ +# endif +# if CONF_CLOCK_DFLL_KEEP_LOCK_ON_WAKEUP == true + SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_KEEP, /* Lock during wakeup */ +# else + SYSTEM_CLOCK_DFLL_WAKEUP_LOCK_LOSE, /* Lock during wakeup */ +# endif +# if CONF_CLOCK_DFLL_TRACK_AFTER_FINE_LOCK == true + SYSTEM_CLOCK_DFLL_STABLE_TRACKING_TRACK_AFTER_LOCK, +# else + SYSTEM_CLOCK_DFLL_STABLE_TRACKING_FIX_AFTER_LOCK, +# endif + CONF_CLOCK_DFLL_COARSE_VALUE, /* Open Loop - Coarse calib */ + CONF_CLOCK_DFLL_FINE_VALUE, /* Open Loop - Fine calib */ + CONF_CLOCK_DFLL_MAX_COARSE_STEP_SIZE, /* Closed Loop - Coarse Max step */ + CONF_CLOCK_DFLL_MAX_FINE_STEP_SIZE, /* Closed Loop - Fine Max step */ + CONF_CLOCK_DFLL_MULTIPLY_FACTOR); /* Frequency Multiplication */ +#endif + + /* OSC8M */ + system_clock_source_osc8m_set_config(CONF_CLOCK_OSC8M_PRESCALER, + CONF_CLOCK_OSC8M_ON_DEMAND, + CONF_CLOCK_OSC8M_RUN_IN_STANDBY); + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC8M); + + + /* GCLK */ +#if CONF_CLOCK_CONFIGURE_GCLK == true + system_gclk_init(); + + /* Configure all GCLK generators except for the main generator, which + * is configured later after all other clock systems are set up */ + _CONF_CLOCK_GCLK_CONFIG(1); + _CONF_CLOCK_GCLK_CONFIG(2); + _CONF_CLOCK_GCLK_CONFIG(3); + _CONF_CLOCK_GCLK_CONFIG(4); + _CONF_CLOCK_GCLK_CONFIG(5); + _CONF_CLOCK_GCLK_CONFIG(6); + _CONF_CLOCK_GCLK_CONFIG(7); + +# if CONF_CLOCK_DFLL_ENABLE == true + /* Enable DFLL reference clock if in closed loop mode */ + if (CONF_CLOCK_DFLL_LOOP_MODE == SYSTEM_CLOCK_DFLL_LOOP_MODE_CLOSED) { + + system_gclk_chan_set_config(SYSCTRL_GCLK_ID_DFLL48, + CONF_CLOCK_DFLL_SOURCE_GCLK_GENERATOR); + + system_gclk_chan_enable(SYSCTRL_GCLK_ID_DFLL48); + } +# endif +#endif + + + /* DFLL Enable (Open and Closed Loop) */ +#if CONF_CLOCK_DFLL_ENABLE == true + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_DFLL); + while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_DFLL)); + if (CONF_CLOCK_DFLL_ON_DEMAND) { + SYSCTRL->DFLLCTRL.bit.ONDEMAND = 1; + } +#endif + + /* CPU and BUS clocks */ + system_cpu_clock_set_divider(CONF_CLOCK_CPU_DIVIDER); + +#ifdef FEATURE_SYSTEM_CLOCK_FAILURE_DETECT + system_main_clock_set_failure_detect(CONF_CLOCK_CPU_CLOCK_FAILURE_DETECT); +#endif + + system_apb_clock_set_divider(SYSTEM_CLOCK_APB_APBA, CONF_CLOCK_APBA_DIVIDER); + system_apb_clock_set_divider(SYSTEM_CLOCK_APB_APBB, CONF_CLOCK_APBB_DIVIDER); + + /* GCLK 0 */ +#if CONF_CLOCK_CONFIGURE_GCLK == true + /* Configure the main GCLK last as it might depend on other generators */ + _CONF_CLOCK_GCLK_CONFIG(0); +#endif +} diff --git a/loader/src/system/events.c b/loader/src/system/events.c new file mode 100644 index 0000000..d98fbca --- /dev/null +++ b/loader/src/system/events.c @@ -0,0 +1,180 @@ +/* + * SAM D20/D21/R21 Event System Controller Driver + * + * Copyright (C) 2013-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/events.h" +#include "system/system.h" +#include "samd20.h" + +#define EVENTS_INVALID_CHANNEL 0xff +#define _EVENTS_START_OFFSET_BUSY_BITS 8 +#define _EVENTS_START_OFFSET_USER_READY_BIT 0 +#define _EVENTS_START_OFFSET_DETECTION_BIT 8 +#define _EVENTS_START_OFFSET_OVERRUN_BIT 0 + +/** + * internal + * + */ +uint32_t _events_find_bit_position(uint8_t channel, uint8_t start_offset) +{ + uint8_t byte_offset = channel >> 3; + uint32_t pos; + + pos = (((channel % 8) + 1) << start_offset) * ((0xffff * byte_offset) + 1); + + return pos; +} + + +void system_events_init(void) +{ + /* Enable EVSYS register interface */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBC, PM_APBCMASK_EVSYS); + + /* Make sure the EVSYS module is properly reset */ + EVSYS->CTRL.reg = EVSYS_CTRL_SWRST; + + while (EVSYS->CTRL.reg & EVSYS_CTRL_SWRST); +} + + +enum status_code events_allocate(uint8_t channel, + enum events_edge_detect edge_detect, /** edge detection mode */ + enum events_path_selection path, /** events channel path */ + uint8_t generator, /** event generator for the channel */ + uint8_t clock_source) /** clock source for the event channel */ +{ + if (path != EVENTS_PATH_ASYNCHRONOUS) { + /* Set up a GLCK channel to use with the specific channel */ + system_gclk_chan_set_config(EVSYS_GCLK_ID_0 + channel, (enum gclk_generator)clock_source); + system_gclk_chan_enable(EVSYS_GCLK_ID_0 + channel); + } + + EVSYS->CHANNEL.reg = EVSYS_CHANNEL_CHANNEL(channel) | + EVSYS_CHANNEL_EVGEN(generator) | + EVSYS_CHANNEL_PATH(path) | + EVSYS_CHANNEL_EDGSEL(edge_detect); + + return STATUS_OK; +} + +enum status_code events_trigger(uint8_t channel) +{ + /* Because of indirect access the channel must be set first */ + ((uint8_t*)&EVSYS->CHANNEL)[0] = EVSYS_CHANNEL_CHANNEL(channel); + + /* Assert if event path is asynchronous */ + if (EVSYS->CHANNEL.reg & EVSYS_CHANNEL_PATH(EVENTS_PATH_ASYNCHRONOUS)) { + return STATUS_ERR_DENIED; + } + + /* Assert if event edge detection is not set to RISING */ + if (!(EVSYS->CHANNEL.reg & EVSYS_CHANNEL_EDGSEL(EVENTS_EDGE_DETECT_RISING))) { + return STATUS_ERR_DENIED; + } + + + /* The GCLKREQ bit has to be set while triggering the software event */ + EVSYS->CTRL.reg = EVSYS_CTRL_GCLKREQ; + + ((uint16_t*)&EVSYS->CHANNEL)[0] = EVSYS_CHANNEL_CHANNEL(channel) | + EVSYS_CHANNEL_SWEVT; + + EVSYS->CTRL.reg &= ~EVSYS_CTRL_GCLKREQ; + + return STATUS_OK; +} + +bool events_is_busy(uint8_t channel) +{ + return EVSYS->CHSTATUS.reg & (_events_find_bit_position(channel, _EVENTS_START_OFFSET_BUSY_BITS)); +} + +bool events_is_users_ready(uint8_t channel) +{ + return EVSYS->CHSTATUS.reg & (_events_find_bit_position(channel, _EVENTS_START_OFFSET_USER_READY_BIT)); +} + +bool events_is_detected(uint8_t channel) +{ + uint32_t flag = _events_find_bit_position(channel, _EVENTS_START_OFFSET_DETECTION_BIT); + + /* Clear flag when read */ + if (EVSYS->INTFLAG.reg & flag) { + EVSYS->INTFLAG.reg = flag; + return true; + } + + return false; +} + +bool events_is_overrun(uint8_t channel) +{ + uint32_t flag = _events_find_bit_position(channel, _EVENTS_START_OFFSET_OVERRUN_BIT); + + /* Clear flag when read */ + if (EVSYS->INTFLAG.reg & flag) { + EVSYS->INTFLAG.reg = flag; + return true; + } + + return false; +} + +enum status_code events_attach_user(uint8_t channel, uint8_t user_id) +{ + /* Channel number is n + 1 */ + EVSYS->USER.reg = EVSYS_USER_CHANNEL(channel + 1) | + EVSYS_USER_USER(user_id); + + return STATUS_OK; +} + +enum status_code events_detach_user(uint8_t channel, uint8_t user_id) +{ + /* Unused */ + (void)channel; + + /* Write 0 to the channel bit field to select no input */ + EVSYS->USER.reg = EVSYS_USER_USER(user_id); + + return STATUS_OK; +} diff --git a/loader/src/system/extint.c b/loader/src/system/extint.c new file mode 100644 index 0000000..ad48aeb --- /dev/null +++ b/loader/src/system/extint.c @@ -0,0 +1,311 @@ +/** + * SAM D20/D21/R21 External Interrupt Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/extint.h" +#include "system/system.h" +#include "system/interrupt.h" +#include "system/gclk.h" +#include "system/pinmux.h" + +/** + * \brief Determin if the general clock is required + * + * \param[in] filter_input_signal Filter the raw input signal to prevent noise + * \param[in] detection_criteria Edge detection mode to use (\ref extint_detect) + */ +#define _extint_is_gclk_required(filter_input_signal, detection_criteria) \ + ((filter_input_signal) ? true : (\ + (EXTINT_DETECT_RISING == (detection_criteria)) ? true : (\ + (EXTINT_DETECT_FALLING == (detection_criteria)) ? true : (\ + (EXTINT_DETECT_BOTH == (detection_criteria)) ? true : false)))) + +/** + * Initializes and enables the External Interrupt driver. + * + * Enable the clocks used by External Interrupt driver. + * + * Resets the External Interrupt driver, resetting all hardware + * module registers to their power-on defaults, then enable it for further use. + * + * Reset the callback list if callback mode is used. + * + * This function must be called before attempting to use any NMI or standard + * external interrupt channel functions. + * + * \note When SYSTEM module is used, this function will be invoked by + * \ref system_init() automatically if the module is included. + */ +void system_extint_init(void) +{ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + /* Turn on the digital interface clock */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_EIC); + + /* Configure the generic clock for the module and enable it */ + system_gclk_chan_set_config(EIC_GCLK_ID, EXTINT_CLOCK_SOURCE); + + /* Enable the clock anyway, since when needed it will be requested + * by External Interrupt driver */ + system_gclk_chan_enable(EIC_GCLK_ID); + + /* Reset all EIC hardware modules. */ + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + eics[i]->CTRL.reg |= EIC_CTRL_SWRST; + } + + while (extint_is_syncing()) { + /* Wait for all hardware modules to complete synchronization */ + } +} + +/** + * Enables the External Interrupt driver. + * + * Enables EIC modules. + * Registered callback list will not be affected if callback mode is used. + */ +void extint_enable(void) +{ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + /* Enable all EIC hardware modules. */ + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + eics[i]->CTRL.reg |= EIC_CTRL_ENABLE; + } + + while (extint_is_syncing()) { + /* Wait for all hardware modules to complete synchronization */ + } +} + +/** + * Disables the External Interrupt driver. + * + * Disables EIC modules that were previously started via a call to + * \ref _extint_enable(). + * Registered callback list will not be affected if callback mode is used. + */ +void extint_disable(void) +{ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + /* Disable all EIC hardware modules. */ + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + eics[i]->CTRL.reg &= ~EIC_CTRL_ENABLE; + } + + while (extint_is_syncing()) { + /* Wait for all hardware modules to complete synchronization */ + } +} + +/** + * Writes an External Interrupt channel configuration to the hardware module. + * + * Writes out a given configuration of an External Interrupt channel + * configuration to the hardware module. If the channel is already configured, + * the new configuration will replace the existing one. + * + * \param[in] channel External Interrupt channel to configure + * \param[in] config Configuration settings for the channel + + */ +void extint_chan_set_config( + const uint8_t channel, + const struct extint_chan_conf *const config) +{ + /* Sanity check clock requirements */ +// Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && +// _extint_is_gclk_required(config->filter_input_signal, +// config->detection_criteria))); + + system_pinmux_pin_set_config(config->gpio_pin, + config->gpio_pin_mux, + SYSTEM_PINMUX_PIN_DIR_INPUT, + (enum system_pinmux_pin_pull)config->gpio_pin_pull, + false); + + /* Get a pointer to the module hardware instance */ + Eic *const EIC_module = _extint_get_eic_from_channel(channel); + + uint32_t config_pos = (4 * (channel % 8)); + uint32_t new_config; + + /* Determine the channel's new edge detection configuration */ + new_config = (config->detection_criteria << EIC_CONFIG_SENSE0_Pos); + + /* Enable the hardware signal filter if requested in the config */ + if (config->filter_input_signal) { + new_config |= EIC_CONFIG_FILTEN0; + } + + /* Clear the existing and set the new channel configuration */ + EIC_module->CONFIG[channel / 8].reg + = (EIC_module->CONFIG[channel / 8].reg & + ~((EIC_CONFIG_SENSE0_Msk | EIC_CONFIG_FILTEN0) << config_pos)) | + (new_config << config_pos); + + /* Set the channel's new wake up mode setting */ + if (config->wake_if_sleeping) { + EIC_module->WAKEUP.reg |= (1UL << channel); + } else { + EIC_module->WAKEUP.reg &= ~(1UL << channel); + } +} + +/** + * Writes an External Interrupt NMI channel configuration to the hardware module. + * + * Writes out a given configuration of an External Interrupt NMI channel + * configuration to the hardware module. If the channel is already configured, + * the new configuration will replace the existing one. + * + * \param[in] nmi_channel External Interrupt NMI channel to configure + * \param[in] config Configuration settings for the channel + * + * \returns Status code indicating the success or failure of the request. + * \retval STATUS_OK Configuration succeeded + * \retval STATUS_ERR_PIN_MUX_INVALID An invalid pin mux value was supplied + * \retval STATUS_ERR_BAD_FORMAT An invalid detection mode was requested + */ +void extint_nmi_set_config( + const uint8_t nmi_channel, + const struct extint_nmi_conf *const config) +{ + /* Sanity check clock requirements */ +// Assert(!(!system_gclk_gen_is_enabled(EXTINT_CLOCK_SOURCE) && +// _extint_is_gclk_required(config->filter_input_signal, +// config->detection_criteria))); + + system_pinmux_pin_set_config(config->gpio_pin, + config->gpio_pin_mux, + SYSTEM_PINMUX_PIN_DIR_INPUT, + (enum system_pinmux_pin_pull)config->gpio_pin_pull, + false); + + /* Get a pointer to the module hardware instance */ + Eic *const EIC_module = _extint_get_eic_from_channel(nmi_channel); + + uint32_t new_config; + + /* Determine the NMI's new edge detection configuration */ + new_config = (config->detection_criteria << EIC_NMICTRL_NMISENSE_Pos); + + /* Enable the hardware signal filter if requested in the config */ + if (config->filter_input_signal) { + new_config |= EIC_NMICTRL_NMIFILTEN; + } + + /* Disable EIC and general clock to configure NMI */ + extint_disable(); + system_gclk_chan_disable(EIC_GCLK_ID); + + EIC_module->NMICTRL.reg = new_config; + + /* Enable the general clock and EIC after configure NMI */ + system_gclk_chan_enable(EIC_GCLK_ID); + extint_enable(); +} + +/** + * Enables an External Interrupt event output. + * + * Enables one or more output events from the External Interrupt module. See + * \ref extint_events "here" for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in] events Struct containing flags of events to enable + */ +void extint_enable_events( + struct extint_events *const events) +{ + /* Array of available EICs. */ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + /* Update the event control register for each physical EIC instance */ + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + uint32_t event_mask = 0; + + /* Create an enable mask for the current EIC module */ + for (uint32_t j = 0; j < 32; j++) { + if (events->generate_event_on_detect[(32 * i) + j]) { + event_mask |= (1UL << j); + } + } + + /* Enable the masked events */ + eics[i]->EVCTRL.reg |= event_mask; + } +} + +/** + * Disables an External Interrupt event output. + * + * Disables one or more output events from the External Interrupt module. See + * \ref extint_events "here" for a list of events this module supports. + * + * \note Events cannot be altered while the module is enabled. + * + * \param[in] events Struct containing flags of events to disable + */ +void extint_disable_events( + struct extint_events *const events) +{ + /* Array of available EICs. */ + Eic *const eics[EIC_INST_NUM] = EIC_INSTS; + + /* Update the event control register for each physical EIC instance */ + for (uint32_t i = 0; i < EIC_INST_NUM; i++) { + uint32_t event_mask = 0; + + /* Create a disable mask for the current EIC module */ + for (uint32_t j = 0; j < 32; j++) { + if (events->generate_event_on_detect[(32 * i) + j]) { + event_mask |= (1UL << j); + } + } + + /* Disable the masked events */ + eics[i]->EVCTRL.reg &= ~event_mask; + } +} diff --git a/loader/src/system/gclk.c b/loader/src/system/gclk.c new file mode 100644 index 0000000..32d4953 --- /dev/null +++ b/loader/src/system/gclk.c @@ -0,0 +1,454 @@ +/** + * SAM D20 Generic Clock Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/gclk.h" +#include "system/clock.h" +#include "system/interrupt.h" + +#define GCLK_WAIT_FOR_SYNC() while(GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY) + +/** + * Initializes the Generic Clock module, disabling and resetting all active + * Generic Clock Generators and Channels to their power-on default values. + */ +void system_gclk_init(void) +{ + /* Turn on the digital interface clock */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_GCLK); + + /* Software reset the module to ensure it is re-initialized correctly */ + GCLK->CTRL.reg = GCLK_CTRL_SWRST; + + /* Wait for reset to complete */ + while (GCLK->CTRL.reg & GCLK_CTRL_SWRST); +} + +/** + * Writes out a given configuration of a Generic Clock Generator configuration + * to the hardware module. + * + * \note Changing the clock source on the fly (on a running + * generator) can take additional time if the clock source is configured + * to only run on-demand (ONDEMAND bit is set) and it is not currently + * running (no peripheral is requesting the clock source). In this case + * the GCLK will request the new clock while still keeping a request to + * the old clock source until the new clock source is ready. + * + * \note This function will not start a generator that is not already running; + * to start the generator, call system_gclk_gen_enable() + * after configuring a generator. + * + * \param[in] generator Generic Clock Generator index to configure + */ +void system_gclk_gen_set_config(const uint8_t generator, + const uint8_t source_clock, + const bool high_when_disabled, + const uint32_t division_factor, + const bool run_in_standby, + const bool output_enable) +{ + /* Cache new register configurations to minimize sync requirements. */ + uint32_t new_genctrl_config = (generator << GCLK_GENCTRL_ID_Pos); + uint32_t new_gendiv_config = (generator << GCLK_GENDIV_ID_Pos); + + /* Select the requested source clock for the generator */ + new_genctrl_config |= source_clock << GCLK_GENCTRL_SRC_Pos; + + /* Configure the clock to be either high or low when disabled */ + if (high_when_disabled) { + new_genctrl_config |= GCLK_GENCTRL_OOV; + } + + /* Configure if the clock output to I/O pin should be enabled. */ + if (output_enable) { + new_genctrl_config |= GCLK_GENCTRL_OE; + } + + /* Set division factor */ + if (division_factor > 1) { + /* Check if division is a power of two */ + if (((division_factor & (division_factor - 1)) == 0)) { + /* Determine the index of the highest bit set to get the + * division factor that must be loaded into the division + * register */ + + uint32_t div2_count = 0; + + uint32_t mask; + for (mask = (1UL << 1); mask < division_factor; mask <<= 1) { + div2_count++; + } + + /* Set binary divider power of 2 division factor */ + new_gendiv_config |= (div2_count << GCLK_GENDIV_DIV_Pos); + new_genctrl_config |= GCLK_GENCTRL_DIVSEL; + } else { + /* Set integer division factor */ + new_gendiv_config |= (division_factor << GCLK_GENDIV_DIV_Pos); + + /* Enable non-binary division with increased duty cycle accuracy */ + new_genctrl_config |= GCLK_GENCTRL_IDC; + } + } + + /* Enable or disable the clock in standby mode */ + if (run_in_standby) { + new_genctrl_config |= GCLK_GENCTRL_RUNSTDBY; + } + + GCLK_WAIT_FOR_SYNC(); + cpu_irq_enter_critical(); + + /* Select the correct generator */ + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + *((uint8_t*)&GCLK->GENDIV.reg) = generator; + + /* Write the new generator configuration */ + GCLK_WAIT_FOR_SYNC(); + GCLK->GENDIV.reg = new_gendiv_config; + GCLK->GENCTRL.reg = new_genctrl_config | (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN); + + cpu_irq_leave_critical(); +} +void system_gclk_gen_set_config_defaults(const uint8_t generator) +{ + system_gclk_gen_set_config(generator, + GCLK_SOURCE_OSC8M, /* Source Clock */ + false, /* High When Disabled */ + 1, /* Division Factor */ + false, /* Run in standby */ + false); /* Output Pin Enable */ +} + +/** + * Starts the clock generation of a Generic Clock Generator that was previously + * configured via a call to system_gclk_gen_set_config(). + * + * \param[in] generator Generic Clock Generator index to enable + */ +void system_gclk_gen_enable(const uint8_t generator) +{ + GCLK_WAIT_FOR_SYNC(); + cpu_irq_enter_critical(); + + /* Select the requested generator */ + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + + GCLK_WAIT_FOR_SYNC(); + /* Enable generator */ + GCLK->GENCTRL.reg |= GCLK_GENCTRL_GENEN; + + cpu_irq_leave_critical(); +} + +/** + * Stops the clock generation of a Generic Clock Generator that was previously + * started via a call to system_gclk_gen_enable(). + * + * \param[in] generator Generic Clock Generator index to disable + */ +void system_gclk_gen_disable(const uint8_t generator) +{ + GCLK_WAIT_FOR_SYNC(); + cpu_irq_enter_critical(); + + /* Select the requested generator */ + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + + GCLK_WAIT_FOR_SYNC(); + /* Disable generator */ + GCLK->GENCTRL.reg &= ~GCLK_GENCTRL_GENEN; + + /* Wait for clock to become disabled */ + while (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN); + + cpu_irq_leave_critical(); +} + +/** + * Determines if the specified Generic Clock Generator is enabled + * + * \param[in] generator Generic Clock Generator index to check + * + * \return The enabled status. + * \retval true The Generic Clock Generator is enabled; + * \retval false The Generic Clock Generator is disabled. + */ +bool system_gclk_gen_is_enabled(const uint8_t generator) +{ + bool enabled; + + cpu_irq_enter_critical(); + + /* Select the requested generator */ + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + + /* Obtain the enabled status */ + enabled = (GCLK->GENCTRL.reg & GCLK_GENCTRL_GENEN); + + cpu_irq_leave_critical(); + + return enabled; +} + +/** + * \brief Retrieves the clock frequency of a Generic Clock generator. + * + * Determines the clock frequency (in Hz) of a specified Generic Clock + * generator, used as a source to a Generic Clock Channel module. + * + * \param[in] generator Generic Clock Generator index + * + * \return The frequency of the generic clock generator, in Hz. + */ +uint32_t system_gclk_gen_get_hz(const uint8_t generator) +{ + GCLK_WAIT_FOR_SYNC(); + cpu_irq_enter_critical(); + + /* Select the appropriate generator */ + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + GCLK_WAIT_FOR_SYNC(); + enum system_clock_source src = (enum system_clock_source)GCLK->GENCTRL.bit.SRC; + + /* Get the frequency of the source connected to the GCLK generator */ + uint32_t gen_input_hz = system_clock_source_get_hz(src); + + *((uint8_t*)&GCLK->GENCTRL.reg) = generator; + + uint8_t divsel = GCLK->GENCTRL.bit.DIVSEL; + + /* Select the appropriate generator division register */ + *((uint8_t*)&GCLK->GENDIV.reg) = generator; + GCLK_WAIT_FOR_SYNC(); + uint32_t divider = GCLK->GENDIV.bit.DIV; + + cpu_irq_leave_critical(); + + /* Check if the generator is using fractional or binary division */ + if (!divsel && divider > 1) { + gen_input_hz /= divider; + } else if (divsel) { + gen_input_hz >>= (divider+1); + } + + return gen_input_hz; +} + + + +/** + * Writes out a given configuration of a Generic Clock Channel + * configuration to the hardware module. If the clock is currently + * running, it will be stopped. + * + * \note Once called the clock will not be running; to start the clock, + * call system_gclk_chan_enable() after configuring a clock channel. + * + * \param[in] channel Generic Clock channel to configure + * \param[in] source_generator Generator to source clock from + * + */ +void system_gclk_chan_set_config(const uint8_t channel, + enum gclk_generator source_generator) +{ + /* Cache the new config to reduce sync requirements */ + uint32_t new_clkctrl_config = (channel << GCLK_CLKCTRL_ID_Pos); + + /* Select the desired generic clock generator */ + new_clkctrl_config |= source_generator << GCLK_CLKCTRL_GEN_Pos; + + /* Disable generic clock channel */ + system_gclk_chan_disable(channel); + + /* Write the new configuration */ + GCLK->CLKCTRL.reg = new_clkctrl_config; +} +void system_gclk_chan_set_config_default(const uint8_t channel) +{ + system_gclk_chan_set_config(channel, GCLK_GENERATOR_0); +} + +/** + * \brief Enables a Generic Clock that was previously configured. + * + * Starts the clock generation of a Generic Clock that was previously + * configured via a call to \ref system_gclk_chan_set_config(). + * + * \param[in] channel Generic Clock channel to enable + */ +void system_gclk_chan_enable(const uint8_t channel) +{ + cpu_irq_enter_critical(); + + /* Select the requested generator channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + + /* Enable the generic clock */ + GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; + + cpu_irq_leave_critical(); +} + +/** + * Stops the clock generation of a Generic Clock that was previously started + * via a call to \ref system_gclk_chan_enable(). + * + * \param[in] channel Generic Clock channel to disable + */ +void system_gclk_chan_disable(const uint8_t channel) +{ + cpu_irq_enter_critical(); + + /* Select the requested generator channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + + /* Sanity check WRTLOCK */ + if(GCLK->CLKCTRL.bit.WRTLOCK) { + while(1); + } + + /* Switch to known-working source so that the channel can be disabled */ + uint32_t prev_gen_id = GCLK->CLKCTRL.bit.GEN; + GCLK->CLKCTRL.bit.GEN = 0; + + /* Disable the generic clock */ + GCLK->CLKCTRL.reg &= ~GCLK_CLKCTRL_CLKEN; + while (GCLK->CLKCTRL.reg & GCLK_CLKCTRL_CLKEN) { + /* Wait for clock to become disabled */ + } + + /* Restore previous configured clock generator */ + GCLK->CLKCTRL.bit.GEN = prev_gen_id; + + cpu_irq_leave_critical(); +} + +/** + * Determines if the specified Generic Clock channel is enabled + * + * \param[in] channel Generic Clock Channel index + * + * \return The enabled status. + * \retval true The Generic Clock channel is enabled; + * \retval false The Generic Clock channel is disabled. + */ +bool system_gclk_chan_is_enabled(const uint8_t channel) +{ + bool enabled; + + cpu_irq_enter_critical(); + + /* Select the requested generic clock channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + enabled = GCLK->CLKCTRL.bit.CLKEN; + + cpu_irq_leave_critical(); + + return enabled; +} + +/** + * Locks a generic clock channel from further configuration writes. It is only + * possible to unlock the channel configuration through a power on reset. + * + * \param[in] channel Generic Clock channel to enable + */ +void system_gclk_chan_lock(const uint8_t channel) +{ + cpu_irq_enter_critical(); + + /* Select the requested generator channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + + /* Enable the generic clock */ + GCLK->CLKCTRL.reg |= GCLK_CLKCTRL_CLKEN; + + cpu_irq_leave_critical(); +} + +/** + * Determines if the specified Generic Clock channel is locked + * + * \param[in] channel Generic Clock Channel index + * + * \return The lock status. + * \retval true The Generic Clock channel is locked; + * \retval false The Generic Clock channel is not locked. + */ +bool system_gclk_chan_is_locked(const uint8_t channel) +{ + bool locked; + + cpu_irq_enter_critical(); + + /* Select the requested generic clock channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + locked = GCLK->CLKCTRL.bit.WRTLOCK; + + cpu_irq_leave_critical(); + + return locked; +} + +/** + * Determines the clock frequency (in Hz) of a specified Generic Clock + * channel, used as a source to a device peripheral module. + * + * \param[in] channel Generic Clock Channel index + * + * \return The frequency of the generic clock channel, in Hz. + */ +uint32_t system_gclk_chan_get_hz(const uint8_t channel) +{ + uint8_t gen_id; + + cpu_irq_enter_critical(); + + /* Select the requested generic clock channel */ + *((uint8_t*)&GCLK->CLKCTRL.reg) = channel; + gen_id = GCLK->CLKCTRL.bit.GEN; + + cpu_irq_leave_critical(); + + /* Return the clock speed of the associated GCLK generator */ + return system_gclk_gen_get_hz(gen_id); +} diff --git a/loader/src/system/interrupt.c b/loader/src/system/interrupt.c new file mode 100644 index 0000000..7bc76cd --- /dev/null +++ b/loader/src/system/interrupt.c @@ -0,0 +1,78 @@ +/** + * Global interrupt management for SAM D20, SAM3 and SAM4 (NVIC based) + * + * Copyright (c) 2012-2013 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/interrupt.h" +#include + +static volatile uint32_t cpu_irq_critical_section_counter; +static volatile bool cpu_irq_prev_interrupt_state; + +void cpu_irq_enter_critical(void) +{ + if (cpu_irq_critical_section_counter == 0) { + if (cpu_irq_is_enabled()) { + cpu_irq_disable(); + cpu_irq_prev_interrupt_state = true; + } else { + /* Make sure the to save the prev state as false */ + cpu_irq_prev_interrupt_state = false; + } + } + + cpu_irq_critical_section_counter++; +} +void cpu_irq_leave_critical(void) +{ + /* Check if the user is trying to leave a critical section when not + * in a critical section */ + if(cpu_irq_critical_section_counter == 0) { + while (1); + } + + cpu_irq_critical_section_counter--; + + /* Only enable global interrupts when the counter reaches 0 and the + state of the global interrupt flag was enabled when entering + critical state */ + if ((cpu_irq_critical_section_counter == 0) && (cpu_irq_prev_interrupt_state)) { + cpu_irq_enable(); + } +} diff --git a/loader/src/system/pinmux.c b/loader/src/system/pinmux.c new file mode 100644 index 0000000..e45657c --- /dev/null +++ b/loader/src/system/pinmux.c @@ -0,0 +1,213 @@ +/** + * SAM D20/D21/R21 Pin Multiplexer Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include +#include "samd20.h" +#include "system/pinmux.h" + +/** + * Writes out a given configuration of a Port pin configuration to the + * hardware module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[in] port Base of the PORT module to configure. + * \param[in] pin_mask Mask of the port pin to configure. + * \param[in] config Configuration settings for the pin. + */ +static void _system_pinmux_config(PortGroup *const port, + const uint32_t pin_mask, + const uint8_t mux_position, + const enum system_pinmux_pin_dir direction, + const enum system_pinmux_pin_pull input_pull, + bool powersave) +{ + + + /* Track the configuration bits into a temporary variable before writing */ + uint32_t pin_cfg = 0; + + /* Enabled powersave mode, don't create configuration */ + if (!powersave) { + /* Enable the pin peripheral mux flag if non-GPIO selected (pin mux will + * be written later) and store the new mux mask */ + if (mux_position != SYSTEM_PINMUX_GPIO) { + pin_cfg |= PORT_WRCONFIG_PMUXEN; + pin_cfg |= (mux_position << PORT_WRCONFIG_PMUX_Pos); + } + + /* Check if the user has requested that the input buffer be enabled */ + if ((direction == SYSTEM_PINMUX_PIN_DIR_INPUT) || + (direction == SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK)) { + /* Enable input buffer flag */ + pin_cfg |= PORT_WRCONFIG_INEN; + + /* Enable pull-up/pull-down control flag if requested */ + if (input_pull != SYSTEM_PINMUX_PIN_PULL_NONE) { + pin_cfg |= PORT_WRCONFIG_PULLEN; + } + + /* Clear the port DIR bits to disable the output buffer */ + port->DIRCLR.reg = pin_mask; + } + + /* Check if the user has requested that the output buffer be enabled */ + if ((direction == SYSTEM_PINMUX_PIN_DIR_OUTPUT) || + (direction == SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK)) { + /* Cannot use a pullup if the output driver is enabled, + * if requested the input buffer can only sample the current + * output state */ + pin_cfg &= ~PORT_WRCONFIG_PULLEN; + } + } + + /* The Write Configuration register (WRCONFIG) requires the + * pins to to grouped into two 16-bit half-words - split them out here */ + uint32_t lower_pin_mask = (pin_mask & 0xFFFF); + uint32_t upper_pin_mask = (pin_mask >> 16); + + /* Configure the lower 16-bits of the port to the desired configuration, + * including the pin peripheral multiplexer just in case it is enabled */ + port->WRCONFIG.reg + = (lower_pin_mask << PORT_WRCONFIG_PINMASK_Pos) | + pin_cfg | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_WRPINCFG; + + /* Configure the upper 16-bits of the port to the desired configuration, + * including the pin peripheral multiplexer just in case it is enabled */ + port->WRCONFIG.reg + = (upper_pin_mask << PORT_WRCONFIG_PINMASK_Pos) | + pin_cfg | PORT_WRCONFIG_WRPMUX | PORT_WRCONFIG_WRPINCFG | + PORT_WRCONFIG_HWSEL; + + if(!powersave) { + /* Set the pull-up state once the port pins are configured if one was + * requested and it does not violate the valid set of port + * configurations */ + if (pin_cfg & PORT_WRCONFIG_PULLEN) { + /* Set the OUT register bits to enable the pullup if requested, + * clear to enable pull-down */ + if (input_pull == SYSTEM_PINMUX_PIN_PULL_UP) { + port->OUTSET.reg = pin_mask; + } else { + port->OUTCLR.reg = pin_mask; + } + } + + /* Check if the user has requested that the output buffer be enabled */ + if ((direction == SYSTEM_PINMUX_PIN_DIR_OUTPUT) || + (direction == SYSTEM_PINMUX_PIN_DIR_OUTPUT_WITH_READBACK)) { + /* Set the port DIR bits to enable the output buffer */ + port->DIRSET.reg = pin_mask; + } + } +} + +/** + * Writes out a given configuration of a Port pin configuration to the hardware + * module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[in] gpio_pin Index of the GPIO pin to configure. + * \param[in] config Configuration settings for the pin. + */ +void system_pinmux_pin_set_config(const uint8_t gpio_pin, + const uint8_t mux_position, + const enum system_pinmux_pin_dir direction, + const enum system_pinmux_pin_pull input_pull, + bool powersave) +{ + PortGroup *const port = system_pinmux_get_group_from_gpio_pin(gpio_pin); + uint32_t pin_mask = (1UL << (gpio_pin % 32)); + + _system_pinmux_config(port, pin_mask, + mux_position, direction, input_pull, powersave); +} + +/** + * Writes out a given configuration of a Port pin group configuration to the + * hardware module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[in] port Base of the PORT module to configure. + * \param[in] mask Mask of the port pin(s) to configure. + */ +void system_pinmux_group_set_config(PortGroup *const port, + const uint32_t mask, + const uint8_t mux_position, + const enum system_pinmux_pin_dir direction, + const enum system_pinmux_pin_pull input_pull, + bool powersave) +{ + + + for (int i = 0; i < 32; i++) { + if (mask & (1UL << i)) { + _system_pinmux_config(port, (1UL << i), + mux_position, direction, input_pull, powersave); + } + } +} + +/** + * Configures the input sampling mode for a group of pins, to + * control when the physical I/O pin value is sampled and + * stored inside the microcontroller. + * + * \param[in] port Base of the PORT module to configure. + * \param[in] mask Mask of the port pin(s) to configure. + */ +void system_pinmux_group_set_input_sample_mode(PortGroup *const port, + const uint32_t mask, + const enum system_pinmux_pin_sample mode) +{ + + + if (mode == SYSTEM_PINMUX_PIN_SAMPLE_ONDEMAND) { + port->CTRL.reg |= mask; + } else { + port->CTRL.reg &= ~mask; + } +} diff --git a/loader/src/system/port.c b/loader/src/system/port.c new file mode 100644 index 0000000..bc3602b --- /dev/null +++ b/loader/src/system/port.c @@ -0,0 +1,125 @@ +/** + * SAM D20/D21/R21 GPIO Port Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/port.h" + +/** + * Writes out a given configuration of a Port pin configuration to the hardware + * module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[in] gpio_pin Index of the GPIO pin to configure. + */ +void port_pin_set_config(const uint8_t gpio_pin, + enum port_pin_dir direction, + enum port_pin_pull input_pull, + bool powersave) +{ + system_pinmux_pin_set_config(gpio_pin, + SYSTEM_PINMUX_GPIO, + direction, + input_pull, + powersave); +} +/** + * Writes out the default configuration of a Port pin to the hardware + * module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[in] gpio_pin Index of the GPIO pin to configure. + * + * - Input mode with internal pullup enabled + */ +void port_pin_set_config_default(const uint8_t gpio_pin) +{ + port_pin_set_config(gpio_pin, + PORT_PIN_DIR_INPUT, /* Direction */ + PORT_PIN_PULL_UP, /* Pull */ + false); /* Powersave */ +} + +/** + * Writes out a given configuration of a Port group configuration to the + * hardware module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[out] port Base of the PORT module to write to. + * \param[in] mask Mask of the port pin(s) to configure. + */ +void port_group_set_config(PortGroup *const port, + const uint32_t mask, + enum port_pin_dir direction, + enum port_pin_pull input_pull, + bool powersave) +{ + system_pinmux_group_set_config(port, mask, + SYSTEM_PINMUX_GPIO, + direction, + input_pull, + powersave); +} + +/** + * Writes out a given configuration of a Port group configuration to the + * hardware module. + * + * \note If the pin direction is set as an output, the pull-up/pull-down input + * configuration setting is ignored. + * + * \param[out] port Base of the PORT module to write to. + * \param[in] mask Mask of the port pin(s) to configure. + * + * - Input mode with internal pullup enabled + */ +void port_group_set_config_default(PortGroup *const port, + const uint32_t mask) +{ + port_group_set_config(port, mask, + PORT_PIN_DIR_INPUT, + PORT_PIN_PULL_UP, + false); +} diff --git a/loader/src/system/rtc_count.c b/loader/src/system/rtc_count.c new file mode 100644 index 0000000..c7c3648 --- /dev/null +++ b/loader/src/system/rtc_count.c @@ -0,0 +1,427 @@ +/** + * \file + * + * \brief SAM D20/D21/R21 RTC Driver (16-bit Count Mode) + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "samd20.h" + +#include "system/rtc_count.h" +#include "system/gclk.h" +#include "system/events.h" + + +/** + * \brief Resets the RTC module. + * Resets the RTC to hardware defaults. + * + * \param[in,out] module Pointer to the software instance struct + */ +void rtc_count_reset(void) +{ + /* Disable module before reset. */ + rtc_count_disable(); + + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Initiate software reset. */ + RTC->MODE1.CTRL.reg |= RTC_MODE1_CTRL_SWRST; +} + +/** + * \internal Applies the given configuration. + * + * Sets the configurations given from the configuration structure to the + * hardware module + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] config Pointer to the configuration structure. + * + * \return Status of the configuration procedure. + * \retval STATUS_OK RTC configurations was set successfully. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were given. + */ +static enum status_code _rtc_count_set_config( + const struct rtc_count_config *const config) +{ + RTC->MODE1.CTRL.reg = RTC_MODE1_CTRL_MODE(0) | config->prescaler; + + /* Set 16bit mode. */ + RTC->MODE1.CTRL.reg |= RTC_MODE1_CTRL_MODE(1); + + /* Check if match on clear is set, and return invalid + * argument if set. */ + if (config->clear_on_match) { + return STATUS_ERR_INVALID_ARG; + } + /* Set compare values. */ + for (uint8_t i = 0; i < RTC_NUM_OF_COMP16; i++) { + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + rtc_count_set_compare(config->compare_values[i], + (enum rtc_count_compare)i); + } + + /* Check to set continuously clock read update mode. */ + if (config->continuously_update) { + /* Set continuously mode. */ + RTC->MODE1.READREQ.reg |= RTC_READREQ_RCONT; + } + + /* Return status OK if everything was configured. */ + return STATUS_OK; +} + +/** + * \brief Initializes the RTC module with given configurations. + * + * Initializes the module, setting up all given configurations to provide + * the desired functionality of the RTC. + * + * \param[out] module Pointer to the software instance struct + * \param[in] hw Pointer to hardware instance + * \param[in] config Pointer to the configuration structure. + * + * \return Status of the initialization procedure. + * \retval STATUS_OK If the initialization was run stressfully. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were given. + */ +enum status_code rtc_count_init( + const struct rtc_count_config *const config) +{ + /* Turn on the digital interface clock */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_RTC); + + /* Set up GCLK */ + system_gclk_chan_set_config(RTC_GCLK_ID, GCLK_GENERATOR_2); + system_gclk_chan_enable(RTC_GCLK_ID); + + /* Reset module to hardware defaults. */ + rtc_count_reset(); + + /* Set config and return status. */ + return _rtc_count_set_config(config); +} + +/** + * \brief Set the current count value to desired value. + * + * Sets the value of the counter to the specified value. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] count_value The value to be set in count register. + * + * \return Status of setting the register. + * \retval STATUS_OK If everything was executed correctly. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + */ +enum status_code rtc_count_set_count( + const uint32_t count_value) +{ + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Check if 16 bit value is provided. */ + if(count_value > 0xffff){ + return STATUS_ERR_INVALID_ARG; + } + + /* Write value to register. */ + RTC->MODE1.COUNT.reg = (uint32_t)count_value; + + return STATUS_OK; +} + +/** + * \brief Get the current count value. + * + * \param[in,out] module Pointer to the software instance struct + * + * Returns the current count value. + * + * \return The current counter value as a 32 bit unsigned integer. + */ +uint32_t rtc_count_get_count(void) +{ + /* Initialize return value. */ + uint32_t ret_val; + + /* Request read on count register. */ + RTC->MODE1.READREQ.reg = RTC_READREQ_RREQ; + + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Return count value in 16 bit mode. */ + ret_val = (uint32_t)RTC->MODE1.COUNT.reg; + + return ret_val; +} + +/** + * \brief Set the compare value for the specified compare. + * + * Sets the value specified by the implementer to the requested compare. + * + * \note Compare 4 and 5 are only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] comp_value The value to be written to the compare. + * \param[in] comp_index Index of the compare to set. + * + * \return Status indicating if compare was successfully set. + * \retval STATUS_OK If compare was successfully set. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_ERR_BAD_FORMAT If the module was not initialized in a mode. + */ +enum status_code rtc_count_set_compare( + const uint32_t comp_value, + const enum rtc_count_compare comp_index) +{ + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Check sanity of comp_index. */ + if ((uint32_t)comp_index > RTC_NUM_OF_COMP16) { + return STATUS_ERR_INVALID_ARG; + } + + /* Check that 16 bit value is provided. */ + if (comp_value > 0xffff) { + return STATUS_ERR_INVALID_ARG; + } + + /* Set compare value for COMP. */ + RTC->MODE1.COMP[comp_index].reg = comp_value & 0xffff; + + /* Return status if everything is OK. */ + return STATUS_OK; +} + +/** + * \brief Get the current compare value of specified compare. + * + * Retrieves the current value of the specified compare. + * + * \note Compare 4 and 5 are only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[out] comp_value Pointer to 32 bit integer that will be populated with + * the current compare value. + * \param[in] comp_index Index of compare to check. + * + * \return Status of the reading procedure. + * \retval STATUS_OK If the value was read correctly. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_ERR_BAD_FORMAT If the module was not initialized in a mode. + */ +enum status_code rtc_count_get_compare( + uint32_t *const comp_value, + const enum rtc_count_compare comp_index) +{ + /* Check sanity of comp_index. */ + if ((uint32_t)comp_index > RTC_NUM_OF_COMP16) { + return STATUS_ERR_INVALID_ARG; + } + + /* Get compare value for COMP. */ + *comp_value = (uint32_t)RTC->MODE1.COMP[comp_index].reg; + + /* Return status showing everything is OK. */ + return STATUS_OK; +} + +/** + * \brief Retrieves the value of period. + * + * Retrieves the value of the period for the 16 bit mode counter. + * + * \note Only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[out] period_value Pointer to value for return argument. + * + * \return Status of getting the period value. + * \retval STATUS_OK If the period value was read correctly. + * \retval STATUS_ERR_UNSUPPORTED_DEV If incorrect mode was set. + */ +enum status_code rtc_count_get_period( + uint16_t *const period_value) +{ + /* Returns the value. */ + *period_value = RTC->MODE1.PER.reg; + + return STATUS_OK; +} + +/** + * \brief Set the given value to the period. + * + * Sets the given value to the period. + * + * \note Only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] period_value The value to set to the period. + * + * \return Status of setting the period value. + * \retval STATUS_OK If the period was set correctly. + * \retval STATUS_ERR_UNSUPPORTED_DEV If module is not operated in 16 bit mode. + */ +enum status_code rtc_count_set_period( + const uint16_t period_value) +{ + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Write value to register. */ + RTC->MODE1.PER.reg = period_value; + + return STATUS_OK; +} + +/** + * \brief Check if RTC compare match has occurred. + * + * Checks the compare flag to see if a match has occurred. The compare flag is + * set when there is a compare match between counter and the compare. + * + * \note Compare 4 and 5 are only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] comp_index Index of compare to check current flag. + */ +bool rtc_count_is_compare_match( + const enum rtc_count_compare comp_index) +{ + /* Check sanity for 16 bit mode. */ + if (comp_index > RTC_NUM_OF_COMP16) { + return false; + } + + /* Set status of INTFLAG as return argument. */ + return (RTC->MODE1.INTFLAG.reg & (1 << comp_index)); +} + +/** + * \brief Clears RTC compare match flag. + * + * Clears the compare flag. The compare flag is set when there is a compare + * match between the counter and the compare. + * + * \note Compare 4 and 5 are only available in 16 bit mode. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] comp_index Index of compare to check current flag. + * + * \return Status indicating if flag was successfully cleared. + * \retval STATUS_OK If flag was successfully cleared. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + * \retval STATUS_ERR_BAD_FORMAT If the module was not initialized in a mode. + */ +enum status_code rtc_count_clear_compare_match( + const enum rtc_count_compare comp_index) +{ + /* Check sanity for 16 bit mode. */ + if (comp_index > RTC_NUM_OF_COMP16) { + return STATUS_ERR_INVALID_ARG; + } + + /* Clear INTFLAG. */ + RTC->MODE1.INTFLAG.reg = RTC_MODE1_INTFLAG_CMP(1 << comp_index); + + return STATUS_OK; +} + +/** + * \brief Calibrate for too-slow or too-fast oscillator. + * + * When used, the RTC will compensate for an inaccurate oscillator. The + * RTC module will add or subtract cycles from the RTC prescaler to adjust the + * frequency in approximately 1 PPM steps. The provided correction value should + * be between 0 and 127, allowing for a maximum 127 PPM correction. + * + * If no correction is needed, set value to zero. + * + * \note Can only be used when the RTC is operated in 1Hz. + * + * \param[in,out] module Pointer to the software instance struct + * \param[in] value Ranging from -127 to 127 used for the correction. + * + * \return Status of the calibration procedure. + * \retval STATUS_OK If calibration was executed correctly. + * \retval STATUS_ERR_INVALID_ARG If invalid argument(s) were provided. + */ +enum status_code rtc_count_frequency_correction( + const int8_t value) +{ + /* Check if valid argument. */ + if (abs(value) > 0x7F) { + /* Value bigger than allowed, return invalid argument. */ + return STATUS_ERR_INVALID_ARG; + } + + uint32_t new_correction_value; + + /* Load the new correction value as a positive value, sign added later */ + new_correction_value = abs(value); + + /* Convert to positive value and adjust register sign bit. */ + if (value < 0) { + new_correction_value |= RTC_FREQCORR_SIGN; + } + + while (rtc_count_is_syncing()) { + /* Wait for synchronization */ + } + + /* Set value. */ + RTC->MODE1.FREQCORR.reg = new_correction_value; + + return STATUS_OK; +} diff --git a/loader/src/system/wdt.c b/loader/src/system/wdt.c new file mode 100644 index 0000000..16cf19f --- /dev/null +++ b/loader/src/system/wdt.c @@ -0,0 +1,170 @@ +/** + * SAM D20/D21/R21 Watchdog Driver + * + * Copyright (C) 2012-2014 Atmel Corporation. All rights reserved. + * + * \asf_license_start + * + * \page License + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * 3. The name of Atmel may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * 4. This software may only be redistributed and used in connection with an + * Atmel microcontroller product. + * + * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE + * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + * \asf_license_stop + * + */ + +#include "system/wdt.h" +#include "system/system.h" + +#define WDT_WAIT_FOR_SYNC(hw) while (hw->STATUS.reg & WDT_STATUS_SYNCBUSY) + +/** + * Writes a given configuration of a WDT configuration to the + * hardware module + */ +void wdt_set_config(bool always_on, + bool enable, + enum gclk_generator clock_source, + enum wdt_period timeout_period, + enum wdt_period window_period, + enum wdt_period early_warning_period) +{ + Wdt *const hw = WDT; + + /* Turn on the digital interface clock */ + system_apb_clock_set_mask(SYSTEM_CLOCK_APB_APBA, PM_APBAMASK_WDT); + + /* Check of the Watchdog has been locked to be always on, if so, abort */ + if (wdt_is_locked()) { + return;// STATUS_ERR_IO; + } + + /* Check for an invalid timeout period, abort if found */ + if (timeout_period == WDT_PERIOD_NONE) { + return;// STATUS_ERR_INVALID_ARG; + } + + /* Make sure the Window and Early Warning periods are not more than the + * reset period, abort if either is invalid */ + if ((timeout_period < window_period) || + (timeout_period < early_warning_period)) { + return;// STATUS_ERR_INVALID_ARG; + } + + /* Disable the Watchdog module */ + hw->CTRL.reg &= ~WDT_CTRL_ENABLE; + + if(enable == false) { + return;// STATUS_OK; + } + + /* Configure GCLK channel and enable clock */ + system_gclk_chan_set_config(WDT_GCLK_ID, clock_source); + system_gclk_chan_enable(WDT_GCLK_ID); + if (always_on) { + system_gclk_chan_lock(WDT_GCLK_ID); + } + + WDT_WAIT_FOR_SYNC(hw); + + uint32_t new_config = 0; + + /* Update the timeout period value with the requested period */ + new_config |= (timeout_period - 1) << WDT_CONFIG_PER_Pos; + + /* Check if the user has requested a reset window period */ + if (window_period != WDT_PERIOD_NONE) { + hw->CTRL.reg |= WDT_CTRL_WEN; + + /* Update and enable the timeout period value */ + new_config |= (window_period - 1) << WDT_CONFIG_WINDOW_Pos; + } else { + /* Ensure the window enable control flag is cleared */ + hw->CTRL.reg &= ~WDT_CTRL_WEN; + } + + WDT_WAIT_FOR_SYNC(hw); + + /* Write the new Watchdog configuration */ + hw->CONFIG.reg = new_config; + + /* Check if the user has requested an early warning period */ + if (early_warning_period != WDT_PERIOD_NONE) { + WDT_WAIT_FOR_SYNC(hw); + + /* Set the Early Warning period */ + hw->EWCTRL.reg + = (early_warning_period - 1) << WDT_EWCTRL_EWOFFSET_Pos; + } + + WDT_WAIT_FOR_SYNC(hw); + + /* Either enable or lock-enable the Watchdog timer depending on the user + * settings */ + if (always_on) { + hw->CTRL.reg |= WDT_CTRL_ALWAYSON; + } else { + hw->CTRL.reg |= WDT_CTRL_ENABLE; + } +} +/** + * Writes the default configuration of thw WDT to the hardware module + * + * - Not locked, to allow for further (re-)configuration + * - Enable WDT + * - Watchdog timer sourced from Generic Clock Channel 4 + * - A timeout period of 16384 clocks of the Watchdog module clock + * - No window period, so that the Watchdog count can be reset at any time + * - No early warning period to indicate the Watchdog will soon expire + */ +void wdt_set_config_default(void) +{ + wdt_set_config(false, /* Lock WDT */ + true, /* Enable WDT */ + GCLK_GENERATOR_4, /* Clock Source */ + WDT_PERIOD_16384CLK, /* Timeout Period */ + WDT_PERIOD_NONE, /* Window Period */ + WDT_PERIOD_NONE); /* Early Warning Period */ +} + +/** + * Resets the current count of the Watchdog Timer, restarting the timeout + * period count elapsed. This function should be called after the window + * period (if one was set in the module configuration) but before the timeout + * period to prevent a reset of the system. + */ +void wdt_reset_count(void) +{ + Wdt *const hw = WDT; + + WDT_WAIT_FOR_SYNC(hw); + + /* Reset the Watchdog module */ + hw->CLEAR.reg = WDT_CLEAR_CLEAR_KEY; +} diff --git a/loader/src/watchdog.c b/loader/src/watchdog.c new file mode 100644 index 0000000..d98debc --- /dev/null +++ b/loader/src/watchdog.c @@ -0,0 +1,168 @@ +/* + * Functions related to the watchdog. + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "samd20.h" +#include "watchdog.h" +#include "hw_config.h" +#include "system/gclk.h" +#include "system/wdt.h" +#include "system/interrupt.h" +#include "system/port.h" +#include "init.h" + +struct idle_counter idle_count, idle_count_max; + +idle_wait_t last_idle_t = IDLE_NONE; + +#define kick_external_watchdog() do { port_pin_set_output_level(WDT_WDI_PIN, 1); \ + __NOP(); /* > 50ns high */ \ + port_pin_set_output_level(WDT_WDI_PIN, 0); \ + } while(0) + +/** + * Increments the specified idle counter + */ +void increment_idle_counter(idle_wait_t idle_t) +{ + + switch (idle_t) { + case IDLE_LOADER: + idle_count.while_loader++; + break; + default: + /* Oh no no no. Let's die here */ + while(1); + } +} +/** + * Halts if any idle counter is above it's max + */ +void check_idle_counters(void) +{ + if ((idle_count.while_loader > MAXIDLE_WHILE_LOADER)) { + /* Oh dear. Let's die here */ + while (1); + } +} +#define MAX(a,b) ((a>b)?a:b) +#define SET_COUNT_MAX(A) idle_count_max.A = MAX(idle_count_max.A, idle_count.A) +/** + * Clears the idle counters + */ +void clear_idle_counters(void) +{ + SET_COUNT_MAX(while_loader); + + /* Zero out counter */ + memset(&idle_count, 0, sizeof(struct idle_counter)); +} + +/** + * To be run when we wake from sleep + */ +void awake_do_watchdog(void) +{ +#ifdef DEBUG_USE_INTWATCHDOG + wdt_reset_count(); +#endif + + /* WDI high */ + port_pin_set_output_level(WDT_WDI_PIN, 1); +} +/** + * Kick + */ +void kick_the_watchdog(void) +{ +#ifdef DEBUG_USE_INTWATCHDOG + wdt_reset_count(); +#endif + kick_external_watchdog(); +} +/** + * Called in idle loops. Kicks the watchdog + * + * idle_t - The type of idle loop + */ +void idle(idle_wait_t idle_t) +{ + /* Check valid */ + if ((idle_t != IDLE_LOADER)) { + /* Oh dear */ + while (1); + } + + /* Maybe clear */ + if (idle_t != last_idle_t) { + clear_idle_counters(); + last_idle_t = idle_t; + } + + /* Increment the idle counter */ + increment_idle_counter(idle_t); + + /* Check idle counter is still okay */ + check_idle_counters(); + + /* Kick the watchdog */ +#ifdef DEBUG_USE_INTWATCHDOG + wdt_reset_count(); +#endif + + /* WDI toggle */ + port_pin_toggle_output_level(WDT_WDI_PIN); + + /* And sleep */ + system_sleep(); +} + +/** + * Put the external watchdog is a safe state where it will trigger if + * watchdog_init is not called within tout + */ +void external_watchdog_safe(void) +{ + port_pin_set_output_level(WDT_WDI_PIN, 0); + /* Setup the external watchdog interrupt pin */ + port_pin_set_config(WDT_WDI_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ +} +/** + * The external watchdog then resets the MCU and GPS to bring the + * system back up in a clean state. + * 1.2s < tout < 2.4s (ADM6823 Table 1.) + */ +void watchdog_init(void) +{ + /* Setup the external watchdog interrupt pin */ + port_pin_set_config(WDT_WDI_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + kick_external_watchdog(); /* Kick External */ +} diff --git a/loader/src/xosc.c b/loader/src/xosc.c new file mode 100644 index 0000000..2e606c0 --- /dev/null +++ b/loader/src/xosc.c @@ -0,0 +1,260 @@ +/* + * Functions for controlling and calibrating against the external oscillator + * Copyright (C) 2015 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +#include + +#include "samd20.h" +#include "system/clock.h" +#include "system/gclk.h" +#include "system/interrupt.h" +#include "system/port.h" +#include "system/pinmux.h" +#include "system/events.h" +#include "system/extint.h" +#include "hw_config.h" +#include "xosc.h" +//#include "rtc.h" +#include "watchdog.h" + +enum measure_state_t { + MEASURE_WAIT_FOR_FIRST_EVENT, + MEASURE_MEASUREMENT, +} measure_state = MEASURE_WAIT_FOR_FIRST_EVENT; +enum xosc_measurement_t _measurement_t; +uint8_t _measurement_oneshot; +measurement_result_t _callback; + +/** + * ============================================================================= + * HF Clock ======================================================= + * ============================================================================= + */ + +/** + * Init hf clock + */ +void hf_clock_init(void) +{ +#ifdef SI4xxx_TCXO_REG_EN_PIN /* TCXO enable/disable pin */ + port_pin_set_config(SI4xxx_TCXO_REG_EN_PIN, + PORT_PIN_DIR_OUTPUT, /* Direction */ + PORT_PIN_PULL_NONE, /* Pull */ + false); /* Powersave */ + port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 1); /* Enable by default */ +#endif +} +/** + * Enables a high frequency clock for the system, either XOSC or OSC8M + */ +void hf_clock_enable(void) +{ +#if USE_XOSC + + /* Enable TCXO if required */ +#ifdef SI4xxx_TCXO_REG_EN_PIN + port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 1); +#endif + + /* Setup XOSC */ + system_clock_source_xosc_set_config(SYSTEM_CLOCK_EXTERNAL_CLOCK, + SYSTEM_XOSC_STARTUP_1, + true, + XOSC_FREQUENCY, + false, + false); + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC); + + /* Wait for it to stabilise */ + while (!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC)); + +#else + + /* Setup OSC8M */ + system_clock_source_osc8m_set_config(SYSTEM_OSC8M_DIV_2, /* Prescaler */ + false, /* Run in Standby */ + false); /* Run on Demand */ + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_OSC8M); + + /* Wait for it to stabilise */ + while(!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_OSC8M)); + +#endif +} +/** + * Disables the high frequency clock for the system, either XOSC or OSC8M + */ +void hf_clock_disable(void) +{ +#if USE_XOSC + + /* Disable XOSC */ + system_clock_source_disable(SYSTEM_CLOCK_SOURCE_XOSC); + + /* Disable TCXO to save power */ +#ifdef SI4xxx_TCXO_REG_EN_PIN +#if XOSC_TCXO_SHUTDOWN_EN + port_pin_set_output_level(SI4xxx_TCXO_REG_EN_PIN, 0); +#endif +#endif + +#else + + /* Disable OSC8M */ + system_clock_source_disable(SYSTEM_CLOCK_SOURCE_OSC8M); + +#endif +} + +/** + * ============================================================================= + * LF Clock ======================================================= + * ============================================================================= + */ + +/** + * Startup lf clock + */ +void lf_clock_startup(void) +{ +#if USE_LFTIMER + /* Setup XOSC */ + system_clock_source_xosc32k_set_config(SYSTEM_CLOCK_EXTERNAL_CLOCK, + SYSTEM_XOSC32K_STARTUP_4096, /* 100-200ms startup*/ + false, + false, + true, + true, + false, + false); /* write lock */ + system_clock_source_enable(SYSTEM_CLOCK_SOURCE_XOSC32K); + + /* Wait for it to stabilise */ + while (!system_clock_source_is_ready(SYSTEM_CLOCK_SOURCE_XOSC32K)); +#else +/* OSCULP32K is always enabled, nothing to do here */ +#endif +} + +/** + * ============================================================================= + * GCLK0 ======================================================= + * ============================================================================= + */ + +/** + * Switches GLCK0 to the HF clock + */ +void gclk0_to_hf_clock(void) +{ + /* Configure GCLK0 to XOSC / OSC8M */ + system_gclk_gen_set_config(GCLK_GENERATOR_0, +#if USE_XOSC + GCLK_SOURCE_XOSC, /* Source */ +#else + GCLK_SOURCE_OSC8M, /* Source */ +#endif + false, /* High When Disabled */ +#if USE_XOSC + XOSC_GCLK_DIVIDE, /* Division Factor */ +#else + OSC8M_GCLK_DIVIDE, /* Division Factor */ +#endif + true, /* Run in standby */ + false); /* Output Pin Enable */ +} +/** + * Switches GCLK0 to the LF clock + */ +void gclk0_to_lf_clock(void) +{ + /* Configure GCLK0 to XOSC32K / OSCULP32K */ + system_gclk_gen_set_config(GCLK_GENERATOR_0, +#if USE_LFTIMER + GCLK_SOURCE_XOSC32K, /* Source */ +#else + GCLK_SOURCE_OSCULP32K, /* Source */ +#endif + false, /* High When Disabled */ + 1, /* Division Factor */ + true, /* Run in standby */ + false); /* Output Pin Enable */ +} + +/** + * ============================================================================= + * GCLK1 ======================================================= + * ============================================================================= + */ + +/** + * Inits GCLK1. The appropriate source should have been enabled already + */ +void gclk1_init(void) +{ + /* Configure GCLK1 */ + system_gclk_gen_set_config(GCLK_GENERATOR_1, +#if USE_XOSC + GCLK_SOURCE_XOSC, /* Source */ +#else + GCLK_SOURCE_OSC8M, /* Source */ +#endif + false, /* High When Disabled */ +#if USE_XOSC + XOSC_GCLK_DIVIDE, /* Division Factor */ +#else + OSC8M_GCLK_DIVIDE,/* Division Factor */ +#endif + false, /* Run in standby */ + false); /* Output Pin Enable */ + + /* Enable GCLK1 */ + system_gclk_gen_enable(GCLK_GENERATOR_1); +} + +/** + * ============================================================================= + * GCLK2 ======================================================= + * ============================================================================= + */ + +/** + * Inits GCLK2. The appropriate source should have been enabled already using lf_clock_init + */ +void gclk2_init(void) +{ + /* Configure GCLK2 */ + system_gclk_gen_set_config(GCLK_GENERATOR_2, +#if USE_LFTIMER + GCLK_SOURCE_XOSC32K, /* Source */ +#else + GCLK_SOURCE_OSCULP32K, /* Source */ +#endif + false, /* High When Disabled */ + 32, /* GLCK2 is 1024Hz nom. */ + true, /* Run in standby */ + false); /* Output Pin Enable */ + + /* Enable GCLK2 */ + system_gclk_gen_enable(GCLK_GENERATOR_2); +} diff --git a/loader/test/Makefile b/loader/test/Makefile new file mode 100644 index 0000000..c0e3262 --- /dev/null +++ b/loader/test/Makefile @@ -0,0 +1,26 @@ +# +# Makes new test cases +# + +ECHO := echo +SED := sed + +# +# +# +.PHONY: new +new: +ifdef name + @$(ECHO) + @$(ECHO) "Creating $(name)_tc..." + @$(SED) "s/\[template\]/$(name)/g" template/template.h > tc/$(name).h + @$(SED) "s/\[template\]/$(name)/g" template/template.py > tc/$(name).py + @$(SED) -i "s/\/\* \[new_tc\] \*\//\#include \"$(name).h\"\n\/\* \[new_tc\] \*\//" tmain.c + @$(ECHO) "Done!" + @$(ECHO) + @$(ECHO) "Your testcase is at tc/$(name).{py,h}" + @$(ECHO) +else + @$(ECHO) "Please specify a name for the test case!! Like 'make name=new'" + @$(ECHO) "(Note the '_tc' will be appended automatically)" +endif diff --git a/loader/test/README.md b/loader/test/README.md new file mode 100644 index 0000000..24d624f --- /dev/null +++ b/loader/test/README.md @@ -0,0 +1,62 @@ +## Verification + +#### Setup + +``` +sudo apt-get install python-pip +sudo pip install colorama +``` + +#### Usage + +Something like this. + +`> /dev/null arm-none-eabi-gdb -q -x tools/tests.py ` + +You need to have your debugger configured in config.mk and possibly +also have gdbscript-custom. The test driver just issues an `attach 1` +command after gdb startup and expects that to work. + +##### From the makefile + +From the main firmware makefile you can just run + +``` +make test +``` + +to run all tests, or + +``` +make test tc= +``` + +to run a specific test case. To get extra debug info + +``` +make test tc= tc-gdb-info=1 +``` + +#### Operation + +Initially `tests.py` loads the latest binary, and runs `Reset_Handler` +until the top of `main`. It then jumps to `tc_main` instead. + +While stopped in `tc_main` a pointer to the test case is set. The +program is then run, and one loop of `tc_main` runs the test case. + +#### Writing a new test case + +``` +From this directory you can just run 'make name=' +``` + +* Choose a testcase name `[tc-name]` +* Create `tc/[tc-name].py` and `tc/[tc_name].h`. Use a pre-existing test case as a template. +* Add `#include [tc-name].h` to the section at the top of `tmain.c` + +You'll need to fill in the `/* Parameters In */` and `/* Results Out +*/` structures in `tc/[tc-name].h` + +`tc/[tc-name].py` must contain a class called `[tc-name]_tc` that +defines `get_test` and `is_correct` methods. diff --git a/loader/test/main.py b/loader/test/main.py new file mode 100644 index 0000000..ddeb8fd --- /dev/null +++ b/loader/test/main.py @@ -0,0 +1,2233 @@ +'''Wrapper for tmain.c + +Generated with: +test/ctypesgen/ctypesgen.py -o test/main.py --cpp=arm-none-eabi-gcc -E -DCTYPESGEN -g3 -ggdb -O1 -Wall -Wextra -std=gnu99 -ffunction-sections -fdata-sections -mcpu=cortex-m0plus -mthumb -DSAMD20E18 -D__SAMD20E18__ -Iinc/ -Ichip/ -Ichip/cmsis/ -Isamd20/ -Isamd20/component/ -Itest/tc/ test/tmain.c test/tc/osc8m_calib.h test/tc/mem_write_page.h test/tc/location_aprs_file.h test/tc/barometric_altitude.h test/tc/backlog_write_read.h test/tc/mem_write_all.h test/tc/times_two.h test/tc/mem_erase_all.h test/tc/location_telemetry.h test/tc/pressure_temperature.h test/tc/gps_poll.h test/tc/epoch_from_time.h test/tc/gps_baud_error.h test/tc/crc32_gen_buf.h test/tc/analogue_read.h test/tc/read_rocket.h test/tc/adc_battery_solar_read.h test/tc/location_aprs.h test/tc/backlog_read.h test/tc/thermistor_equation.h + +Do not modify this file. +''' + +__docformat__ = 'restructuredtext' + +# Begin preamble + +import ctypes, os, sys +from ctypes import * + +_int_types = (c_int16, c_int32) +if hasattr(ctypes, 'c_int64'): + # Some builds of ctypes apparently do not have c_int64 + # defined; it's a pretty good bet that these builds do not + # have 64-bit pointers. + _int_types += (c_int64,) +for t in _int_types: + if sizeof(t) == sizeof(c_size_t): + c_ptrdiff_t = t +del t +del _int_types + +class c_void(Structure): + # c_void_p is a buggy return type, converting to int, so + # POINTER(None) == c_void_p is actually written as + # POINTER(c_void), so it can be treated as a real pointer. + _fields_ = [('dummy', c_int)] + +def POINTER(obj): + p = ctypes.POINTER(obj) + + # Convert None to a real NULL pointer to work around bugs + # in how ctypes handles None on 64-bit platforms + if not isinstance(p.from_param, classmethod): + def from_param(cls, x): + if x is None: + return cls() + else: + return x + p.from_param = classmethod(from_param) + + return p + +class UserString: + def __init__(self, seq): + if isinstance(seq, basestring): + self.data = seq + elif isinstance(seq, UserString): + self.data = seq.data[:] + else: + self.data = str(seq) + def __str__(self): return str(self.data) + def __repr__(self): return repr(self.data) + def __int__(self): return int(self.data) + def __long__(self): return long(self.data) + def __float__(self): return float(self.data) + def __complex__(self): return complex(self.data) + def __hash__(self): return hash(self.data) + + def __cmp__(self, string): + if isinstance(string, UserString): + return cmp(self.data, string.data) + else: + return cmp(self.data, string) + def __contains__(self, char): + return char in self.data + + def __len__(self): return len(self.data) + def __getitem__(self, index): return self.__class__(self.data[index]) + def __getslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + return self.__class__(self.data[start:end]) + + def __add__(self, other): + if isinstance(other, UserString): + return self.__class__(self.data + other.data) + elif isinstance(other, basestring): + return self.__class__(self.data + other) + else: + return self.__class__(self.data + str(other)) + def __radd__(self, other): + if isinstance(other, basestring): + return self.__class__(other + self.data) + else: + return self.__class__(str(other) + self.data) + def __mul__(self, n): + return self.__class__(self.data*n) + __rmul__ = __mul__ + def __mod__(self, args): + return self.__class__(self.data % args) + + # the following methods are defined in alphabetical order: + def capitalize(self): return self.__class__(self.data.capitalize()) + def center(self, width, *args): + return self.__class__(self.data.center(width, *args)) + def count(self, sub, start=0, end=sys.maxint): + return self.data.count(sub, start, end) + def decode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.decode(encoding, errors)) + else: + return self.__class__(self.data.decode(encoding)) + else: + return self.__class__(self.data.decode()) + def encode(self, encoding=None, errors=None): # XXX improve this? + if encoding: + if errors: + return self.__class__(self.data.encode(encoding, errors)) + else: + return self.__class__(self.data.encode(encoding)) + else: + return self.__class__(self.data.encode()) + def endswith(self, suffix, start=0, end=sys.maxint): + return self.data.endswith(suffix, start, end) + def expandtabs(self, tabsize=8): + return self.__class__(self.data.expandtabs(tabsize)) + def find(self, sub, start=0, end=sys.maxint): + return self.data.find(sub, start, end) + def index(self, sub, start=0, end=sys.maxint): + return self.data.index(sub, start, end) + def isalpha(self): return self.data.isalpha() + def isalnum(self): return self.data.isalnum() + def isdecimal(self): return self.data.isdecimal() + def isdigit(self): return self.data.isdigit() + def islower(self): return self.data.islower() + def isnumeric(self): return self.data.isnumeric() + def isspace(self): return self.data.isspace() + def istitle(self): return self.data.istitle() + def isupper(self): return self.data.isupper() + def join(self, seq): return self.data.join(seq) + def ljust(self, width, *args): + return self.__class__(self.data.ljust(width, *args)) + def lower(self): return self.__class__(self.data.lower()) + def lstrip(self, chars=None): return self.__class__(self.data.lstrip(chars)) + def partition(self, sep): + return self.data.partition(sep) + def replace(self, old, new, maxsplit=-1): + return self.__class__(self.data.replace(old, new, maxsplit)) + def rfind(self, sub, start=0, end=sys.maxint): + return self.data.rfind(sub, start, end) + def rindex(self, sub, start=0, end=sys.maxint): + return self.data.rindex(sub, start, end) + def rjust(self, width, *args): + return self.__class__(self.data.rjust(width, *args)) + def rpartition(self, sep): + return self.data.rpartition(sep) + def rstrip(self, chars=None): return self.__class__(self.data.rstrip(chars)) + def split(self, sep=None, maxsplit=-1): + return self.data.split(sep, maxsplit) + def rsplit(self, sep=None, maxsplit=-1): + return self.data.rsplit(sep, maxsplit) + def splitlines(self, keepends=0): return self.data.splitlines(keepends) + def startswith(self, prefix, start=0, end=sys.maxint): + return self.data.startswith(prefix, start, end) + def strip(self, chars=None): return self.__class__(self.data.strip(chars)) + def swapcase(self): return self.__class__(self.data.swapcase()) + def title(self): return self.__class__(self.data.title()) + def translate(self, *args): + return self.__class__(self.data.translate(*args)) + def upper(self): return self.__class__(self.data.upper()) + def zfill(self, width): return self.__class__(self.data.zfill(width)) + +class MutableString(UserString): + """mutable string objects + + Python strings are immutable objects. This has the advantage, that + strings may be used as dictionary keys. If this property isn't needed + and you insist on changing string values in place instead, you may cheat + and use MutableString. + + But the purpose of this class is an educational one: to prevent + people from inventing their own mutable string class derived + from UserString and than forget thereby to remove (override) the + __hash__ method inherited from UserString. This would lead to + errors that would be very hard to track down. + + A faster and better solution is to rewrite your program using lists.""" + def __init__(self, string=""): + self.data = string + def __hash__(self): + raise TypeError("unhashable type (it is mutable)") + def __setitem__(self, index, sub): + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + sub + self.data[index+1:] + def __delitem__(self, index): + if index < 0: + index += len(self.data) + if index < 0 or index >= len(self.data): raise IndexError + self.data = self.data[:index] + self.data[index+1:] + def __setslice__(self, start, end, sub): + start = max(start, 0); end = max(end, 0) + if isinstance(sub, UserString): + self.data = self.data[:start]+sub.data+self.data[end:] + elif isinstance(sub, basestring): + self.data = self.data[:start]+sub+self.data[end:] + else: + self.data = self.data[:start]+str(sub)+self.data[end:] + def __delslice__(self, start, end): + start = max(start, 0); end = max(end, 0) + self.data = self.data[:start] + self.data[end:] + def immutable(self): + return UserString(self.data) + def __iadd__(self, other): + if isinstance(other, UserString): + self.data += other.data + elif isinstance(other, basestring): + self.data += other + else: + self.data += str(other) + return self + def __imul__(self, n): + self.data *= n + return self + +class String(MutableString, Union): + + _fields_ = [('raw', POINTER(c_char)), + ('data', c_char_p)] + + def __init__(self, obj=""): + if isinstance(obj, (str, unicode, UserString)): + self.data = str(obj) + else: + self.raw = obj + + def __len__(self): + return self.data and len(self.data) or 0 + + def from_param(cls, obj): + # Convert None or 0 + if obj is None or obj == 0: + return cls(POINTER(c_char)()) + + # Convert from String + elif isinstance(obj, String): + return obj + + # Convert from str + elif isinstance(obj, str): + return cls(obj) + + # Convert from c_char_p + elif isinstance(obj, c_char_p): + return obj + + # Convert from POINTER(c_char) + elif isinstance(obj, POINTER(c_char)): + return obj + + # Convert from raw pointer + elif isinstance(obj, int): + return cls(cast(obj, POINTER(c_char))) + + # Convert from object + else: + return String.from_param(obj._as_parameter_) + from_param = classmethod(from_param) + +def ReturnString(obj, func=None, arguments=None): + return String.from_param(obj) + +# As of ctypes 1.0, ctypes does not support custom error-checking +# functions on callbacks, nor does it support custom datatypes on +# callbacks, so we must ensure that all callbacks return +# primitive datatypes. +# +# Non-primitive return values wrapped with UNCHECKED won't be +# typechecked, and will be converted to c_void_p. +def UNCHECKED(type): + if (hasattr(type, "_type_") and isinstance(type._type_, str) + and type._type_ != "P"): + return type + else: + return c_void_p + +# ctypes doesn't have direct support for variadic functions, so we have to write +# our own wrapper class +class _variadic_function(object): + def __init__(self,func,restype,argtypes): + self.func=func + self.func.restype=restype + self.argtypes=argtypes + def _as_parameter_(self): + # So we can pass this variadic function as a function pointer + return self.func + def __call__(self,*args): + fixed_args=[] + i=0 + for argtype in self.argtypes: + # Typecheck what we can + fixed_args.append(argtype.from_param(args[i])) + i+=1 + return self.func(*fixed_args+list(args[i:])) + +# End preamble + +_libs = {} +_libdirs = [] + +# Begin loader + +# ---------------------------------------------------------------------------- +# Copyright (c) 2008 David James +# Copyright (c) 2006-2008 Alex Holkner +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in +# the documentation and/or other materials provided with the +# distribution. +# * Neither the name of pyglet nor the names of its +# contributors may be used to endorse or promote products +# derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# ---------------------------------------------------------------------------- + +import os.path, re, sys, glob +import platform +import ctypes +import ctypes.util + +def _environ_path(name): + if name in os.environ: + return os.environ[name].split(":") + else: + return [] + +class LibraryLoader(object): + def __init__(self): + self.other_dirs=[] + + def load_library(self,libname): + """Given the name of a library, load it.""" + paths = self.getpaths(libname) + + for path in paths: + if os.path.exists(path): + return self.load(path) + + raise ImportError("%s not found." % libname) + + def load(self,path): + """Given a path to a library, load it.""" + try: + # Darwin requires dlopen to be called with mode RTLD_GLOBAL instead + # of the default RTLD_LOCAL. Without this, you end up with + # libraries not being loadable, resulting in "Symbol not found" + # errors + if sys.platform == 'darwin': + return ctypes.CDLL(path, ctypes.RTLD_GLOBAL) + else: + return ctypes.cdll.LoadLibrary(path) + except OSError,e: + raise ImportError(e) + + def getpaths(self,libname): + """Return a list of paths where the library might be found.""" + if os.path.isabs(libname): + yield libname + else: + # FIXME / TODO return '.' and os.path.dirname(__file__) + for path in self.getplatformpaths(libname): + yield path + + path = ctypes.util.find_library(libname) + if path: yield path + + def getplatformpaths(self, libname): + return [] + +# Darwin (Mac OS X) + +class DarwinLibraryLoader(LibraryLoader): + name_formats = ["lib%s.dylib", "lib%s.so", "lib%s.bundle", "%s.dylib", + "%s.so", "%s.bundle", "%s"] + + def getplatformpaths(self,libname): + if os.path.pathsep in libname: + names = [libname] + else: + names = [format % libname for format in self.name_formats] + + for dir in self.getdirs(libname): + for name in names: + yield os.path.join(dir,name) + + def getdirs(self,libname): + '''Implements the dylib search as specified in Apple documentation: + + http://developer.apple.com/documentation/DeveloperTools/Conceptual/ + DynamicLibraries/Articles/DynamicLibraryUsageGuidelines.html + + Before commencing the standard search, the method first checks + the bundle's ``Frameworks`` directory if the application is running + within a bundle (OS X .app). + ''' + + dyld_fallback_library_path = _environ_path("DYLD_FALLBACK_LIBRARY_PATH") + if not dyld_fallback_library_path: + dyld_fallback_library_path = [os.path.expanduser('~/lib'), + '/usr/local/lib', '/usr/lib'] + + dirs = [] + + if '/' in libname: + dirs.extend(_environ_path("DYLD_LIBRARY_PATH")) + else: + dirs.extend(_environ_path("LD_LIBRARY_PATH")) + dirs.extend(_environ_path("DYLD_LIBRARY_PATH")) + + dirs.extend(self.other_dirs) + dirs.append(".") + dirs.append(os.path.dirname(__file__)) + + if hasattr(sys, 'frozen') and sys.frozen == 'macosx_app': + dirs.append(os.path.join( + os.environ['RESOURCEPATH'], + '..', + 'Frameworks')) + + dirs.extend(dyld_fallback_library_path) + + return dirs + +# Posix + +class PosixLibraryLoader(LibraryLoader): + _ld_so_cache = None + + def _create_ld_so_cache(self): + # Recreate search path followed by ld.so. This is going to be + # slow to build, and incorrect (ld.so uses ld.so.cache, which may + # not be up-to-date). Used only as fallback for distros without + # /sbin/ldconfig. + # + # We assume the DT_RPATH and DT_RUNPATH binary sections are omitted. + + directories = [] + for name in ("LD_LIBRARY_PATH", + "SHLIB_PATH", # HPUX + "LIBPATH", # OS/2, AIX + "LIBRARY_PATH", # BE/OS + ): + if name in os.environ: + directories.extend(os.environ[name].split(os.pathsep)) + directories.extend(self.other_dirs) + directories.append(".") + directories.append(os.path.dirname(__file__)) + + try: directories.extend([dir.strip() for dir in open('/etc/ld.so.conf')]) + except IOError: pass + + unix_lib_dirs_list = ['/lib', '/usr/lib', '/lib64', '/usr/lib64'] + if sys.platform.startswith('linux'): + # Try and support multiarch work in Ubuntu + # https://wiki.ubuntu.com/MultiarchSpec + bitage = platform.architecture()[0] + if bitage.startswith('32'): + # Assume Intel/AMD x86 compat + unix_lib_dirs_list += ['/lib/i386-linux-gnu', '/usr/lib/i386-linux-gnu'] + elif bitage.startswith('64'): + # Assume Intel/AMD x86 compat + unix_lib_dirs_list += ['/lib/x86_64-linux-gnu', '/usr/lib/x86_64-linux-gnu'] + else: + # guess... + unix_lib_dirs_list += glob.glob('/lib/*linux-gnu') + directories.extend(unix_lib_dirs_list) + + cache = {} + lib_re = re.compile(r'lib(.*)\.s[ol]') + ext_re = re.compile(r'\.s[ol]$') + for dir in directories: + try: + for path in glob.glob("%s/*.s[ol]*" % dir): + file = os.path.basename(path) + + # Index by filename + if file not in cache: + cache[file] = path + + # Index by library name + match = lib_re.match(file) + if match: + library = match.group(1) + if library not in cache: + cache[library] = path + except OSError: + pass + + self._ld_so_cache = cache + + def getplatformpaths(self, libname): + if self._ld_so_cache is None: + self._create_ld_so_cache() + + result = self._ld_so_cache.get(libname) + if result: yield result + + path = ctypes.util.find_library(libname) + if path: yield os.path.join("/lib",path) + +# Windows + +class _WindowsLibrary(object): + def __init__(self, path): + self.cdll = ctypes.cdll.LoadLibrary(path) + self.windll = ctypes.windll.LoadLibrary(path) + + def __getattr__(self, name): + try: return getattr(self.cdll,name) + except AttributeError: + try: return getattr(self.windll,name) + except AttributeError: + raise + +class WindowsLibraryLoader(LibraryLoader): + name_formats = ["%s.dll", "lib%s.dll", "%slib.dll"] + + def load_library(self, libname): + try: + result = LibraryLoader.load_library(self, libname) + except ImportError: + result = None + if os.path.sep not in libname: + for name in self.name_formats: + try: + result = getattr(ctypes.cdll, name % libname) + if result: + break + except WindowsError: + result = None + if result is None: + try: + result = getattr(ctypes.cdll, libname) + except WindowsError: + result = None + if result is None: + raise ImportError("%s not found." % libname) + return result + + def load(self, path): + return _WindowsLibrary(path) + + def getplatformpaths(self, libname): + if os.path.sep not in libname: + for name in self.name_formats: + dll_in_current_dir = os.path.abspath(name % libname) + if os.path.exists(dll_in_current_dir): + yield dll_in_current_dir + path = ctypes.util.find_library(name % libname) + if path: + yield path + +# Platform switching + +# If your value of sys.platform does not appear in this dict, please contact +# the Ctypesgen maintainers. + +loaderclass = { + "darwin": DarwinLibraryLoader, + "cygwin": WindowsLibraryLoader, + "win32": WindowsLibraryLoader +} + +loader = loaderclass.get(sys.platform, PosixLibraryLoader)() + +def add_library_search_dirs(other_dirs): + loader.other_dirs = other_dirs + +load_library = loader.load_library + +del loaderclass + +# End loader + +add_library_search_dirs([]) + +# No libraries + +# No modules + +# test/tc/times_two.h: 11 +class struct_times_two_tc_params(Structure): + pass + +struct_times_two_tc_params.__slots__ = [ + 'input', +] +struct_times_two_tc_params._fields_ = [ + ('input', c_int), +] + +# test/tc/times_two.h: 11 +for _lib in _libs.values(): + try: + times_two_tc_params = (struct_times_two_tc_params).in_dll(_lib, 'times_two_tc_params') + break + except: + pass + +# test/tc/times_two.h: 15 +class struct_times_two_tc_results(Structure): + pass + +struct_times_two_tc_results.__slots__ = [ + 'result', +] +struct_times_two_tc_results._fields_ = [ + ('result', c_int), +] + +# test/tc/times_two.h: 15 +for _lib in _libs.values(): + try: + times_two_tc_results = (struct_times_two_tc_results).in_dll(_lib, 'times_two_tc_results') + break + except: + pass + +# test/tc/osc8m_calib.h: 13 +class struct_osc8m_calib_tc_params(Structure): + pass + +struct_osc8m_calib_tc_params.__slots__ = [ + 'dummy', +] +struct_osc8m_calib_tc_params._fields_ = [ + ('dummy', c_int), +] + +# test/tc/osc8m_calib.h: 13 +for _lib in _libs.values(): + try: + osc8m_calib_tc_params = (struct_osc8m_calib_tc_params).in_dll(_lib, 'osc8m_calib_tc_params') + break + except: + pass + +# test/tc/osc8m_calib.h: 19 +class struct_osc8m_calib_tc_results(Structure): + pass + +struct_osc8m_calib_tc_results.__slots__ = [ + 'result', + 'c_process', + 'c_temp', +] +struct_osc8m_calib_tc_results._fields_ = [ + ('result', c_int), + ('c_process', c_int), + ('c_temp', c_int), +] + +# test/tc/osc8m_calib.h: 19 +for _lib in _libs.values(): + try: + osc8m_calib_tc_results = (struct_osc8m_calib_tc_results).in_dll(_lib, 'osc8m_calib_tc_results') + break + except: + pass + +# test/tc/osc8m_calib.h: 22 +for _lib in _libs.values(): + try: + _result = (c_uint32).in_dll(_lib, '_result') + break + except: + pass + +# inc/cron.h: 33 +class struct_tracker_time(Structure): + pass + +struct_tracker_time.__slots__ = [ + 'epoch', + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'valid', +] +struct_tracker_time._fields_ = [ + ('epoch', c_uint32), + ('year', c_uint16), + ('month', c_uint8), + ('day', c_uint8), + ('hour', c_uint8), + ('minute', c_uint8), + ('second', c_uint8), + ('valid', c_uint8), +] + +# inc/data.h: 59 +class struct_tracker_datapoint(Structure): + pass + +struct_tracker_datapoint.__slots__ = [ + 'time', + 'latitude', + 'longitude', + 'altitude', + 'satillite_count', + 'time_to_first_fix', + 'battery', + 'solar', + 'main_pressure', + 'thermistor_temperature', + 'bmp180_temperature', + 'radio_die_temperature', + 'xosc_error', + 'flash_status', +] +struct_tracker_datapoint._fields_ = [ + ('time', struct_tracker_time), + ('latitude', c_int32), + ('longitude', c_int32), + ('altitude', c_int32), + ('satillite_count', c_uint8), + ('time_to_first_fix', c_uint8), + ('battery', c_float), + ('solar', c_float), + ('main_pressure', c_int32), + ('thermistor_temperature', c_float), + ('bmp180_temperature', c_float), + ('radio_die_temperature', c_float), + ('xosc_error', c_uint32), + ('flash_status', c_uint8), +] + +# test/tc/location_aprs.h: 16 +class struct_location_aprs_tc_params(Structure): + pass + +struct_location_aprs_tc_params.__slots__ = [ + 'lat', + 'lon', +] +struct_location_aprs_tc_params._fields_ = [ + ('lat', c_float), + ('lon', c_float), +] + +# test/tc/location_aprs.h: 16 +for _lib in _libs.values(): + try: + location_aprs_tc_params = (struct_location_aprs_tc_params).in_dll(_lib, 'location_aprs_tc_params') + break + except: + pass + +# test/tc/location_aprs.h: 23 +class struct_location_aprs_tc_results(Structure): + pass + +struct_location_aprs_tc_results.__slots__ = [ + 'tx_allow', + 'frequency', + 'prefix', + 'callsign', +] +struct_location_aprs_tc_results._fields_ = [ + ('tx_allow', c_bool), + ('frequency', c_double), + ('prefix', String), + ('callsign', String), +] + +# test/tc/location_aprs.h: 23 +for _lib in _libs.values(): + try: + location_aprs_tc_results = (struct_location_aprs_tc_results).in_dll(_lib, 'location_aprs_tc_results') + break + except: + pass + +# test/tc/location_telemetry.h: 15 +class struct_location_telemetry_tc_params(Structure): + pass + +struct_location_telemetry_tc_params.__slots__ = [ + 'lat', + 'lon', +] +struct_location_telemetry_tc_params._fields_ = [ + ('lat', c_float), + ('lon', c_float), +] + +# test/tc/location_telemetry.h: 15 +for _lib in _libs.values(): + try: + location_telemetry_tc_params = (struct_location_telemetry_tc_params).in_dll(_lib, 'location_telemetry_tc_params') + break + except: + pass + +# test/tc/location_telemetry.h: 19 +class struct_location_telemetry_tc_results(Structure): + pass + +struct_location_telemetry_tc_results.__slots__ = [ + 'tx_allow', +] +struct_location_telemetry_tc_results._fields_ = [ + ('tx_allow', c_bool), +] + +# test/tc/location_telemetry.h: 19 +for _lib in _libs.values(): + try: + location_telemetry_tc_results = (struct_location_telemetry_tc_results).in_dll(_lib, 'location_telemetry_tc_results') + break + except: + pass + +# test/tc/mem_write_page.h: 18 +class struct_mem_write_page_tc_params(Structure): + pass + +struct_mem_write_page_tc_params.__slots__ = [ + 'address', + 'page', +] +struct_mem_write_page_tc_params._fields_ = [ + ('address', c_uint32), + ('page', c_uint8 * 256), +] + +# test/tc/mem_write_page.h: 18 +for _lib in _libs.values(): + try: + mem_write_page_tc_params = (struct_mem_write_page_tc_params).in_dll(_lib, 'mem_write_page_tc_params') + break + except: + pass + +# test/tc/mem_write_page.h: 25 +class struct_mem_write_page_tc_results(Structure): + pass + +struct_mem_write_page_tc_results.__slots__ = [ + 'page_read', +] +struct_mem_write_page_tc_results._fields_ = [ + ('page_read', c_uint8 * 256), +] + +# test/tc/mem_write_page.h: 25 +for _lib in _libs.values(): + try: + mem_write_page_tc_results = (struct_mem_write_page_tc_results).in_dll(_lib, 'mem_write_page_tc_results') + break + except: + pass + +# test/tc/mem_write_all.h: 17 +class struct_mem_write_all_tc_params(Structure): + pass + +struct_mem_write_all_tc_params.__slots__ = [ + 'page_data', +] +struct_mem_write_all_tc_params._fields_ = [ + ('page_data', c_uint8 * 256), +] + +# test/tc/mem_write_all.h: 17 +for _lib in _libs.values(): + try: + mem_write_all_tc_params = (struct_mem_write_all_tc_params).in_dll(_lib, 'mem_write_all_tc_params') + break + except: + pass + +# test/tc/mem_write_all.h: 26 +class struct_mem_write_all_tc_results(Structure): + pass + +struct_mem_write_all_tc_results.__slots__ = [ + 'all_good', + 'fail_address', + 'fail_wrote', + 'fail_read', +] +struct_mem_write_all_tc_results._fields_ = [ + ('all_good', c_uint8), + ('fail_address', c_uint32), + ('fail_wrote', c_uint8), + ('fail_read', c_uint8), +] + +# test/tc/mem_write_all.h: 26 +for _lib in _libs.values(): + try: + mem_write_all_tc_results = (struct_mem_write_all_tc_results).in_dll(_lib, 'mem_write_all_tc_results') + break + except: + pass + +# test/tc/mem_write_all.h: 36 +for _lib in _libs.values(): + try: + page_read = (c_uint8 * 256).in_dll(_lib, 'page_read') + break + except: + pass + +# test/tc/mem_write_all.h: 37 +for _lib in _libs.values(): + try: + i = (c_uint32).in_dll(_lib, 'i') + break + except: + pass + +# test/tc/mem_write_all.h: 37 +for _lib in _libs.values(): + try: + j = (c_uint32).in_dll(_lib, 'j') + break + except: + pass + +# test/tc/location_aprs_file.h: 17 +class struct_location_aprs_file_tc_params(Structure): + pass + +struct_location_aprs_file_tc_params.__slots__ = [ + 'lat', + 'lon', +] +struct_location_aprs_file_tc_params._fields_ = [ + ('lat', c_float), + ('lon', c_float), +] + +# test/tc/location_aprs_file.h: 17 +for _lib in _libs.values(): + try: + location_aprs_file_tc_params = (struct_location_aprs_file_tc_params).in_dll(_lib, 'location_aprs_file_tc_params') + break + except: + pass + +# test/tc/location_aprs_file.h: 25 +class struct_location_aprs_file_tc_results(Structure): + pass + +struct_location_aprs_file_tc_results.__slots__ = [ + 'tx_allow', + 'frequency', +] +struct_location_aprs_file_tc_results._fields_ = [ + ('tx_allow', c_bool), + ('frequency', c_float), +] + +# test/tc/location_aprs_file.h: 25 +for _lib in _libs.values(): + try: + location_aprs_file_tc_results = (struct_location_aprs_file_tc_results).in_dll(_lib, 'location_aprs_file_tc_results') + break + except: + pass + +# test/tc/backlog_write_read.h: 19 +class struct_backlog_write_read_tc_params(Structure): + pass + +struct_backlog_write_read_tc_params.__slots__ = [ + 'record_not_get', + 'epoch_write', +] +struct_backlog_write_read_tc_params._fields_ = [ + ('record_not_get', c_uint8), + ('epoch_write', c_uint32), +] + +# test/tc/backlog_write_read.h: 19 +for _lib in _libs.values(): + try: + backlog_write_read_tc_params = (struct_backlog_write_read_tc_params).in_dll(_lib, 'backlog_write_read_tc_params') + break + except: + pass + +# test/tc/backlog_write_read.h: 27 +class struct_backlog_write_read_tc_results(Structure): + pass + +struct_backlog_write_read_tc_results.__slots__ = [ + 'epoch_read', + 'wptr', + 'rptr', +] +struct_backlog_write_read_tc_results._fields_ = [ + ('epoch_read', c_uint32), + ('wptr', c_uint32), + ('rptr', c_uint32), +] + +# test/tc/backlog_write_read.h: 27 +for _lib in _libs.values(): + try: + backlog_write_read_tc_results = (struct_backlog_write_read_tc_results).in_dll(_lib, 'backlog_write_read_tc_results') + break + except: + pass + +# test/tc/backlog_write_read.h: 29 +for _lib in _libs.values(): + try: + backlog_write_index = (c_uint16).in_dll(_lib, 'backlog_write_index') + break + except: + pass + +# test/tc/backlog_write_read.h: 32 +for _lib in _libs.values(): + try: + dp = (struct_tracker_datapoint).in_dll(_lib, 'dp') + break + except: + pass + +# test/tc/backlog_write_read.h: 33 +for _lib in _libs.values(): + try: + dp_ptr = (POINTER(struct_tracker_datapoint)).in_dll(_lib, 'dp_ptr') + break + except: + pass + +# test/tc/backlog_read.h: 20 +class struct_backlog_read_tc_params(Structure): + pass + +struct_backlog_read_tc_params.__slots__ = [ + 'dummy', +] +struct_backlog_read_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/backlog_read.h: 20 +for _lib in _libs.values(): + try: + backlog_read_tc_params = (struct_backlog_read_tc_params).in_dll(_lib, 'backlog_read_tc_params') + break + except: + pass + +# test/tc/backlog_read.h: 28 +class struct_backlog_read_tc_results(Structure): + pass + +struct_backlog_read_tc_results.__slots__ = [ + 'aprs_backlog_str', + 'returned_null', +] +struct_backlog_read_tc_results._fields_ = [ + ('aprs_backlog_str', c_char * 256), + ('returned_null', c_uint8), +] + +# test/tc/backlog_read.h: 28 +for _lib in _libs.values(): + try: + backlog_read_tc_results = (struct_backlog_read_tc_results).in_dll(_lib, 'backlog_read_tc_results') + break + except: + pass + +# test/tc/backlog_read.h: 30 +for _lib in _libs.values(): + try: + backlog_index = (c_uint16).in_dll(_lib, 'backlog_index') + break + except: + pass + +# test/tc/backlog_read.h: 33 +for _lib in _libs.values(): + try: + dp_ptr = (POINTER(struct_tracker_datapoint)).in_dll(_lib, 'dp_ptr') + break + except: + pass + +# test/tc/mem_erase_all.h: 17 +class struct_mem_erase_all_tc_params(Structure): + pass + +struct_mem_erase_all_tc_params.__slots__ = [ + 'dummy', +] +struct_mem_erase_all_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/mem_erase_all.h: 17 +for _lib in _libs.values(): + try: + mem_erase_all_tc_params = (struct_mem_erase_all_tc_params).in_dll(_lib, 'mem_erase_all_tc_params') + break + except: + pass + +# test/tc/mem_erase_all.h: 24 +class struct_mem_erase_all_tc_results(Structure): + pass + +struct_mem_erase_all_tc_results.__slots__ = [ + 'dummy', +] +struct_mem_erase_all_tc_results._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/mem_erase_all.h: 24 +for _lib in _libs.values(): + try: + mem_erase_all_tc_results = (struct_mem_erase_all_tc_results).in_dll(_lib, 'mem_erase_all_tc_results') + break + except: + pass + +# test/tc/analogue_read.h: 18 +class struct_analogue_read_tc_params(Structure): + pass + +struct_analogue_read_tc_params.__slots__ = [ + 'dummy', +] +struct_analogue_read_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/analogue_read.h: 18 +for _lib in _libs.values(): + try: + analogue_read_tc_params = (struct_analogue_read_tc_params).in_dll(_lib, 'analogue_read_tc_params') + break + except: + pass + +# test/tc/analogue_read.h: 27 +class struct_analogue_read_tc_results(Structure): + pass + +struct_analogue_read_tc_results.__slots__ = [ + 'battery', + 'thermistor', + 'solar', +] +struct_analogue_read_tc_results._fields_ = [ + ('battery', c_float), + ('thermistor', c_float), + ('solar', c_float), +] + +# test/tc/analogue_read.h: 27 +for _lib in _libs.values(): + try: + analogue_read_tc_results = (struct_analogue_read_tc_results).in_dll(_lib, 'analogue_read_tc_results') + break + except: + pass + +# test/tc/adc_battery_solar_read.h: 17 +class struct_adc_battery_solar_read_tc_params(Structure): + pass + +struct_adc_battery_solar_read_tc_params.__slots__ = [ + 'dummy', +] +struct_adc_battery_solar_read_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/adc_battery_solar_read.h: 17 +for _lib in _libs.values(): + try: + adc_battery_solar_read_tc_params = (struct_adc_battery_solar_read_tc_params).in_dll(_lib, 'adc_battery_solar_read_tc_params') + break + except: + pass + +# test/tc/adc_battery_solar_read.h: 25 +class struct_adc_battery_solar_read_tc_results(Structure): + pass + +struct_adc_battery_solar_read_tc_results.__slots__ = [ + 'battery', + 'solar', +] +struct_adc_battery_solar_read_tc_results._fields_ = [ + ('battery', c_float), + ('solar', c_float), +] + +# test/tc/adc_battery_solar_read.h: 25 +for _lib in _libs.values(): + try: + adc_battery_solar_read_tc_results = (struct_adc_battery_solar_read_tc_results).in_dll(_lib, 'adc_battery_solar_read_tc_results') + break + except: + pass + +# inc/gps.h: 59 +class struct_gps_data_t(Structure): + pass + +struct_gps_data_t.__slots__ = [ + 'year', + 'month', + 'day', + 'hour', + 'minute', + 'second', + 'latitude', + 'longitude', + 'altitude', + 'satillite_count', + 'is_locked', + 'time_to_first_fix', +] +struct_gps_data_t._fields_ = [ + ('year', c_uint16), + ('month', c_uint8), + ('day', c_uint8), + ('hour', c_uint8), + ('minute', c_uint8), + ('second', c_uint8), + ('latitude', c_int32), + ('longitude', c_int32), + ('altitude', c_int32), + ('satillite_count', c_uint8), + ('is_locked', c_uint8), + ('time_to_first_fix', c_uint8), +] + +# test/tc/gps_baud_error.h: 20 +class struct_gps_baud_error_tc_params(Structure): + pass + +struct_gps_baud_error_tc_params.__slots__ = [ + 'dummy', +] +struct_gps_baud_error_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/gps_baud_error.h: 20 +for _lib in _libs.values(): + try: + gps_baud_error_tc_params = (struct_gps_baud_error_tc_params).in_dll(_lib, 'gps_baud_error_tc_params') + break + except: + pass + +# test/tc/gps_baud_error.h: 30 +class struct_gps_baud_error_tc_results(Structure): + pass + +struct_gps_baud_error_tc_results.__slots__ = [ + 'intended_baud', + 'peripheral_clock', + 'register_value', + 'calculated_baud_milli', +] +struct_gps_baud_error_tc_results._fields_ = [ + ('intended_baud', c_uint32), + ('peripheral_clock', c_uint32), + ('register_value', c_uint16), + ('calculated_baud_milli', c_uint32), +] + +# test/tc/gps_baud_error.h: 30 +for _lib in _libs.values(): + try: + gps_baud_error_tc_results = (struct_gps_baud_error_tc_results).in_dll(_lib, 'gps_baud_error_tc_results') + break + except: + pass + +# test/tc/gps_baud_error.h: 41 +for _lib in _libs.values(): + try: + sercom_index = (c_uint32).in_dll(_lib, 'sercom_index') + break + except: + pass + +# test/tc/gps_baud_error.h: 42 +for _lib in _libs.values(): + try: + gclk_index = (c_uint32).in_dll(_lib, 'gclk_index') + break + except: + pass + +# test/tc/gps_baud_error.h: 43 +for _lib in _libs.values(): + try: + baudrate = (c_uint32).in_dll(_lib, 'baudrate') + break + except: + pass + +# test/tc/gps_baud_error.h: 44 +for _lib in _libs.values(): + try: + baud = (c_uint16).in_dll(_lib, 'baud') + break + except: + pass + +# test/tc/gps_baud_error.h: 45 +for _lib in _libs.values(): + try: + calcuated_baud = (c_uint32).in_dll(_lib, 'calcuated_baud') + break + except: + pass + +# test/tc/crc32_gen_buf.h: 19 +class struct_crc32_gen_buf_tc_params(Structure): + pass + +struct_crc32_gen_buf_tc_params.__slots__ = [ + 'test_buffer', +] +struct_crc32_gen_buf_tc_params._fields_ = [ + ('test_buffer', c_uint8 * 32), +] + +# test/tc/crc32_gen_buf.h: 19 +for _lib in _libs.values(): + try: + crc32_gen_buf_tc_params = (struct_crc32_gen_buf_tc_params).in_dll(_lib, 'crc32_gen_buf_tc_params') + break + except: + pass + +# test/tc/crc32_gen_buf.h: 27 +class struct_crc32_gen_buf_tc_results(Structure): + pass + +struct_crc32_gen_buf_tc_results.__slots__ = [ + 'calculated_crc32', + 'extracted_crc32', +] +struct_crc32_gen_buf_tc_results._fields_ = [ + ('calculated_crc32', c_uint32), + ('extracted_crc32', c_uint32), +] + +# test/tc/crc32_gen_buf.h: 27 +for _lib in _libs.values(): + try: + crc32_gen_buf_tc_results = (struct_crc32_gen_buf_tc_results).in_dll(_lib, 'crc32_gen_buf_tc_results') + break + except: + pass + +# test/tc/crc32_gen_buf.h: 37 +for _lib in _libs.values(): + try: + test = (c_uint32).in_dll(_lib, 'test') + break + except: + pass + +# test/tc/crc32_gen_buf.h: 38 +for _lib in _libs.values(): + try: + uint8t_buffer = (POINTER(c_uint8)).in_dll(_lib, 'uint8t_buffer') + break + except: + pass + +# test/tc/barometric_altitude.h: 17 +class struct_barometric_altitude_tc_params(Structure): + pass + +struct_barometric_altitude_tc_params.__slots__ = [ + 'pressure', +] +struct_barometric_altitude_tc_params._fields_ = [ + ('pressure', c_float), +] + +# test/tc/barometric_altitude.h: 17 +for _lib in _libs.values(): + try: + barometric_altitude_tc_params = (struct_barometric_altitude_tc_params).in_dll(_lib, 'barometric_altitude_tc_params') + break + except: + pass + +# test/tc/barometric_altitude.h: 24 +class struct_barometric_altitude_tc_results(Structure): + pass + +struct_barometric_altitude_tc_results.__slots__ = [ + 'altitude', +] +struct_barometric_altitude_tc_results._fields_ = [ + ('altitude', c_double), +] + +# test/tc/barometric_altitude.h: 24 +for _lib in _libs.values(): + try: + barometric_altitude_tc_results = (struct_barometric_altitude_tc_results).in_dll(_lib, 'barometric_altitude_tc_results') + break + except: + pass + +# test/tc/pressure_temperature.h: 19 +class struct_pressure_temperature_tc_params(Structure): + pass + +struct_pressure_temperature_tc_params.__slots__ = [ + 'dummy', +] +struct_pressure_temperature_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/pressure_temperature.h: 19 +for _lib in _libs.values(): + try: + pressure_temperature_tc_params = (struct_pressure_temperature_tc_params).in_dll(_lib, 'pressure_temperature_tc_params') + break + except: + pass + +# test/tc/pressure_temperature.h: 26 +class struct_pressure_temperature_tc_results(Structure): + pass + +struct_pressure_temperature_tc_results.__slots__ = [ + 'pressure', + 'temperature', +] +struct_pressure_temperature_tc_results._fields_ = [ + ('pressure', c_float), + ('temperature', c_float), +] + +# test/tc/pressure_temperature.h: 26 +for _lib in _libs.values(): + try: + pressure_temperature_tc_results = (struct_pressure_temperature_tc_results).in_dll(_lib, 'pressure_temperature_tc_results') + break + except: + pass + +# test/tc/thermistor_equation.h: 18 +class struct_thermistor_equation_tc_params(Structure): + pass + +struct_thermistor_equation_tc_params.__slots__ = [ + 'value', +] +struct_thermistor_equation_tc_params._fields_ = [ + ('value', c_float), +] + +# test/tc/thermistor_equation.h: 18 +for _lib in _libs.values(): + try: + thermistor_equation_tc_params = (struct_thermistor_equation_tc_params).in_dll(_lib, 'thermistor_equation_tc_params') + break + except: + pass + +# test/tc/thermistor_equation.h: 25 +class struct_thermistor_equation_tc_results(Structure): + pass + +struct_thermistor_equation_tc_results.__slots__ = [ + 'temperature', +] +struct_thermistor_equation_tc_results._fields_ = [ + ('temperature', c_float), +] + +# test/tc/thermistor_equation.h: 25 +for _lib in _libs.values(): + try: + thermistor_equation_tc_results = (struct_thermistor_equation_tc_results).in_dll(_lib, 'thermistor_equation_tc_results') + break + except: + pass + +# test/tc/gps_poll.h: 17 +class struct_gps_poll_tc_params(Structure): + pass + +struct_gps_poll_tc_params.__slots__ = [ + 'dummy', +] +struct_gps_poll_tc_params._fields_ = [ + ('dummy', c_uint32), +] + +# test/tc/gps_poll.h: 17 +for _lib in _libs.values(): + try: + gps_poll_tc_params = (struct_gps_poll_tc_params).in_dll(_lib, 'gps_poll_tc_params') + break + except: + pass + +# test/tc/gps_poll.h: 27 +class struct_gps_poll_tc_results(Structure): + pass + +struct_gps_poll_tc_results.__slots__ = [ + 'latitude', + 'longitude', + 'altitude', + 'satillite_count', + 'is_locked', +] +struct_gps_poll_tc_results._fields_ = [ + ('latitude', c_int32), + ('longitude', c_int32), + ('altitude', c_int32), + ('satillite_count', c_uint8), + ('is_locked', c_uint8), +] + +# test/tc/gps_poll.h: 27 +for _lib in _libs.values(): + try: + gps_poll_tc_results = (struct_gps_poll_tc_results).in_dll(_lib, 'gps_poll_tc_results') + break + except: + pass + +# test/tc/gps_poll.h: 38 +for _lib in _libs.values(): + try: + data = (struct_gps_data_t).in_dll(_lib, 'data') + break + except: + pass + +# test/tc/epoch_from_time.h: 17 +class struct_epoch_from_time_tc_params(Structure): + pass + +struct_epoch_from_time_tc_params.__slots__ = [ + 'dummy', +] +struct_epoch_from_time_tc_params._fields_ = [ + ('dummy', c_int), +] + +# test/tc/epoch_from_time.h: 17 +for _lib in _libs.values(): + try: + epoch_from_time_tc_params = (struct_epoch_from_time_tc_params).in_dll(_lib, 'epoch_from_time_tc_params') + break + except: + pass + +# test/tc/epoch_from_time.h: 24 +class struct_epoch_from_time_tc_results(Structure): + pass + +struct_epoch_from_time_tc_results.__slots__ = [ + 'epoch', +] +struct_epoch_from_time_tc_results._fields_ = [ + ('epoch', c_uint32), +] + +# test/tc/epoch_from_time.h: 24 +for _lib in _libs.values(): + try: + epoch_from_time_tc_results = (struct_epoch_from_time_tc_results).in_dll(_lib, 'epoch_from_time_tc_results') + break + except: + pass + +# test/tc/epoch_from_time.h: 35 +for _lib in _libs.values(): + try: + t = (struct_tracker_time).in_dll(_lib, 't') + break + except: + pass + +tc_ptr_type = CFUNCTYPE(UNCHECKED(None), ) # /richard/_pico-tracker/firmware/test/tmain.c: 65 + +# /richard/_pico-tracker/firmware/test/tmain.c: 66 +for _lib in _libs.values(): + try: + tc_ptr = (tc_ptr_type).in_dll(_lib, 'tc_ptr') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/osc8m_calib.h: 13 +for _lib in _libs.values(): + try: + osc8m_calib_tc_params = (struct_osc8m_calib_tc_params).in_dll(_lib, 'osc8m_calib_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/osc8m_calib.h: 19 +for _lib in _libs.values(): + try: + osc8m_calib_tc_results = (struct_osc8m_calib_tc_results).in_dll(_lib, 'osc8m_calib_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/osc8m_calib.h: 22 +for _lib in _libs.values(): + try: + _result = (c_uint32).in_dll(_lib, '_result') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_page.h: 18 +for _lib in _libs.values(): + try: + mem_write_page_tc_params = (struct_mem_write_page_tc_params).in_dll(_lib, 'mem_write_page_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_page.h: 25 +for _lib in _libs.values(): + try: + mem_write_page_tc_results = (struct_mem_write_page_tc_results).in_dll(_lib, 'mem_write_page_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_aprs_file.h: 17 +for _lib in _libs.values(): + try: + location_aprs_file_tc_params = (struct_location_aprs_file_tc_params).in_dll(_lib, 'location_aprs_file_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_aprs_file.h: 25 +for _lib in _libs.values(): + try: + location_aprs_file_tc_results = (struct_location_aprs_file_tc_results).in_dll(_lib, 'location_aprs_file_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/barometric_altitude.h: 17 +for _lib in _libs.values(): + try: + barometric_altitude_tc_params = (struct_barometric_altitude_tc_params).in_dll(_lib, 'barometric_altitude_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/barometric_altitude.h: 24 +for _lib in _libs.values(): + try: + barometric_altitude_tc_results = (struct_barometric_altitude_tc_results).in_dll(_lib, 'barometric_altitude_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_write_read.h: 19 +for _lib in _libs.values(): + try: + backlog_write_read_tc_params = (struct_backlog_write_read_tc_params).in_dll(_lib, 'backlog_write_read_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_write_read.h: 27 +for _lib in _libs.values(): + try: + backlog_write_read_tc_results = (struct_backlog_write_read_tc_results).in_dll(_lib, 'backlog_write_read_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_write_read.h: 29 +for _lib in _libs.values(): + try: + backlog_write_index = (c_uint16).in_dll(_lib, 'backlog_write_index') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_write_read.h: 32 +for _lib in _libs.values(): + try: + dp = (struct_tracker_datapoint).in_dll(_lib, 'dp') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_write_read.h: 33 +for _lib in _libs.values(): + try: + dp_ptr = (POINTER(struct_tracker_datapoint)).in_dll(_lib, 'dp_ptr') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_all.h: 17 +for _lib in _libs.values(): + try: + mem_write_all_tc_params = (struct_mem_write_all_tc_params).in_dll(_lib, 'mem_write_all_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_all.h: 26 +for _lib in _libs.values(): + try: + mem_write_all_tc_results = (struct_mem_write_all_tc_results).in_dll(_lib, 'mem_write_all_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_all.h: 36 +for _lib in _libs.values(): + try: + page_read = (c_uint8 * 256).in_dll(_lib, 'page_read') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_all.h: 37 +for _lib in _libs.values(): + try: + i = (c_uint32).in_dll(_lib, 'i') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_write_all.h: 37 +for _lib in _libs.values(): + try: + j = (c_uint32).in_dll(_lib, 'j') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/times_two.h: 11 +for _lib in _libs.values(): + try: + times_two_tc_params = (struct_times_two_tc_params).in_dll(_lib, 'times_two_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/times_two.h: 15 +for _lib in _libs.values(): + try: + times_two_tc_results = (struct_times_two_tc_results).in_dll(_lib, 'times_two_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_erase_all.h: 17 +for _lib in _libs.values(): + try: + mem_erase_all_tc_params = (struct_mem_erase_all_tc_params).in_dll(_lib, 'mem_erase_all_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/mem_erase_all.h: 24 +for _lib in _libs.values(): + try: + mem_erase_all_tc_results = (struct_mem_erase_all_tc_results).in_dll(_lib, 'mem_erase_all_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_telemetry.h: 15 +for _lib in _libs.values(): + try: + location_telemetry_tc_params = (struct_location_telemetry_tc_params).in_dll(_lib, 'location_telemetry_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_telemetry.h: 19 +for _lib in _libs.values(): + try: + location_telemetry_tc_results = (struct_location_telemetry_tc_results).in_dll(_lib, 'location_telemetry_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/pressure_temperature.h: 19 +for _lib in _libs.values(): + try: + pressure_temperature_tc_params = (struct_pressure_temperature_tc_params).in_dll(_lib, 'pressure_temperature_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/pressure_temperature.h: 26 +for _lib in _libs.values(): + try: + pressure_temperature_tc_results = (struct_pressure_temperature_tc_results).in_dll(_lib, 'pressure_temperature_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_poll.h: 17 +for _lib in _libs.values(): + try: + gps_poll_tc_params = (struct_gps_poll_tc_params).in_dll(_lib, 'gps_poll_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_poll.h: 27 +for _lib in _libs.values(): + try: + gps_poll_tc_results = (struct_gps_poll_tc_results).in_dll(_lib, 'gps_poll_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_poll.h: 38 +for _lib in _libs.values(): + try: + data = (struct_gps_data_t).in_dll(_lib, 'data') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/epoch_from_time.h: 17 +for _lib in _libs.values(): + try: + epoch_from_time_tc_params = (struct_epoch_from_time_tc_params).in_dll(_lib, 'epoch_from_time_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/epoch_from_time.h: 24 +for _lib in _libs.values(): + try: + epoch_from_time_tc_results = (struct_epoch_from_time_tc_results).in_dll(_lib, 'epoch_from_time_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/epoch_from_time.h: 35 +for _lib in _libs.values(): + try: + t = (struct_tracker_time).in_dll(_lib, 't') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 20 +for _lib in _libs.values(): + try: + gps_baud_error_tc_params = (struct_gps_baud_error_tc_params).in_dll(_lib, 'gps_baud_error_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 30 +for _lib in _libs.values(): + try: + gps_baud_error_tc_results = (struct_gps_baud_error_tc_results).in_dll(_lib, 'gps_baud_error_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 41 +for _lib in _libs.values(): + try: + sercom_index = (c_uint32).in_dll(_lib, 'sercom_index') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 42 +for _lib in _libs.values(): + try: + gclk_index = (c_uint32).in_dll(_lib, 'gclk_index') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 43 +for _lib in _libs.values(): + try: + baudrate = (c_uint32).in_dll(_lib, 'baudrate') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 44 +for _lib in _libs.values(): + try: + baud = (c_uint16).in_dll(_lib, 'baud') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/gps_baud_error.h: 45 +for _lib in _libs.values(): + try: + calcuated_baud = (c_uint32).in_dll(_lib, 'calcuated_baud') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/crc32_gen_buf.h: 19 +for _lib in _libs.values(): + try: + crc32_gen_buf_tc_params = (struct_crc32_gen_buf_tc_params).in_dll(_lib, 'crc32_gen_buf_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/crc32_gen_buf.h: 27 +for _lib in _libs.values(): + try: + crc32_gen_buf_tc_results = (struct_crc32_gen_buf_tc_results).in_dll(_lib, 'crc32_gen_buf_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/crc32_gen_buf.h: 37 +for _lib in _libs.values(): + try: + test = (c_uint32).in_dll(_lib, 'test') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/crc32_gen_buf.h: 38 +for _lib in _libs.values(): + try: + uint8t_buffer = (POINTER(c_uint8)).in_dll(_lib, 'uint8t_buffer') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/analogue_read.h: 18 +for _lib in _libs.values(): + try: + analogue_read_tc_params = (struct_analogue_read_tc_params).in_dll(_lib, 'analogue_read_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/analogue_read.h: 27 +for _lib in _libs.values(): + try: + analogue_read_tc_results = (struct_analogue_read_tc_results).in_dll(_lib, 'analogue_read_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 12 +for _lib in _libs.values(): + try: + buffer = (c_uint8 * 256).in_dll(_lib, 'buffer') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 20 +class struct_read_rocket_tc_params(Structure): + pass + +struct_read_rocket_tc_params.__slots__ = [ + 'index', +] +struct_read_rocket_tc_params._fields_ = [ + ('index', c_uint32), +] + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 20 +for _lib in _libs.values(): + try: + read_rocket_tc_params = (struct_read_rocket_tc_params).in_dll(_lib, 'read_rocket_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 27 +class struct_read_rocket_tc_results(Structure): + pass + +struct_read_rocket_tc_results.__slots__ = [ + 'dp', +] +struct_read_rocket_tc_results._fields_ = [ + ('dp', struct_tracker_datapoint), +] + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 27 +for _lib in _libs.values(): + try: + read_rocket_tc_results = (struct_read_rocket_tc_results).in_dll(_lib, 'read_rocket_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 38 +for _lib in _libs.values(): + try: + index = (c_uint32).in_dll(_lib, 'index') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/adc_battery_solar_read.h: 17 +for _lib in _libs.values(): + try: + adc_battery_solar_read_tc_params = (struct_adc_battery_solar_read_tc_params).in_dll(_lib, 'adc_battery_solar_read_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/adc_battery_solar_read.h: 25 +for _lib in _libs.values(): + try: + adc_battery_solar_read_tc_results = (struct_adc_battery_solar_read_tc_results).in_dll(_lib, 'adc_battery_solar_read_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_aprs.h: 16 +for _lib in _libs.values(): + try: + location_aprs_tc_params = (struct_location_aprs_tc_params).in_dll(_lib, 'location_aprs_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/location_aprs.h: 23 +for _lib in _libs.values(): + try: + location_aprs_tc_results = (struct_location_aprs_tc_results).in_dll(_lib, 'location_aprs_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_read.h: 20 +for _lib in _libs.values(): + try: + backlog_read_tc_params = (struct_backlog_read_tc_params).in_dll(_lib, 'backlog_read_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_read.h: 28 +for _lib in _libs.values(): + try: + backlog_read_tc_results = (struct_backlog_read_tc_results).in_dll(_lib, 'backlog_read_tc_results') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_read.h: 30 +for _lib in _libs.values(): + try: + backlog_index = (c_uint16).in_dll(_lib, 'backlog_index') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/backlog_read.h: 33 +for _lib in _libs.values(): + try: + dp_ptr = (POINTER(struct_tracker_datapoint)).in_dll(_lib, 'dp_ptr') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/thermistor_equation.h: 18 +for _lib in _libs.values(): + try: + thermistor_equation_tc_params = (struct_thermistor_equation_tc_params).in_dll(_lib, 'thermistor_equation_tc_params') + break + except: + pass + +# /richard/_pico-tracker/firmware/test/tc/thermistor_equation.h: 25 +for _lib in _libs.values(): + try: + thermistor_equation_tc_results = (struct_thermistor_equation_tc_results).in_dll(_lib, 'thermistor_equation_tc_results') + break + except: + pass + +# test/tc/crc32_gen_buf.h: 11 +try: + TEST_BUF_LEN = 32 +except: + pass + +# /richard/_pico-tracker/firmware/test/tc/crc32_gen_buf.h: 11 +try: + TEST_BUF_LEN = 32 +except: + pass + +times_two_tc_params = struct_times_two_tc_params # test/tc/times_two.h: 11 + +times_two_tc_results = struct_times_two_tc_results # test/tc/times_two.h: 15 + +osc8m_calib_tc_params = struct_osc8m_calib_tc_params # test/tc/osc8m_calib.h: 13 + +osc8m_calib_tc_results = struct_osc8m_calib_tc_results # test/tc/osc8m_calib.h: 19 + +location_aprs_tc_params = struct_location_aprs_tc_params # test/tc/location_aprs.h: 16 + +location_aprs_tc_results = struct_location_aprs_tc_results # test/tc/location_aprs.h: 23 + +location_telemetry_tc_params = struct_location_telemetry_tc_params # test/tc/location_telemetry.h: 15 + +location_telemetry_tc_results = struct_location_telemetry_tc_results # test/tc/location_telemetry.h: 19 + +mem_write_page_tc_params = struct_mem_write_page_tc_params # test/tc/mem_write_page.h: 18 + +mem_write_page_tc_results = struct_mem_write_page_tc_results # test/tc/mem_write_page.h: 25 + +mem_write_all_tc_params = struct_mem_write_all_tc_params # test/tc/mem_write_all.h: 17 + +mem_write_all_tc_results = struct_mem_write_all_tc_results # test/tc/mem_write_all.h: 26 + +location_aprs_file_tc_params = struct_location_aprs_file_tc_params # test/tc/location_aprs_file.h: 17 + +location_aprs_file_tc_results = struct_location_aprs_file_tc_results # test/tc/location_aprs_file.h: 25 + +backlog_write_read_tc_params = struct_backlog_write_read_tc_params # test/tc/backlog_write_read.h: 19 + +backlog_write_read_tc_results = struct_backlog_write_read_tc_results # test/tc/backlog_write_read.h: 27 + +backlog_read_tc_params = struct_backlog_read_tc_params # test/tc/backlog_read.h: 20 + +backlog_read_tc_results = struct_backlog_read_tc_results # test/tc/backlog_read.h: 28 + +mem_erase_all_tc_params = struct_mem_erase_all_tc_params # test/tc/mem_erase_all.h: 17 + +mem_erase_all_tc_results = struct_mem_erase_all_tc_results # test/tc/mem_erase_all.h: 24 + +analogue_read_tc_params = struct_analogue_read_tc_params # test/tc/analogue_read.h: 18 + +analogue_read_tc_results = struct_analogue_read_tc_results # test/tc/analogue_read.h: 27 + +adc_battery_solar_read_tc_params = struct_adc_battery_solar_read_tc_params # test/tc/adc_battery_solar_read.h: 17 + +adc_battery_solar_read_tc_results = struct_adc_battery_solar_read_tc_results # test/tc/adc_battery_solar_read.h: 25 + +gps_baud_error_tc_params = struct_gps_baud_error_tc_params # test/tc/gps_baud_error.h: 20 + +gps_baud_error_tc_results = struct_gps_baud_error_tc_results # test/tc/gps_baud_error.h: 30 + +crc32_gen_buf_tc_params = struct_crc32_gen_buf_tc_params # test/tc/crc32_gen_buf.h: 19 + +crc32_gen_buf_tc_results = struct_crc32_gen_buf_tc_results # test/tc/crc32_gen_buf.h: 27 + +barometric_altitude_tc_params = struct_barometric_altitude_tc_params # test/tc/barometric_altitude.h: 17 + +barometric_altitude_tc_results = struct_barometric_altitude_tc_results # test/tc/barometric_altitude.h: 24 + +pressure_temperature_tc_params = struct_pressure_temperature_tc_params # test/tc/pressure_temperature.h: 19 + +pressure_temperature_tc_results = struct_pressure_temperature_tc_results # test/tc/pressure_temperature.h: 26 + +thermistor_equation_tc_params = struct_thermistor_equation_tc_params # test/tc/thermistor_equation.h: 18 + +thermistor_equation_tc_results = struct_thermistor_equation_tc_results # test/tc/thermistor_equation.h: 25 + +gps_poll_tc_params = struct_gps_poll_tc_params # test/tc/gps_poll.h: 17 + +gps_poll_tc_results = struct_gps_poll_tc_results # test/tc/gps_poll.h: 27 + +epoch_from_time_tc_params = struct_epoch_from_time_tc_params # test/tc/epoch_from_time.h: 17 + +epoch_from_time_tc_results = struct_epoch_from_time_tc_results # test/tc/epoch_from_time.h: 24 + +read_rocket_tc_params = struct_read_rocket_tc_params # /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 20 + +read_rocket_tc_results = struct_read_rocket_tc_results # /richard/_pico-tracker/firmware/test/tc/read_rocket.h: 27 + +# No inserted files + diff --git a/loader/test/tc/times_two.h b/loader/test/tc/times_two.h new file mode 100644 index 0000000..55bc16e --- /dev/null +++ b/loader/test/tc/times_two.h @@ -0,0 +1,20 @@ +#ifndef __verification__ +#define __verification__ +#endif + +/****************************//* times_two_tc *//****************************/ +/* The simplest test case. ever. Used to check for sanity */ + +/* Parameters in */ +struct times_two_tc_params { + int input; +} times_two_tc_params; +/* Results out */ +struct times_two_tc_results { + int result; +} times_two_tc_results; +/* Function */ +__verification__ void times_two_tc(void) { + + times_two_tc_results.result = 2 * times_two_tc_params.input; +} diff --git a/loader/test/tc/times_two.py b/loader/test/tc/times_two.py new file mode 100644 index 0000000..7e090aa --- /dev/null +++ b/loader/test/tc/times_two.py @@ -0,0 +1,38 @@ +#!/usr/bin/env python + +# ------------------------------------------------------------------------------ +# Imports +# ------------------------------------------------------------------------------ + +import sys +sys.path.append("./test") +import main + +from random import randint + +# ------------------------------------------------------------------------------ +# Test Script +# ------------------------------------------------------------------------------ + +class times_two_tc: + def __init__(self): + self.name = self.__class__.__name__ + self.iterations = 20 + + + def get_test(self): + """Returns some suitable test parameters""" + params = main.struct_times_two_tc_params() + params.input = randint(0, 10000) + + return params + + def is_correct(self, params, result, print_info): + """Returns if a result is correct for the given parameters""" + + print_info("%d * 2 = %d"%(params.input, result['result'])) + + if (params.input * 2 == result['result']): + return True + else: + return False diff --git a/loader/test/template/template.h b/loader/test/template/template.h new file mode 100644 index 0000000..bb80c65 --- /dev/null +++ b/loader/test/template/template.h @@ -0,0 +1,33 @@ +#ifndef __verification__ +#define __verification__ +#endif + +/****************************//* [template]_tc *//****************************/ +/** + * Write a description of your test case here + */ + +/* Parameters in */ +struct [template]_tc_params { + + /* Input paramters to your test case go here */ + +} [template]_tc_params; +/* Results out */ +struct [template]_tc_results { + + /* Result values should be populated here */ + +} [template]_tc_results; +/* Function */ +__verification__ void [template]_tc(void) { + + /** + * The main body of the test case goes here. + * + * Use the input parameters to run the test case. Populate the + * results structure at the end + */ + + [template]_tc_results.result = 2 * [template]_tc_params.input; +} diff --git a/loader/test/template/template.py b/loader/test/template/template.py new file mode 100644 index 0000000..8cf14b4 --- /dev/null +++ b/loader/test/template/template.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python + +# ------------------------------------------------------------------------------ +# Imports +# ------------------------------------------------------------------------------ + +import sys +sys.path.append("./test") +import main + +from random import randint + +# ------------------------------------------------------------------------------ +# Test Script +# ------------------------------------------------------------------------------ + +class [template]_tc: + def __init__(self): + self.name = self.__class__.__name__ + self.iterations = 20 + + + def get_test(self): + """Returns some suitable test parameters""" + params = main.struct_[template]_tc_params() + + """ + Assign input parameters here + """ + + return params + + def is_correct(self, params, result, print_info): + """Returns if a result is correct for the given parameters""" + + """ + Compare result and params here, decide sth. + Can use print_info + """ + + return True diff --git a/loader/test/tests.py b/loader/test/tests.py new file mode 100644 index 0000000..9ad06d2 --- /dev/null +++ b/loader/test/tests.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python + +# ------------------------------------------------------------------------------ +# Verification Framework +# ------------------------------------------------------------------------------ + +from __future__ import print_function + +import gdb +import re +import sys +import importlib +from time import * +from colorama import * +import arrow + +sys.path.append("./test") +import tc +from tc import * + +LINE_LENGTH = 80 + +class Tests(): + + def printf(self, string): + """All writes go to stderr""" + print (string, file=sys.stderr) + + def print_info(self, string): + """Prints an info line""" + self.printf(Fore.CYAN + "INFO " + Fore.RESET + string + Fore.RESET) + + def print_good(self, string): + """Prints an good line""" + self.printf(Fore.GREEN + "GOOD " + Fore.RESET + string + Fore.RESET) + + def print_error(self, string): + """Prints an error line""" + self.printf(Fore.RED + "ERROR " + Fore.RESET + string + Fore.RESET) + + def print_centre(self, string): + """Prints something in the centre of the line""" + count = (LINE_LENGTH - len(string)) / 2 + self.printf ((" " * count) + string) + + def print_header_line(self): + """Prints a yellow line. Yo""" + self.printf (Fore.YELLOW + ("*" * LINE_LENGTH) + Fore.RESET) + + def print_header(self, string): + """Prints a pretty header""" + self.printf ("") + self.print_header_line() + self.print_centre(string) + self.print_header_line() + + def print_pass(self, tc_name, time): + """Nice green pass notice""" + offset = (LINE_LENGTH / 2) - len(tc_name) + + self.printf("") + self.printf(Fore.GREEN + " " + tc_name + " - PASS" \ + + (" " * offset) + "CLOCK " + str(time) + Fore.RESET) + + def print_fail(self, tc_name, time): + """Evil red pass notice""" + offset = (LINE_LENGTH / 2) - len(tc_name) + + self.printf("") + self.printf(Fore.RED + " p " + tc_name + "- FAIL" \ + + (" " * offset) + "CLOCK " + str(time) + Fore.RESET) + + def print_summary(self, results): + passes = 0 + for result in results: + (passed) = result + if passed: + passes += 1 + + self.print_header("SUMMARY - %d%% PASS"%(100*passes/len(results))) + + for result in results: + (passed, name, time) = result + if passed: + self.print_pass(name, time) + else: + self.print_fail(name, time) + + self.print_header("") + + #### GDB + + def __init__(self): + self.inferior = gdb.selected_inferior() + + # Pagination is not helpful here + gdb.execute("set pagination off") + # Connect to our target + gdb.execute("att 1") + # Load everything into gdb and run + gdb.execute("load") + gdb.execute("b main") + gdb.execute("run") + # Stopped at the top of main. Go to tc_main via tc_prelude + gdb.execute("del 1") + gdb.execute("b tc_main") + gdb.execute("set $pc=tc_prelude") + gdb.execute("c") + + def __del__(self): + self.print_info("quit") + gdb.execute("quit") + + + def hw_run_tc(self, tc_name, parameters): + """Runs a test case on hardware""" + # If we're stopped where we'd expect + if self.read_variable("($pc == tc_main + 4)"): + # Write the parameters + self.write_varible(tc_name+"_params", parameters) + # Presuming there"s a breakpoint at the top of tc_main + gdb.execute("set tc_ptr="+tc_name+"+1") + gdb.execute("c") + # Test case done. Return results + return self.read_variable(tc_name+"_results") + else: + return None + + #### Read / Write + + def read_variable(self, name): + gdb.execute("p " + name, to_string=True) + return gdb.history(0) + + def write_varible(self, name, value): + pvar = self.read_variable(name) + self.inferior.write_memory(pvar.address, value) + + #### Test Case + def run_test_case(self, test_case): + tc_name = test_case.__class__.__name__ + self.print_header(tc_name) + fail = False + + start = arrow.now() + + if hasattr(test_case, 'iterations'): + """This is for test cases that need to be run multiple time to check + the result is always correct + + """ + for i in range(test_case.iterations): + params = test_case.get_test() + result = self.hw_run_tc(tc_name, params) + + if result: + if not test_case.is_correct(params, result, self.print_info): + fail = True + else: # No result, Failure + fail = True + else: + """This is for test cases that only run once or that use a pre-set + list of cases + + """ + params = test_case.get_test() + while (params): + result = self.hw_run_tc(tc_name, params) + + if result: + if not test_case.is_correct(params, result, self.print_info): + fail = True + else: # No result, Failure + fail = True + + params = test_case.get_test() + + # Teardown testcase if required + if hasattr(test_case, 'teardown'): + test_case.teardown() + + # Calculate time taken + ttime = (arrow.now()-start) + + if not fail: + self.print_pass(tc_name, ttime) + else: + self.print_fail(tc_name, ttime) + + # Return data tuple + return (not fail, tc_name, ttime) + + def get_testcase_from_name(self, name): + tc_module = importlib.import_module('tc.'+name) + return getattr(tc_module, name+'_tc') + + def print_testcases(self): + for tc_name in tc.__all__: + self.print_header(tc_name) + + + +# ------------------------------------------------------------------------------ +# Entry Point +# ------------------------------------------------------------------------------ + +if __name__ == '__main__': + t = Tests() + + # Read in our command file + with open("./test/.testcommand") as f: + tc_name = f.readline().strip('\n') + + if tc_name in tc.__all__: + # If we've been commanded to run a test + t.run_test_case(t.get_testcase_from_name(tc_name)()) + + else: + # Run all testcases + for tc_name in tc.__all__: + t.run_test_case(t.get_testcase_from_name(tc_name)()) + + del t diff --git a/loader/test/tmain.c b/loader/test/tmain.c new file mode 100644 index 0000000..7db9750 --- /dev/null +++ b/loader/test/tmain.c @@ -0,0 +1,78 @@ +/* + * C stubs for verification suite test cases + * Copyright (C) 2014 Richard Meadows + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + + +/* CTypes just gets confused by function attributes... */ +#ifdef CTYPESGEN +#define __verification__ + +#else +#define __verification__ \ + __attribute__ ((section(".text.verif"))) \ + __attribute__ ((optimize("O0"))) \ + +#endif + +/***************************** test cases *******************************/ + +#include "times_two.h" +/* [new_tc] */ + + +/******************************* tc_main ********************************/ + +#include "init.h" + +typedef void (*tc_ptr_type)(void); +volatile tc_ptr_type tc_ptr; + +/** + * Runs a test case + */ +__verification__ void tc_run() { + (*tc_ptr)(); +} + +/** + * Called to trigger the test case run + */ +__verification__ void tc_main(void) { + + /* Wait forever while test cases execute */ + while (1) { + tc_run(); + } +} + +/** + * Prelude to main loop + */ +__verification__ void tc_prelude(void) { + + /* Initialise the board */ + init(INIT_TESTCASE); + + /* Proceed to main loop */ + tc_main(); +}