From 03819b8904609851d87380985de33c341b930cd7 Mon Sep 17 00:00:00 2001 From: Jeremy Sherrill Date: Thu, 30 Apr 2015 11:33:13 -0700 Subject: [PATCH] Build 329 --- CONTRIBUTING.txt | 80 + CREDITS.txt | 18 + LICENSE.txt | 340 + README.md | 114 +- README.txt | 129 + build/reliance.mk | 126 + core/driver/blockio.c | 160 + core/driver/buffer.c | 1061 +++ core/driver/core.c | 1903 +++++ core/driver/dir.c | 876 ++ core/driver/format.c | 248 + core/driver/imap.c | 354 + core/driver/imapextern.c | 332 + core/driver/imapinline.c | 134 + core/driver/inode.c | 1093 +++ core/driver/inodedata.c | 1692 ++++ core/driver/volume.c | 460 ++ core/include/redcore.h | 221 + core/include/redcoremacs.h | 97 + core/include/redcorevol.h | 95 + core/include/redexclude.h | 47 + core/include/rednodes.h | 195 + doc/coding_style.txt | 389 + doc/release_notes.md | 20 + doc/release_notes.txt | 24 + fse/fse.c | 647 ++ include/redapimacs.h | 112 + include/redconfigchk.h | 299 + include/redcoreapi.h | 97 + include/rederrno.h | 114 + include/redfs.h | 44 + include/redfse.h | 102 + include/redmacs.h | 160 + include/redmisc.h | 48 + include/redosserv.h | 86 + include/redposix.h | 196 + include/redstat.h | 94 + include/redtests.h | 80 + include/redtestutils.h | 47 + include/redutils.h | 87 + include/redver.h | 118 + include/redvolume.h | 134 + os/freertos/include/ostypes.h | 39 + os/freertos/services/osassert.c | 59 + os/freertos/services/osbdev.c | 1205 +++ os/freertos/services/osclock.c | 79 + os/freertos/services/osmutex.c | 120 + os/freertos/services/osoutput.c | 63 + os/freertos/services/ostask.c | 66 + os/freertos/services/ostimestamp.c | 178 + os/stub/include/ostypes.h | 41 + os/stub/services/osassert.c | 53 + os/stub/services/osbdev.c | 241 + os/stub/services/osclock.c | 75 + os/stub/services/osmutex.c | 102 + os/stub/services/osoutput.c | 48 + os/stub/services/ostask.c | 46 + os/stub/services/ostimestamp.c | 105 + os/win32/build/host.mk | 66 + os/win32/include/ostypes.h | 39 + os/win32/services/osassert.c | 58 + os/win32/services/osbdev.c | 1172 +++ os/win32/services/osclock.c | 79 + os/win32/services/osmutex.c | 102 + os/win32/services/osoutput.c | 49 + os/win32/services/ostask.c | 47 + os/win32/services/ostimestamp.c | 149 + os/win32/tools/config/allsettings.cpp | 809 ++ os/win32/tools/config/allsettings.h | 244 + os/win32/tools/config/application.cpp | 136 + os/win32/tools/config/application.h | 89 + os/win32/tools/config/boolsetting.cpp | 75 + os/win32/tools/config/boolsetting.h | 73 + os/win32/tools/config/cbsetting.cpp | 69 + os/win32/tools/config/cbsetting.h | 65 + os/win32/tools/config/cmbintsetting.cpp | 56 + os/win32/tools/config/cmbintsetting.h | 65 + os/win32/tools/config/cmbstrsetting.cpp | 54 + os/win32/tools/config/cmbstrsetting.h | 66 + os/win32/tools/config/configwindow.cpp | 370 + os/win32/tools/config/configwindow.h | 109 + os/win32/tools/config/configwindow.ui | 2866 +++++++ os/win32/tools/config/d-ic.ico | Bin 0 -> 82726 bytes os/win32/tools/config/debug.h | 37 + os/win32/tools/config/errordialog.cpp | 121 + os/win32/tools/config/errordialog.h | 121 + os/win32/tools/config/errordialog.ui | 88 + os/win32/tools/config/filedialog.cpp | 103 + os/win32/tools/config/filedialog.h | 81 + os/win32/tools/config/ic.rc | 1 + os/win32/tools/config/icon-error-16.png | Bin 0 -> 448 bytes os/win32/tools/config/icon-warning-16.png | Bin 0 -> 361 bytes os/win32/tools/config/icons.qrc | 6 + os/win32/tools/config/input.cpp | 153 + os/win32/tools/config/input.h | 88 + os/win32/tools/config/intsetting.cpp | 88 + os/win32/tools/config/intsetting.h | 71 + os/win32/tools/config/lesetting.cpp | 54 + os/win32/tools/config/lesetting.h | 66 + os/win32/tools/config/limitreporter.cpp | 92 + os/win32/tools/config/limitreporter.h | 61 + os/win32/tools/config/main.cpp | 35 + os/win32/tools/config/notifiable.h | 47 + os/win32/tools/config/output.cpp | 217 + os/win32/tools/config/output.h | 125 + os/win32/tools/config/pathsepsetting.cpp | 112 + os/win32/tools/config/pathsepsetting.h | 76 + os/win32/tools/config/rbtnsetting.cpp | 55 + os/win32/tools/config/rbtnsetting.h | 64 + os/win32/tools/config/redconfig.pro | 75 + os/win32/tools/config/sbsetting.cpp | 69 + os/win32/tools/config/sbsetting.h | 67 + os/win32/tools/config/setting.h | 214 + os/win32/tools/config/settingbase.h | 58 + os/win32/tools/config/strsetting.cpp | 65 + os/win32/tools/config/strsetting.h | 70 + os/win32/tools/config/validators.cpp | 800 ++ os/win32/tools/config/validators.h | 83 + os/win32/tools/config/validity.h | 44 + os/win32/tools/config/volumesettings.cpp | 834 ++ os/win32/tools/config/volumesettings.h | 258 + os/win32/tools/config/warningbtn.cpp | 115 + os/win32/tools/config/warningbtn.h | 95 + os/win32/tools/config/warningbtn.ui | 49 + os/win32/tools/imgbld/ibcommon.c | 231 + os/win32/tools/imgbld/ibfse.c | 962 +++ os/win32/tools/imgbld/ibheader.h | 100 + os/win32/tools/imgbld/ibposix.c | 479 ++ os/win32/tools/imgbld/imgbld.c | 512 ++ os/win32/tools/winfmt.c | 178 + os/win32/tools/wintlcmn.c | 209 + os/win32/tools/wintlcmn.h | 36 + posix/path.c | 383 + posix/posix.c | 3053 +++++++ posix/redposixutil.h | 37 + projects/freertos/atmel/sam4e-ek/README.txt | 70 + .../atmel/sam4e-ek/RelianceEdge.atsln | 20 + .../atmel/sam4e-ek/RelianceEdge.cproj | 1188 +++ .../freertos/atmel/sam4e-ek/host/Makefile | 10 + .../freertos/atmel/sam4e-ek/host/redconf.c | 7 + .../freertos/atmel/sam4e-ek/host/redconf.h | 95 + .../freertos/atmel/sam4e-ek/host/redtypes.h | 110 + .../sam4e-ek/src/ASF/common/boards/board.h | 392 + .../example1/sam4e16e_sam4e_ek/conf_example.h | 61 + .../common/components/memory/sd_mmc/sd_mmc.c | 2141 +++++ .../common/components/memory/sd_mmc/sd_mmc.h | 313 + .../components/memory/sd_mmc/sd_mmc_mem.c | 379 + .../components/memory/sd_mmc/sd_mmc_mem.h | 248 + .../memory/sd_mmc/sd_mmc_protocol.h | 1007 +++ .../src/ASF/common/services/clock/genclk.h | 191 + .../src/ASF/common/services/clock/osc.h | 177 + .../src/ASF/common/services/clock/pll.h | 333 + .../ASF/common/services/clock/sam4e/genclk.h | 269 + .../src/ASF/common/services/clock/sam4e/osc.h | 247 + .../src/ASF/common/services/clock/sam4e/pll.h | 228 + .../ASF/common/services/clock/sam4e/sysclk.c | 240 + .../ASF/common/services/clock/sam4e/sysclk.h | 459 ++ .../src/ASF/common/services/clock/sysclk.h | 186 + .../src/ASF/common/services/delay/delay.h | 139 + .../common/services/delay/sam/cycle_counter.c | 61 + .../common/services/delay/sam/cycle_counter.h | 114 + .../src/ASF/common/services/ioport/ioport.h | 541 ++ .../common/services/ioport/sam/ioport_pio.h | 380 + .../services/serial/sam_uart/uart_serial.h | 686 ++ .../src/ASF/common/services/serial/serial.h | 269 + .../ASF/common/services/serial/usart_serial.c | 87 + .../storage/ctrl_access/ctrl_access.c | 644 ++ .../storage/ctrl_access/ctrl_access.h | 402 + .../sam4e-ek/src/ASF/common/utils/interrupt.h | 142 + .../utils/interrupt/interrupt_sam_nvic.c | 86 + .../utils/interrupt/interrupt_sam_nvic.h | 189 + .../sam4e-ek/src/ASF/common/utils/parts.h | 1280 +++ .../src/ASF/common/utils/stdio/read.c | 167 + .../utils/stdio/stdio_serial/stdio_serial.h | 129 + .../src/ASF/common/utils/stdio/write.c | 147 + .../src/ASF/sam/boards/sam4e_ek/init.c | 373 + .../src/ASF/sam/boards/sam4e_ek/led.h | 81 + .../src/ASF/sam/boards/sam4e_ek/sam4e_ek.h | 814 ++ .../src/ASF/sam/drivers/hsmci/hsmci.c | 862 ++ .../src/ASF/sam/drivers/hsmci/hsmci.h | 211 + .../sam4e-ek/src/ASF/sam/drivers/pdc/pdc.c | 334 + .../sam4e-ek/src/ASF/sam/drivers/pdc/pdc.h | 305 + .../pdc/pdc_uart_example/pdc_uart_example.h | 89 + .../sam4e-ek/src/ASF/sam/drivers/pmc/pmc.c | 1552 ++++ .../sam4e-ek/src/ASF/sam/drivers/pmc/pmc.h | 540 ++ .../sam4e-ek/src/ASF/sam/drivers/pmc/sleep.c | 389 + .../sam4e-ek/src/ASF/sam/drivers/pmc/sleep.h | 133 + .../sam4e-ek/src/ASF/sam/drivers/uart/uart.c | 558 ++ .../sam4e-ek/src/ASF/sam/drivers/uart/uart.h | 158 + .../src/ASF/sam/drivers/usart/usart.c | 1834 +++++ .../src/ASF/sam/drivers/usart/usart.h | 723 ++ .../utils/cmsis/sam4e/include/component/acc.h | 139 + .../utils/cmsis/sam4e/include/component/aes.h | 148 + .../cmsis/sam4e/include/component/afec.h | 574 ++ .../utils/cmsis/sam4e/include/component/can.h | 307 + .../cmsis/sam4e/include/component/chipid.h | 133 + .../cmsis/sam4e/include/component/cmcc.h | 130 + .../cmsis/sam4e/include/component/dacc.h | 264 + .../cmsis/sam4e/include/component/dmac.h | 308 + .../utils/cmsis/sam4e/include/component/efc.h | 113 + .../cmsis/sam4e/include/component/gmac.h | 628 ++ .../cmsis/sam4e/include/component/gpbr.h | 68 + .../cmsis/sam4e/include/component/hsmci.h | 393 + .../cmsis/sam4e/include/component/matrix.h | 264 + .../utils/cmsis/sam4e/include/component/pdc.h | 113 + .../utils/cmsis/sam4e/include/component/pio.h | 1686 ++++ .../utils/cmsis/sam4e/include/component/pmc.h | 429 + .../utils/cmsis/sam4e/include/component/pwm.h | 621 ++ .../cmsis/sam4e/include/component/rstc.h | 93 + .../cmsis/sam4e/include/component/rswdt.h | 87 + .../utils/cmsis/sam4e/include/component/rtc.h | 234 + .../utils/cmsis/sam4e/include/component/rtt.h | 86 + .../utils/cmsis/sam4e/include/component/smc.h | 154 + .../utils/cmsis/sam4e/include/component/spi.h | 241 + .../cmsis/sam4e/include/component/supc.h | 339 + .../utils/cmsis/sam4e/include/component/tc.h | 386 + .../utils/cmsis/sam4e/include/component/twi.h | 244 + .../cmsis/sam4e/include/component/uart.h | 207 + .../utils/cmsis/sam4e/include/component/udp.h | 200 + .../cmsis/sam4e/include/component/usart.h | 371 + .../utils/cmsis/sam4e/include/component/wdt.h | 87 + .../utils/cmsis/sam4e/include/instance/acc.h | 71 + .../utils/cmsis/sam4e/include/instance/aes.h | 73 + .../cmsis/sam4e/include/instance/afec0.h | 123 + .../cmsis/sam4e/include/instance/afec1.h | 123 + .../utils/cmsis/sam4e/include/instance/can0.h | 207 + .../utils/cmsis/sam4e/include/instance/can1.h | 207 + .../cmsis/sam4e/include/instance/chipid.h | 57 + .../utils/cmsis/sam4e/include/instance/cmcc.h | 73 + .../utils/cmsis/sam4e/include/instance/dacc.h | 91 + .../utils/cmsis/sam4e/include/instance/dmac.h | 129 + .../utils/cmsis/sam4e/include/instance/efc.h | 61 + .../utils/cmsis/sam4e/include/instance/gmac.h | 235 + .../utils/cmsis/sam4e/include/instance/gpbr.h | 55 + .../cmsis/sam4e/include/instance/hsmci.h | 111 + .../cmsis/sam4e/include/instance/matrix.h | 79 + .../utils/cmsis/sam4e/include/instance/pioa.h | 173 + .../utils/cmsis/sam4e/include/instance/piob.h | 161 + .../utils/cmsis/sam4e/include/instance/pioc.h | 161 + .../utils/cmsis/sam4e/include/instance/piod.h | 161 + .../utils/cmsis/sam4e/include/instance/pioe.h | 161 + .../utils/cmsis/sam4e/include/instance/pmc.h | 105 + .../utils/cmsis/sam4e/include/instance/pwm.h | 263 + .../utils/cmsis/sam4e/include/instance/rstc.h | 59 + .../cmsis/sam4e/include/instance/rswdt.h | 59 + .../utils/cmsis/sam4e/include/instance/rtc.h | 77 + .../utils/cmsis/sam4e/include/instance/rtt.h | 61 + .../utils/cmsis/sam4e/include/instance/smc.h | 95 + .../utils/cmsis/sam4e/include/instance/spi.h | 95 + .../utils/cmsis/sam4e/include/instance/supc.h | 65 + .../utils/cmsis/sam4e/include/instance/tc0.h | 183 + .../utils/cmsis/sam4e/include/instance/tc1.h | 183 + .../utils/cmsis/sam4e/include/instance/tc2.h | 147 + .../utils/cmsis/sam4e/include/instance/twi0.h | 99 + .../utils/cmsis/sam4e/include/instance/twi1.h | 99 + .../cmsis/sam4e/include/instance/uart0.h | 93 + .../cmsis/sam4e/include/instance/uart1.h | 93 + .../utils/cmsis/sam4e/include/instance/udp.h | 77 + .../cmsis/sam4e/include/instance/usart0.h | 107 + .../cmsis/sam4e/include/instance/usart1.h | 107 + .../utils/cmsis/sam4e/include/instance/wdt.h | 59 + .../utils/cmsis/sam4e/include/pio/sam4e16c.h | 395 + .../utils/cmsis/sam4e/include/pio/sam4e16e.h | 540 ++ .../utils/cmsis/sam4e/include/pio/sam4e8c.h | 395 + .../utils/cmsis/sam4e/include/pio/sam4e8e.h | 540 ++ .../ASF/sam/utils/cmsis/sam4e/include/sam4e.h | 59 + .../sam/utils/cmsis/sam4e/include/sam4e16c.h | 563 ++ .../sam/utils/cmsis/sam4e/include/sam4e16e.h | 612 ++ .../sam/utils/cmsis/sam4e/include/sam4e8c.h | 563 ++ .../sam/utils/cmsis/sam4e/include/sam4e8e.h | 612 ++ .../cmsis/sam4e/source/templates/exceptions.c | 218 + .../cmsis/sam4e/source/templates/exceptions.h | 74 + .../source/templates/gcc/startup_sam4e.c | 206 + .../sam4e/source/templates/system_sam4e.c | 234 + .../sam4e/source/templates/system_sam4e.h | 88 + .../sam4e-ek/src/ASF/sam/utils/compiler.h | 1197 +++ .../sam4e-ek/src/ASF/sam/utils/fpu/fpu.h | 94 + .../src/ASF/sam/utils/header_files/io.h | 137 + .../linker_scripts/sam4e/sam4e16/gcc/flash.ld | 156 + .../src/ASF/sam/utils/make/Makefile.sam.in | 496 ++ .../src/ASF/sam/utils/preprocessor/mrepeat.h | 339 + .../ASF/sam/utils/preprocessor/preprocessor.h | 55 + .../src/ASF/sam/utils/preprocessor/stringz.h | 85 + .../src/ASF/sam/utils/preprocessor/tpaste.h | 105 + .../sam4e-ek/src/ASF/sam/utils/status_codes.h | 113 + .../src/ASF/sam/utils/syscalls/gcc/syscalls.c | 145 + .../ASF/thirdparty/CMSIS/ATMEL-disclaimer.txt | 6 + .../CMSIS END USER LICENCE AGREEMENT.pdf | Bin 0 -> 46999 bytes .../ASF/thirdparty/CMSIS/Include/arm_math.h | 7062 +++++++++++++++++ .../ASF/thirdparty/CMSIS/Include/core_cm4.h | 1692 ++++ .../thirdparty/CMSIS/Include/core_cm4_simd.h | 652 ++ .../thirdparty/CMSIS/Include/core_cmFunc.h | 619 ++ .../thirdparty/CMSIS/Include/core_cmInstr.h | 621 ++ .../CMSIS/Lib/GCC/libarm_cortexM4lf_math.a | Bin 0 -> 2270540 bytes .../src/ASF/thirdparty/CMSIS/README.txt | 37 + projects/freertos/atmel/sam4e-ek/src/asf.h | 117 + .../sam4e-ek/src/config/FreeRTOSConfig.h | 251 + .../atmel/sam4e-ek/src/config/conf_access.h | 183 + .../atmel/sam4e-ek/src/config/conf_board.h | 62 + .../atmel/sam4e-ek/src/config/conf_clock.h | 86 + .../atmel/sam4e-ek/src/config/conf_sd_mmc.h | 60 + .../sam4e-ek/src/config/conf_uart_serial.h | 51 + .../atmel/sam4e-ek/src/config/redconf.c | 15 + .../atmel/sam4e-ek/src/config/redconf.h | 102 + .../atmel/sam4e-ek/src/config/redtypes.h | 97 + projects/freertos/atmel/sam4e-ek/src/hooks.c | 111 + projects/freertos/atmel/sam4e-ek/src/main.c | 176 + .../freertos/atmel/sam4e-ek/src/memtest.c | 521 ++ .../freertos/atmel/sam4e-ek/src/memtest.h | 33 + projects/newproj/host/Makefile | 9 + projects/newproj/host/redconf.c | 7 + projects/newproj/host/redconf.h | 94 + projects/newproj/host/redtypes.h | 110 + projects/newproj/redtypes.h | 97 + projects/win32/Makefile | 47 + projects/win32/fsstress_main.c | 183 + projects/win32/host/Makefile | 10 + projects/win32/host/redconf.c | 7 + projects/win32/host/redconf.h | 94 + projects/win32/host/redtypes.h | 110 + projects/win32/redconf.c | 15 + projects/win32/redconf.h | 102 + projects/win32/redtypes.h | 110 + tests/posix/fsstress.c | 2029 +++++ tests/posix/redposixcompat.h | 150 + tests/util/printf.c | 1398 ++++ tests/util/rand.c | 159 + util/bitmap.c | 101 + util/crc.c | 672 ++ util/endian.c | 82 + util/memory.c | 249 + util/namelen.c | 54 + util/sign.c | 59 + util/string.c | 225 + 334 files changed, 96359 insertions(+), 2 deletions(-) create mode 100644 CONTRIBUTING.txt create mode 100644 CREDITS.txt create mode 100644 LICENSE.txt create mode 100644 README.txt create mode 100644 build/reliance.mk create mode 100644 core/driver/blockio.c create mode 100644 core/driver/buffer.c create mode 100644 core/driver/core.c create mode 100644 core/driver/dir.c create mode 100644 core/driver/format.c create mode 100644 core/driver/imap.c create mode 100644 core/driver/imapextern.c create mode 100644 core/driver/imapinline.c create mode 100644 core/driver/inode.c create mode 100644 core/driver/inodedata.c create mode 100644 core/driver/volume.c create mode 100644 core/include/redcore.h create mode 100644 core/include/redcoremacs.h create mode 100644 core/include/redcorevol.h create mode 100644 core/include/redexclude.h create mode 100644 core/include/rednodes.h create mode 100644 doc/coding_style.txt create mode 100644 doc/release_notes.md create mode 100644 doc/release_notes.txt create mode 100644 fse/fse.c create mode 100644 include/redapimacs.h create mode 100644 include/redconfigchk.h create mode 100644 include/redcoreapi.h create mode 100644 include/rederrno.h create mode 100644 include/redfs.h create mode 100644 include/redfse.h create mode 100644 include/redmacs.h create mode 100644 include/redmisc.h create mode 100644 include/redosserv.h create mode 100644 include/redposix.h create mode 100644 include/redstat.h create mode 100644 include/redtests.h create mode 100644 include/redtestutils.h create mode 100644 include/redutils.h create mode 100644 include/redver.h create mode 100644 include/redvolume.h create mode 100644 os/freertos/include/ostypes.h create mode 100644 os/freertos/services/osassert.c create mode 100644 os/freertos/services/osbdev.c create mode 100644 os/freertos/services/osclock.c create mode 100644 os/freertos/services/osmutex.c create mode 100644 os/freertos/services/osoutput.c create mode 100644 os/freertos/services/ostask.c create mode 100644 os/freertos/services/ostimestamp.c create mode 100644 os/stub/include/ostypes.h create mode 100644 os/stub/services/osassert.c create mode 100644 os/stub/services/osbdev.c create mode 100644 os/stub/services/osclock.c create mode 100644 os/stub/services/osmutex.c create mode 100644 os/stub/services/osoutput.c create mode 100644 os/stub/services/ostask.c create mode 100644 os/stub/services/ostimestamp.c create mode 100644 os/win32/build/host.mk create mode 100644 os/win32/include/ostypes.h create mode 100644 os/win32/services/osassert.c create mode 100644 os/win32/services/osbdev.c create mode 100644 os/win32/services/osclock.c create mode 100644 os/win32/services/osmutex.c create mode 100644 os/win32/services/osoutput.c create mode 100644 os/win32/services/ostask.c create mode 100644 os/win32/services/ostimestamp.c create mode 100644 os/win32/tools/config/allsettings.cpp create mode 100644 os/win32/tools/config/allsettings.h create mode 100644 os/win32/tools/config/application.cpp create mode 100644 os/win32/tools/config/application.h create mode 100644 os/win32/tools/config/boolsetting.cpp create mode 100644 os/win32/tools/config/boolsetting.h create mode 100644 os/win32/tools/config/cbsetting.cpp create mode 100644 os/win32/tools/config/cbsetting.h create mode 100644 os/win32/tools/config/cmbintsetting.cpp create mode 100644 os/win32/tools/config/cmbintsetting.h create mode 100644 os/win32/tools/config/cmbstrsetting.cpp create mode 100644 os/win32/tools/config/cmbstrsetting.h create mode 100644 os/win32/tools/config/configwindow.cpp create mode 100644 os/win32/tools/config/configwindow.h create mode 100644 os/win32/tools/config/configwindow.ui create mode 100644 os/win32/tools/config/d-ic.ico create mode 100644 os/win32/tools/config/debug.h create mode 100644 os/win32/tools/config/errordialog.cpp create mode 100644 os/win32/tools/config/errordialog.h create mode 100644 os/win32/tools/config/errordialog.ui create mode 100644 os/win32/tools/config/filedialog.cpp create mode 100644 os/win32/tools/config/filedialog.h create mode 100644 os/win32/tools/config/ic.rc create mode 100644 os/win32/tools/config/icon-error-16.png create mode 100644 os/win32/tools/config/icon-warning-16.png create mode 100644 os/win32/tools/config/icons.qrc create mode 100644 os/win32/tools/config/input.cpp create mode 100644 os/win32/tools/config/input.h create mode 100644 os/win32/tools/config/intsetting.cpp create mode 100644 os/win32/tools/config/intsetting.h create mode 100644 os/win32/tools/config/lesetting.cpp create mode 100644 os/win32/tools/config/lesetting.h create mode 100644 os/win32/tools/config/limitreporter.cpp create mode 100644 os/win32/tools/config/limitreporter.h create mode 100644 os/win32/tools/config/main.cpp create mode 100644 os/win32/tools/config/notifiable.h create mode 100644 os/win32/tools/config/output.cpp create mode 100644 os/win32/tools/config/output.h create mode 100644 os/win32/tools/config/pathsepsetting.cpp create mode 100644 os/win32/tools/config/pathsepsetting.h create mode 100644 os/win32/tools/config/rbtnsetting.cpp create mode 100644 os/win32/tools/config/rbtnsetting.h create mode 100644 os/win32/tools/config/redconfig.pro create mode 100644 os/win32/tools/config/sbsetting.cpp create mode 100644 os/win32/tools/config/sbsetting.h create mode 100644 os/win32/tools/config/setting.h create mode 100644 os/win32/tools/config/settingbase.h create mode 100644 os/win32/tools/config/strsetting.cpp create mode 100644 os/win32/tools/config/strsetting.h create mode 100644 os/win32/tools/config/validators.cpp create mode 100644 os/win32/tools/config/validators.h create mode 100644 os/win32/tools/config/validity.h create mode 100644 os/win32/tools/config/volumesettings.cpp create mode 100644 os/win32/tools/config/volumesettings.h create mode 100644 os/win32/tools/config/warningbtn.cpp create mode 100644 os/win32/tools/config/warningbtn.h create mode 100644 os/win32/tools/config/warningbtn.ui create mode 100644 os/win32/tools/imgbld/ibcommon.c create mode 100644 os/win32/tools/imgbld/ibfse.c create mode 100644 os/win32/tools/imgbld/ibheader.h create mode 100644 os/win32/tools/imgbld/ibposix.c create mode 100644 os/win32/tools/imgbld/imgbld.c create mode 100644 os/win32/tools/winfmt.c create mode 100644 os/win32/tools/wintlcmn.c create mode 100644 os/win32/tools/wintlcmn.h create mode 100644 posix/path.c create mode 100644 posix/posix.c create mode 100644 posix/redposixutil.h create mode 100644 projects/freertos/atmel/sam4e-ek/README.txt create mode 100644 projects/freertos/atmel/sam4e-ek/RelianceEdge.atsln create mode 100644 projects/freertos/atmel/sam4e-ek/RelianceEdge.cproj create mode 100644 projects/freertos/atmel/sam4e-ek/host/Makefile create mode 100644 projects/freertos/atmel/sam4e-ek/host/redconf.c create mode 100644 projects/freertos/atmel/sam4e-ek/host/redconf.h create mode 100644 projects/freertos/atmel/sam4e-ek/host/redtypes.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/boards/board.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek/conf_example.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_protocol.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/genclk.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/osc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/pll.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/genclk.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/osc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/pll.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sysclk.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/delay.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/ioport.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/sam/ioport_pio.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/sam_uart/uart_serial.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/serial.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/usart_serial.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/parts.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/read.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/stdio_serial/stdio_serial.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/write.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/init.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/led.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/sam4e_ek.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc_uart_example/pdc_uart_example.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/acc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/aes.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/afec.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/can.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/chipid.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/cmcc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dacc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dmac.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/efc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gmac.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gpbr.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/hsmci.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/matrix.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pdc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pio.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pmc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pwm.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rstc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rswdt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/smc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/spi.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/supc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/tc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/twi.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/uart.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/udp.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/usart.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/wdt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/acc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/aes.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/chipid.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/cmcc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dacc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dmac.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/efc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gmac.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gpbr.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/hsmci.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/matrix.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioa.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piob.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piod.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioe.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pmc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pwm.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rstc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rswdt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/smc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/spi.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/supc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc2.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/udp.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart0.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart1.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/wdt.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16c.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8c.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16c.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8c.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/gcc/startup_sam4e.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/compiler.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/fpu/fpu.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/header_files/io.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/make/Makefile.sam.in create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/mrepeat.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/preprocessor.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/stringz.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/tpaste.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/status_codes.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/syscalls/gcc/syscalls.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/ATMEL-disclaimer.txt create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/CMSIS END USER LICENCE AGREEMENT.pdf create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/arm_math.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4_simd.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmFunc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmInstr.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a create mode 100644 projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/README.txt create mode 100644 projects/freertos/atmel/sam4e-ek/src/asf.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/FreeRTOSConfig.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/conf_access.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/conf_board.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/conf_clock.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/conf_sd_mmc.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/conf_uart_serial.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/redconf.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/redconf.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/config/redtypes.h create mode 100644 projects/freertos/atmel/sam4e-ek/src/hooks.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/main.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/memtest.c create mode 100644 projects/freertos/atmel/sam4e-ek/src/memtest.h create mode 100644 projects/newproj/host/Makefile create mode 100644 projects/newproj/host/redconf.c create mode 100644 projects/newproj/host/redconf.h create mode 100644 projects/newproj/host/redtypes.h create mode 100644 projects/newproj/redtypes.h create mode 100644 projects/win32/Makefile create mode 100644 projects/win32/fsstress_main.c create mode 100644 projects/win32/host/Makefile create mode 100644 projects/win32/host/redconf.c create mode 100644 projects/win32/host/redconf.h create mode 100644 projects/win32/host/redtypes.h create mode 100644 projects/win32/redconf.c create mode 100644 projects/win32/redconf.h create mode 100644 projects/win32/redtypes.h create mode 100644 tests/posix/fsstress.c create mode 100644 tests/posix/redposixcompat.h create mode 100644 tests/util/printf.c create mode 100644 tests/util/rand.c create mode 100644 util/bitmap.c create mode 100644 util/crc.c create mode 100644 util/endian.c create mode 100644 util/memory.c create mode 100644 util/namelen.c create mode 100644 util/sign.c create mode 100644 util/string.c diff --git a/CONTRIBUTING.txt b/CONTRIBUTING.txt new file mode 100644 index 0000000..212f720 --- /dev/null +++ b/CONTRIBUTING.txt @@ -0,0 +1,80 @@ +Reliance Edge Contribution Guidelines +===================================== + +This document describes how to go about contributing to Reliance Edge. + +How Can I Contribute? +--------------------- + +A few examples of how you can contribute: + +- Fixing bugs, including: compiler warnings, portability issues, or erroneous + driver logic. +- Porting Reliance Edge to a new RTOS. +- Improving the documentation, including: fixing typos, dead links, or poor + wording; or pointing out unclear or incomplete instructions. +- Creating new tools or tests. +- Adding new features or APIs (though for major new features, it might be good + to discuss your idea with Datalight). + +Suggestions and feedback of any kind are welcome at +. If there is something about Reliance Edge +which you like or do not like, let us know. + +Reporting Bugs +-------------- + +To report bugs, please create a GitHub issue or contact +. Search the existing GitHub issues to make +sure that your issue is not a known issue. + +Submitting Changes +------------------ + +To submit code changes, fork the Reliance Edge repository, commit your changes, +and use GitHub to submit a pull request. See details here: + + + +After submitting a pull request, it will be reviewed by Datalight engineers. +You may be asked to make changes via the comments on the pull request. If the +pull request contributes a substantial amount of code, you will need to assign +copyright to Datalight before it will be accepted (see the next section). + +Pull requests will never be directly merged into the Reliance Edge GitHub repo. +Due to quality assurance and packaging requirements, pull requests which are +accepted will be incorporated indirectly and pushed into the GitHub repository +as part of a build. As such, all pull requests will be closed, but a comment +will indicate whether the changes were incorporated or not. + +For the portions of the _Developer's Guide_ that are included in the GitHub +repository (like the API documentation, which is derived from Doxygen comments +in the code), changes should be submitted as pull requests just like code. For +the prose chapters which are excluded from the repository, send an email to + to request changes. + +Copyright +--------- + +Datalight policy is that Datalight must own the copyright of all code +incorporated into Reliance Edge; if contributing a substantial amount of code, +you must file a copyright assignment agreement. After submitting your pull +request, contact if you believe you will +need to assign the copyright. If Datalight determines that a copyright +assignment agreement is required, and you have not made contact, you will be +notified via a comment left on the pull request. + +CREDITS.TXT +----------- + +CREDITS.TXT is a list of people who have made non-trivial contributions to +Reliance Edge. If you contribute to Reliance Edge, it is understood that +Datalight may, at our discretion, add your name and GitHub account name to +CREDITS.TXT, unless you explicitly request to be excluded. + +Datalight Coding Style +---------------------- + +Code contributed to Reliance Edge should make an attempt to follow Datalight +coding style. See the doc/coding_style.txt document. + diff --git a/CREDITS.txt b/CREDITS.txt new file mode 100644 index 0000000..e5031b3 --- /dev/null +++ b/CREDITS.txt @@ -0,0 +1,18 @@ +Reliance Edge Credits +===================== + +This is a list (or partial list) of people who have made non-trivial or +noteworthy contributions to the Reliance Edge project. It is sorted by name. +Entries are formatted as below: + +Real Name (githubaccount) +Short description of how Real Name contributed to Reliance Edge. + +The real name may be withheld by request and the GitHub account name might be +missing if the contributor does not use GitHub. + +Credits +------- + +None yet! ;) + diff --git a/LICENSE.txt b/LICENSE.txt new file mode 100644 index 0000000..1f963da --- /dev/null +++ b/LICENSE.txt @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Lesser General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. + diff --git a/README.md b/README.md index d23e584..20f5d42 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,112 @@ -# reliance-edge -File System for Decision-Quality Data at the Edge of the IoT +# Reliance Edge + +Reliance Edge is a small, portable, highly reliable power-fail safe file system +for resource-constrained embedded systems like microcontrollers. It is written +in C and provides a familiar POSIX-like file system API, making it easy to use +in your application; or an alternate minimalist API if your application has +simple storage needs. Reliance Edge is highly configurable and can be tuned to +the precise needs of your application. + +## Documentation + +The complete documentation for Reliance Edge is distributed separately. It +includes an API reference and detailed discussions of various aspects of using +Reliance Edge, including porting, building, configuring, and testing. This +complete documentation, called the _Developer's Guide_, can be obtained for free +from here: + + + +In addition this README, see [doc/release_notes.md](doc/release_notes.md) for a +list of updates to Reliance Edge and a list of known issues. + +## Why Use Reliance Edge? + +Reliance Edge is ideal for small embedded systems with data storage +requirements, especially if there is a chance of sudden power loss or other +system failures. Compared to "raw" disk access, using a file system like +Reliance Edge removes the burden of tracking which sectors belong to which +objects, and allows data to be updated more reliably. Compared to the FAT file +system, using Reliance Edge eliminates the possibility that file system data +will be left in an inconsistent state, corrupting the disk; Reliance Edge does +not need a fsck/CHKDSK utility. Compared to journaling file systems, Reliance +Edge has less overhead and results in less storage media wear for longer device +lifetimes. + +Reliance Edge uses a unique transactional model that not only prevents file +system corruption but also allows a set of changes to be made in an atomic "all +or nothing" fashion. This is very useful for applications that make sets of +interrelated changes. By using the features of Reliance Edge, a set of changes +can be incorporated into a single atomic transaction, which is committed in its +entirety or not at all even if interrupted by power loss; this means the +application does not need code to recover from partially-finished updates. + +## Hardware + +The typical hardware for Reliance Edge is a 32-bit microcontroller, but other +targets are possible. In its typical configurations, Reliance Edge needs at +least 4 KB to 5 KB of RAM, 10 to 18 KB of code space (on the ROM or NOR flash), +and 600 to 750 bytes of stack. + +Reliance Edge is not designed for high-end embedded systems that run complicated +operating systems like Linux or Windows Embedded Compact. Embedded systems of +that variety are better served by other file systems, like Datalight's +[Reliance Nitro](http://www.datalight.com/products/embedded-file-systems/reliance-nitro). + +## Getting Reliance Edge Working + +Before you can use Reliance Edge, it must be ported and configured. At a +minimum, porting includes filling-in functions so that Reliance Edge can issue +commands to your storage medium; depending on your needs, other functions may +need to be filled in as well. These functions reside in a subdirectory in the +os/ directory; see os/stub/ for a blank set of functions. Configuring includes +creating a project directory (start by copying projects/newproj) and creating +the two configuration files (redconf.h/redconf.c) using the Reliance Edge +Configuration Utility (included with the _Developer's Guide_ download). + +These topics are covered in much greater detail in the _Developer's Guide_, +linked above. + +## Using Reliance Edge + +Using Reliance Edge is a simple matter of including the primary Reliance Edge +application header in your application (either include/redposix.h or +include/redfse.h) and compiling and linking against Reliance Edge binaries. +The Reliance Edge driver must be initialized before it is used (via the +red\_init() or RedFseInit() functions) and then volumes can be mounted and file +and directory functions invoked. The Reliance Edge API is documented in the +_Developer's Guide_ (linked above) and also via comments in the source code. + +## Licensing + +Reliance Edge is an open-source project licensed under the GNU General Public +License v2 (GPLv2). Businesses and individuals that for commercial or other +reasons cannot comply with the terms of the GPLv2 license may obtain a +commercial license before incorporating Reliance Edge into proprietary software +for distribution in any form. Visit +for more information. The commercial distribution also includes extra tests and +tools not distributed with the GPLv2 version. + +See LICENSE.txt for the full license terms of this distribution of the product. + +## Getting Help + +If you need assistance using Reliance Edge, and you have already consulted the +_Developer's Guide_, contact . + +In the near future, a community forum or message board will be set up to +facilitate discussion of Reliance Edge and allow users to get help from +Datalight and from each other. In the meantime, please use the email address +given above. + +## Contributing + +Contributions to Reliance Edge are welcome. Our policy is that Datalight must +own the copyright of all code incorporated into Reliance Edge; if contributing a +significant amount of code, you will be asked to file a copyright assignment +agreement. See CONTRIBUTING.txt for further details and contribution +guidelines. + +To report bugs, please create a GitHub issue or contact +. + diff --git a/README.txt b/README.txt new file mode 100644 index 0000000..91d6d6f --- /dev/null +++ b/README.txt @@ -0,0 +1,129 @@ + + +RELIANCE EDGE + + +Reliance Edge is a small, portable, highly reliable power-fail safe file +system for resource-constrained embedded systems like microcontrollers. +It is written in C and provides a familiar POSIX-like file system API, +making it easy to use in your application; or an alternate minimalist +API if your application has simple storage needs. Reliance Edge is +highly configurable and can be tuned to the precise needs of your +application. + + +Documentation + +The complete documentation for Reliance Edge is distributed separately. +It includes an API reference and detailed discussions of various aspects +of using Reliance Edge, including porting, building, configuring, and +testing. This complete documentation, called the _Developer's Guide_, +can be obtained for free from here: + +http://www.datalight.com/reliance-edge + +In addition this README, see doc/release_notes.md for a list of updates +to Reliance Edge and a list of known issues. + + +Why Use Reliance Edge? + +Reliance Edge is ideal for small embedded systems with data storage +requirements, especially if there is a chance of sudden power loss or +other system failures. Compared to "raw" disk access, using a file +system like Reliance Edge removes the burden of tracking which sectors +belong to which objects, and allows data to be updated more reliably. +Compared to the FAT file system, using Reliance Edge eliminates the +possibility that file system data will be left in an inconsistent state, +corrupting the disk; Reliance Edge does not need a fsck/CHKDSK utility. +Compared to journaling file systems, Reliance Edge has less overhead and +results in less storage media wear for longer device lifetimes. + +Reliance Edge uses a unique transactional model that not only prevents +file system corruption but also allows a set of changes to be made in an +atomic "all or nothing" fashion. This is very useful for applications +that make sets of interrelated changes. By using the features of +Reliance Edge, a set of changes can be incorporated into a single atomic +transaction, which is committed in its entirety or not at all even if +interrupted by power loss; this means the application does not need code +to recover from partially-finished updates. + + +Hardware + +The typical hardware for Reliance Edge is a 32-bit microcontroller, but +other targets are possible. In its typical configurations, Reliance Edge +needs at least 4 KB to 5 KB of RAM, 10 to 18 KB of code space (on the +ROM or NOR flash), and 600 to 750 bytes of stack. + +Reliance Edge is not designed for high-end embedded systems that run +complicated operating systems like Linux or Windows Embedded Compact. +Embedded systems of that variety are better served by other file +systems, like Datalight's Reliance Nitro. + + +Getting Reliance Edge Working + +Before you can use Reliance Edge, it must be ported and configured. At a +minimum, porting includes filling-in functions so that Reliance Edge can +issue commands to your storage medium; depending on your needs, other +functions may need to be filled in as well. These functions reside in a +subdirectory in the os/ directory; see os/stub/ for a blank set of +functions. Configuring includes creating a project directory (start by +copying projects/newproj) and creating the two configuration files +(redconf.h/redconf.c) using the Reliance Edge Configuration Utility +(included with the _Developer's Guide_ download). + +These topics are covered in much greater detail in the _Developer's +Guide_, linked above. + + +Using Reliance Edge + +Using Reliance Edge is a simple matter of including the primary Reliance +Edge application header in your application (either include/redposix.h +or include/redfse.h) and compiling and linking against Reliance Edge +binaries. The Reliance Edge driver must be initialized before it is used +(via the red_init() or RedFseInit() functions) and then volumes can be +mounted and file and directory functions invoked. The Reliance Edge API +is documented in the _Developer's Guide_ (linked above) and also via +comments in the source code. + + +Licensing + +Reliance Edge is an open-source project licensed under the GNU General +Public License v2 (GPLv2). Businesses and individuals that for +commercial or other reasons cannot comply with the terms of the GPLv2 +license may obtain a commercial license before incorporating Reliance +Edge into proprietary software for distribution in any form. Visit +http://www.datalight.com/reliance-edge for more information. The +commercial distribution also includes extra tests and tools not +distributed with the GPLv2 version. + +See LICENSE.txt for the full license terms of this distribution of the +product. + + +Getting Help + +If you need assistance using Reliance Edge, and you have already +consulted the _Developer's Guide_, contact +RelianceEdgeSupport@datalight.com. + +In the near future, a community forum or message board will be set up to +facilitate discussion of Reliance Edge and allow users to get help from +Datalight and from each other. In the meantime, please use the email +address given above. + + +Contributing + +Contributions to Reliance Edge are welcome. Our policy is that Datalight +must own the copyright of all code incorporated into Reliance Edge; if +contributing a significant amount of code, you will be asked to file a +copyright assignment agreement. See CONTRIBUTING.txt for further details +and contribution guidelines. + +To report bugs, please create a GitHub issue or contact +RelianceEdgeSupport@datalight.com. diff --git a/build/reliance.mk b/build/reliance.mk new file mode 100644 index 0000000..03e0dab --- /dev/null +++ b/build/reliance.mk @@ -0,0 +1,126 @@ +## +# Objects and rules for building Reliance Edge. +## + +## +# Part 1 - the object files. +## + +# Objects necessary (in some configuration) to build the file system driver. +REDDRIVOBJ= \ + $(P_BASEDIR)/core/driver/blockio.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/buffer.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/core.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/dir.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/format.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/imap.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/imapextern.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/imapinline.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/inode.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/inodedata.$(B_OBJEXT) \ + $(P_BASEDIR)/core/driver/volume.$(B_OBJEXT) \ + $(P_BASEDIR)/fse/fse.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/osassert.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/osbdev.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/osclock.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/osmutex.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/osoutput.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/ostask.$(B_OBJEXT) \ + $(P_BASEDIR)/os/$(P_OS)/services/ostimestamp.$(B_OBJEXT) \ + $(P_BASEDIR)/posix/path.$(B_OBJEXT) \ + $(P_BASEDIR)/posix/posix.$(B_OBJEXT) \ + $(P_BASEDIR)/util/bitmap.$(B_OBJEXT) \ + $(P_BASEDIR)/util/crc.$(B_OBJEXT) \ + $(P_BASEDIR)/util/memory.$(B_OBJEXT) \ + $(P_BASEDIR)/util/namelen.$(B_OBJEXT) \ + $(P_BASEDIR)/util/sign.$(B_OBJEXT) \ + $(P_BASEDIR)/util/string.$(B_OBJEXT) \ + $(P_PROJDIR)/redconf.$(B_OBJEXT) + +# Additional objects necessary to build the host tools. +REDTOOLOBJ= \ + $(P_BASEDIR)/util/endian.$(B_OBJEXT) + +# Additional objects necessary to build the tests. +REDTESTOBJ= \ + $(P_BASEDIR)/tests/util/printf.$(B_OBJEXT) \ + $(P_BASEDIR)/tests/util/rand.$(B_OBJEXT) +REDTESTOBJ += \ + $(P_BASEDIR)/tests/posix/fsstress.$(B_OBJEXT) + +REDALLOBJ=$(REDDRIVOBJ) $(REDTESTOBJ) $(REDTOOLOBJ) + +## +# Part 2 - the compilation rules. +## + +ifndef REDPROJHDR +REDPROJHDR= +endif + +REDHDR= \ + $(P_BASEDIR)/include/redfs.h \ + $(P_BASEDIR)/include/redapimacs.h \ + $(P_BASEDIR)/include/redcoreapi.h \ + $(P_BASEDIR)/include/rederrno.h \ + $(P_BASEDIR)/include/redfse.h \ + $(P_BASEDIR)/include/redmacs.h \ + $(P_BASEDIR)/include/redmisc.h \ + $(P_BASEDIR)/include/redosserv.h \ + $(P_BASEDIR)/include/redposix.h \ + $(P_BASEDIR)/include/redstat.h \ + $(P_BASEDIR)/include/redtests.h \ + $(P_BASEDIR)/include/redtestutils.h \ + $(P_BASEDIR)/include/redutils.h \ + $(P_BASEDIR)/include/redver.h \ + $(P_BASEDIR)/include/redvolume.h \ + $(P_BASEDIR)/os/$(P_OS)/include/ostypes.h \ + $(P_PROJDIR)/redconf.h \ + $(P_PROJDIR)/redtypes.h \ + $(REDPROJHDR) + +REDCOREHDR= \ + $(REDHDR) \ + $(P_BASEDIR)/core/include/redcore.h \ + $(P_BASEDIR)/core/include/redcoremacs.h \ + $(P_BASEDIR)/core/include/redcorevol.h \ + $(P_BASEDIR)/core/include/redexclude.h \ + $(P_BASEDIR)/core/include/rednodes.h + + +REDPOSIXTESTHDR= \ + $(REDTESTHDR) \ + $(P_BASEDIR)/tests/posix_api/redtposixprotos.h + +$(P_BASEDIR)/core/driver/blockio.$(B_OBJEXT): $(P_BASEDIR)/core/driver/blockio.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/buffer.$(B_OBJEXT): $(P_BASEDIR)/core/driver/buffer.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/core.$(B_OBJEXT): $(P_BASEDIR)/core/driver/core.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/dir.$(B_OBJEXT): $(P_BASEDIR)/core/driver/dir.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/format.$(B_OBJEXT): $(P_BASEDIR)/core/driver/format.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/imap.$(B_OBJEXT): $(P_BASEDIR)/core/driver/imap.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/imapextern.$(B_OBJEXT): $(P_BASEDIR)/core/driver/imapextern.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/imapinline.$(B_OBJEXT): $(P_BASEDIR)/core/driver/imapinline.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/inode.$(B_OBJEXT): $(P_BASEDIR)/core/driver/inode.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/inodedata.$(B_OBJEXT): $(P_BASEDIR)/core/driver/inodedata.c $(REDCOREHDR) +$(P_BASEDIR)/core/driver/volume.$(B_OBJEXT): $(P_BASEDIR)/core/driver/volume.c $(REDCOREHDR) +$(P_BASEDIR)/fse/fse.$(B_OBJEXT): $(P_BASEDIR)/fse/fse.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/osassert.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/osassert.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/osbdev.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/osbdev.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/osclock.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/osclock.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/osmutex.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/osmutex.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/osoutput.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/osoutput.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/ostask.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/ostask.c $(REDHDR) +$(P_BASEDIR)/os/$(P_OS)/services/ostimestamp.$(B_OBJEXT): $(P_BASEDIR)/os/$(P_OS)/services/ostimestamp.c $(REDHDR) +$(P_BASEDIR)/posix/path.$(B_OBJEXT): $(P_BASEDIR)/posix/path.c $(REDHDR) $(P_BASEDIR)/posix/redposixutil.h +$(P_BASEDIR)/posix/posix.$(B_OBJEXT): $(P_BASEDIR)/posix/posix.c $(REDHDR) $(P_BASEDIR)/posix/redposixutil.h +$(P_BASEDIR)/tests/posix/fsstress.$(B_OBJEXT): $(P_BASEDIR)/tests/posix/fsstress.c $(REDHDR) $(P_BASEDIR)/tests/posix/redposixcompat.h +$(P_BASEDIR)/tests/util/printf.$(B_OBJEXT): $(P_BASEDIR)/tests/util/printf.c $(REDHDR) +$(P_BASEDIR)/tests/util/rand.$(B_OBJEXT): $(P_BASEDIR)/tests/util/rand.c $(REDHDR) +$(P_BASEDIR)/util/bitmap.$(B_OBJEXT): $(P_BASEDIR)/util/bitmap.c $(REDHDR) +$(P_BASEDIR)/util/crc.$(B_OBJEXT): $(P_BASEDIR)/util/crc.c $(REDHDR) +$(P_BASEDIR)/util/memory.$(B_OBJEXT): $(P_BASEDIR)/util/memory.c $(REDHDR) +$(P_BASEDIR)/util/namelen.$(B_OBJEXT): $(P_BASEDIR)/util/namelen.c $(REDHDR) +$(P_BASEDIR)/util/sign.$(B_OBJEXT): $(P_BASEDIR)/util/sign.c $(REDHDR) +$(P_BASEDIR)/util/string.$(B_OBJEXT): $(P_BASEDIR)/util/string.c $(REDHDR) +$(P_PROJDIR)/redconf.$(B_OBJEXT): $(P_PROJDIR)/redconf.c $(REDHDR) + diff --git a/core/driver/blockio.c b/core/driver/blockio.c new file mode 100644 index 0000000..055abdf --- /dev/null +++ b/core/driver/blockio.c @@ -0,0 +1,160 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements block device I/O using logical blocks as the units. + + The OS block device implementations operate on sectors. The core does I/O + in terms of logical blocks: this module translates from logical blocks to + sectors. +*/ +#include +#include +#include + + +/** @brief Read a range of logical blocks. + + @param bVolNum The volume whose block device is being read from. + @param ulBlockStart The first block to read. + @param ulBlockCount The number of blocks to read. + @param pBuffer The buffer to populate with the data read. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL Invalid parameters. +*/ +REDSTATUS RedIoRead( + uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + void *pBuffer) +{ + REDSTATUS ret; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) + || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; + uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; + uint32_t ulSectorCount = ulBlockCount << bSectorShift; + + REDASSERT(bSectorShift < 32U); + REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); + + ret = RedOsBDevRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + } + + CRITICAL_ASSERT(ret == 0); + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write a range of logical blocks. + + @param bVolNum The volume whose block device is being written to. + @param ulBlockStart The first block to write. + @param ulBlockCount The number of blocks to write. + @param pBuffer The buffer containing the data to write. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL Invalid parameters. +*/ +REDSTATUS RedIoWrite( + uint8_t bVolNum, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + const void *pBuffer) +{ + REDSTATUS ret; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ulBlockStart >= gaRedVolume[bVolNum].ulBlockCount) + || ((gaRedVolume[bVolNum].ulBlockCount - ulBlockStart) < ulBlockCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint8_t bSectorShift = gaRedVolume[bVolNum].bBlockSectorShift; + uint64_t ullSectorStart = (uint64_t)ulBlockStart << bSectorShift; + uint32_t ulSectorCount = ulBlockCount << bSectorShift; + + REDASSERT(bSectorShift < 32U); + REDASSERT((ulSectorCount >> bSectorShift) == ulBlockCount); + + ret = RedOsBDevWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + } + + CRITICAL_ASSERT(ret == 0); + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedIoFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + ret = RedOsBDevFlush(bVolNum); + } + + CRITICAL_ASSERT(ret == 0); + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + diff --git a/core/driver/buffer.c b/core/driver/buffer.c new file mode 100644 index 0000000..c8560b1 --- /dev/null +++ b/core/driver/buffer.c @@ -0,0 +1,1061 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements the block device buffering system. + + This module implements the block buffer cache. It has a number of block + sized buffers which are used to store data from a given block (identified + by both block number and volume number: this cache is shared among all + volumes). Block buffers may be either dirty or clean. Most I/O passes + through this module. When a buffer is needed for a block which is not in + the cache, a "victim" is selected via a simple LRU scheme. +*/ +#include +#include +#include + + +#if DINDIR_POINTERS > 0U + #define INODE_META_BUFFERS 3U /* Inode, double indirect, indirect */ +#elif REDCONF_INDIRECT_POINTERS > 0U + #define INODE_META_BUFFERS 2U /* Inode, indirect */ +#elif REDCONF_DIRECT_POINTERS == INODE_ENTRIES + #define INODE_META_BUFFERS 1U /* Inode only */ +#endif + +#define INODE_BUFFERS (INODE_META_BUFFERS + 1U) /* Add data buffer */ + +#if REDCONF_IMAP_EXTERNAL == 1 + #define IMAP_BUFFERS 1U +#else + #define IMAP_BUFFERS 0U +#endif + +#if (REDCONF_READ_ONLY == 1) || (REDCONF_API_FSE == 1) + /* Read, write, truncate, lookup: One inode all the way down, plus imap. + */ + #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + IMAP_BUFFERS) +#elif REDCONF_API_POSIX == 1 + #if REDCONF_API_POSIX_RENAME == 1 + #if REDCONF_RENAME_ATOMIC == 1 + /* Two parent directories all the way down. Source and destination inode + buffer. One inode buffer for cyclic rename detection. Imap. The + parent inode buffers are released before deleting the destination + inode, so that does not increase the minimum. + */ + #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 3U + IMAP_BUFFERS) + #else + /* Two parent directories all the way down. Source inode buffer. One + inode buffer for cyclic rename detection. Imap. + */ + #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + INODE_BUFFERS + 2U + IMAP_BUFFERS) + #endif + #else + /* Link/create: Needs a parent inode all the way down, an extra inode + buffer, and an imap buffer. + + Unlink is the same, since the parent inode buffers are released before + the inode is deleted. + */ + #define MINIMUM_BUFFER_COUNT (INODE_BUFFERS + 1U + IMAP_BUFFERS) + #endif +#endif + +#if REDCONF_BUFFER_COUNT < MINIMUM_BUFFER_COUNT +#error "REDCONF_BUFFER_COUNT is too low for the configuration" +#endif + + +/* A note on the typecasts in the below macro: Operands to bitwise operators + are subject to the "usual arithmetic conversions". This means that the + flags, which have uint16_t values, are promoted to int. MISRA-C:2012 R10.1 + forbids using signed integers in bitwise operations, so we cast to uint32_t + to avoid the integer promotion, then back to uint16_t to reflect the actual + type. +*/ +#define BFLAG_META_MASK (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_META_IMAP | BFLAG_META_INODE | BFLAG_META_INDIR | BFLAG_META_DINDIR) + + +/* An invalid block number. Used to indicate buffers which are not currently + in use. +*/ +#define BBLK_INVALID UINT32_MAX + + +/** @brief Metadata stored for each block buffer. + + To make better use of CPU caching when searching the BUFFERHEAD array, this + structure should be kept small. +*/ +typedef struct +{ + uint32_t ulBlock; /**< Block number the buffer is associated with; BBLK_INVALID if unused. */ + uint8_t bVolNum; /**< Volume the block resides on. */ + uint8_t bRefCount; /**< Number of references. */ + uint16_t uFlags; /**< Buffer flags: mask of BFLAG_* values. */ +} BUFFERHEAD; + + +/** @brief State information for the block buffer module. +*/ +typedef struct +{ + /** Number of buffers which are referenced (have a bRefCount > 0). + */ + uint16_t uNumUsed; + + /** MRU array. Each element of the array stores a buffer index; each buffer + index appears in the array once and only once. The first element of the + array is the most-recently-used (MRU) buffer, followed by the next most + recently used, and so on, till the last element, which is the least- + recently-used (LRU) buffer. + */ + uint8_t abMRU[REDCONF_BUFFER_COUNT]; + + /** Buffer heads, storing metadata for each buffer. + */ + BUFFERHEAD aHead[REDCONF_BUFFER_COUNT]; + + /** Array of memory for the block buffers themselves. + + Force 64-bit alignment of the aabBuffer array to ensure that it is safe + to cast buffer pointers to node structure pointers. + */ + ALIGNED_2D_BYTE_ARRAY(b, aabBuffer, REDCONF_BUFFER_COUNT, REDCONF_BLOCK_SIZE); +} BUFFERCTX; + + +static bool BufferIsValid(const uint8_t *pbBuffer, uint16_t uFlags); +static bool BufferToIdx(const void *pBuffer, uint8_t *pbIdx); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS BufferWrite(uint8_t bIdx); +static void BufferFinalize(uint8_t *pbBuffer, uint16_t uFlags); +#endif +static void BufferMakeLRU(uint8_t bIdx); +static void BufferMakeMRU(uint8_t bIdx); +static bool BufferFind(uint32_t ulBlock, uint8_t *pbIdx); + +#ifdef REDCONF_ENDIAN_SWAP +static void BufferEndianSwap(const void *pBuffer, uint16_t uFlags); +static void BufferEndianSwapHeader(NODEHEADER *pHeader); +static void BufferEndianSwapMaster(MASTERBLOCK *pMaster); +static void BufferEndianSwapMetaRoot(METAROOT *pMetaRoot); +static void BufferEndianSwapInode(INODE *pInode); +static void BufferEndianSwapIndir(INDIR *pIndir); +#endif + + +static BUFFERCTX gBufCtx; + + +/** @brief Initialize the buffers. +*/ +void RedBufferInit(void) +{ + uint8_t bIdx; + + RedMemSet(&gBufCtx, 0U, sizeof(gBufCtx)); + + for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + { + /* When the buffers have been freshly initialized, acquire the buffers + in the order in which they appear in the array. + */ + gBufCtx.abMRU[bIdx] = (uint8_t)((REDCONF_BUFFER_COUNT - bIdx) - 1U); + gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID; + } +} + + +/** @brief Acquire a buffer. + + @param ulBlock Block number to acquire. + @param uFlags BFLAG_ values for the operation. + @param ppBuffer On success, populated with the acquired buffer. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL Invalid parameters. + @retval -RED_EBUSY All buffers are referenced. +*/ +REDSTATUS RedBufferGet( + uint32_t ulBlock, + uint16_t uFlags, + void **ppBuffer) +{ + REDSTATUS ret = 0; + uint8_t bIdx; + + if(BufferFind(ulBlock, &bIdx)) + { + if((uFlags & BFLAG_NEW) != 0U) + { + CRITICAL_ERROR(); + ret = -RED_EINVAL; + } + } + else if(gBufCtx.uNumUsed == REDCONF_BUFFER_COUNT) + { + ret = -RED_EBUSY; + } + else + { + BUFFERHEAD *pHead; + + /* Search for the least recently used buffer which is not referenced. + */ + for(bIdx = (uint8_t)(REDCONF_BUFFER_COUNT - 1U); bIdx > 0U; bIdx--) + { + if(gBufCtx.aHead[gBufCtx.abMRU[bIdx]].bRefCount == 0U) + { + break; + } + } + + bIdx = gBufCtx.abMRU[bIdx]; + pHead = &gBufCtx.aHead[bIdx]; + + if(pHead->bRefCount == 0U) + { + /* If the LRU buffer is valid and dirty, write it out before + repurposing it. + */ + if(((pHead->uFlags & BFLAG_DIRTY) != 0U) && (pHead->ulBlock != BBLK_INVALID)) + { + #if REDCONF_READ_ONLY == 1 + ret = -RED_EINVAL; + CRITICAL_ERROR(); + #else + ret = BufferWrite(bIdx); + #endif + } + } + else + { + /* All the buffers are used, which should have been caught by + checking gBufCtx.uNumUsed. + */ + CRITICAL_ERROR(); + ret = -RED_EBUSY; + } + + if(ret == 0) + { + if((uFlags & BFLAG_NEW) == 0U) + { + /* If the read fails, the old contents of the LRU may no + longer be there. + */ + pHead->ulBlock = BBLK_INVALID; + + ret = RedIoRead(gbRedVolNum, ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]); + + if((ret == 0) && ((uFlags & BFLAG_META) != 0U) && !BufferIsValid(gBufCtx.b.aabBuffer[bIdx], uFlags)) + { + ret = -RED_EIO; + } + + #ifdef REDCONF_ENDIAN_SWAP + if(ret == 0) + { + BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], uFlags); + } + #endif + } + else + { + RedMemSet(gBufCtx.b.aabBuffer[bIdx], 0U, REDCONF_BLOCK_SIZE); + } + } + + if(ret == 0) + { + pHead->bVolNum = gbRedVolNum; + pHead->ulBlock = ulBlock; + pHead->uFlags = 0U; + } + } + + if(ret == 0) + { + BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + pHead->bRefCount++; + + if(pHead->bRefCount == 1U) + { + gBufCtx.uNumUsed++; + } + + pHead->uFlags |= (uFlags & (~BFLAG_NEW)); + + BufferMakeMRU(bIdx); + + *ppBuffer = gBufCtx.b.aabBuffer[bIdx]; + } + + return ret; +} + + +/** @brief Release a buffer. + + @param pBuffer The buffer to release. + */ +void RedBufferPut( + const void *pBuffer) +{ + uint8_t bIdx; + + if(!BufferToIdx(pBuffer, &bIdx)) + { + REDERROR(); + } + else + { + REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U); + gBufCtx.aHead[bIdx].bRefCount--; + + if(gBufCtx.aHead[bIdx].bRefCount == 0U) + { + REDASSERT(gBufCtx.uNumUsed > 0U); + gBufCtx.uNumUsed--; + } + } +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Flush all buffers for the active volume in the given range of blocks. + + @param ulBlockStart Starting block number to flush. + @param ulBlockCount Count of blocks, starting at @p ulBlockStart, to flush. + Must not be zero. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL Invalid parameters. +*/ +REDSTATUS RedBufferFlush( + uint32_t ulBlockStart, + uint32_t ulBlockCount) +{ + REDSTATUS ret = 0; + + if( (ulBlockStart >= gpRedVolume->ulBlockCount) + || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount) + || (ulBlockCount == 0U)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint8_t bIdx; + + for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + { + BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + if( (pHead->bVolNum == gbRedVolNum) + && (pHead->ulBlock != BBLK_INVALID) + && ((pHead->uFlags & BFLAG_DIRTY) != 0U) + && (pHead->ulBlock >= ulBlockStart) + && (pHead->ulBlock < (ulBlockStart + ulBlockCount))) + { + ret = BufferWrite(bIdx); + + if(ret == 0) + { + pHead->uFlags &= (~BFLAG_DIRTY); + } + else + { + break; + } + } + } + } + + return ret; +} + + +/** @brief Mark a buffer dirty + + @param pBuffer The buffer to mark dirty. +*/ +void RedBufferDirty( + const void *pBuffer) +{ + uint8_t bIdx; + + if(!BufferToIdx(pBuffer, &bIdx)) + { + REDERROR(); + } + else + { + REDASSERT(gBufCtx.aHead[bIdx].bRefCount > 0U); + + gBufCtx.aHead[bIdx].uFlags |= BFLAG_DIRTY; + } +} + + +/** @brief Branch a buffer, marking it dirty and assigning a new block number. + + @param pBuffer The buffer to branch. + @param ulBlockNew The new block number for the buffer. +*/ +void RedBufferBranch( + const void *pBuffer, + uint32_t ulBlockNew) +{ + uint8_t bIdx; + + if( !BufferToIdx(pBuffer, &bIdx) + || (ulBlockNew >= gpRedVolume->ulBlockCount)) + { + REDERROR(); + } + else + { + BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + REDASSERT(pHead->bRefCount > 0U); + REDASSERT((pHead->uFlags & BFLAG_DIRTY) == 0U); + + pHead->uFlags |= BFLAG_DIRTY; + pHead->ulBlock = ulBlockNew; + } +} + + +#if (REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1) +/** @brief Discard a buffer, releasing it and marking it invalid. + + @param pBuffer The buffer to discard. +*/ +void RedBufferDiscard( + const void *pBuffer) +{ + uint8_t bIdx; + + if(!BufferToIdx(pBuffer, &bIdx)) + { + REDERROR(); + } + else + { + REDASSERT(gBufCtx.aHead[bIdx].bRefCount == 1U); + REDASSERT(gBufCtx.uNumUsed > 0U); + + gBufCtx.aHead[bIdx].bRefCount = 0U; + gBufCtx.aHead[bIdx].ulBlock = BBLK_INVALID; + + gBufCtx.uNumUsed--; + + BufferMakeLRU(bIdx); + } +} +#endif +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Discard a range of buffers, marking them invalid. + + @param ulBlockStart The starting block number to discard + @param ulBlockCount The number of blocks, starting at @p ulBlockStart, to + discard. Must not be zero. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL Invalid parameters. + @retval -RED_EBUSY A block in the desired range is referenced. +*/ +REDSTATUS RedBufferDiscardRange( + uint32_t ulBlockStart, + uint32_t ulBlockCount) +{ + REDSTATUS ret = 0; + + if( (ulBlockStart >= gpRedVolume->ulBlockCount) + || ((gpRedVolume->ulBlockCount - ulBlockStart) < ulBlockCount) + || (ulBlockCount == 0U)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint8_t bIdx; + + for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + { + BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + if( (pHead->bVolNum == gbRedVolNum) + && (pHead->ulBlock != BBLK_INVALID) + && (pHead->ulBlock >= ulBlockStart) + && (pHead->ulBlock < (ulBlockStart + ulBlockCount))) + { + if(pHead->bRefCount == 0U) + { + pHead->ulBlock = BBLK_INVALID; + + BufferMakeLRU(bIdx); + } + else + { + /* This should never happen. + */ + CRITICAL_ERROR(); + ret = -RED_EBUSY; + break; + } + } + } + } + + return ret; +} + + +/** Determine whether a metadata buffer is valid. + + This includes checking its signature, CRC, and sequence number. + + @param pbBuffer Pointer to the metadata buffer to validate. + @param uFlags The buffer flags provided by the caller. Used to determine + the expected signature. + + @return Whether the metadata buffer is valid. + + @retval true The metadata buffer is valid. + @retval false The metadata buffer is invalid. +*/ +static bool BufferIsValid( + const uint8_t *pbBuffer, + uint16_t uFlags) +{ + bool fValid; + + if(pbBuffer == NULL) + { + REDERROR(); + fValid = false; + } + else + { + NODEHEADER buf; + uint16_t uMetaFlags = uFlags & BFLAG_META_MASK; + + /* Casting pbBuffer to (NODEHEADER *) would run afoul MISRA-C:2012 + R11.3, so instead copy the fields out. + */ + RedMemCpy(&buf.ulSignature, &pbBuffer[NODEHEADER_OFFSET_SIG], sizeof(buf.ulSignature)); + RedMemCpy(&buf.ulCRC, &pbBuffer[NODEHEADER_OFFSET_CRC], sizeof(buf.ulCRC)); + RedMemCpy(&buf.ullSequence, &pbBuffer[NODEHEADER_OFFSET_SEQ], sizeof(buf.ullSequence)); + + #ifdef REDCONF_ENDIAN_SWAP + buf.ulCRC = RedRev32(buf.ulCRC); + buf.ulSignature = RedRev32(buf.ulSignature); + buf.ullSequence = RedRev64(buf.ullSequence); + #endif + + /* Make sure the signature is correct for the type of metadata block + requested by the caller. + */ + switch(buf.ulSignature) + { + case META_SIG_MASTER: + fValid = (uMetaFlags == BFLAG_META_MASTER); + break; + case META_SIG_IMAP: + fValid = (uMetaFlags == BFLAG_META_IMAP); + break; + case META_SIG_INODE: + fValid = (uMetaFlags == BFLAG_META_INODE); + break; + #if DINDIR_POINTERS > 0U + case META_SIG_DINDIR: + fValid = (uMetaFlags == BFLAG_META_DINDIR); + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case META_SIG_INDIR: + fValid = (uMetaFlags == BFLAG_META_INDIR); + break; + #endif + default: + fValid = false; + break; + } + + if(fValid) + { + uint32_t ulComputedCrc; + + /* Check for disk corruption by comparing the stored CRC with one + computed from the data. + + Also check the sequence number: if it is greater than the + current sequence number, the block is from a previous format + or the disk is writing blocks out of order. During mount, + before the metaroots have been read, the sequence number will + be unknown, and the check is skipped. + */ + ulComputedCrc = RedCrcNode(pbBuffer); + if(buf.ulCRC != ulComputedCrc) + { + fValid = false; + } + else if(gpRedVolume->fMounted && (buf.ullSequence >= gpRedVolume->ullSequence)) + { + fValid = false; + } + else + { + /* Buffer is valid. No action, fValid is already true. + */ + } + } + } + + return fValid; +} + + +/** @brief Derive the index of the buffer. + + @param pBuffer The buffer to derive the index of. + @param pbIdx On success, populated with the index of the buffer. + + @return Boolean indicating result. + + @retval true Success. + @retval false Failure. @p pBuffer is not a valid buffer pointer. +*/ +static bool BufferToIdx( + const void *pBuffer, + uint8_t *pbIdx) +{ + bool fRet = false; + + if((pBuffer != NULL) && (pbIdx != NULL)) + { + uint8_t bIdx; + + /* pBuffer should be a pointer to one of the handles. + + A good compiler should optimize this loop into a bounds check and an + alignment check, although GCC has been observed to not do so; if the + number of buffers is small, it should not make much difference. The + alternative is to use pointer comparisons, but this both deviates + from MISRA-C:2012 and involves undefined behavior. + */ + for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + { + if(pBuffer == &gBufCtx.b.aabBuffer[bIdx][0U]) + { + break; + } + } + + if((bIdx < REDCONF_BUFFER_COUNT) && (gBufCtx.aHead[bIdx].bVolNum == gbRedVolNum)) + { + *pbIdx = bIdx; + fRet = true; + } + } + + return fRet; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write out a dirty buffer. + + @param bIdx The index of the buffer to write. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL Invalid parameters. +*/ +static REDSTATUS BufferWrite( + uint8_t bIdx) +{ + REDSTATUS ret; + + if(bIdx < REDCONF_BUFFER_COUNT) + { + const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + REDASSERT((pHead->uFlags & BFLAG_DIRTY) != 0U); + + if((pHead->uFlags & BFLAG_META) != 0U) + { + BufferFinalize(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags); + } + + ret = RedIoWrite(pHead->bVolNum, pHead->ulBlock, 1U, gBufCtx.b.aabBuffer[bIdx]); + + #ifdef REDCONF_ENDIAN_SWAP + BufferEndianSwap(gBufCtx.b.aabBuffer[bIdx], pHead->uFlags); + #endif + } + else + { + REDERROR(); + ret = -RED_EINVAL; + } + + return ret; +} + + +/** @brief Finalize a metadata buffer. + + This updates the CRC and the sequence number. It also sets the signature, + though this is only truly needed if the buffer is new. + + @param pbBuffer Pointer to the metadata buffer to finalize. + @param uFlags The associated buffer flags. Used to determine the expected + signature. +*/ +static void BufferFinalize( + uint8_t *pbBuffer, + uint16_t uFlags) +{ + uint32_t ulSignature; + + switch(uFlags & BFLAG_META_MASK) + { + case BFLAG_META_MASTER: + ulSignature = META_SIG_MASTER; + break; + case BFLAG_META_IMAP: + ulSignature = META_SIG_IMAP; + break; + case BFLAG_META_INODE: + ulSignature = META_SIG_INODE; + break; + #if DINDIR_POINTERS > 0U + case BFLAG_META_DINDIR: + ulSignature = META_SIG_DINDIR; + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case BFLAG_META_INDIR: + ulSignature = META_SIG_INDIR; + break; + #endif + default: + ulSignature = 0U; + break; + } + + if((ulSignature == 0U) || (pbBuffer == NULL)) + { + REDERROR(); + } + else + { + uint32_t ulCrc; + + RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SIG], &ulSignature, sizeof(ulSignature)); + RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_SEQ], &gpRedVolume->ullSequence, sizeof(gpRedVolume->ullSequence)); + + gpRedVolume->ullSequence++; + + #ifdef REDCONF_ENDIAN_SWAP + BufferEndianSwap(pbBuffer, uFlags); + #endif + + ulCrc = RedCrcNode(pbBuffer); + #ifdef REDCONF_ENDIAN_SWAP + ulCrc = RedRev32(ulCrc); + #endif + RedMemCpy(&pbBuffer[NODEHEADER_OFFSET_CRC], &ulCrc, sizeof(ulCrc)); + } +} +#endif + + +#ifdef REDCONF_ENDIAN_SWAP +/** @brief Swap the byte order of a metadata buffer + + Does nothing if the buffer is not a metadata node. Also does nothing for + meta roots, which don't go through the buffers anyways. + + @param pBuffer Pointer to the metadata buffer to swap + @param uFlags The associated buffer flags. Used to determin the type of + metadata node. +*/ +static void BufferEndianSwap( + void *pBuffer, + uint16_t uFlags) +{ + if((uFlags & BFLAG_META_MASK) != 0) + { + BufferEndianSwapHeader(pBuffer); + + switch(uFlags & BFLAG_META_MASK) + { + case BFLAG_META_MASTER: + BufferEndianSwapMaster(pBuffer); + break; + case BFLAG_META_INODE: + BufferEndianSwapInode(pBuffer); + break; + #if DINDIR_POINTERS > 0U + case BFLAG_META_DINDIR: + BufferEndianSwapIndir(pBuffer); + break; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + case BFLAG_META_INDIR: + BufferEndianSwapIndir(pBuffer); + break; + #endif + default: + break; + } + } +} + + +/** @brief Swap the byte order of a metadata node header + + @param pHeader Pointer to the metadata node header to swap +*/ +static void BufferEndianSwapHeader( + NODEHEADER *pHeader) +{ + pHeader->ulSignature = RedRev32(pHeader->ulSignature); + pHeader->ulCRC = RedRev32(pHeader->ulCRC); + pHeader->ullSequence = RedRev64(pHeader->ullSequence); +} + + +/** @brief Swap the byte order of a master block + + @param pMaster Pointer to the master block to swap +*/ +static void BufferEndianSwapMaster( + MASTERBLOCK *pMaster) +{ + pMaster->ulVersion = RedRev32(pMaster->ulVersion); + pMaster->ulFormatTime = RedRev32(pMaster->ulFormatTime); + pMaster->ulInodeCount = RedRev32(pMaster->ulInodeCount); + pMaster->ulBlockCount = RedRev32(pMaster->ulBlockCount); + pMaster->uMaxNameLen = RedRev16(pMaster->uMaxNameLen); + pMaster->uDirectPointers = RedRev16(pMaster->uDirectPointers); + pMaster->uIndirectPointers = RedRev16(pMaster->uIndirectPointers); +} + + +/** @brief Swap the byte order of an inode + + @param pInode Pointer to the inode to swap +*/ +static void BufferEndianSwapInode( + INODE *pInode) +{ + uint32_t ulIdx; + + pInode->ullSize = RedRev64(pInode->ullSize); + + #if REDCONF_INODE_BLOCKS == 1 + pInode->ulBlocks = RedRev32(pInode->ulBlocks); + #endif + + #if REDCONF_INODE_TIMESTAMPS == 1 + pInode->ulATime = RedRev32(pInode->ulATime); + pInode->ulMTime = RedRev32(pInode->ulMTime); + pInode->ulCTime = RedRev32(pInode->ulCTime); + #endif + + pInode->uMode = RedRev16(pInode->uMode); + + #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) + pInode->uNLink = RedRev16(pInode->uNLink); + #endif + + #if REDCONF_API_POSIX == 1 + pInode->ulPInode = RedRev32(pInode->ulPInode); + #endif + + for(ulIdx = 0; ulIdx < INODE_ENTRIES; ulIdx++) + { + pInode->aulEntries[ulIdx] = RedRev32(pInode->aulEntries[ulIdx]); + } +} + + +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES +/** @brief Swap the byte order of an indirect or double indirect node + + @param pIndir Pointer to the node to swap +*/ +static void BufferEndianSwapIndir( + INDIR *pIndir) +{ + uint32_t ulIdx; + + pIndir->ulInode = RedRev32(pIndir->ulInode); + + for(ulIdx = 0; ulIdx < INDIR_ENTRIES; ulIdx++) + { + pIndir->aulEntries[ulIdx] = RedRev32(pIndir->aulEntries[ulIdx]); + } +} + +#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ +#endif /* #ifdef REDCONF_ENDIAN_SWAP */ + + +/** @brief Mark a buffer as least recently used. + + @param bIdx The index of the buffer to make LRU. +*/ +static void BufferMakeLRU( + uint8_t bIdx) +{ + uint8_t bMruIdx; + + REDASSERT(bIdx < REDCONF_BUFFER_COUNT); + + if(bIdx != gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U]) + { + /* Find the current position of the buffer in the MRU array. + */ + for(bMruIdx = 0U; bMruIdx < (REDCONF_BUFFER_COUNT - 1U); bMruIdx++) + { + if(bIdx == gBufCtx.abMRU[bMruIdx]) + { + break; + } + } + + if(bMruIdx < (REDCONF_BUFFER_COUNT - 1U)) + { + /* Move the buffer index to the back of the MRU array, making it + the LRU buffer. + */ + RedMemMove(&gBufCtx.abMRU[bMruIdx], &gBufCtx.abMRU[bMruIdx + 1U], REDCONF_BUFFER_COUNT - ((uint32_t)bMruIdx + 1U)); + gBufCtx.abMRU[REDCONF_BUFFER_COUNT - 1U] = bIdx; + } + else + { + REDERROR(); + } + } +} + + +/** @brief Mark a buffer as most recently used. + + @param bIdx The index of the buffer to make MRU. +*/ +static void BufferMakeMRU( + uint8_t bIdx) +{ + uint8_t bMruIdx; + + REDASSERT(bIdx < REDCONF_BUFFER_COUNT); + + if(bIdx != gBufCtx.abMRU[0U]) + { + /* Find the current position of the buffer in the MRU array. + */ + for(bMruIdx = 1U; bMruIdx < REDCONF_BUFFER_COUNT; bMruIdx++) + { + if(bIdx == gBufCtx.abMRU[bMruIdx]) + { + break; + } + } + + if(bMruIdx < REDCONF_BUFFER_COUNT) + { + /* Move the buffer index to the front of the MRU array, making it + the MRU buffer. + */ + RedMemMove(&gBufCtx.abMRU[1U], &gBufCtx.abMRU[0U], bMruIdx); + gBufCtx.abMRU[0U] = bIdx; + } + else + { + REDERROR(); + } + } +} + + +/** @brief Find a block in the buffers. + + @param ulBlock The block number to find. + @param pbIdx If the block is buffered (true is returned), populated with + the index of the buffer. + + @return Boolean indicating whether or not the block is buffered. + + @retval true @p ulBlock is buffered, and its index has been stored in + @p pbIdx. + @retval false @p ulBlock is not buffered. +*/ +static bool BufferFind( + uint32_t ulBlock, + uint8_t *pbIdx) +{ + bool ret = false; + uint8_t bIdx; + + REDASSERT(ulBlock <= gpRedVolume->ulBlockCount); + + for(bIdx = 0U; bIdx < REDCONF_BUFFER_COUNT; bIdx++) + { + const BUFFERHEAD *pHead = &gBufCtx.aHead[bIdx]; + + if((pHead->bVolNum == gbRedVolNum) && (pHead->ulBlock == ulBlock)) + { + *pbIdx = bIdx; + ret = true; + break; + } + } + + return ret; +} + diff --git a/core/driver/core.c b/core/driver/core.c new file mode 100644 index 0000000..ef17b25 --- /dev/null +++ b/core/driver/core.c @@ -0,0 +1,1903 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements the entry-points to the core file system. +*/ +#include +#include +#include +#include + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +static REDSTATUS CoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) +static REDSTATUS CoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) +static REDSTATUS CoreUnlink(uint32_t ulPInode, const char *pszName); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) +static REDSTATUS CoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName); +#endif +#if REDCONF_READ_ONLY == 0 +static REDSTATUS CoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); +#endif +#if TRUNCATE_SUPPORTED +static REDSTATUS CoreFileTruncate(uint32_t ulInode, uint64_t ullSize); +#endif + + +VOLUME gaRedVolume[REDCONF_VOLUME_COUNT]; +static COREVOLUME gaCoreVol[REDCONF_VOLUME_COUNT]; + +const VOLCONF *gpRedVolConf = &gaRedVolConf[0U]; +VOLUME *gpRedVolume = &gaRedVolume[0U]; +COREVOLUME *gpRedCoreVol = &gaCoreVol[0U]; +METAROOT *gpRedMR = &gaCoreVol[0U].aMR[0U]; + +uint8_t gbRedVolNum; + + +/** @brief Initialize the Reliance Edge file system driver. + + Prepares the Reliance Edge file system driver to be used. Must be the first + Reliance Edge function to be invoked: no volumes can be mounted until the + driver has been initialized. + + If this function is called when the Reliance Edge driver is already + initialized, the behavior is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedCoreInit(void) +{ + REDSTATUS ret = 0; + uint8_t bVolNum; + #if REDCONF_OUTPUT == 1 + static uint8_t bSignedOn = 0U; /* Whether the sign on has been printed. */ + + if(bSignedOn == 0U) + { + RedSignOn(); + bSignedOn = 1U; + } + #else + /* Call RedSignOn() even when output is disabled, to force the copyright + text to be referenced and pulled into the program data. + */ + RedSignOn(); + #endif + + RedMemSet(gaRedVolume, 0U, sizeof(gaRedVolume)); + RedMemSet(gaCoreVol, 0U, sizeof(gaCoreVol)); + + RedBufferInit(); + + for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) + { + VOLUME *pVol = &gaRedVolume[bVolNum]; + COREVOLUME *pCoreVol = &gaCoreVol[bVolNum]; + const VOLCONF *pVolConf = &gaRedVolConf[bVolNum]; + + if((pVolConf->ulSectorSize == 0U) || (pVolConf->ulSectorSize > REDCONF_BLOCK_SIZE) || (pVolConf->ulInodeCount == 0U)) + { + ret = -RED_EINVAL; + } + #if REDCONF_API_POSIX == 1 + else if(pVolConf->pszPathPrefix == NULL) + { + ret = -RED_EINVAL; + } + else + { + /* Ensure there are no duplicate path prefixes. + */ + #if REDCONF_VOLUME_COUNT > 1U + uint8_t bCmpVol; + + /* Check against all previous volumes, which are already verified. + */ + for(bCmpVol = 0U; bCmpVol < bVolNum; bCmpVol++) + { + const char *pszCmpPathPrefix = gaRedVolConf[bCmpVol].pszPathPrefix; + + if(RedStrCmp(pVolConf->pszPathPrefix, pszCmpPathPrefix) == 0) + { + ret = -RED_EINVAL; + break; + } + } + #endif + } + #endif + + if(ret == 0) + { + pVol->bBlockSectorShift = 0U; + while((pVolConf->ulSectorSize << pVol->bBlockSectorShift) < REDCONF_BLOCK_SIZE) + { + pVol->bBlockSectorShift++; + } + + pVol->ulBlockCount = (uint32_t)(pVolConf->ullSectorCount >> pVol->bBlockSectorShift); + + if(pVol->ulBlockCount < 5U) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_READ_ONLY == 0 + pVol->ulTransMask = REDCONF_TRANSACT_DEFAULT; + #endif + + pVol->ullMaxInodeSize = INODE_SIZE_MAX; + + /* To understand the following code, note that the fixed- + location metadata is located at the start of the disk, in + the following order: + + - Master block (1 block) + - Metaroots (2 blocks) + - External imap blocks (variable) + - Inode blocks (pVolConf->ulInodeCount * 2 blocks) + */ + + /* The imap needs bits for all inode and allocable blocks. If + that bitmap will fit into the metaroot, the inline imap is + used and there are no imap nodes on disk. + */ + pCoreVol->fImapInline = (pVol->ulBlockCount - 3U) <= METAROOT_ENTRIES; + + if(pCoreVol->fImapInline) + { + #if REDCONF_IMAP_INLINE == 1 + pCoreVol->ulInodeTableStartBN = 3U; + #else + ret = -RED_EINVAL; + #endif + } + else + { + #if REDCONF_IMAP_EXTERNAL == 1 + pCoreVol->ulImapStartBN = 3U; + + /* The imap does not include bits for itself, so the number + of imap nodes required must be computed iteratively. + */ + pCoreVol->ulImapNodeCount = 1U; + while(((pVol->ulBlockCount - 3U) - (pCoreVol->ulImapNodeCount * 2U)) > (IMAPNODE_ENTRIES * pCoreVol->ulImapNodeCount)) + { + pCoreVol->ulImapNodeCount++; + } + + pCoreVol->ulInodeTableStartBN = pCoreVol->ulImapStartBN + (pCoreVol->ulImapNodeCount * 2U); + #else + ret = -RED_EINVAL; + #endif + } + } + + if(ret == 0) + { + pCoreVol->ulFirstAllocableBN = pCoreVol->ulInodeTableStartBN + (pVolConf->ulInodeCount * 2U); + + if(pCoreVol->ulFirstAllocableBN > pVol->ulBlockCount) + { + /* We can get here if there is not enough space for the + number of configured inodes. + */ + ret = -RED_EINVAL; + } + else + { + pVol->ulBlocksAllocable = pVol->ulBlockCount - pCoreVol->ulFirstAllocableBN; + } + } + } + + if(ret != 0) + { + break; + } + } + + /* Make sure the configured endianness is correct. + */ + if(ret == 0) + { + uint16_t uValue = 0xFF00U; + uint8_t abBytes[2U]; + + RedMemCpy(abBytes, &uValue, sizeof(abBytes)); + + #if REDCONF_ENDIAN_BIG == 1 + if(abBytes[0U] != 0xFFU) + #else + if(abBytes[0U] != 0x00U) + #endif + { + ret = -RED_EINVAL; + } + } + + if(ret == 0) + { + ret = RedOsClockInit(); + + #if REDCONF_TASK_COUNT > 1U + if(ret == 0) + { + ret = RedOsMutexInit(); + + if(ret != 0) + { + (void)RedOsClockUninit(); + } + } + #endif + } + + return ret; +} + + +/** @brief Uninitialize the Reliance Edge file system driver. + + Tears down the Reliance Edge file system driver. Cannot be used until all + Reliance Edge volumes are unmounted. A subsequent call to RedCoreInit() + will initialize the driver again. + + If this function is called when the Reliance Edge driver is already + uninitialized, it does nothing and returns success. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBUSY At least one volume is still mounted. +*/ +REDSTATUS RedCoreUninit(void) +{ + REDSTATUS ret; + + #if REDCONF_TASK_COUNT > 1U + ret = RedOsMutexUninit(); + + if(ret == 0) + #endif + { + ret = RedOsClockUninit(); + } + + return ret; +} + + +/** @brief Set the current volume. + + All core APIs operate on the current volume. This call must precede all + core accesses. + + @param bVolNum The volume number to access. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. +*/ +REDSTATUS RedCoreVolSetCurrent( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_VOLUME_COUNT > 1U + gbRedVolNum = bVolNum; + gpRedVolConf = &gaRedVolConf[bVolNum]; + gpRedVolume = &gaRedVolume[bVolNum]; + gpRedCoreVol = &gaCoreVol[bVolNum]; + gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; + #endif + + ret = 0; + } + + return ret; +} + + +#if (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) +/** @brief Format a file system volume. + + Uses the statically defined volume configuration. After calling this + function, the volume needs to be mounted -- see RedCoreVolMount(). + + An error is returned if the volume is mounted. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBUSY Volume is mounted. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedCoreVolFormat(void) +{ + return RedVolFormat(); +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Mount a file system volume. + + Prepares the file system volume to be accessed. Mount will fail if the + volume has never been formatted, or if the on-disk format is inconsistent + with the compile-time configuration. + + If the volume is already mounted, the behavior is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. +*/ +REDSTATUS RedCoreVolMount(void) +{ + return RedVolMount(); +} + + +/** @brief Unmount a file system volume. + + This function discards the in-memory state for the file system and marks it + as unmounted. Subsequent attempts to access the volume will fail until the + volume is mounted again. + + If unmount automatic transaction points are enabled, this function will + commit a transaction point prior to unmounting. If unmount automatic + transaction points are disabled, this function will unmount without + transacting, effectively discarding the working state. + + If the volume is already unmounted, the behavior is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO I/O error during unmount automatic transaction point. +*/ +REDSTATUS RedCoreVolUnmount(void) +{ + REDSTATUS ret = 0; + + #if REDCONF_READ_ONLY == 0 + if(!gpRedVolume->fReadOnly && ((gpRedVolume->ulTransMask & RED_TRANSACT_UMOUNT) != 0U)) + { + ret = RedVolTransact(); + } + #endif + + if(ret == 0) + { + ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); + } + + if(ret == 0) + { + ret = RedOsBDevClose(gbRedVolNum); + } + + if(ret == 0) + { + gpRedVolume->fMounted = false; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Commit a transaction point. + + Reliance Edge is a transactional file system. All modifications, of both + metadata and filedata, are initially working state. A transaction point + is a process whereby the working state atomically becomes the committed + state, replacing the previous committed state. Whenever Reliance Edge is + mounted, including after power loss, the state of the file system after + mount is the most recent committed state. Nothing from the committed + state is ever missing, and nothing from the working state is ever included. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The volume is not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedCoreVolTransact(void) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = RedVolTransact(); + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if REDCONF_API_POSIX == 1 +/** @brief Query file system status information. + + @param pStatFS The buffer to populate with volume information. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval -RED_EINVAL Volume is not mounted; or @p pStatFS is `NULL`. +*/ +REDSTATUS RedCoreVolStat( + REDSTATFS *pStatFS) +{ + REDSTATUS ret; + + if((pStatFS == NULL) || (!gpRedVolume->fMounted)) + { + ret = -RED_EINVAL; + } + else + { + RedMemSet(pStatFS, 0U, sizeof(*pStatFS)); + + pStatFS->f_bsize = REDCONF_BLOCK_SIZE; + pStatFS->f_frsize = REDCONF_BLOCK_SIZE; + pStatFS->f_blocks = gpRedVolume->ulBlockCount; + pStatFS->f_bfree = (gpRedMR->ulFreeBlocks > RESERVED_BLOCKS) ? (gpRedMR->ulFreeBlocks - RESERVED_BLOCKS) : 0U; + pStatFS->f_bavail = pStatFS->f_bfree; + pStatFS->f_files = gpRedVolConf->ulInodeCount; + pStatFS->f_ffree = gpRedMR->ulFreeInodes; + pStatFS->f_favail = gpRedMR->ulFreeInodes; + + pStatFS->f_flag = RED_ST_NOSUID; + #if REDCONF_READ_ONLY == 0 + if(gpRedVolume->fReadOnly) + #endif + { + pStatFS->f_flag |= RED_ST_RDONLY; + } + + pStatFS->f_namemax = REDCONF_NAME_MAX; + pStatFS->f_maxfsize = INODE_SIZE_MAX; + pStatFS->f_dev = gbRedVolNum; + + ret = 0; + } + + return ret; +} +#endif /* REDCONF_API_POSIX == 1 */ + + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_FSE == 0) || (REDCONF_API_FSE_TRANSMASKSET == 1)) +/** @brief Update the transaction mask. + + The following events are available when using the FSE API: + + - #RED_TRANSACT_UMOUNT + - #RED_TRANSACT_WRITE + - #RED_TRANSACT_TRUNCATE + - #RED_TRANSACT_VOLFULL + + The following events are available when using the POSIX-like API: + + - #RED_TRANSACT_UMOUNT + - #RED_TRANSACT_CREAT + - #RED_TRANSACT_UNLINK + - #RED_TRANSACT_MKDIR + - #RED_TRANSACT_RENAME + - #RED_TRANSACT_LINK + - #RED_TRANSACT_CLOSE + - #RED_TRANSACT_WRITE + - #RED_TRANSACT_FSYNC + - #RED_TRANSACT_TRUNCATE + - #RED_TRANSACT_VOLFULL + + The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of + all transaction flags, excluding those representing excluded functionality. + + Attempting to enable events for excluded functionality will result in an + error. + + @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + be set as the current transaction mode. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The volume is not mounted; or @p ulEventMask contains + invalid bits. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedCoreTransMaskSet( + uint32_t ulEventMask) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted || ((ulEventMask & RED_TRANSACT_MASK) != ulEventMask)) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + gpRedVolume->ulTransMask = ulEventMask; + ret = 0; + } + + return ret; +} +#endif + + +#if (REDCONF_API_FSE == 0) || (REDCONF_API_FSE_TRANSMASKGET == 1) +/** @brief Read the transaction mask. + + If the volume is read-only, the returned event mask is always zero. + + @param pulEventMask Populated with a bitwise-OR'd mask of automatic + transaction events which represent the current + transaction mode for the volume. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The volume is not mounted; or @p pulEventMask is `NULL`. +*/ +REDSTATUS RedCoreTransMaskGet( + uint32_t *pulEventMask) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted || (pulEventMask == NULL)) + { + ret = -RED_EINVAL; + } + else + { + #if REDCONF_READ_ONLY == 1 + *pulEventMask = 0U; + #else + *pulEventMask = gpRedVolume->ulTransMask; + #endif + ret = 0; + } + + return ret; +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +/** @brief Create a file or directory. + + @param ulPInode The inode number of the parent directory. + @param pszName A null-terminated name for the new inode. + @param fDir Whether to create a directory (true) or file (false). + @param pulInode On successful return, populated with the inode number of the + new file or directory. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The volume is not mounted; or @p pszName is not + a valid name; or @p pulInode is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The file system volume is read-only. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_EBADF @p ulPInode is not a valid inode. + @retval -RED_ENOSPC There is not enough space on the volume to + createthe new directory entry; or the directory + is full. + @retval -RED_ENFILE No available inode slots. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_EEXIST @p pszName already exists in @p ulPInode. +*/ +REDSTATUS RedCoreCreate( + uint32_t ulPInode, + const char *pszName, + bool fDir, + uint32_t *pulInode) +{ + REDSTATUS ret; + + if((pulInode == NULL) || (pszName == NULL) || (pszName[0U] == '\0') || !gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreCreate(ulPInode, pszName, fDir, pulInode); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreCreate(ulPInode, pszName, fDir, pulInode); + } + } + + if(ret == 0) + { + if(fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_MKDIR) != 0U)) + { + ret = RedVolTransact(); + } + else if(!fDir && ((gpRedVolume->ulTransMask & RED_TRANSACT_CREAT) != 0U)) + { + ret = RedVolTransact(); + } + else + { + /* No automatic transaction for this operation. + */ + } + } + } + + return ret; +} + + +/** @brief Create a file or directory. + + @param ulPInode The inode number of the parent directory. + @param pszName A null-terminated name for the new inode. + @param fDir Whether to create a directory (true) or file (false). + @param pulInode On successful return, populated with the inode number of the + new file or directory. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The file system volume is read-only. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_EBADF @p ulPInode is not a valid inode. + @retval -RED_ENOSPC There is not enough space on the volume to + create the new directory entry; or the directory + is full. + @retval -RED_ENFILE No available inode slots. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_EEXIST @p pszName already exists in @p ulPInode. +*/ +static REDSTATUS CoreCreate( + uint32_t ulPInode, + const char *pszName, + bool fDir, + uint32_t *pulInode) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount(&pino, FTYPE_DIR, false); + + if(ret == 0) + { + CINODE ino; + + ino.ulInode = INODE_INVALID; + ret = RedInodeCreate(&ino, ulPInode, fDir ? RED_S_IFDIR : RED_S_IFREG); + + if(ret == 0) + { + ret = RedInodeBranch(&pino); + + if(ret == 0) + { + ret = RedDirEntryCreate(&pino, pszName, ino.ulInode); + } + + if(ret == 0) + { + *pulInode = ino.ulInode; + } + else + { + REDSTATUS ret2; + + ret2 = RedInodeFree(&ino); + CRITICAL_ASSERT(ret2 == 0); + } + + RedInodePut(&ino, 0U); + } + + RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) +/** @brief Create a hard link. + + This creates an additional name (link) for @p ulInode. The new name refers + to the same file with the same contents. If a name is deleted, but the + underlying file has other names, the file continues to exist. The link + count (accessible via RedCoreStat()) indicates the number of names that a + file has. All of a file's names are on equal footing: there is nothing + special about the original name. + + If @p ulInode names a directory, the operation will fail. + + @param ulPInode The inode number of the parent directory. + @param pszName The null-terminated name for the new link. + @param ulInode The inode to create a hard link to. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode + is not a valid inode. + @retval -RED_EEXIST @p pszName resolves to an existing file. + @retval -RED_EINVAL The volume is not mounted; or @p pszName is + `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EMLINK Creating the link would exceed the maximum link + count of @p ulInode. + @retval -RED_ENAMETOOLONG Attempting to create a link with a name that + exceeds the maximum name length. + @retval -RED_ENOSPC There is insufficient free space to expand the + directory that would contain the link. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_EPERM @p ulInode is a directory. + @retval -RED_EROFS The requested link requires writing in a + directory on a read-only file system. +*/ +REDSTATUS RedCoreLink( + uint32_t ulPInode, + const char *pszName, + uint32_t ulInode) +{ + REDSTATUS ret; + + if((pszName == NULL) || (pszName[0U] == '\0') || !gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreLink(ulPInode, pszName, ulInode); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreLink(ulPInode, pszName, ulInode); + } + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_LINK) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} + + +/** @brief Create a hard link. + + @param ulPInode The inode number of the parent directory. + @param pszName The null-terminated name for the new link. + @param ulInode The inode to create a hard link to. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulPInode is not a valid inode; or @p ulInode + is not a valid inode. + @retval -RED_EEXIST @p pszName resolves to an existing file. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EMLINK Creating the link would exceed the maximum link + count of @p ulInode. + @retval -RED_ENAMETOOLONG Attempting to create a link with a name that + exceeds the maximum name length. + @retval -RED_ENOSPC There is insufficient free space to expand the + directory that would contain the link. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_EPERM @p ulInode is a directory. + @retval -RED_EROFS The requested link requires writing in a + directory on a read-only file system. +*/ +static REDSTATUS CoreLink( + uint32_t ulPInode, + const char *pszName, + uint32_t ulInode) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount(&pino, FTYPE_DIR, false); + + if(ret == 0) + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_FILE, false); + + /* POSIX specifies EPERM as the errno thrown when link() is given a + directory. Switch the errno returned if EISDIR was the return + value. + */ + if(ret == -RED_EISDIR) + { + ret = -RED_EPERM; + } + + if(ret == 0) + { + if(ino.pBuffer->uNLink == UINT16_MAX) + { + ret = -RED_EMLINK; + } + else + { + ret = RedInodeBranch(&pino); + } + + if(ret == 0) + { + ret = RedInodeBranch(&ino); + } + + if(ret == 0) + { + ret = RedDirEntryCreate(&pino, pszName, ino.ulInode); + } + + if(ret == 0) + { + ino.pBuffer->uNLink++; + } + + RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U); + } + + RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) */ + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) +/** @brief Delete a file or directory. + + The given name is deleted and the link count of the corresponding inode is + decremented. If the link count falls to zero (no remaining hard links), + the inode will be deleted. + + If the path names a directory which is not empty, the unlink will fail. + + If the deletion frees data in the committed state, it will not return to + free space until after a transaction point. Similarly, if the inode was + part of the committed state, the inode slot will not be available until + after a transaction point. + + This function can fail when the disk is full. To fix this, transact and + try again: Reliance Edge guarantees that it is possible to delete at least + one file or directory after a transaction point. If disk full automatic + transactions are enabled, this will happen automatically. + + @param ulPInode The inode number of the parent directory. + @param pszName The null-terminated name of the file or directory to + delete. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulPInode is not a valid inode. + @retval -RED_EINVAL The volume is not mounted; or @p pszName is + `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_ENOENT @p pszName does not name an existing file or + directory. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_ENOSPC The file system does not have enough space to + modify the parent directory to perform the + deletion. + @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a + directory which is not empty. +*/ +REDSTATUS RedCoreUnlink( + uint32_t ulPInode, + const char *pszName) +{ + REDSTATUS ret; + + if((pszName == NULL) && !gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreUnlink(ulPInode, pszName); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreUnlink(ulPInode, pszName); + } + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_UNLINK) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} + + +/** @brief Delete a file or directory. + + @param ulPInode The inode number of the parent directory. + @param pszName The null-terminated name of the file or directory to + delete. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulPInode is not a valid inode. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_ENOENT @p pszName does not name an existing file or + directory. + @retval -RED_ENOTDIR @p ulPInode is not a directory. + @retval -RED_ENOSPC The file system does not have enough space to + modify the parent directory to perform the + deletion. + @retval -RED_ENOTEMPTY The inode refered to by @p pszName is a + directory which is not empty. +*/ +static REDSTATUS CoreUnlink( + uint32_t ulPInode, + const char *pszName) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + CINODE pino; + + pino.ulInode = ulPInode; + ret = RedInodeMount(&pino, FTYPE_EITHER, false); + + if(ret == 0) + { + uint32_t ulDeleteIdx; + uint32_t ulInode; + + ret = RedDirEntryLookup(&pino, pszName, &ulDeleteIdx, &ulInode); + + if(ret == 0) + { + ret = RedInodeBranch(&pino); + } + + if(ret == 0) + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_EITHER, false); + + if(ret == 0) + { + if(ino.fDirectory && (ino.pBuffer->ullSize > 0U)) + { + ret = -RED_ENOTEMPTY; + } + else + { + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = true; + #endif + + ret = RedDirEntryDelete(&pino, ulDeleteIdx); + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + + if(ret == 0) + { + /* If the inode is deleted, buffers are needed to + read all of the indirects and free the data + blocks. Before doing that, to reduce the + minimum number of buffers needed to complete the + unlink, release the parent directory inode + buffers which are no longer needed. + */ + RedInodePutCoord(&pino); + + ret = RedInodeLinkDec(&ino); + CRITICAL_ASSERT(ret == 0); + } + } + + RedInodePut(&ino, (ret == 0) ? IPUT_UPDATE_CTIME : 0U); + } + } + + RedInodePut(&pino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) */ + + +#if REDCONF_API_POSIX == 1 +/** @brief Look up the inode number of a file or directory. + + @param ulPInode The inode number of the parent directory. + @param pszName The null-terminated name of the file or directory to look + up. + @param pulInode On successful return, populated with the inode number named + by @p pszName. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulPInode is not a valid inode. + @retval -RED_EINVAL The volume is not mounted; @p pszName is `NULL`; or + @p pulInode is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT @p pszName does not name an existing file or directory. + @retval -RED_ENOTDIR @p ulPInode is not a directory. +*/ +REDSTATUS RedCoreLookup( + uint32_t ulPInode, + const char *pszName, + uint32_t *pulInode) +{ + REDSTATUS ret; + + if((pulInode == NULL) && !gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulPInode; + ret = RedInodeMount(&ino, FTYPE_DIR, false); + + if(ret == 0) + { + ret = RedDirEntryLookup(&ino, pszName, NULL, pulInode); + + RedInodePut(&ino, 0U); + } + } + + return ret; +} +#endif /* REDCONF_API_POSIX == 1 */ + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) +/** @brief Rename a file or directory. + + If @p pszDstName names an existing file or directory, the behavior depends + on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the + destination name exists, this function always fails with -RED_EEXIST. + + If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one + atomic operation, the destination name is unlinked and the source name is + renamed to the destination name. Both names must be of the same type (both + files or both directories). As with RedCoreUnlink(), if the destination + name is a directory, it must be empty. The major exception to this + behavior is that if both names are links to the same inode, then the rename + does nothing and both names continue to exist. + + If the rename deletes the old destination, it may free data in the + committed state, which will not return to free space until after a + transaction point. Similarly, if the deleted inode was part of the + committed state, the inode slot will not be available until after a + transaction point. + + @param ulSrcPInode The inode number of the parent directory of the file or + directory to rename. + @param pszSrcName The name of the file or directory to rename. + @param ulDstPInode The new parent directory inode number of the file or + directory after the rename. + @param pszNewPath The new name of the file or directory after the rename. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or + @p ulDstPInode is not a valid inode number. + @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the + destination name exists. + @retval -RED_EINVAL The volume is not mounted; @p pszSrcName is + `NULL`; or @p pszDstName is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The destination name exists and is a directory, + and the source name is a non-directory. + @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + than #REDCONF_NAME_MAX. + @retval -RED_ENOENT The source name is not an existing entry; or + either @p pszSrcName or @p pszDstName point to + an empty string. + @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or + @p ulDstPInode is not a directory; or the source + name is a directory and the destination name is + a file. + @retval -RED_ENOTEMPTY The destination name is a directory which is not + empty. + @retval -RED_ENOSPC The file system does not have enough space to + extend the @p ulDstPInode directory. + @retval -RED_EROFS The directory to be removed resides on a + read-only file system. +*/ +REDSTATUS RedCoreRename( + uint32_t ulSrcPInode, + const char *pszSrcName, + uint32_t ulDstPInode, + const char *pszDstName) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreRename(ulSrcPInode, pszSrcName, ulDstPInode, pszDstName); + } + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_RENAME) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} + + +/** @brief Rename a file or directory. + + @param ulSrcPInode The inode number of the parent directory of the file or + directory to rename. + @param pszSrcName The name of the file or directory to rename. + @param ulDstPInode The new parent directory inode number of the file or + directory after the rename. + @param pszNewPath The new name of the file or directory after the rename. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulSrcPInode is not a valid inode number; or + @p ulDstPInode is not a valid inode number. + @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the + destination name exists. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The destination name exists and is a directory, + and the source name is a non-directory. + @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + than #REDCONF_NAME_MAX. + @retval -RED_ENOENT The source name is not an existing entry; or + either @p pszSrcName or @p pszDstName point to + an empty string. + @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or + @p ulDstPInode is not a directory; or the source + name is a directory and the destination name is + a file. + @retval -RED_ENOTEMPTY The destination name is a directory which is not + empty. + @retval -RED_ENOSPC The file system does not have enough space to + extend the @p ulDstPInode directory. + @retval -RED_EROFS The directory to be removed resides on a + read-only file system. +*/ +static REDSTATUS CoreRename( + uint32_t ulSrcPInode, + const char *pszSrcName, + uint32_t ulDstPInode, + const char *pszDstName) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + bool fUpdateTimestamps = false; + CINODE SrcPInode; + + SrcPInode.ulInode = ulSrcPInode; + ret = RedInodeMount(&SrcPInode, FTYPE_DIR, true); + + if(ret == 0) + { + CINODE DstPInode; + CINODE *pDstPInode; + + if(ulSrcPInode == ulDstPInode) + { + pDstPInode = &SrcPInode; + } + else + { + pDstPInode = &DstPInode; + DstPInode.ulInode = ulDstPInode; + ret = RedInodeMount(pDstPInode, FTYPE_DIR, true); + } + + if(ret == 0) + { + /* Initialize these to zero so we can unconditionally put them, + even if RedDirEntryRename() fails before mounting them. + */ + CINODE SrcInode = {0}; + CINODE DstInode = {0}; + + ret = RedDirEntryRename(&SrcPInode, pszSrcName, &SrcInode, pDstPInode, pszDstName, &DstInode); + + #if REDCONF_RENAME_ATOMIC == 1 + if((ret == 0) && (DstInode.ulInode != INODE_INVALID) && (DstInode.ulInode != SrcInode.ulInode)) + { + /* If the inode is deleted, buffers are needed to read all + of the indirects and free the data blocks. Before doing + that, to reduce the minimum number of buffers needed to + complete the rename, release parent directory inode + buffers which are no longer needed. + */ + RedInodePutCoord(&SrcPInode); + RedInodePutCoord(pDstPInode); + + ret = RedInodeLinkDec(&DstInode); + CRITICAL_ASSERT(ret == 0); + } + + if((ret == 0) && (DstInode.ulInode != SrcInode.ulInode)) + #else + if(ret == 0) + #endif + { + fUpdateTimestamps = true; + } + + #if REDCONF_RENAME_ATOMIC == 1 + RedInodePut(&DstInode, 0U); + #endif + + /* POSIX says updating ctime for the source inode is optional, + but searching around it looks like this is common for Linux + and other Unix file systems. + */ + RedInodePut(&SrcInode, fUpdateTimestamps ? IPUT_UPDATE_CTIME : 0U); + RedInodePut(pDstPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + } + + RedInodePut(&SrcPInode, fUpdateTimestamps ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) */ + + +#if REDCONF_API_POSIX == 1 +/** @brief Get the status of a file or directory. + + See the ::REDSTAT type for the details of the information returned. + + @param ulInode The inode number of the file or directory whose information + is to be retrieved. + @param pStat Pointer to a ::REDSTAT buffer to populate. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode. + @retval -RED_EINVAL The volume is not mounted; @p pStat is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedCoreStat( + uint32_t ulInode, + REDSTAT *pStat) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted || (pStat == NULL)) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_EITHER, false); + if(ret == 0) + { + RedMemSet(pStat, 0U, sizeof(*pStat)); + + pStat->st_dev = gbRedVolNum; + pStat->st_ino = ulInode; + pStat->st_mode = ino.pBuffer->uMode; + #if REDCONF_API_POSIX_LINK == 1 + pStat->st_nlink = ino.pBuffer->uNLink; + #else + pStat->st_nlink = 1U; + #endif + pStat->st_size = ino.pBuffer->ullSize; + #if REDCONF_INODE_TIMESTAMPS == 1 + pStat->st_atime = ino.pBuffer->ulATime; + pStat->st_mtime = ino.pBuffer->ulMTime; + pStat->st_ctime = ino.pBuffer->ulCTime; + #endif + #if REDCONF_INODE_BLOCKS == 1 + pStat->st_blocks = ino.pBuffer->ulBlocks; + #endif + + RedInodePut(&ino, 0U); + } + } + + return ret; +} +#endif /* REDCONF_API_POSIX == 1 */ + + +#if REDCONF_API_FSE == 1 +/** @brief Get the size of a file. + + @param ulInode The inode number of the file whose size is to be retrieved. + @param pullSize On successful exit, populated with the file size. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode. + @retval -RED_EINVAL The volume is not mounted; @p pullSize is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR @p ulInode is a directory inode. +*/ +REDSTATUS RedCoreFileSizeGet( + uint32_t ulInode, + uint64_t *pullSize) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted || (pullSize == NULL)) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_FILE, false); + if(ret == 0) + { + *pullSize = ino.pBuffer->ullSize; + + RedInodePut(&ino, 0U); + } + } + + return ret; +} +#endif /* REDCONF_API_FSE == 1 */ + + +/** @brief Read from a file. + + Data which has not yet been written, but which is before the end-of-file + (sparse data), shall read as zeroes. A short read -- where the number of + bytes read is less than requested -- indicates that the requested read was + partially or, if zero bytes were read, entirely beyond the end-of-file. + + If @p ullStart is at or beyond the maximum file size, it is treated like + any other read entirely beyond the end-of-file: no data is read and + @p pulLen is populated with zero. + + @param ulInode The inode number of the file to read. + @param ullStart The file offset to read from. + @param pulLen On entry, contains the number of bytes to read; on + successful exit, contains the number of bytes actually + read. + @param pBuffer The buffer to populate with the data read. Must be big + enough for the read request. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode number. + @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The inode is a directory inode. +*/ +REDSTATUS RedCoreFileRead( + uint32_t ulInode, + uint64_t ullStart, + uint32_t *pulLen, + void *pBuffer) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted || (pulLen == NULL)) + { + ret = -RED_EINVAL; + } + else + { + #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) + bool fUpdateAtime = (*pulLen > 0U) && !gpRedVolume->fReadOnly; + #else + bool fUpdateAtime = false; + #endif + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_FILE, fUpdateAtime); + if(ret == 0) + { + ret = RedInodeDataRead(&ino, ullStart, pulLen, pBuffer); + + #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) + RedInodePut(&ino, ((ret == 0) && fUpdateAtime) ? IPUT_UPDATE_ATIME : 0U); + #else + RedInodePut(&ino, 0U); + #endif + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write to a file. + + If the write extends beyond the end-of-file, the file size will be + increased. + + A short write -- where the number of bytes written is less than requested + -- indicates either that the file system ran out of space but was still + able to write some of the request; or that the request would have caused + the file to exceed the maximum file size, but some of the data could be + written prior to the file size limit. + + If an error is returned, either none of the data was written or a critical + error occurred (like an I/O error) and the file system volume will be + read-only. + + @param ulInode The file number of the file to write. + @param ullStart The file offset to write at. + @param pulLen On entry, the number of bytes to write; on successful exit, + the number of bytes actually written. + @param pBuffer The buffer containing the data to be written. Must big + enough for the write request. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid file number. + @retval -RED_EFBIG No data can be written to the given file offset since + the resulting file size would exceed the maximum file + size. + @retval -RED_EINVAL The volume is not mounted; or @p pBuffer is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The inode is a directory inode. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedCoreFileWrite( + uint32_t ulInode, + uint64_t ullStart, + uint32_t *pulLen, + const void *pBuffer) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreFileWrite(ulInode, ullStart, pulLen, pBuffer); + } + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_WRITE) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} + + +/** @brief Write to a file. + + @param ulInode The file number of the file to write. + @param ullStart The file offset to write at. + @param pulLen On entry, the number of bytes to write; on successful exit, + the number of bytes actually written. + @param pBuffer The buffer containing the data to be written. Must big + enough for the write request. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid file number. + @retval -RED_EFBIG No data can be written to the given file offset since + the resulting file size would exceed the maximum file + size. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The inode is a directory inode. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. + @retval -RED_EROFS The file system volume is read-only. +*/ +static REDSTATUS CoreFileWrite( + uint32_t ulInode, + uint64_t ullStart, + uint32_t *pulLen, + const void *pBuffer) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_FILE, true); + if(ret == 0) + { + ret = RedInodeDataWrite(&ino, ullStart, pulLen, pBuffer); + + RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if TRUNCATE_SUPPORTED +/** @brief Set the file size. + + Allows the file size to be increased, decreased, or to remain the same. If + the file size is increased, the new area is sparse (will read as zeroes). + If the file size is decreased, the data beyond the new end-of-file will + return to free space once it is no longer part of the committed state + (either immediately or after the next transaction point). + + @param ulInode The inode of the file to truncate. + @param ullSize The new file size, in bytes. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode number. + @retval -RED_EFBIG @p ullSize exceeds the maximum file size. + @retval -RED_EINVAL The volume is not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The inode is a directory inode. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedCoreFileTruncate( + uint32_t ulInode, + uint64_t ullSize) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + ret = CoreFileTruncate(ulInode, ullSize); + + if( (ret == -RED_ENOSPC) + && ((gpRedVolume->ulTransMask & RED_TRANSACT_VOLFULL) != 0U) + && (gpRedCoreVol->ulAlmostFreeBlocks > 0U)) + { + ret = RedVolTransact(); + + if(ret == 0) + { + ret = CoreFileTruncate(ulInode, ullSize); + } + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_TRUNCATE) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} + + +/** @brief Set the file size. + + @param ulInode The inode of the file to truncate. + @param ullSize The new file size, in bytes. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode number. + @retval -RED_EFBIG @p ullSize exceeds the maximum file size. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The inode is a directory inode. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. + @retval -RED_EROFS The file system volume is read-only. +*/ +static REDSTATUS CoreFileTruncate( + uint32_t ulInode, + uint64_t ullSize) +{ + REDSTATUS ret; + + if(gpRedVolume->fReadOnly) + { + ret = -RED_EROFS; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_FILE, true); + if(ret == 0) + { + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = (ullSize < ino.pBuffer->ullSize); + #endif + + ret = RedInodeDataTruncate(&ino, ullSize); + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + + RedInodePut(&ino, (ret == 0) ? (uint8_t)(IPUT_UPDATE_MTIME | IPUT_UPDATE_CTIME) : 0U); + } + + if((ret == 0) && ((gpRedVolume->ulTransMask & RED_TRANSACT_TRUNCATE) != 0U)) + { + ret = RedVolTransact(); + } + } + + return ret; +} +#endif /* TRUNCATE_SUPPORTED */ + + +#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) +/** @brief Read from a directory. + + If files are added to the directory after it is opened, the new files may + or may not be returned by this function. If files are deleted, the deleted + files will not be returned. + + @param ulInode The directory inode to read from. + @param pulPos A token which stores the position within the directory. To + read from the beginning of the directory, populate with + zero. + @param pszName Pointer to a buffer which must be big enough to store a + maximum size name, including a null terminator. On + successful exit, populated with the name of the next + directory entry. + @param pulInode On successful return, populated with the inode number of the + next directory entry. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode number. + @retval -RED_EINVAL The volume is not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT There are no more entries in the directory. + @retval -RED_ENOTDIR @p ulInode refers to a file. +*/ +REDSTATUS RedCoreDirRead( + uint32_t ulInode, + uint32_t *pulPos, + char *pszName, + uint32_t *pulInode) +{ + REDSTATUS ret; + + if(!gpRedVolume->fMounted) + { + ret = -RED_EINVAL; + } + else + { + CINODE ino; + + ino.ulInode = ulInode; + ret = RedInodeMount(&ino, FTYPE_DIR, false); + + if(ret == 0) + { + ret = RedDirEntryRead(&ino, pulPos, pszName, pulInode); + + #if (REDCONF_ATIME == 1) && (REDCONF_READ_ONLY == 0) + if((ret == 0) && !gpRedVolume->fReadOnly) + { + ret = RedInodeBranch(&ino); + } + + RedInodePut(&ino, ((ret == 0) && !gpRedVolume->fReadOnly) ? IPUT_UPDATE_ATIME : 0U); + #else + RedInodePut(&ino, 0U); + #endif + } + } + + return ret; +} +#endif /* (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) */ + diff --git a/core/driver/dir.c b/core/driver/dir.c new file mode 100644 index 0000000..0c1c952 --- /dev/null +++ b/core/driver/dir.c @@ -0,0 +1,876 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements directory operations. +*/ +#include + +#if REDCONF_API_POSIX == 1 + +#include + + +/** @brief Cast a pointer to a (const DIRENT *). + + Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). + It is used for populating a directory entry structure pointer with a + buffer pointer. Buffer pointers are 8-byte aligned, and DIRENT only + requires 4-byte alignment, thus the typecast is safe. + + As Rule 11.3 is required, a separate deviation record is required. +*/ +#define CAST_CONST_DIRENT_PTR(PTR) ((const DIRENT *)(PTR)) + +#define DIR_INDEX_INVALID UINT32_MAX + +#if (REDCONF_NAME_MAX % 4U) != 0U +#define DIRENT_PADDING (4U - (REDCONF_NAME_MAX % 4U)) +#else +#define DIRENT_PADDING (0U) +#endif +#define DIRENT_SIZE (4U + REDCONF_NAME_MAX + DIRENT_PADDING) +#define DIRENTS_PER_BLOCK (REDCONF_BLOCK_SIZE / DIRENT_SIZE) +#define DIRENTS_MAX (uint32_t)REDMIN(UINT32_MAX, (INODE_SIZE_MAX / DIRENT_SIZE)) + + +/** @brief On-disk directory entry. +*/ +typedef struct +{ + /** The inode number that the directory entry points at. If the directory + entry is available, this holds INODE_INVALID. + */ + uint32_t ulInode; + + /** The name of the directory entry. For names shorter than + REDCONF_NAME_MAX, unused bytes in the array are zeroed. For names of + the maximum length, the string is not null terminated. + */ + char szName[REDCONF_NAME_MAX]; + + #if DIRENT_PADDING > 0U + /** Unused padding so that ulInode is always aligned on a four-byte + boundary. + */ + uint8_t abPadding[DIRENT_PADDING]; + #endif +} DIRENT; + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) +static REDSTATUS DirCyclicRenameCheck(uint32_t ulSrcInode, const CINODE *pDstPInode); +#endif +#if REDCONF_READ_ONLY == 0 +static REDSTATUS DirEntryWrite(CINODE *pPInode, uint32_t ulIdx, uint32_t ulInode, const char *pszName, uint32_t ulNameLen); +static uint64_t DirEntryIndexToOffset(uint32_t ulIdx); +#endif +static uint32_t DirOffsetToEntryIndex(uint64_t ullOffset); + + +#if REDCONF_READ_ONLY == 0 +/** @brief Create a new entry in a directory. + + @param pPInode A pointer to the cached inode structure of the directory + to which the new entry will be added. + @param pszName The name to be given to the new entry, terminated by a + null or a path separator. + @param ulInode The inode number the new name will point at. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC There is not enough space on the volume to + create the new directory entry; or the directory + is full. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_EEXIST @p pszName already exists in @p ulPInode. + @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode + structure; or @p pszName is not a valid name. +*/ +REDSTATUS RedDirEntryCreate( + CINODE *pPInode, + const char *pszName, + uint32_t ulInode) +{ + REDSTATUS ret; + + if((pPInode == NULL) || (pPInode->pBuffer == NULL) || !pPInode->fDirty || (pszName == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint32_t ulNameLen = RedNameLen(pszName); + + if(ulNameLen == 0U) + { + ret = -RED_EINVAL; + } + else if(ulNameLen > REDCONF_NAME_MAX) + { + ret = -RED_ENAMETOOLONG; + } + else + { + uint32_t ulEntryIdx; + + ret = RedDirEntryLookup(pPInode, pszName, &ulEntryIdx, NULL); + if(ret == 0) + { + ret = -RED_EEXIST; + } + else if(ret == -RED_ENOENT) + { + if(ulEntryIdx == DIR_INDEX_INVALID) + { + ret = -RED_ENOSPC; + } + else + { + ret = 0; + } + } + else + { + /* Unexpected error, no action. + */ + } + + if(ret == 0) + { + ret = DirEntryWrite(pPInode, ulEntryIdx, ulInode, pszName, ulNameLen); + } + } + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if DELETE_SUPPORTED +/** @brief Delete an existing directory entry. + + @param pPInode A pointer to the cached inode structure of the directory + containing the entry to be deleted. + @param ulDeleteIdx Position within the directory of the entry to be + deleted. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC The file system does not have enough space to modify the + parent directory to perform the deletion. + @retval -RED_EINVAL @p pPInode is not a mounted dirty cached inode + structure; or @p ulIdx is out of range. +*/ +REDSTATUS RedDirEntryDelete( + CINODE *pPInode, + uint32_t ulDeleteIdx) +{ + REDSTATUS ret = 0; + + if((pPInode == NULL) || (pPInode->pBuffer == NULL) || !pPInode->fDirty || (ulDeleteIdx >= DIRENTS_MAX)) + { + ret = -RED_EINVAL; + } + else if((DirEntryIndexToOffset(ulDeleteIdx) + DIRENT_SIZE) == pPInode->pBuffer->ullSize) + { + uint32_t ulTruncIdx = ulDeleteIdx; + + /* We are deleting the last dirent in the directory, so search + backwards to find the last populated dirent, allowing us to truncate + the directory to that point. + */ + if(ulDeleteIdx > 0U) + { + bool fDone = false; + + while((ret == 0) && (ulTruncIdx > 0U) && !fDone) + { + ret = RedInodeDataSeekAndRead(pPInode, ulTruncIdx / DIRENTS_PER_BLOCK); + + if(ret == 0) + { + const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); + uint32_t ulBlockIdx = (ulTruncIdx - 1U) % DIRENTS_PER_BLOCK; + + do + { + if(pDirents[ulBlockIdx].ulInode != INODE_INVALID) + { + fDone = true; + break; + } + + ulTruncIdx--; + ulBlockIdx--; + } while(ulBlockIdx != UINT32_MAX); + } + else if(ret == -RED_ENODATA) + { + ret = 0; + + REDASSERT((ulTruncIdx % DIRENTS_PER_BLOCK) == 0U); + ulTruncIdx -= DIRENTS_PER_BLOCK; + } + else + { + /* Unexpected error, loop will terminate; nothing else + to be done. + */ + } + } + } + + /* Truncate the directory, deleting the requested entry and any empty + dirents at the end of the directory. + */ + if(ret == 0) + { + ret = RedInodeDataTruncate(pPInode, DirEntryIndexToOffset(ulTruncIdx)); + } + } + else + { + /* The dirent to delete is not the last entry in the directory, so just + zero it. + */ + ret = DirEntryWrite(pPInode, ulDeleteIdx, INODE_INVALID, "", 0U); + } + + return ret; +} +#endif /* DELETE_SUPPORTED */ + + +/** @brief Perform a case-sensitive search of a directory for a given name. + + If found, then position of the entry within the directory and the inode + number it points to are returned. As an optimization for directory entry + creation, in the case where the requested entry does not exist, the position + of the first available (unused) entry is returned. + + @param pPInode A pointer to the cached inode structure of the directory + to search. + @param pszName The name of the desired entry, terminated by either a + null or a path separator. + @param pulEntryIdx On successful return, meaning that the desired entry + exists, populated with the position of the entry. If + returning an -RED_ENOENT error, populated with the + position of the first available entry, or set to + DIR_INDEX_INVALID if the directory is full. Optional. + @param pulInode On successful return, populated with the inode number + that the name points to. Optional; may be `NULL`. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT @p pszName does not name an existing file or + directory. + @retval -RED_EINVAL @p pPInode is not a mounted cached inode + structure; or @p pszName is not a valid name; or + @p pulEntryIdx is `NULL`. + @retval -RED_ENAMETOOLONG @p pszName is too long. +*/ +REDSTATUS RedDirEntryLookup( + CINODE *pPInode, + const char *pszName, + uint32_t *pulEntryIdx, + uint32_t *pulInode) +{ + REDSTATUS ret = 0; + + if((pPInode == NULL) || (pPInode->pBuffer == NULL) || (pszName == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint32_t ulNameLen = RedNameLen(pszName); + + if(ulNameLen == 0U) + { + ret = -RED_EINVAL; + } + else if(ulNameLen > REDCONF_NAME_MAX) + { + ret = -RED_ENAMETOOLONG; + } + else + { + uint32_t ulIdx = 0U; + uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pBuffer->ullSize); + uint32_t ulFreeIdx = DIR_INDEX_INVALID; /* Index of first free dirent. */ + + /* Loop over the directory blocks, searching each block for a + dirent that matches the given name. + */ + while((ret == 0) && (ulIdx < ulDirentCount)) + { + ret = RedInodeDataSeekAndRead(pPInode, ulIdx / DIRENTS_PER_BLOCK); + + if(ret == 0) + { + const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); + uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - ulIdx); + uint32_t ulBlockIdx; + + for(ulBlockIdx = 0U; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++) + { + const DIRENT *pDirent = &pDirents[ulBlockIdx]; + + if( (pDirent->ulInode != INODE_INVALID) + && (RedStrNCmp(pDirent->szName, pszName, ulNameLen) == 0) + && ((ulNameLen == REDCONF_NAME_MAX) || (pDirent->szName[ulNameLen] == '\0'))) + { + /* Found a matching dirent, stop and return its + information. + */ + if(pulInode != NULL) + { + *pulInode = pDirent->ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + *pulInode = RedRev32(*pulInode); + #endif + } + + ulIdx += ulBlockIdx; + break; + } + + if((ulFreeIdx == DIR_INDEX_INVALID) && (pDirent->ulInode == INODE_INVALID)) + { + ulFreeIdx = ulIdx + ulBlockIdx; + } + } + + if(ulBlockIdx < ulBlockLastIdx) + { + /* If we broke out of the for loop, we found a matching + dirent and can stop the search. + */ + break; + } + + ulIdx += ulBlockLastIdx; + } + else if(ret == -RED_ENODATA) + { + if(ulFreeIdx == DIR_INDEX_INVALID) + { + ulFreeIdx = ulIdx; + } + + ret = 0; + ulIdx += DIRENTS_PER_BLOCK; + } + else + { + /* Unexpected error, let the loop terminate, no action + here. + */ + } + } + + if(ret == 0) + { + /* If we made it all the way to the end of the directory + without stopping, then the given name does not exist in the + directory. + */ + if(ulIdx == ulDirentCount) + { + /* If the directory had no sparse dirents, then the first + free dirent is beyond the end of the directory. If the + directory is already the maximum size, then there is no + free dirent. + */ + if((ulFreeIdx == DIR_INDEX_INVALID) && (ulDirentCount < DIRENTS_MAX)) + { + ulFreeIdx = ulDirentCount; + } + + ulIdx = ulFreeIdx; + + ret = -RED_ENOENT; + } + + if(pulEntryIdx != NULL) + { + *pulEntryIdx = ulIdx; + } + } + } + } + + return ret; +} + + +#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1) +/** @brief Read the next entry from a directory, given a starting index. + + @param pInode A pointer to the cached inode structure of the directory to + read from. + @param pulIdx On entry, the directory index to start reading from. On + successful return, populated with the directory index to use + for subsequent reads. On -RED_ENOENT return, populated with + the directory index immediately following the last valid + one. + @param pszName On successful return, populated with the name of the next + directory entry. + @param pulInode On successful return, populated with the inode number + pointed at by the next directory entry. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT There are no more entries in the directory. + @retval -RED_EINVAL @p pPInode is not a mounted cached inode structure; or + @p pszName is `NULL`; or @p pulIdx is `NULL`; or + @p pulInode is `NULL`. +*/ +REDSTATUS RedDirEntryRead( + CINODE *pPInode, + uint32_t *pulIdx, + char *pszName, + uint32_t *pulInode) +{ + REDSTATUS ret = 0; + + if((pPInode == NULL) || (pPInode->pBuffer == NULL) || (pulIdx == NULL) || (pszName == NULL) || (pulInode == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint32_t ulIdx = *pulIdx; + uint32_t ulDirentCount = DirOffsetToEntryIndex(pPInode->pBuffer->ullSize); + + /* Starting either at the beginning of the directory or where we left + off, loop over the directory blocks, searching each block for a + non-sparse dirent to return as the next entry in the directory. + */ + while((ret == 0) && (ulIdx < ulDirentCount)) + { + uint32_t ulBlockOffset = ulIdx / DIRENTS_PER_BLOCK; + + ret = RedInodeDataSeekAndRead(pPInode, ulBlockOffset); + + if(ret == 0) + { + const DIRENT *pDirents = CAST_CONST_DIRENT_PTR(pPInode->pbData); + uint32_t ulBlockLastIdx = REDMIN(DIRENTS_PER_BLOCK, ulDirentCount - (ulBlockOffset * DIRENTS_PER_BLOCK)); + uint32_t ulBlockIdx; + + for(ulBlockIdx = ulIdx % DIRENTS_PER_BLOCK; ulBlockIdx < ulBlockLastIdx; ulBlockIdx++) + { + if(pDirents[ulBlockIdx].ulInode != INODE_INVALID) + { + *pulIdx = ulIdx + 1U; + RedStrNCpy(pszName, pDirents[ulBlockIdx].szName, REDCONF_NAME_MAX); + pszName[REDCONF_NAME_MAX] = '\0'; + + *pulInode = pDirents[ulBlockIdx].ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + *pulInode = RedRev32(*pulInode); + #endif + break; + } + + ulIdx++; + } + + if(ulBlockIdx < ulBlockLastIdx) + { + REDASSERT(ulIdx <= ulDirentCount); + break; + } + } + else if(ret == -RED_ENODATA) + { + ulIdx += DIRENTS_PER_BLOCK - (ulIdx % DIRENTS_PER_BLOCK); + ret = 0; + } + else + { + /* Unexpected error, loop will terminate; nothing else to do. + */ + } + + REDASSERT(ulIdx <= ulDirentCount); + } + + if((ret == 0) && (ulIdx >= ulDirentCount)) + { + *pulIdx = ulDirentCount; + ret = -RED_ENOENT; + } + } + + return ret; +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) +/** Rename a directory entry. + + @param pSrcPInode The inode of the directory containing @p pszSrcName. + @param pszSrcName The name of the directory entry to be renamed. + @param pSrcInode On successful return, populated with the inode of the + source entry. + @param pDstPInode The inode of the directory in which @p pszDstName will + be created or replaced. + @param pszDstName The name of the directory entry to be created or + replaced. + @param pDstInode On successful return, if the destination previously + existed, populated with the inode previously pointed to + by the destination. This may be the same as the source + inode. If the destination did not exist, populated with + INODE_INVALID. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EEXIST #REDCONF_RENAME_POSIX is false and the + destination name exists. + @retval -RED_EINVAL @p pSrcPInode is not a mounted dirty cached + inode structure; or @p pSrcInode is `NULL`; or + @p pszSrcName is not a valid name; or + @p pDstPInode is not a mounted dirty cached + inode structure; or @p pDstInode is `NULL`; or + @p pszDstName is not a valid name. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR The destination name exists and is a directory, + and the source name is a non-directory. + @retval -RED_ENAMETOOLONG Either @p pszSrcName or @p pszDstName is longer + than #REDCONF_NAME_MAX. + @retval -RED_ENOENT The source name is not an existing entry; or + either @p pszSrcName or @p pszDstName point to + an empty string. + @retval -RED_ENOTDIR @p ulSrcPInode is not a directory; or + @p ulDstPInode is not a directory; or the source + name is a directory and the destination name is + a file. + @retval -RED_ENOTEMPTY The destination name is a directory which is not + empty. + @retval -RED_ENOSPC The file system does not have enough space to + extend the @p ulDstPInode directory. + @retval -RED_EROFS The directory to be removed resides on a + read-only file system. +*/ +REDSTATUS RedDirEntryRename( + CINODE *pSrcPInode, + const char *pszSrcName, + CINODE *pSrcInode, + CINODE *pDstPInode, + const char *pszDstName, + CINODE *pDstInode) +{ + REDSTATUS ret; + + if( (pSrcPInode == NULL) + || (pSrcPInode->pBuffer == NULL) + || !pSrcPInode->fDirty + || (pSrcInode == NULL) + || (pszSrcName == NULL) + || (pDstPInode == NULL) + || (pDstPInode->pBuffer == NULL) + || !pDstPInode->fDirty + || (pszDstName == NULL) + || (pDstInode == NULL)) + { + ret = -RED_EINVAL; + } + else + { + uint32_t ulDstIdx = 0U; /* Init'd to quiet warnings. */ + uint32_t ulSrcIdx; + + /* Look up the source and destination names. + */ + ret = RedDirEntryLookup(pSrcPInode, pszSrcName, &ulSrcIdx, &pSrcInode->ulInode); + + if(ret == 0) + { + ret = RedDirEntryLookup(pDstPInode, pszDstName, &ulDstIdx, &pDstInode->ulInode); + + if(ret == -RED_ENOENT) + { + if(ulDstIdx == DIR_INDEX_INVALID) + { + ret = -RED_ENOSPC; + } + else + { + #if REDCONF_RENAME_ATOMIC == 1 + pDstInode->ulInode = INODE_INVALID; + #endif + ret = 0; + } + } + #if REDCONF_RENAME_ATOMIC == 0 + else if(ret == 0) + { + ret = -RED_EEXIST; + } + else + { + /* Nothing to do here, just propagate the error. + */ + } + #endif + } + + #if REDCONF_RENAME_ATOMIC == 1 + /* If both names point to the same inode, POSIX says to do nothing to + either name. + */ + if((ret == 0) && (pSrcInode->ulInode != pDstInode->ulInode)) + #else + if(ret == 0) + #endif + { + ret = RedInodeMount(pSrcInode, FTYPE_EITHER, true); + + #if REDCONF_RENAME_ATOMIC == 1 + if((ret == 0) && (pDstInode->ulInode != INODE_INVALID)) + { + /* Source and destination must be the same type (file/dir). + */ + ret = RedInodeMount(pDstInode, pSrcInode->fDirectory ? FTYPE_DIR : FTYPE_FILE, true); + + /* If renaming directories, the destination must be empty. + */ + if((ret == 0) && pDstInode->fDirectory && (pDstInode->pBuffer->ullSize > 0U)) + { + ret = -RED_ENOTEMPTY; + } + } + #endif + + /* If we are renaming a directory, make sure the rename isn't + cyclic (e.g., renaming "foo" into "foo/bar"). + */ + if((ret == 0) && pSrcInode->fDirectory) + { + ret = DirCyclicRenameCheck(pSrcInode->ulInode, pDstPInode); + } + + if(ret == 0) + { + ret = DirEntryWrite(pDstPInode, ulDstIdx, pSrcInode->ulInode, pszDstName, RedNameLen(pszDstName)); + } + + if(ret == 0) + { + ret = RedDirEntryDelete(pSrcPInode, ulSrcIdx); + + if(ret == -RED_ENOSPC) + { + REDSTATUS ret2; + + /* If there was not enough space to branch the parent + directory inode and data block containin the source + entry, revert destination directory entry to its + previous state. + */ + #if REDCONF_RENAME_ATOMIC == 1 + if(pDstInode->ulInode != INODE_INVALID) + { + ret2 = DirEntryWrite(pDstPInode, ulDstIdx, pDstInode->ulInode, pszDstName, RedNameLen(pszDstName)); + } + else + #endif + { + ret2 = RedDirEntryDelete(pDstPInode, ulDstIdx); + } + + if(ret2 != 0) + { + ret = ret2; + CRITICAL_ERROR(); + } + } + } + + if(ret == 0) + { + pSrcInode->pBuffer->ulPInode = pDstPInode->ulInode; + } + } + } + + return ret; +} + + +/** @brief Check for a cyclic rename. + + A cyclic rename is renaming a directory into a subdirectory of itself. For + example, renaming "a" into "a/b/c/d" is cyclic. These renames must not be + allowed since they would corrupt the directory tree. + + @param ulSrcInode The inode number of the directory being renamed. + @param pDstPInode A pointer to the cached inode structure of the directory + into which the source is being renamed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL The rename is cyclic. +*/ +static REDSTATUS DirCyclicRenameCheck( + uint32_t ulSrcInode, + const CINODE *pDstPInode) +{ + REDSTATUS ret = 0; + + if(ulSrcInode == pDstPInode->ulInode) + { + ret = -RED_EINVAL; + } + else + { + CINODE NextParent; + + NextParent.ulInode = pDstPInode->pBuffer->ulPInode; + + while((NextParent.ulInode != ulSrcInode) && (NextParent.ulInode != INODE_ROOTDIR) && (NextParent.ulInode != INODE_INVALID)) + { + ret = RedInodeMount(&NextParent, FTYPE_DIR, false); + if(ret != 0) + { + break; + } + + NextParent.ulInode = NextParent.pBuffer->ulPInode; + + RedInodePut(&NextParent, 0U); + } + + if((ret == 0) && (ulSrcInode == NextParent.ulInode)) + { + ret = -RED_EINVAL; + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) */ + + +#if REDCONF_READ_ONLY == 0 +/** @brief Update the contents of a directory entry. + + @param pPInode A pointer to the cached inode structure of the directory + whose entry is being written. + @param ulIdx The index of the directory entry to write. + @param ulInode The inode number the directory entry is to point at. + @param pszName The name of the directory entry. + @param ulNameLen The length of @p pszName. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC There is not enough space on the volume to write the + directory entry. +*/ +static REDSTATUS DirEntryWrite( + CINODE *pPInode, + uint32_t ulIdx, + uint32_t ulInode, + const char *pszName, + uint32_t ulNameLen) +{ + uint64_t ullOffset = DirEntryIndexToOffset(ulIdx); + uint32_t ulLen = DIRENT_SIZE; + DIRENT de = {0}; + + de.ulInode = ulInode; + + #ifdef REDCONF_ENDIAN_SWAP + de.ulInode = RedRev32(de.ulInode); + #endif + + RedStrNCpy(de.szName, pszName, ulNameLen); + + return RedInodeDataWrite(pPInode, ullOffset, &ulLen, &de); +} + + +/** @brief Convert a directory entry index to a byte offset. + + @param ulIdx Directory entry index. + + @return Byte offset in the directory corresponding with ulIdx. +*/ +static uint64_t DirEntryIndexToOffset( + uint32_t ulIdx) +{ + uint32_t ulBlock = ulIdx / DIRENTS_PER_BLOCK; + uint32_t ulOffsetInBlock = ulIdx % DIRENTS_PER_BLOCK; + uint64_t ullOffset; + + ullOffset = (uint64_t)ulBlock << BLOCK_SIZE_P2; + ullOffset += (uint64_t)ulOffsetInBlock * DIRENT_SIZE; + + return ullOffset; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Convert a byte offset to a directory entry index. + + @param ullOffset Byte offset in the directory. + + @return Directory entry index corresponding with @p ullOffset. +*/ +static uint32_t DirOffsetToEntryIndex( + uint64_t ullOffset) +{ + uint32_t ulIdx; + + /* Avoid doing any 64-bit divides. + */ + ulIdx = (uint32_t)(ullOffset >> BLOCK_SIZE_P2) * DIRENTS_PER_BLOCK; + ulIdx += (uint32_t)(ullOffset & (REDCONF_BLOCK_SIZE - 1U)) / DIRENT_SIZE; + + return ulIdx; +} + + +#endif /* REDCONF_API_POSIX == 1 */ + diff --git a/core/driver/format.c b/core/driver/format.c new file mode 100644 index 0000000..c9f7d15 --- /dev/null +++ b/core/driver/format.c @@ -0,0 +1,248 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#if (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) + +#include +#include +#include + + +/** @brief Format a file system volume. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBUSY Volume is mounted. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedVolFormat(void) +{ + REDSTATUS ret; + + if(gpRedVolume->fMounted) + { + ret = -RED_EBUSY; + } + else + { + ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR); + } + + if(ret == 0) + { + MASTERBLOCK *pMB; + REDSTATUS ret2; + + /* Overwrite the master block with zeroes, so that if formatting is + interrupted, the volume will not be mountable. + */ + ret = RedBufferGet(0U, BFLAG_NEW | BFLAG_DIRTY, CAST_VOID_PTR_PTR(&pMB)); + + if(ret == 0) + { + ret = RedBufferFlush(0U, 1U); + + RedBufferDiscard(pMB); + } + + if(ret == 0) + { + ret = RedIoFlush(gbRedVolNum); + } + + #if REDCONF_IMAP_EXTERNAL == 1 + if((ret == 0) && !gpRedCoreVol->fImapInline) + { + uint32_t ulImapNode; + + for(ulImapNode = 0U; ulImapNode < gpRedCoreVol->ulImapNodeCount; ulImapNode++) + { + uint8_t bWhichImap; + + /* Technically it is only necessary to create one copy of each + imap node (the copy the metaroot points at), but creating + them both avoids headaches during disk image analysis from + stale imaps left over from previous formats. + */ + for(bWhichImap = 0U; bWhichImap < 2U; bWhichImap++) + { + uint32_t ulBlock = gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U) + bWhichImap; + IMAPNODE *pImap; + + ret = RedBufferGet(ulBlock, (uint16_t)((uint32_t)BFLAG_META_IMAP | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pImap)); + if(ret != 0) + { + break; + } + + RedBufferPut(pImap); + } + + if(ret != 0) + { + break; + } + } + } + #endif + + /* Write the first metaroot. + */ + if(ret == 0) + { + RedMemSet(gpRedMR, 0U, sizeof(*gpRedMR)); + + gpRedMR->ulFreeBlocks = gpRedVolume->ulBlocksAllocable; + #if REDCONF_API_POSIX == 1 + gpRedMR->ulFreeInodes = gpRedVolConf->ulInodeCount; + #endif + gpRedMR->ulAllocNextBlock = gpRedCoreVol->ulFirstAllocableBN; + + /* The branched flag is typically set automatically when bits in + the imap change. It is set here explicitly because the imap has + only been initialized, not changed. + */ + gpRedCoreVol->fBranched = true; + + ret = RedVolTransact(); + } + + #if REDCONF_API_POSIX == 1 + /* Create the root directory. + */ + if(ret == 0) + { + CINODE rootdir; + + rootdir.ulInode = INODE_ROOTDIR; + ret = RedInodeCreate(&rootdir, INODE_INVALID, RED_S_IFDIR); + + if(ret == 0) + { + RedInodePut(&rootdir, 0U); + } + } + #endif + + #if REDCONF_API_FSE == 1 + /* The FSE API does not support creating or deletes files, so all the + inodes are created during setup. + */ + if(ret == 0) + { + uint32_t ulInodeIdx; + + for(ulInodeIdx = 0U; ulInodeIdx < gpRedVolConf->ulInodeCount; ulInodeIdx++) + { + CINODE ino; + + ino.ulInode = INODE_FIRST_FREE + ulInodeIdx; + ret = RedInodeCreate(&ino, INODE_INVALID, RED_S_IFREG); + + if(ret == 0) + { + RedInodePut(&ino, 0U); + } + } + } + #endif + + /* Write the second metaroot. + */ + if(ret == 0) + { + ret = RedVolTransact(); + } + + /* Populate and write out the master block. + */ + if(ret == 0) + { + ret = RedBufferGet(0U, (uint16_t)((uint32_t)BFLAG_META_MASTER | BFLAG_NEW | BFLAG_DIRTY), CAST_VOID_PTR_PTR(&pMB)); + } + + if(ret == 0) + { + pMB->ulVersion = RED_DISK_LAYOUT_VERSION; + RedStrNCpy(pMB->acBuildNum, RED_BUILD_NUMBER, sizeof(pMB->acBuildNum)); + pMB->ulFormatTime = RedOsClockGetTime(); + pMB->ulInodeCount = gpRedVolConf->ulInodeCount; + pMB->ulBlockCount = gpRedVolume->ulBlockCount; + pMB->uMaxNameLen = REDCONF_NAME_MAX; + pMB->uDirectPointers = REDCONF_DIRECT_POINTERS; + pMB->uIndirectPointers = REDCONF_INDIRECT_POINTERS; + + pMB->bBlockSizeP2 = 1U; + while((1UL << pMB->bBlockSizeP2) != REDCONF_BLOCK_SIZE) + { + pMB->bBlockSizeP2++; + } + + #if REDCONF_API_POSIX == 1 + pMB->bFlags |= MBFLAG_API_POSIX; + #endif + #if REDCONF_INODE_TIMESTAMPS == 1 + pMB->bFlags |= MBFLAG_INODE_TIMESTAMPS; + #endif + #if REDCONF_INODE_BLOCKS == 1 + pMB->bFlags |= MBFLAG_INODE_BLOCKS; + #endif + #if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) + pMB->bFlags |= MBFLAG_INODE_NLINK; + #endif + + ret = RedBufferFlush(0U, 1U); + + RedBufferPut(pMB); + } + + if(ret == 0) + { + ret = RedIoFlush(gbRedVolNum); + } + + ret2 = RedOsBDevClose(gbRedVolNum); + if(ret == 0) + { + ret = ret2; + } + } + + /* Discard the buffers so a subsequent format will not run into blocks it + does not expect. + */ + if(ret == 0) + { + ret = RedBufferDiscardRange(0U, gpRedVolume->ulBlockCount); + } + + return ret; +} + + +#endif /* (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) */ + diff --git a/core/driver/imap.c b/core/driver/imap.c new file mode 100644 index 0000000..58ac8a1 --- /dev/null +++ b/core/driver/imap.c @@ -0,0 +1,354 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements allocation routines. + + This module implements routines for working with the imap, a bitmap which + tracks which blocks are allocated or free. Some of the functionality is + delegated to imapinline.c and imapextern.c. +*/ +#include +#include +#include + + +/** @brief Get the allocation bit of a block from either metaroot. + + Will pass the call down either to the inline imap or to the external imap + implementation, whichever is appropriate for the current volume. + + @param bMR The metaroot index: either 0 or 1. + @param ulBlock The block number to query. + @param pfAllocated On successful return, populated with the allocation bit + of the block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + or @p pfAllocated is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapBlockGet( + uint8_t bMR, + uint32_t ulBlock, + bool *pfAllocated) +{ + REDSTATUS ret; + + if( (bMR > 1U) + || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount) + || (pfAllocated == NULL)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1) + if(gpRedCoreVol->fImapInline) + { + ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated); + } + else + { + ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated); + } + #elif REDCONF_IMAP_INLINE == 1 + ret = RedImapIBlockGet(bMR, ulBlock, pfAllocated); + #else + ret = RedImapEBlockGet(bMR, ulBlock, pfAllocated); + #endif + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Set the allocation bit of a block in the working metaroot. + + Will pass the call down either to the inline imap or to the external imap + implementation, whichever is appropriate for the current volume. + + @param ulBlock The block number to allocate or free. + @param fAllocated Whether to allocate the block (true) or free it (false). + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulBlock is out of range; or @p ulBlock is allocable + and @p fAllocated is 1. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapBlockSet( + uint32_t ulBlock, + bool fAllocated) +{ + REDSTATUS ret; + + if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if( (ulBlock >= gpRedCoreVol->ulFirstAllocableBN) + && ( (fAllocated && (gpRedMR->ulFreeBlocks == 0U)) + || ((!fAllocated) && (gpRedMR->ulFreeBlocks >= gpRedVolume->ulBlocksAllocable)))) + { + /* Attempting either to free more blocks than are allocable, or + allocate a block when there are none available. This could indicate + metadata corruption. + */ + CRITICAL_ERROR(); + ret = -RED_EINVAL; + } + else + { + #if (REDCONF_IMAP_INLINE == 1) && (REDCONF_IMAP_EXTERNAL == 1) + if(gpRedCoreVol->fImapInline) + { + ret = RedImapIBlockSet(ulBlock, fAllocated); + } + else + { + ret = RedImapEBlockSet(ulBlock, fAllocated); + } + #elif REDCONF_IMAP_INLINE == 1 + ret = RedImapIBlockSet(ulBlock, fAllocated); + #else + ret = RedImapEBlockSet(ulBlock, fAllocated); + #endif + + /* Any change to the allocation state of a block indicates that the + volume is now branched. + */ + gpRedCoreVol->fBranched = true; + } + + /* If a block was marked as no longer in use, discard it from the buffers. + */ + if((ret == 0) && (!fAllocated)) + { + ret = RedBufferDiscardRange(ulBlock, 1U); + CRITICAL_ASSERT(ret == 0); + } + + /* Adjust the free/almost free block count if the block was allocable. + */ + if((ret == 0) && (ulBlock >= gpRedCoreVol->ulFirstAllocableBN)) + { + if(fAllocated) + { + gpRedMR->ulFreeBlocks--; + } + else + { + bool fWasAllocated; + + /* Whether the block became free or almost free depends on its + previous allocation state. If it was used, then it is now + almost free. Otherwise, it was new and is now free. + */ + ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fWasAllocated); + CRITICAL_ASSERT(ret == 0); + + if(ret == 0) + { + if(fWasAllocated) + { + gpRedCoreVol->ulAlmostFreeBlocks++; + } + else + { + gpRedMR->ulFreeBlocks++; + } + } + } + } + + return ret; +} + + +/** @brief Allocate one block. + + @param pulBlock On successful return, populated with the allocated block + number. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pulBlock is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the allocation. +*/ +REDSTATUS RedImapAllocBlock( + uint32_t *pulBlock) +{ + REDSTATUS ret; + + if(pulBlock == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if(gpRedMR->ulFreeBlocks == 0U) + { + ret = -RED_ENOSPC; + } + else + { + uint32_t ulBlock = gpRedMR->ulAllocNextBlock; + uint32_t ulStopBlock = ulBlock; + bool fAllocated = false; + + do + { + ALLOCSTATE state; + + ret = RedImapBlockState(ulBlock, &state); + CRITICAL_ASSERT(ret == 0); + + if(ret == 0) + { + if(state == ALLOCSTATE_FREE) + { + ret = RedImapBlockSet(ulBlock, true); + CRITICAL_ASSERT(ret == 0); + + *pulBlock = ulBlock; + fAllocated = true; + + break; + } + + /* Increment the next block number, wrapping it when the end of + the volume is reached. + */ + ulBlock++; + if(ulBlock == gpRedVolume->ulBlockCount) + { + ulBlock = gpRedCoreVol->ulFirstAllocableBN; + } + + gpRedMR->ulAllocNextBlock = ulBlock; + } + } + while((ret == 0) && (ulBlock != ulStopBlock)); + + if((ret == 0) && !fAllocated) + { + /* The free block count was already determined to be non-zero, no + error occurred while looking for free blocks, but no free blocks + were found. This indicates metadata corruption. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Get the allocation state of a block. + + Takes into account the allocation bits from both metaroots, and returns one + of four possible allocation state values: + + - ::ALLOCSTATE_FREE Free and may be allocated; writeable. + - ::ALLOCSTATE_USED In-use and transacted; not writeable. + - ::ALLOCSTATE_NEW In-use but not transacted; writeable. + - ::ALLOCSTATE_AFREE Will become free after a transaction; not writeable. + + @param ulBlock The block number to query. + @param pState On successful return, populated with the state of the block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulBlock is out of range; or @p pState is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapBlockState( + uint32_t ulBlock, + ALLOCSTATE *pState) +{ + REDSTATUS ret; + + if( (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount) + || (pState == NULL)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fBitCurrent; + + ret = RedImapBlockGet(gpRedCoreVol->bCurMR, ulBlock, &fBitCurrent); + + if(ret == 0) + { + bool fBitOld; + + ret = RedImapBlockGet(1U - gpRedCoreVol->bCurMR, ulBlock, &fBitOld); + + if(ret == 0) + { + if(fBitCurrent) + { + if(fBitOld) + { + *pState = ALLOCSTATE_USED; + } + else + { + *pState = ALLOCSTATE_NEW; + } + } + else + { + if(fBitOld) + { + *pState = ALLOCSTATE_AFREE; + } + else + { + *pState = ALLOCSTATE_FREE; + } + } + } + } + } + + return ret; +} + diff --git a/core/driver/imapextern.c b/core/driver/imapextern.c new file mode 100644 index 0000000..0214ecd --- /dev/null +++ b/core/driver/imapextern.c @@ -0,0 +1,332 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements routines for the external imap. + + The external imap is used on volumes that are too big for the imap bitmap + to be stored entirely in the metaroot, so instead the bitmap is stored in + imap nodes on disk, and the metaroot bitmap is used to toggle between imap + nodes. +*/ +#include + +#if REDCONF_IMAP_EXTERNAL == 1 + +#include +#include + + +#if REDCONF_READ_ONLY == 0 +static REDSTATUS ImapNodeBranch(uint32_t ulImapNode, IMAPNODE **ppImap); +static bool ImapNodeIsBranched(uint32_t ulImapNode); +#endif +static uint8_t ImapNodeWhich(uint8_t bMR, uint32_t ulImapNode); + + +/** @brief Get the allocation bit of a block from the imap as it exists in + either metaroot. + + @param bMR The metaroot index: either 0 or 1. + @param ulBlock The block number to query. + @param pfAllocated On successful exit, populated with the allocation bit + of the block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + or @p pfAllocated is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapEBlockGet( + uint8_t bMR, + uint32_t ulBlock, + bool *pfAllocated) +{ + REDSTATUS ret; + + if( gpRedCoreVol->fImapInline + || (bMR > 1U) + || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount) + || (pfAllocated == NULL)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; + uint8_t bMRToRead; + IMAPNODE *pImap; + + #if REDCONF_READ_ONLY == 0 + /* If the imap node is not branched, then both copies of the imap are + identical. If the old metaroot copy is requested, use the current + copy instead, since it is more likely to be buffered. + */ + if((bMR == (1U - gpRedCoreVol->bCurMR)) && !ImapNodeIsBranched(ulImapNode)) + { + bMRToRead = 1U - bMR; + } + else + #endif + { + bMRToRead = bMR; + } + + ret = RedBufferGet(RedImapNodeBlock(bMRToRead, ulImapNode), BFLAG_META_IMAP, CAST_VOID_PTR_PTR(&pImap)); + + if(ret == 0) + { + *pfAllocated = RedBitGet(pImap->abEntries, ulOffset % IMAPNODE_ENTRIES); + + RedBufferPut(pImap); + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Set the allocation bit of a block in the working-state imap. + + @param ulBlock The block number to allocate or free. + @param fAllocated Whether to allocate the block (true) or free it (false). + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulBlock is out of range. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapEBlockSet( + uint32_t ulBlock, + bool fAllocated) +{ + REDSTATUS ret; + + if( gpRedCoreVol->fImapInline + || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + uint32_t ulImapNode = ulOffset / IMAPNODE_ENTRIES; + IMAPNODE *pImap; + + ret = ImapNodeBranch(ulImapNode, &pImap); + + if(ret == 0) + { + uint32_t ulImapEntry = ulOffset % IMAPNODE_ENTRIES; + + if(RedBitGet(pImap->abEntries, ulImapEntry) == fAllocated) + { + /* The driver shouldn't ever set a bit in the imap to its + current value. That shouldn't ever be needed, and it + indicates that the driver is doing unnecessary I/O, or + that the imap is corrupt. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else if(fAllocated) + { + RedBitSet(pImap->abEntries, ulImapEntry); + } + else + { + RedBitClear(pImap->abEntries, ulImapEntry); + } + + RedBufferPut(pImap); + } + } + + return ret; +} + + +/** @brief Branch an imap node and get a buffer for it. + + If the imap node is already branched, it can be overwritten in its current + location, and this function just gets it buffered dirty. If the node is not + already branched, the metaroot must be updated to toggle the imap node to + its alternate location, thereby preserving the committed state copy of the + imap node. + + @param ulImapNode The imap node to branch and buffer. + @param ppImap On successful return, populated with the imap node + buffer, which will be marked dirty. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulImapNode is out of range; or @p ppImap is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS ImapNodeBranch( + uint32_t ulImapNode, + IMAPNODE **ppImap) +{ + REDSTATUS ret; + + if((ulImapNode >= gpRedCoreVol->ulImapNodeCount) || (ppImap == NULL)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if(ImapNodeIsBranched(ulImapNode)) + { + /* Imap node is already branched, so just get it buffered dirty. + */ + ret = RedBufferGet(RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode), BFLAG_META_IMAP | BFLAG_DIRTY, CAST_VOID_PTR_PTR(ppImap)); + } + else + { + uint32_t ulBlockCurrent; + uint32_t ulBlockOld; + + /* The metaroot currently points to the committed state imap node. + Toggle the metaroot to point at the alternate, writeable location. + */ + if(ImapNodeWhich(gpRedCoreVol->bCurMR, ulImapNode) == 0U) + { + RedBitSet(gpRedMR->abEntries, ulImapNode); + } + else + { + RedBitClear(gpRedMR->abEntries, ulImapNode); + } + + ulBlockCurrent = RedImapNodeBlock(gpRedCoreVol->bCurMR, ulImapNode); + ulBlockOld = RedImapNodeBlock(1U - gpRedCoreVol->bCurMR, ulImapNode); + + ret = RedBufferDiscardRange(ulBlockCurrent, 1U); + + /* Buffer the committed copy then reassign the block number to the + writeable location. This also dirties the buffer. + */ + if(ret == 0) + { + ret = RedBufferGet(ulBlockOld, BFLAG_META_IMAP, CAST_VOID_PTR_PTR(ppImap)); + + if(ret == 0) + { + RedBufferBranch(*ppImap, ulBlockCurrent); + } + } + } + + return ret; +} + + +/** @brief Determine whether an imap node is branched. + + If the imap node is branched, it can be overwritten in its current location. + + @param ulImapNode The imap node to examine. + + @return Whether the imap node is branched. +*/ +static bool ImapNodeIsBranched( + uint32_t ulImapNode) +{ + return ImapNodeWhich(0U, ulImapNode) != ImapNodeWhich(1U, ulImapNode); +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Calculate the block number of the imap node location indicated by the + given metaroot. + + An imap node has two locations on disk. A bit in the metaroot bitmap + indicates which location is the valid one, according to that metaroot. This + function returns the block number of the imap node which is valid in the + given metaroot. + + @param bMR Which metaroot to examine. + @param ulImapNode The imap node for which to calculate the block number. + + @return Block number of the imap node, as indicated by the given metaroot. +*/ +uint32_t RedImapNodeBlock( + uint8_t bMR, + uint32_t ulImapNode) +{ + uint8_t bWhichImap = ImapNodeWhich(bMR, ulImapNode); + + REDASSERT(ulImapNode < gpRedCoreVol->ulImapNodeCount); + REDASSERT(bWhichImap <= 1U); + + return gpRedCoreVol->ulImapStartBN + (ulImapNode * 2U) + bWhichImap; +} + + +/** @brief Determine which copy of the imap node is current according to the + given metaroot. + + An imap node has two locations on disk. A bit in the metaroot bitmap + indicates whether the first copy or the second copy is the valid one, + according to that metaroot. + + @param bMR Which metaroot to examine. + @param ulImapNode The imap node to examine. + + @return Either 0 or 1, indicating whether the first or second copy is valid. +*/ +static uint8_t ImapNodeWhich( + uint8_t bMR, + uint32_t ulImapNode) +{ + uint8_t bWhich; + + if((bMR > 1U) || (ulImapNode >= gpRedCoreVol->ulImapNodeCount)) + { + REDERROR(); + bWhich = 0U; + } + else if(RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulImapNode)) + { + bWhich = 1U; + } + else + { + bWhich = 0U; + } + + return bWhich; +} + +#endif /* REDCONF_IMAP_EXTERNAL == 1 */ + diff --git a/core/driver/imapinline.c b/core/driver/imapinline.c new file mode 100644 index 0000000..7680638 --- /dev/null +++ b/core/driver/imapinline.c @@ -0,0 +1,134 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements routines for the inline imap. + + The inline imap is used on volumes that are small enough for the imap bitmap + to be entirely contained within the metaroot. +*/ +#include + +#if REDCONF_IMAP_INLINE == 1 + +#include +#include + + +/** @brief Get the allocation bit of a block from either metaroot. + + @param bMR The metaroot index: either 0 or 1. + @param ulBlock The block number to query. + @param pfAllocated On successful return, populated with the allocation bit + of the block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bMR is out of range; or @p ulBlock is out of range; + or @p pfAllocated is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapIBlockGet( + uint8_t bMR, + uint32_t ulBlock, + bool *pfAllocated) +{ + REDSTATUS ret; + + if( (!gpRedCoreVol->fImapInline) + || (bMR > 1U) + || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount) + || (pfAllocated == NULL)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + *pfAllocated = RedBitGet(gpRedCoreVol->aMR[bMR].abEntries, ulBlock - gpRedCoreVol->ulInodeTableStartBN); + ret = 0; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Set the allocation bit of a block in the working metaroot. + + @param ulBlock The block number to allocate or free. + @param fAllocated Whether to allocate the block (true) or free it (false). + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulBlock is out of range. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedImapIBlockSet( + uint32_t ulBlock, + bool fAllocated) +{ + REDSTATUS ret; + + if( (!gpRedCoreVol->fImapInline) + || (ulBlock < gpRedCoreVol->ulInodeTableStartBN) + || (ulBlock >= gpRedVolume->ulBlockCount)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulOffset = ulBlock - gpRedCoreVol->ulInodeTableStartBN; + + if(RedBitGet(gpRedMR->abEntries, ulOffset) == fAllocated) + { + /* The driver shouldn't ever set a bit in the imap to its current + value. This is more of a problem with the external imap, but it + is checked here for consistency. + */ + CRITICAL_ERROR(); + ret = -RED_EINVAL; + } + else if(fAllocated) + { + RedBitSet(gpRedMR->abEntries, ulOffset); + ret = 0; + } + else + { + RedBitClear(gpRedMR->abEntries, ulOffset); + ret = 0; + } + } + + return ret; +} +#endif + +#endif /* REDCONF_IMAP_INLINE == 1 */ + diff --git a/core/driver/inode.c b/core/driver/inode.c new file mode 100644 index 0000000..aa03ebe --- /dev/null +++ b/core/driver/inode.c @@ -0,0 +1,1093 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements inode functions. +*/ +#include +#include +#include + + +#if REDCONF_READ_ONLY == 0 +static REDSTATUS InodeIsWriteable(uint32_t ulInode, bool *pfIsWriteable); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +static REDSTATUS InodeFindFree(uint32_t *pulInode); +#endif +#if REDCONF_READ_ONLY == 0 +static REDSTATUS InodeGetWriteableCopy(uint32_t ulInode, uint8_t *pbWhich); +#endif +static REDSTATUS InodeGetCurrentCopy(uint32_t ulInode, uint8_t *pbWhich); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS InodeBitSet(uint32_t ulInode, uint8_t bWhich, bool fAllocated); +#endif +static uint32_t InodeBlock(uint32_t ulInode, uint8_t bWhich); + + +/** @brief Mount an existing inode. + + Will populate all fields of the cached inode structure, except those which + are populated during seek. + + @param pInode A pointer to the cached inode structure. The + pInode->ulInode field must already be initialized with the + inode number to mount. All other fields will be discarded. + @param type The expected inode type. + @param fBranch Whether to branch the inode. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pInode is `NULL`. + @retval -RED_EROFS @p fBranch is true but the driver is read-only. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EBADF The inode number is free; or the inode number is not + valid. + @retval -RED_EISDIR @p type is ::FTYPE_FILE and the inode is a directory. + @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the inode is a file. +*/ +REDSTATUS RedInodeMount( + CINODE *pInode, + FTYPE type, + bool fBranch) +{ + REDSTATUS ret = 0; + + if(pInode == NULL) + { + ret = -RED_EINVAL; + } + else if(!INODE_IS_VALID(pInode->ulInode)) + { + ret = -RED_EBADF; + } + #if REDCONF_READ_ONLY == 1 + else if(fBranch) + { + REDERROR(); + ret = -RED_EROFS; + } + #endif + else + { + uint32_t ulInode = pInode->ulInode; + uint8_t bWhich; + + RedMemSet(pInode, 0U, sizeof(*pInode)); + pInode->ulInode = ulInode; + + ret = InodeGetCurrentCopy(pInode->ulInode, &bWhich); + + if(ret == 0) + { + ret = RedBufferGet(InodeBlock(pInode->ulInode, bWhich), BFLAG_META_INODE, CAST_VOID_PTR_PTR(&pInode->pBuffer)); + } + + #if REDCONF_READ_ONLY == 0 + if(ret == 0) + { + ret = InodeIsWriteable(pInode->ulInode, &pInode->fWriteable); + } + #endif + + if(ret == 0) + { + if(RED_S_ISDIR(pInode->pBuffer->uMode)) + { + pInode->fDirectory = true; + + if(type == FTYPE_FILE) + { + ret = -RED_EISDIR; + } + } + else + { + pInode->fDirectory = false; + + if(type == FTYPE_DIR) + { + ret = -RED_ENOTDIR; + } + } + } + + #if REDCONF_READ_ONLY == 0 + if((ret == 0) && fBranch) + { + ret = RedInodeBranch(pInode); + } + #endif + + if(ret != 0) + { + RedInodePut(pInode, 0U); + } + } + + return ret; +} + + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1)) +/** @brief Create an inode. + + @param pInode Pointer to the cached inode structure. If pInode->ulInode + is #INODE_INVALID, a free inode will be found; otherwise, + pInode->ulInode will be the inode number (an error will be + returned if it is not free). + @param ulPInode The parent inode number. + @param uMode The inode mode. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF pInode->ulInode is an invalid inode number other than + #INODE_INVALID. + @retval -RED_EINVAL @p pInode is `NULL`. + @retval -RED_EEXIST Tried to create an inode with an inode number that is + already in use. + @retval -RED_ENFILE All inode slots are already in use. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeCreate( + CINODE *pInode, + uint32_t ulPInode, + uint16_t uMode) +{ + REDSTATUS ret; + + if(pInode == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + uint32_t ulInode = pInode->ulInode; + + RedMemSet(pInode, 0U, sizeof(*pInode)); + + #if REDCONF_API_POSIX == 1 + if(ulInode == INODE_INVALID) + { + /* Caller requested that an inode number be allocated. Search for + an unused inode number, error if there isn't one. + */ + ret = InodeFindFree(&pInode->ulInode); + } + else + #endif + { + /* Caller requested creation of a specific inode number. Make sure + it's valid and doesn't already exist. + */ + if(INODE_IS_VALID(ulInode)) + { + bool fFree; + + ret = RedInodeIsFree(ulInode, &fFree); + if(ret == 0) + { + if(fFree) + { + pInode->ulInode = ulInode; + } + else + { + ret = -RED_EEXIST; + } + } + } + else + { + ret = -RED_EBADF; + } + } + + if(ret == 0) + { + uint8_t bWriteableWhich; + + ret = InodeGetWriteableCopy(pInode->ulInode, &bWriteableWhich); + + if(ret == 0) + { + ret = RedBufferGet(InodeBlock(pInode->ulInode, bWriteableWhich), + (uint16_t)((uint32_t)BFLAG_META_INODE | BFLAG_DIRTY | BFLAG_NEW), CAST_VOID_PTR_PTR(&pInode->pBuffer)); + + if(ret == 0) + { + /* Mark the inode block as allocated. + */ + ret = InodeBitSet(pInode->ulInode, bWriteableWhich, true); + + if(ret != 0) + { + RedBufferPut(pInode->pBuffer); + } + } + } + } + + if(ret == 0) + { + #if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t ulNow = RedOsClockGetTime(); + + pInode->pBuffer->ulATime = ulNow; + pInode->pBuffer->ulMTime = ulNow; + pInode->pBuffer->ulCTime = ulNow; + #endif + + pInode->pBuffer->uMode = uMode; + + #if REDCONF_API_POSIX == 1 + #if REDCONF_API_POSIX_LINK == 1 + pInode->pBuffer->uNLink = 1U; + #endif + pInode->pBuffer->ulPInode = ulPInode; + #else + (void)ulPInode; + #endif + + pInode->fWriteable = true; + pInode->fDirty = true; + + #if REDCONF_API_POSIX == 1 + gpRedMR->ulFreeInodes--; + #endif + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1)) */ + + +#if DELETE_SUPPORTED +/** @brief Delete an inode. + + @param pInode Pointer to the cached inode structure. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF The inode is free. + @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeDelete( + CINODE *pInode) +{ + REDSTATUS ret = 0; + + if((pInode == NULL) || (pInode->pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + if(pInode->pBuffer->ullSize != 0U) + { + ret = RedInodeDataTruncate(pInode, 0ULL); + } + + if(ret == 0) + { + ret = RedInodeFree(pInode); + } + } + + return ret; +} + + +/** @brief Decrement an inode link count and delete the inode if the link count + falls to zero. + + @param pInode A pointer to the cached inode structure. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pInode is not a mounted cachde inode. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeLinkDec( + CINODE *pInode) +{ + REDSTATUS ret; + + if((pInode == NULL) || (pInode->pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + #if REDCONF_API_POSIX_LINK == 1 + else if(pInode->pBuffer->uNLink > 1U) + { + ret = RedInodeBranch(pInode); + + if(ret == 0) + { + pInode->pBuffer->uNLink--; + } + } + #endif + else + { + ret = RedInodeDelete(pInode); + } + + return ret; +} +#endif /* DELETE_SUPPORTED */ + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +/** @brief Free an inode. + + @param pInode Pointer to the cached inode structure. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF The inode is free. + @retval -RED_EINVAL @p pInode is `NULL`; or pInode->pBuffer is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeFree( + CINODE *pInode) +{ + REDSTATUS ret; + + if((pInode == NULL) || (pInode->pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + RedBufferDiscard(pInode->pBuffer); + pInode->pBuffer = NULL; + + /* Determine which of the two slots for the inode is currently + allocated, and free that slot. + */ + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 0U, &fSlot0Allocated); + + if(ret == 0) + { + bool fSlot1Allocated; + + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, pInode->ulInode, 1U, &fSlot1Allocated); + + if(ret == 0) + { + if(fSlot0Allocated) + { + if(fSlot1Allocated) + { + /* Both inode slots should never be allocated at + the same time. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + ret = InodeBitSet(pInode->ulInode, 0U, false); + } + } + else + { + if(!fSlot1Allocated) + { + /* The inode in unallocated, which should have been + caught when it was mounted. + */ + CRITICAL_ERROR(); + ret = -RED_EBADF; + } + else + { + ret = InodeBitSet(pInode->ulInode, 1U, false); + } + } + } + } + + pInode->ulInode = INODE_INVALID; + + if(ret == 0) + { + if(gpRedMR->ulFreeInodes >= gpRedVolConf->ulInodeCount) + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + gpRedMR->ulFreeInodes++; + } + } + } + + return ret; +} +#endif /* (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) */ + + +/** @brief Put the cached inode structure. + + This puts all of the buffers in the ::CINODE structure. Also updates inode + timestamp fields if requested. + + @param pInode The cached inode structure. + @param bTimeFields The inode timestamp fields to update. +*/ +void RedInodePut( + CINODE *pInode, + uint8_t bTimeFields) +{ + if(pInode == NULL) + { + REDERROR(); + } + else + { + RedInodePutCoord(pInode); + + if(pInode->pBuffer != NULL) + { + #if (REDCONF_READ_ONLY == 0) && (REDCONF_INODE_TIMESTAMPS == 1) + if((bTimeFields & IPUT_UPDATE_MASK) != 0U) + { + if(!pInode->fWriteable || !pInode->fDirty) + { + REDERROR(); + } + else + { + uint32_t ulNow = RedOsClockGetTime(); + + #if REDCONF_ATIME == 1 + if((bTimeFields & IPUT_UPDATE_ATIME) != 0U) + { + pInode->pBuffer->ulATime = ulNow; + } + #endif + + if((bTimeFields & IPUT_UPDATE_MTIME) != 0U) + { + pInode->pBuffer->ulMTime = ulNow; + } + + if((bTimeFields & IPUT_UPDATE_CTIME) != 0U) + { + pInode->pBuffer->ulCTime = ulNow; + } + } + } + + pInode->fDirty = false; + #else + (void)bTimeFields; + #endif + + RedBufferPut(pInode->pBuffer); + pInode->pBuffer = NULL; + } + } +} + + +/** @brief Put all inode buffers except for the inode buffer. + + @param pInode A pointer to the cached inode structure. +*/ +void RedInodePutCoord( + CINODE *pInode) +{ + if(pInode == NULL) + { + REDERROR(); + } + else + { + RedInodePutData(pInode); + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + RedInodePutIndir(pInode); + #endif + #if DINDIR_POINTERS > 0U + RedInodePutDindir(pInode); + #endif + } +} + + +#if DINDIR_POINTERS > 0U +/** @brief Put the double indirect buffer. + + @param pInode A pointer to the cached inode structure. +*/ +void RedInodePutDindir( + CINODE *pInode) +{ + if(pInode == NULL) + { + REDERROR(); + } + else if(pInode->pDindir != NULL) + { + RedBufferPut(pInode->pDindir); + pInode->pDindir = NULL; + } + else + { + /* No double indirect buffer, nothing to put. + */ + } +} +#endif + + +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES +/** @brief Put the indirect buffer. + + @param pInode A pointer to the cached inode structure. +*/ +void RedInodePutIndir( + CINODE *pInode) +{ + if(pInode == NULL) + { + REDERROR(); + } + else if(pInode->pIndir != NULL) + { + RedBufferPut(pInode->pIndir); + pInode->pIndir = NULL; + } + else + { + /* No indirect buffer, nothing to put. + */ + } +} +#endif + + +/** @brief Put the inode data buffer. + + @param pInode A pointer to the cached inode structure. +*/ +void RedInodePutData( + CINODE *pInode) +{ + if(pInode == NULL) + { + REDERROR(); + } + else if(pInode->pbData != NULL) + { + RedBufferPut(pInode->pbData); + pInode->pbData = NULL; + } + else + { + /* No data buffer, nothing to put. + */ + } +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Determine if an inode is writeable. + + @param ulInode The inode number to examine. + @param pfIsWriteable On successful return, populated with whether the + inode is writeable. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pInode is `NULL`; or @p ulInode is not a valid inode + number. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS InodeIsWriteable( + uint32_t ulInode, + bool *pfIsWriteable) +{ + REDSTATUS ret; + + if((pfIsWriteable == NULL) || !INODE_IS_VALID(ulInode)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ALLOCSTATE state; + + ret = RedImapBlockState(InodeBlock(ulInode, 0U), &state); + + if(ret == 0) + { + if(state == ALLOCSTATE_NEW) + { + *pfIsWriteable = true; + } + else + { + ret = RedImapBlockState(InodeBlock(ulInode, 1U), &state); + + if(ret == 0) + { + if(state == ALLOCSTATE_NEW) + { + *pfIsWriteable = true; + } + else + { + *pfIsWriteable = false; + } + } + } + } + } + + return ret; +} + + +/** @brief Branch an inode. + + A branched inode is one in which the allocation state for one copy is free + or almost free, and the other copy is in the new state. The copy which is + in the new state is the writeable copy, which is also buffered and dirty. + + @param pInode Pointer to the cached inode structure which has already been + mounted. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pInode is `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeBranch( + CINODE *pInode) +{ + REDSTATUS ret; + + if(pInode == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if(!pInode->fWriteable) + { + uint8_t bWhich; + + ret = InodeGetWriteableCopy(pInode->ulInode, &bWhich); + + if(ret == 0) + { + RedBufferBranch(pInode->pBuffer, InodeBlock(pInode->ulInode, bWhich)); + pInode->fWriteable = true; + pInode->fDirty = true; + } + + /* Toggle the inode slots: the old slot block becomes almost free + (still used by the committed state) and the new slot block becomes + new. + */ + if(ret == 0) + { + ret = InodeBitSet(pInode->ulInode, 1U - bWhich, false); + } + + if(ret == 0) + { + ret = InodeBitSet(pInode->ulInode, bWhich, true); + } + + CRITICAL_ASSERT(ret == 0); + } + else + { + RedBufferDirty(pInode->pBuffer); + pInode->fDirty = true; + ret = 0; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +/** @brief Find a free inode number. + + @param pulInode On successful return, populated with a free inode number. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pulInode is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENFILE No available inode numbers. +*/ +static REDSTATUS InodeFindFree( + uint32_t *pulInode) +{ + REDSTATUS ret; + + if(pulInode == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else if(gpRedMR->ulFreeInodes == 0U) + { + ret = -RED_ENFILE; + } + else + { + uint32_t ulInode; + + ret = 0; + + for(ulInode = INODE_FIRST_FREE; ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount); ulInode++) + { + bool fFree; + + ret = RedInodeIsFree(ulInode, &fFree); + + if((ret != 0) || fFree) + { + break; + } + } + + if(ret == 0) + { + if(ulInode < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount)) + { + *pulInode = ulInode; + } + else + { + /* If gpRedMR->ulFreeInodes > 0, we should have found an inode. + */ + CRITICAL_ERROR(); + ret = -RED_ENFILE; + } + } + } + + return ret; +} +#endif + + +#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1))) || (REDCONF_CHECKER == 1) +/** @brief Determine whether an inode number is available. + + @param ulInode The node number to examine. + @param pfFree On successful return, populated with whether the inode + number is available (true) or in use (false). + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pfFree is `NULL`; or @p ulInode is not a valid inode + number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeIsFree( + uint32_t ulInode, + bool *pfFree) +{ + REDSTATUS ret; + + if(pfFree == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + *pfFree = false; + + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); + if((ret == 0) && !fSlot0Allocated) + { + bool fSlot1Allocated; + + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); + if((ret == 0) && !fSlot1Allocated) + { + *pfFree = true; + } + } + } + + return ret; +} +#endif + + +#if REDCONF_READ_ONLY == 0 +/** @brief Determine which copy of the inode is currently writeable. + + @param ulInode The inode number to examine. + @param pbWhich On successful return, populated with which copy of the inode + (either 0 or 1) is writeable. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode + number. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS InodeGetWriteableCopy( + uint32_t ulInode, + uint8_t *pbWhich) +{ + REDSTATUS ret; + + if(pbWhich == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + /* The writeable inode slot is the one which is free in the committed + state, so look query the committed state metaroot. + */ + ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); + + if(ret == 0) + { + if(!fSlot0Allocated) + { + *pbWhich = 0U; + } + else + { + bool fSlot1Allocated; + + ret = RedInodeBitGet(1U - gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); + + if(ret == 0) + { + if(!fSlot1Allocated) + { + *pbWhich = 1U; + } + else + { + /* Both inode slots were allocated, which should never + happen. + */ + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + } + } + } + + return ret; +} +#endif + + +/** @brief Determine which copy of the inode is current. + + @param ulInode The inode number to examine. + @param pbWhich On successful return, populated with which copy of the inode + (either 0 or 1) is current. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pbWhich is `NULL`; or ulInode is not a valid inode + number. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS InodeGetCurrentCopy( + uint32_t ulInode, + uint8_t *pbWhich) +{ + REDSTATUS ret; + + if(pbWhich == NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + bool fSlot0Allocated; + + /* The current inode slot is the one which is allocated in the working + state metaroot. + */ + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 0U, &fSlot0Allocated); + if(ret == 0) + { + if(fSlot0Allocated) + { + *pbWhich = 0U; + } + else + { + bool fSlot1Allocated; + + ret = RedInodeBitGet(gpRedCoreVol->bCurMR, ulInode, 1U, &fSlot1Allocated); + if(ret == 0) + { + if(fSlot1Allocated) + { + *pbWhich = 1U; + } + else + { + /* Neither slot for this inode was allocated, so the + inode is actually free. + */ + ret = -RED_EBADF; + } + } + } + } + } + + return ret; +} + + +/** @brief Get whether a copy of an inode is allocated. + + @param ulInode The inode number. + @param bWhich Which copy of the inode to set. + @param pfAllocated On successful return, populated with whether the given + copy of the inode is allocated. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bMR is not 1 or 0; @p ulInode is not a valid inode + number; or @p bWhich is not 1 or 0; or @p pfAllocated is + `NULL`. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeBitGet( + uint8_t bMR, + uint32_t ulInode, + uint8_t bWhich, + bool *pfAllocated) +{ + REDSTATUS ret; + + if(!INODE_IS_VALID(ulInode) || (bWhich > 1U)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedImapBlockGet(bMR, InodeBlock(ulInode, bWhich), pfAllocated); + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Set whether a copy of an inode is allocated. + + @param ulInode The inode number. + @param bWhich Which copy of the inode to set. + @param fAllocated If true, the inode is set to allocated; if false, the + inode is set to free. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p ulInode is not a valid inode number; or @p bWhich is + not 1 or 0. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS InodeBitSet( + uint32_t ulInode, + uint8_t bWhich, + bool fAllocated) +{ + REDSTATUS ret; + + if(!INODE_IS_VALID(ulInode) || (bWhich > 1U)) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedImapBlockSet(InodeBlock(ulInode, bWhich), fAllocated); + } + + return ret; +} +#endif + + +/** @brief Determine the block number of an inode. + + @param ulInode The inode number. + @param bWhich Which copy of the inode. + + @return The block number of the inode. +*/ +static uint32_t InodeBlock( + uint32_t ulInode, + uint8_t bWhich) +{ + REDASSERT(INODE_IS_VALID(ulInode)); + REDASSERT(bWhich <= 1U); + + return gpRedCoreVol->ulInodeTableStartBN + ((ulInode - INODE_FIRST_VALID) * 2U) + bWhich; +} + diff --git a/core/driver/inodedata.c b/core/driver/inodedata.c new file mode 100644 index 0000000..df0fd11 --- /dev/null +++ b/core/driver/inodedata.c @@ -0,0 +1,1692 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements inode I/O functions. +*/ +#include +#include +#include + + +#define COORD_ENTRY_INVALID (UINT16_MAX) + +#define BRANCHDEPTH_DINDIR (0U) +#define BRANCHDEPTH_INDIR (1U) +#define BRANCHDEPTH_FILE_DATA (2U) + + +#if REDCONF_READ_ONLY == 0 +#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED +static REDSTATUS Shrink(CINODE *pInode, uint64_t ullSize); +#if DINDIR_POINTERS > 0U +static REDSTATUS TruncDindir(CINODE *pInode, bool *pfFreed); +#endif +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES +static REDSTATUS TruncIndir(CINODE *pInode, bool *pfFreed); +#endif +static REDSTATUS TruncDataBlock(CINODE *pInode, uint32_t *pulBlock, bool fPropagate); +#endif +static REDSTATUS ExpandPrepare(CINODE *pInode); +#endif +static void SeekCoord(CINODE *pInode, uint32_t ulBlock); +static REDSTATUS ReadUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, uint8_t *pbBuffer); +static REDSTATUS ReadAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t ulBlockCount, uint8_t *pbBuffer); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS WriteUnaligned(CINODE *pInode, uint64_t ullStart, uint32_t ulLen, const uint8_t *pbBuffer); +static REDSTATUS WriteAligned(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulBlockCount, const uint8_t *pbBuffer); +#endif +static REDSTATUS GetExtent(CINODE *pInode, uint32_t ulBlockStart, uint32_t *pulExtentStart, uint32_t *pulExtentLen); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS BranchBlock(CINODE *pInode, uint8_t bDepth, bool fBuffer); +static REDSTATUS BranchOneBlock(uint32_t *pulBlock, void **ppBuffer, uint16_t uBFlag); +static REDSTATUS BranchBlockCost(const CINODE *pInode, uint8_t bDepth, uint32_t *pulCost); +static uint32_t FreeBlockCount(void); +#endif + + +/** @brief Read data from an inode. + + @param pInode A pointer to the cached inode structure of the inode from + which to read. + @param ullStart The file offset at which to read. + @param pulLen On input, the number of bytes to attempt to read. On + successful return, populated with the number of bytes + actually read. + @param pBuffer The buffer to read into. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or + @p pulLen is `NULL`; or @p pBuffer is `NULL`. +*/ +REDSTATUS RedInodeDataRead( + CINODE *pInode, + uint64_t ullStart, + uint32_t *pulLen, + void *pBuffer) +{ + REDSTATUS ret = 0; + + if((pInode == NULL) || (pInode->pBuffer == NULL) || (pulLen == NULL) || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else if(ullStart >= pInode->pBuffer->ullSize) + { + *pulLen = 0U; + } + else if(*pulLen == 0U) + { + /* Do nothing, just return success. + */ + } + else + { + uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); + uint32_t ulReadIndex = 0U; + uint32_t ulLen = *pulLen; + uint32_t ulRemaining; + + if((pInode->pBuffer->ullSize - ullStart) < ulLen) + { + ulLen = (uint32_t)(pInode->pBuffer->ullSize - ullStart); + } + + ulRemaining = ulLen; + + /* Partial block at start. + */ + if(((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U) || (ulRemaining < REDCONF_BLOCK_SIZE)) + { + uint32_t ulThisRead = REDMIN(ulRemaining, REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U))); + + ret = ReadUnaligned(pInode, ullStart, ulThisRead, pbBuffer); + + if(ret == 0) + { + ulReadIndex += ulThisRead; + ulRemaining -= ulThisRead; + } + } + + /* Whole blocks. + */ + if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE)) + { + uint32_t ulBlockOffset = (uint32_t)((ullStart + ulReadIndex) >> BLOCK_SIZE_P2); + uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; + + REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); + + ret = ReadAligned(pInode, ulBlockOffset, ulBlockCount, &pbBuffer[ulReadIndex]); + + if(ret == 0) + { + ulReadIndex += ulBlockCount << BLOCK_SIZE_P2; + ulRemaining -= ulBlockCount << BLOCK_SIZE_P2; + } + } + + /* Partial block at end. + */ + if((ret == 0) && (ulRemaining > 0U)) + { + REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE); + REDASSERT(((ullStart + ulReadIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); + + ret = ReadUnaligned(pInode, ullStart + ulReadIndex, ulRemaining, &pbBuffer[ulReadIndex]); + } + + if(ret == 0) + { + *pulLen = ulLen; + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write to an inode. + + @param pInode A pointer to the cached inode structure of the inode into + which to write. + @param ullStart The file offset at which to write. + @param pulLen On input, the number of bytes to attempt to write. On + successful return, populated with the number of bytes + actually written. + @param pBuffer The buffer to write from. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EFBIG @p ullStart is greater than the maximum file size; or + @p ullStart is equal to the maximum file size and the + write length is non-zero. + @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer; or + @p pulLen is `NULL`; or @p pBuffer is `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. +*/ +REDSTATUS RedInodeDataWrite( + CINODE *pInode, + uint64_t ullStart, + uint32_t *pulLen, + const void *pBuffer) +{ + REDSTATUS ret = 0; + + if((pInode == NULL) || (pInode->pBuffer == NULL) || (pulLen == NULL) || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else if((ullStart > INODE_SIZE_MAX) || ((ullStart == INODE_SIZE_MAX) && (*pulLen > 0U))) + { + ret = -RED_EFBIG; + } + else if(*pulLen == 0U) + { + /* Do nothing, just return success. + */ + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + uint32_t ulWriteIndex = 0U; + uint32_t ulLen = *pulLen; + uint32_t ulRemaining; + + if((INODE_SIZE_MAX - ullStart) < ulLen) + { + ulLen = (uint32_t)(INODE_SIZE_MAX - ullStart); + } + + ulRemaining = ulLen; + + /* If the write is beyond the current end of the file, and the current + end of the file is not block-aligned, then there may be some data + that needs to be zeroed in the last block. + */ + if((ullStart > pInode->pBuffer->ullSize) && ((pInode->pBuffer->ullSize & (REDCONF_BLOCK_SIZE - 1U)) != 0U)) + { + ret = ExpandPrepare(pInode); + } + + /* Partial block at start. + */ + if((ret == 0) && (((ullStart & (REDCONF_BLOCK_SIZE - 1U)) != 0U) || (ulRemaining < REDCONF_BLOCK_SIZE))) + { + uint32_t ulThisWrite = REDMIN(ulRemaining, REDCONF_BLOCK_SIZE - (uint32_t)(ullStart & (REDCONF_BLOCK_SIZE - 1U))); + + ret = WriteUnaligned(pInode, ullStart, ulThisWrite, pbBuffer); + + if(ret == 0) + { + ulWriteIndex += ulThisWrite; + ulRemaining -= ulThisWrite; + } + } + + /* Whole blocks. + */ + if((ret == 0) && (ulRemaining >= REDCONF_BLOCK_SIZE)) + { + uint32_t ulBlockOffset = (uint32_t)((ullStart + ulWriteIndex) >> BLOCK_SIZE_P2); + uint32_t ulBlockCount = ulRemaining >> BLOCK_SIZE_P2; + uint32_t ulBlocksWritten = ulBlockCount; + + REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); + + ret = WriteAligned(pInode, ulBlockOffset, &ulBlocksWritten, &pbBuffer[ulWriteIndex]); + + if((ret == -RED_ENOSPC) && (ulWriteIndex > 0U)) + { + ulBlocksWritten = 0U; + ret = 0; + } + + if(ret == 0) + { + ulWriteIndex += ulBlocksWritten << BLOCK_SIZE_P2; + ulRemaining -= ulBlocksWritten << BLOCK_SIZE_P2; + + if(ulBlocksWritten < ulBlockCount) + { + ulRemaining = 0U; + } + } + } + + /* Partial block at end. + */ + if((ret == 0) && (ulRemaining > 0U)) + { + REDASSERT(ulRemaining < REDCONF_BLOCK_SIZE); + REDASSERT(((ullStart + ulWriteIndex) & (REDCONF_BLOCK_SIZE - 1U)) == 0U); + REDASSERT(ulWriteIndex > 0U); + + ret = WriteUnaligned(pInode, ullStart + ulWriteIndex, ulRemaining, &pbBuffer[ulWriteIndex]); + + if(ret == -RED_ENOSPC) + { + ret = 0; + } + else if(ret == 0) + { + ulWriteIndex += ulRemaining; + + REDASSERT(ulWriteIndex == *pulLen); + } + else + { + /* Unexpected error, return it. + */ + } + } + + if(ret == 0) + { + *pulLen = ulWriteIndex; + + if((ullStart + ulWriteIndex) > pInode->pBuffer->ullSize) + { + pInode->pBuffer->ullSize = ullStart + ulWriteIndex; + } + } + } + + return ret; +} + + +#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED +/** @brief Change the size of an inode. + + @param pInode A pointer to the cached inode structure. + @praam ullSize The new file size for the inode. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EFBIG @p ullSize is greater than the maximum file size. + @retval -RED_EINVAL @p pInode is not a mounted cached inode pointer. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. +*/ +REDSTATUS RedInodeDataTruncate( + CINODE *pInode, + uint64_t ullSize) +{ + REDSTATUS ret = 0; + + if((pInode == NULL) || (pInode->pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else if(ullSize > INODE_SIZE_MAX) + { + ret = -RED_EFBIG; + } + else + { + if(ullSize > pInode->pBuffer->ullSize) + { + ret = ExpandPrepare(pInode); + } + else if(ullSize < pInode->pBuffer->ullSize) + { + ret = Shrink(pInode, ullSize); + } + else + { + /* Size is staying the same, nothing to do. + */ + } + + if(ret == 0) + { + pInode->pBuffer->ullSize = ullSize; + } + } + + return ret; +} + + +/** @brief Free all file data beyond a specified point. + + @param pInode A pointer to the cached inode structure. + @param ullSize The point beyond which to free all file data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. +*/ +static REDSTATUS Shrink( + CINODE *pInode, + uint64_t ullSize) +{ + uint32_t ulTruncBlock = (uint32_t)((ullSize + REDCONF_BLOCK_SIZE - 1U) >> BLOCK_SIZE_P2); + REDSTATUS ret = 0; + + RedInodePutData(pInode); + + #if REDCONF_DIRECT_POINTERS > 0U + while(ulTruncBlock < REDCONF_DIRECT_POINTERS) + { + ret = TruncDataBlock(pInode, &pInode->pBuffer->aulEntries[ulTruncBlock], true); + + if(ret != 0) + { + break; + } + + ulTruncBlock++; + } + #endif + + #if REDCONF_INDIRECT_POINTERS > 0U + while((ret == 0) && (ulTruncBlock < (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS))) + { + ret = RedInodeDataSeek(pInode, ulTruncBlock); + + if((ret == 0) || (ret == -RED_ENODATA)) + { + bool fFreed; + + ret = TruncIndir(pInode, &fFreed); + + if(ret == 0) + { + if(fFreed) + { + pInode->pBuffer->aulEntries[pInode->uInodeEntry] = BLOCK_SPARSE; + } + + /* The next seek will go to the beginning of the next + indirect. + */ + ulTruncBlock += (INDIR_ENTRIES - pInode->uIndirEntry); + } + } + } + #endif + + #if DINDIR_POINTERS > 0U + while((ret == 0) && (ulTruncBlock < INODE_DATA_BLOCKS)) + { + ret = RedInodeDataSeek(pInode, ulTruncBlock); + + if((ret == 0) || (ret == -RED_ENODATA)) + { + bool fFreed; + + /* TruncDindir() invokes seek as it goes along, which will + update the entry values (possibly all three of these); + make a copy so we can compute things correctly after. + */ + uint16_t uOrigInodeEntry = pInode->uInodeEntry; + uint16_t uOrigDindirEntry = pInode->uDindirEntry; + uint16_t uOrigIndirEntry = pInode->uIndirEntry; + + ret = TruncDindir(pInode, &fFreed); + + if(ret == 0) + { + if(fFreed) + { + pInode->pBuffer->aulEntries[uOrigInodeEntry] = BLOCK_SPARSE; + } + + /* The next seek will go to the beginning of the next + double indirect. + */ + ulTruncBlock += (DINDIR_DATA_BLOCKS - (uOrigDindirEntry * INDIR_ENTRIES)) - uOrigIndirEntry; + } + } + } + #endif + + return ret; +} + + +#if DINDIR_POINTERS > 0U +/** @brief Truncate a double indirect. + + @param pInode A pointer to the cached inode, whose coordinates indicate + the truncation boundary. + @param pfFreed On successful return, populated with whether the double + indirect node was freed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. +*/ +static REDSTATUS TruncDindir( + CINODE *pInode, + bool *pfFreed) +{ + REDSTATUS ret = 0; + + if(pInode->pDindir == NULL) + { + *pfFreed = false; + } + else + { + bool fBranch = false; + uint16_t uEntry; + + /* The double indirect is definitely going to be branched (instead of + deleted) if any of its indirect pointers which are entirely prior to + the truncation boundary are non-sparse. + */ + for(uEntry = 0U; !fBranch && (uEntry < pInode->uDindirEntry); uEntry++) + { + fBranch = pInode->pDindir->aulEntries[uEntry] != BLOCK_SPARSE; + } + + /* Unless we already know for a fact that the double indirect is going + to be branched, examine the contents of the indirect pointer which + straddles the truncation boundary. If the indirect is going to be + deleted, we know this indirect pointer is going away, and that might + mean the double indirect is going to be deleted also. + */ + if(!fBranch && (pInode->pDindir->aulEntries[pInode->uDindirEntry] != BLOCK_SPARSE)) + { + for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++) + { + fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE; + } + } + + if(fBranch) + { + ret = BranchBlock(pInode, BRANCHDEPTH_DINDIR, false); + } + + if(ret == 0) + { + uint32_t ulBlock = pInode->ulLogicalBlock; + uint16_t uStart = pInode->uDindirEntry; /* pInode->uDindirEntry will change. */ + + for(uEntry = uStart; uEntry < INDIR_ENTRIES; uEntry++) + { + /* Seek so that TruncIndir() has the correct indirect + buffer and indirect entry. + */ + ret = RedInodeDataSeek(pInode, ulBlock); + + if(ret == -RED_ENODATA) + { + ret = 0; + } + + if((ret == 0) && (pInode->ulIndirBlock != BLOCK_SPARSE)) + { + bool fIndirFreed; + + ret = TruncIndir(pInode, &fIndirFreed); + + if(ret == 0) + { + /* All of the indirects after the one which straddles + the truncation boundary should definitely end up + deleted. + */ + REDASSERT((uEntry == uStart) || fIndirFreed); + + /* If the double indirect is being freed, all of the + indirects should be freed too. + */ + REDASSERT(fIndirFreed || fBranch); + + if(fBranch && fIndirFreed) + { + pInode->pDindir->aulEntries[uEntry] = BLOCK_SPARSE; + } + } + } + + if(ret != 0) + { + break; + } + + ulBlock += (INDIR_ENTRIES - pInode->uIndirEntry); + } + + if(ret == 0) + { + *pfFreed = !fBranch; + + if(!fBranch) + { + RedInodePutDindir(pInode); + + ret = RedImapBlockSet(pInode->ulDindirBlock, false); + } + } + } + } + + return ret; +} +#endif /* DINDIR_POINTERS > 0U */ + + +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES +/** @brief Truncate a indirect. + + @param pInode A pointer to the cached inode, whose coordinates indicate + the truncation boundary. + @param pfFreed On successful return, populated with whether the indirect + node was freed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. +*/ +static REDSTATUS TruncIndir( + CINODE *pInode, + bool *pfFreed) +{ + REDSTATUS ret = 0; + + if(pInode->pIndir == NULL) + { + *pfFreed = false; + } + else + { + bool fBranch = false; + uint16_t uEntry; + + /* Scan the range of entries which are not being truncated. If there + is anything there, then the indirect will not be empty after the + truncate, so it is branched and modified instead of deleted. + */ + for(uEntry = 0U; !fBranch && (uEntry < pInode->uIndirEntry); uEntry++) + { + fBranch = pInode->pIndir->aulEntries[uEntry] != BLOCK_SPARSE; + } + + if(fBranch) + { + ret = BranchBlock(pInode, BRANCHDEPTH_INDIR, false); + } + + if(ret == 0) + { + for(uEntry = pInode->uIndirEntry; uEntry < INDIR_ENTRIES; uEntry++) + { + ret = TruncDataBlock(pInode, &pInode->pIndir->aulEntries[uEntry], fBranch); + + if(ret != 0) + { + break; + } + } + + if(ret == 0) + { + *pfFreed = !fBranch; + + if(!fBranch) + { + RedInodePutIndir(pInode); + + ret = RedImapBlockSet(pInode->ulIndirBlock, false); + } + } + } + } + + return ret; +} +#endif /* REDCONF_DIRECT_POINTERS < INODE_ENTRIES */ + + +/** @brief Truncate a file data block. + + @param pInode A pointer to the cached inode structure. + @param pulBlock On entry, contains the block to be truncated. On + successful return, if @p fPropagate is true, populated + with BLOCK_SPARSE, otherwise unmodified. + @param fPropagate Whether the parent node is being branched. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS TruncDataBlock( + CINODE *pInode, + uint32_t *pulBlock, + bool fPropagate) +{ + REDSTATUS ret = 0; + + (void)pInode; /* Unused when REDCONF_INODE_BLOCKS == 0. */ + + if(*pulBlock != BLOCK_SPARSE) + { + ret = RedImapBlockSet(*pulBlock, false); + + #if REDCONF_INODE_BLOCKS == 1 + if(ret == 0) + { + if(pInode->pBuffer->ulBlocks == 0U) + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + else + { + pInode->pBuffer->ulBlocks--; + } + } + #endif + + if((ret == 0) && fPropagate) + { + *pulBlock = BLOCK_SPARSE; + } + } + + return ret; +} +#endif /* DELETE_SUPPORTED || TRUNCATE_SUPPORTED */ + + +/** @brief Prepare to increase the file size. + + When the inode size is increased, a sparse region is created. It is + possible that a prior shrink operation to an unaligned size left stale data + beyond the end of the file in the last data block. That data is not zeroed + while shrinking the inode in order to transfer the disk full burden from the + shrink operation to the expand operation. + + @param pInode A pointer to the cached inode structure. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. +*/ +static REDSTATUS ExpandPrepare( + CINODE *pInode) +{ + uint32_t ulOldSizeByteInBlock = (uint32_t)(pInode->pBuffer->ullSize & (REDCONF_BLOCK_SIZE - 1U)); + REDSTATUS ret = 0; + + if(ulOldSizeByteInBlock != 0U) + { + ret = RedInodeDataSeek(pInode, (uint32_t)(pInode->pBuffer->ullSize >> BLOCK_SIZE_P2)); + + if(ret == -RED_ENODATA) + { + ret = 0; + } + else if(ret == 0) + { + ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true); + + if(ret == 0) + { + RedMemSet(&pInode->pbData[ulOldSizeByteInBlock], 0U, REDCONF_BLOCK_SIZE - ulOldSizeByteInBlock); + } + } + else + { + REDERROR(); + } + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Seek to a given position within an inode, then buffer the data block. + + On successful return, pInode->pbData will be populated with a buffer + corresponding to the @p ulBlock block offset. + + @param pInode A pointer to the cached inode structure. + @param ulBlock The block offset to seek to and buffer. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENODATA The block offset is sparse. + @retval -RED_EINVAL @p ulBlock is too large. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeDataSeekAndRead( + CINODE *pInode, + uint32_t ulBlock) +{ + REDSTATUS ret; + + ret = RedInodeDataSeek(pInode, ulBlock); + + if((ret == 0) && (pInode->pbData == NULL)) + { + REDASSERT(pInode->ulDataBlock != BLOCK_SPARSE); + + ret = RedBufferGet(pInode->ulDataBlock, 0U, CAST_VOID_PTR_PTR(&pInode->pbData)); + } + + return ret; +} + + +/** @brief Seek to a given position within an inode. + + On successful return, pInode->ulDataBlock will be populated with the + physical block number corresponding to the @p ulBlock block offset. + + @param pInode A pointer to the cached inode structure. + @param ulBlock The block offset to seek to. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENODATA The block offset is sparse. + @retval -RED_EINVAL @p ulBlock is too large; or @p pInode is not a + mounted cached inode pointer. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedInodeDataSeek( + CINODE *pInode, + uint32_t ulBlock) +{ + REDSTATUS ret = 0; + + if((pInode == NULL) || (pInode->pBuffer == NULL) || (ulBlock >= INODE_DATA_BLOCKS)) + { + ret = -RED_EINVAL; + } + else + { + SeekCoord(pInode, ulBlock); + + #if DINDIR_POINTERS > 0U + if(pInode->uDindirEntry != COORD_ENTRY_INVALID) + { + if(pInode->ulDindirBlock == BLOCK_SPARSE) + { + /* If the double indirect is unallocated, so is the indirect. + */ + pInode->ulIndirBlock = BLOCK_SPARSE; + } + else + { + if(pInode->pDindir == NULL) + { + ret = RedBufferGet(pInode->ulDindirBlock, BFLAG_META_DINDIR, CAST_VOID_PTR_PTR(&pInode->pDindir)); + } + + if(ret == 0) + { + pInode->ulIndirBlock = pInode->pDindir->aulEntries[pInode->uDindirEntry]; + } + } + } + #endif + + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + if((ret == 0) && (pInode->uIndirEntry != COORD_ENTRY_INVALID)) + { + if(pInode->ulIndirBlock == BLOCK_SPARSE) + { + /* If the indirect is unallocated, so is the data block. + */ + pInode->ulDataBlock = BLOCK_SPARSE; + } + else + { + if(pInode->pIndir == NULL) + { + ret = RedBufferGet(pInode->ulIndirBlock, BFLAG_META_INDIR, CAST_VOID_PTR_PTR(&pInode->pIndir)); + } + + if(ret == 0) + { + pInode->ulDataBlock = pInode->pIndir->aulEntries[pInode->uIndirEntry]; + } + } + } + #endif + + if((ret == 0) && (pInode->ulDataBlock == BLOCK_SPARSE)) + { + ret = -RED_ENODATA; + } + } + + return ret; +} + + +/** @brief Seek to the coordinates. + + Compute the new coordinates, and put any buffers which are not needed or are + no longer appropriate. + + @param pInode A pointer to the cached inode structure. + @param ulBlock The block offset to seek to. +*/ +static void SeekCoord( + CINODE *pInode, + uint32_t ulBlock) +{ + REDASSERT(ulBlock < INODE_DATA_BLOCKS); + + if((pInode->ulLogicalBlock != ulBlock) || !pInode->fCoordInited) + { + RedInodePutData(pInode); + pInode->ulLogicalBlock = ulBlock; + + #if REDCONF_DIRECT_POINTERS > 0U + if(ulBlock < REDCONF_DIRECT_POINTERS) + { + RedInodePutCoord(pInode); + + pInode->uInodeEntry = (uint16_t)ulBlock; + pInode->ulDataBlock = pInode->pBuffer->aulEntries[pInode->uInodeEntry]; + + #if DINDIR_POINTERS > 0U + pInode->uDindirEntry = COORD_ENTRY_INVALID; + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + pInode->uIndirEntry = COORD_ENTRY_INVALID; + #endif + } + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + else + #endif + #endif + #if REDCONF_INDIRECT_POINTERS > 0U + if(ulBlock < (INODE_INDIR_BLOCKS + REDCONF_DIRECT_POINTERS)) + { + uint32_t ulIndirOffset = ulBlock - REDCONF_DIRECT_POINTERS; + uint16_t uInodeEntry = (uint16_t)((ulIndirOffset / INDIR_ENTRIES) + REDCONF_DIRECT_POINTERS); + uint16_t uIndirEntry = (uint16_t)(ulIndirOffset % INDIR_ENTRIES); + + #if DINDIR_POINTERS > 0U + RedInodePutDindir(pInode); + #endif + + if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited) + { + RedInodePutIndir(pInode); + + pInode->uInodeEntry = uInodeEntry; + + pInode->ulIndirBlock = pInode->pBuffer->aulEntries[pInode->uInodeEntry]; + } + + #if DINDIR_POINTERS > 0U + pInode->uDindirEntry = COORD_ENTRY_INVALID; + #endif + pInode->uIndirEntry = uIndirEntry; + + /* At this point, the following pInode members are needed but not + yet populated: + + - pIndir + - ulDataBlock + */ + } + #endif + #if DINDIR_POINTERS > 0U + #if (REDCONF_DIRECT_POINTERS > 0U) || (REDCONF_INDIRECT_POINTERS > 0U) + else + #endif + { + uint32_t ulDindirOffset = ((ulBlock - REDCONF_DIRECT_POINTERS) - INODE_INDIR_BLOCKS); + uint16_t uInodeEntry = (uint16_t)((ulDindirOffset / DINDIR_DATA_BLOCKS) + REDCONF_DIRECT_POINTERS + REDCONF_INDIRECT_POINTERS); + uint32_t ulDindirBlock = ulDindirOffset % DINDIR_DATA_BLOCKS; + uint16_t uDindirEntry = (uint16_t)(ulDindirBlock / INDIR_ENTRIES); + uint16_t uIndirEntry = (uint16_t)(ulDindirBlock % INDIR_ENTRIES); + + if((pInode->uInodeEntry != uInodeEntry) || !pInode->fCoordInited) + { + RedInodePutIndir(pInode); + RedInodePutDindir(pInode); + + pInode->uInodeEntry = uInodeEntry; + + pInode->ulDindirBlock = pInode->pBuffer->aulEntries[pInode->uInodeEntry]; + } + else if(pInode->uDindirEntry != uDindirEntry) + { + RedInodePutIndir(pInode); + } + else + { + /* Data buffer has already been put, nothing to do. + */ + } + + pInode->uDindirEntry = uDindirEntry; + pInode->uIndirEntry = uIndirEntry; + + /* At this point, the following pInode members are needed but not + yet populated: + + - pDindir + - pIndir + - ulIndirBlock + - ulDataBlock + */ + } + #elif (REDCONF_DIRECT_POINTERS > 0U) && (REDCONF_INDIRECT_POINTERS > 0U) + else + { + /* There are no double indirects, so the block should have been in + the direct or indirect range. + */ + REDERROR(); + } + #endif + + pInode->fCoordInited = true; + } +} + + +/** @brief Read an unaligned portion of a block. + + @param pInode A pointer to the cached inode structure. + @param ullStart The file offset at which to read. + @param ulLen The number of bytes to read. + @param pbBuffer The buffer to read into. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS ReadUnaligned( + CINODE *pInode, + uint64_t ullStart, + uint32_t ulLen, + uint8_t *pbBuffer) +{ + REDSTATUS ret; + + REDASSERT((ullStart >> BLOCK_SIZE_P2) == (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2)); + + ret = RedInodeDataSeekAndRead(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2)); + + if(ret == 0) + { + RedMemCpy(pbBuffer, &pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], ulLen); + } + else if(ret == -RED_ENODATA) + { + RedMemSet(pbBuffer, 0U, ulLen); + ret = 0; + } + else + { + /* No action, just return the error. + */ + } + + return ret; +} + + +/** @brief Read one or more whole blocks. + + @param pInode A pointer to the cached inode structure. + @param ulBlockStart The file block offset at which to read. + @param ulBlockCount The number of blocks to read. + @param pbBuffer The buffer to read into. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS ReadAligned( + CINODE *pInode, + uint32_t ulBlockStart, + uint32_t ulBlockCount, + uint8_t *pbBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulBlockIndex = 0U; + + /* Read the data from disk one contiguous extent at a time. + */ + while((ret == 0) && (ulBlockIndex < ulBlockCount)) + { + uint32_t ulExtentStart; + uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; + + ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen); + + if(ret == 0) + { + #if REDCONF_READ_ONLY == 0 + /* Before reading directly from disk, flush any dirty file data + buffers in the range to avoid reading stale data. + */ + ret = RedBufferFlush(ulExtentStart, ulExtentLen); + + if(ret == 0) + #endif + { + ret = RedIoRead(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]); + + if(ret == 0) + { + ulBlockIndex += ulExtentLen; + } + } + } + else if(ret == -RED_ENODATA) + { + RedMemSet(&pbBuffer[ulBlockIndex << BLOCK_SIZE_P2], 0U, REDCONF_BLOCK_SIZE); + ulBlockIndex++; + ret = 0; + } + else + { + /* An unexpected error occurred; the loop will terminate. + */ + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write an unaligned portion of a block. + + @param pInode A pointer to the cached inode structure. + @param ullStart The file offset at which to write. + @param ulLen The number of bytes to write. + @param pbBuffer The buffer to write from. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. +*/ +static REDSTATUS WriteUnaligned( + CINODE *pInode, + uint64_t ullStart, + uint32_t ulLen, + const uint8_t *pbBuffer) +{ + REDSTATUS ret; + + REDASSERT((ullStart >> BLOCK_SIZE_P2) == (((ullStart + ulLen) - 1U) >> BLOCK_SIZE_P2)); + + ret = RedInodeDataSeek(pInode, (uint32_t)(ullStart >> BLOCK_SIZE_P2)); + + if((ret == 0) || (ret == -RED_ENODATA)) + { + ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, true); + + if(ret == 0) + { + RedMemCpy(&pInode->pbData[ullStart & (REDCONF_BLOCK_SIZE - 1U)], pbBuffer, ulLen); + } + } + + return ret; +} + + +/** @brief Write one or more whole blocks. + + @param pInode A pointer to the cached inode structure. + @param ulBlockStart The file block offset at which to write. + @param pulBlockCount On entry, the number of blocks to attempt to write. + On successful return, the number of blocks actually + written. + @param pbBuffer The buffer to write from. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. +*/ +static REDSTATUS WriteAligned( + CINODE *pInode, + uint32_t ulBlockStart, + uint32_t *pulBlockCount, + const uint8_t *pbBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulBlockCount = *pulBlockCount; + uint32_t ulBlockIndex; + + /* Branch all of the file data blocks in advance. + */ + for(ulBlockIndex = 0U; ulBlockIndex < ulBlockCount; ulBlockIndex++) + { + ret = RedInodeDataSeek(pInode, ulBlockStart + ulBlockIndex); + + if((ret == 0) || (ret == -RED_ENODATA)) + { + ret = BranchBlock(pInode, BRANCHDEPTH_FILE_DATA, false); + + if(ret == -RED_ENOSPC) + { + ulBlockCount = ulBlockIndex; + + if(ulBlockCount > 0U) + { + ret = 0; + } + } + } + + if(ret != 0) + { + break; + } + } + + ulBlockIndex = 0; + + /* Write the data to disk one contiguous extent at a time. + */ + while((ret == 0) && (ulBlockIndex < ulBlockCount)) + { + uint32_t ulExtentStart; + uint32_t ulExtentLen = ulBlockCount - ulBlockIndex; + + ret = GetExtent(pInode, ulBlockStart + ulBlockIndex, &ulExtentStart, &ulExtentLen); + + if(ret == 0) + { + ret = RedIoWrite(gbRedVolNum, ulExtentStart, ulExtentLen, &pbBuffer[ulBlockIndex << BLOCK_SIZE_P2]); + + if(ret == 0) + { + /* If there is any buffered file data for the extent we just + wrote, those buffers are now stale. + */ + ret = RedBufferDiscardRange(ulExtentStart, ulExtentLen); + } + + if(ret == 0) + { + ulBlockIndex += ulExtentLen; + } + } + } + + if(ret == 0) + { + *pulBlockCount = ulBlockCount; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Get the physical block number and count of contiguous blocks given a + starting logical block number. + + @param pInode A pointer to the cached inode structure. + @param ulBlockStart The file block offset for the start of the extent. + @param pulExtentStart On successful return, the starting physical block + number of the contiguous extent. + @param pulExtentLen On entry, the maximum length of the extent; on + successful return, the length of the contiguous + extent. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENODATA The block offset is sparse. +*/ +static REDSTATUS GetExtent( + CINODE *pInode, + uint32_t ulBlockStart, + uint32_t *pulExtentStart, + uint32_t *pulExtentLen) +{ + REDSTATUS ret; + + ret = RedInodeDataSeek(pInode, ulBlockStart); + + if(ret == 0) + { + uint32_t ulExtentLen = *pulExtentLen; + uint32_t ulFirstBlock = pInode->ulDataBlock; + uint32_t ulRunLen = 1U; + + while((ret == 0) && (ulRunLen < ulExtentLen)) + { + ret = RedInodeDataSeek(pInode, ulBlockStart + ulRunLen); + + if((ret == -RED_ENODATA) || ((ret == 0) && (pInode->ulDataBlock != (ulFirstBlock + ulRunLen)))) + { + ret = 0; + break; + } + + ulRunLen++; + } + + if(ret == 0) + { + *pulExtentStart = ulFirstBlock; + *pulExtentLen = ulRunLen; + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Allocate or branch the file metadata path and data block if necessary. + + Optionally, can stop allocating/branching at a certain depth. + + @param pInode A pointer to the cached inode structure. + @param bDepth A BRANCHDEPTH_ value indicating the lowest depth to branch. + @param fBuffer Whether to buffer the data block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. +*/ +static REDSTATUS BranchBlock( + CINODE *pInode, + uint8_t bDepth, + bool fBuffer) +{ + REDSTATUS ret; + uint32_t ulCost; + + ret = BranchBlockCost(pInode, bDepth, &ulCost); + + if((ret == 0) && (ulCost > FreeBlockCount())) + { + ret = -RED_ENOSPC; + } + + if(ret == 0) + { + #if DINDIR_POINTERS > 0U + if(pInode->uDindirEntry != COORD_ENTRY_INVALID) + { + ret = BranchOneBlock(&pInode->ulDindirBlock, CAST_VOID_PTR_PTR(&pInode->pDindir), BFLAG_META_DINDIR); + + if(ret == 0) + { + /* In case we just created the double indirect. + */ + pInode->pDindir->ulInode = pInode->ulInode; + + pInode->pBuffer->aulEntries[pInode->uInodeEntry] = pInode->ulDindirBlock; + } + } + + if(ret == 0) + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + { + if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (bDepth >= BRANCHDEPTH_INDIR)) + { + ret = BranchOneBlock(&pInode->ulIndirBlock, CAST_VOID_PTR_PTR(&pInode->pIndir), BFLAG_META_INDIR); + + if(ret == 0) + { + /* In case we just created the indirect. + */ + pInode->pIndir->ulInode = pInode->ulInode; + + #if DINDIR_POINTERS > 0U + if(pInode->uDindirEntry != COORD_ENTRY_INVALID) + { + pInode->pDindir->aulEntries[pInode->uDindirEntry] = pInode->ulIndirBlock; + } + else + #endif + { + pInode->pBuffer->aulEntries[pInode->uInodeEntry] = pInode->ulIndirBlock; + } + } + } + } + + if(ret == 0) + #endif + { + if(bDepth == BRANCHDEPTH_FILE_DATA) + { + #if REDCONF_INODE_BLOCKS == 1 + bool fAllocedNew = (pInode->ulDataBlock == BLOCK_SPARSE); + #endif + + ret = BranchOneBlock(&pInode->ulDataBlock, fBuffer ? CAST_VOID_PTR_PTR(&pInode->pbData) : NULL, 0U); + + if(ret == 0) + { + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + if(pInode->uIndirEntry != COORD_ENTRY_INVALID) + { + pInode->pIndir->aulEntries[pInode->uIndirEntry] = pInode->ulDataBlock; + } + else + #endif + { + pInode->pBuffer->aulEntries[pInode->uInodeEntry] = pInode->ulDataBlock; + } + + #if REDCONF_INODE_BLOCKS == 1 + if(fAllocedNew) + { + if(pInode->pBuffer->ulBlocks < INODE_DATA_BLOCKS) + { + pInode->pBuffer->ulBlocks++; + } + else + { + CRITICAL_ERROR(); + ret = -RED_EFUBAR; + } + } + #endif + } + } + } + } + + return ret; +} + + +/** @brief Branch a block. + + The block can be a double indirect, indirect, or file data block. + + The caller should have already handled the disk full implications of + branching this block. + + @param pulBlock On entry, the current block number, which may be + BLOCK_SPARSE if the block is to be newly allocated. On + successful return, populated with the new block number, + which may be the same as the original block number if it + was not BLOCK_SPARSE and the block was already branched. + @param ppBuffer If NULL, indicates that the caller does not want to buffer + the branched block. If non-NULL, the caller does want the + branched block buffered, and the following is true: On + entry, the current buffer for the block, if there is one, or + NULL if there is no buffer. On successful exit, populated + with a buffer for the block, which will be dirty. If the + block number is initially BLOCK_SPARSE, there should be no + buffer for the block. + @param uBFlag The buffer type flags: BFLAG_META_DINDIR, BFLAG_META_INDIR, + or zero for file data. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS BranchOneBlock( + uint32_t *pulBlock, + void **ppBuffer, + uint16_t uBFlag) +{ + REDSTATUS ret = 0; + ALLOCSTATE state = ALLOCSTATE_FREE; + uint32_t ulPrevBlock = *pulBlock; + + if(ulPrevBlock != BLOCK_SPARSE) + { + ret = RedImapBlockState(ulPrevBlock, &state); + } + + if(ret == 0) + { + if(state == ALLOCSTATE_NEW) + { + if(ppBuffer != NULL) + { + if(*ppBuffer != NULL) + { + RedBufferDirty(*ppBuffer); + } + else + { + ret = RedBufferGet(ulPrevBlock, uBFlag | BFLAG_DIRTY, ppBuffer); + } + } + } + else + { + ret = RedImapAllocBlock(pulBlock); + + if(ret == 0) + { + if(ulPrevBlock == BLOCK_SPARSE) + { + if(ppBuffer != NULL) + { + if(*ppBuffer != NULL) + { + REDERROR(); + ret = -RED_EINVAL; + } + else + { + ret = RedBufferGet(*pulBlock, (uint16_t)((uint32_t)uBFlag | BFLAG_NEW | BFLAG_DIRTY), ppBuffer); + } + } + } + else + { + if(ppBuffer != NULL) + { + if(*ppBuffer == NULL) + { + ret = RedBufferGet(ulPrevBlock, uBFlag, ppBuffer); + } + + if(ret == 0) + { + RedBufferBranch(*ppBuffer, *pulBlock); + } + } + + if(ret == 0) + { + ret = RedImapBlockSet(ulPrevBlock, false); + } + } + } + } + } + + return ret; +} + + +/** @brief Compute the free space cost of branching a block. + + The caller must first use RedInodeDataSeek() to the block to be branched. + + @param pInode A pointer to the cached inode structure, whose coordinates + indicate the block to be branched. + @param pulCost On successful return, populated with the number of blocks + that must be allocated from free space in order to branch + the given block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS BranchBlockCost( + const CINODE *pInode, + uint8_t bDepth, + uint32_t *pulCost) +{ + REDSTATUS ret = 0; + ALLOCSTATE state = ALLOCSTATE_FREE; + #if DINDIR_POINTERS > 0U + uint32_t ulCost = 3U; + #elif REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint32_t ulCost = 2U; + #else + uint32_t ulCost = 1U; + #endif + + #if DINDIR_POINTERS > 0U + if(pInode->uDindirEntry != COORD_ENTRY_INVALID) + { + if(pInode->ulDindirBlock != BLOCK_SPARSE) + { + ret = RedImapBlockState(pInode->ulDindirBlock, &state); + + if((ret == 0) && (state == ALLOCSTATE_NEW)) + { + ulCost--; + } + } + } + else + { + ulCost--; + } + + if(ret == 0) + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + { + if((pInode->uIndirEntry != COORD_ENTRY_INVALID) && (bDepth >= BRANCHDEPTH_INDIR)) + { + if(pInode->ulIndirBlock != BLOCK_SPARSE) + { + ret = RedImapBlockState(pInode->ulIndirBlock, &state); + + if((ret == 0) && (state == ALLOCSTATE_NEW)) + { + ulCost--; + } + } + } + else + { + ulCost--; + } + } + + if(ret == 0) + #endif + { + if(bDepth == BRANCHDEPTH_FILE_DATA) + { + if(pInode->ulDataBlock != BLOCK_SPARSE) + { + ret = RedImapBlockState(pInode->ulDataBlock, &state); + + if((ret == 0) && (state == ALLOCSTATE_NEW)) + { + ulCost--; + REDASSERT(ulCost == 0U); + } + } + } + else + { + ulCost--; + } + } + + if(ret == 0) + { + *pulCost = ulCost; + } + + return ret; +} + + +/** @brief Yields the number of currently available free blocks. + + Accounts for reserved blocks, subtracting the number of reserved blocks if + they are unavailable. + + @return Number of currently available free blocks. +*/ +static uint32_t FreeBlockCount(void) +{ + uint32_t ulFreeBlocks = gpRedMR->ulFreeBlocks; + + #if RESERVED_BLOCKS > 0U + if(!gpRedCoreVol->fUseReservedBlocks) + { + if(ulFreeBlocks >= RESERVED_BLOCKS) + { + ulFreeBlocks -= RESERVED_BLOCKS; + } + else + { + ulFreeBlocks = 0U; + } + } + #endif + + return ulFreeBlocks; +} +#endif /* REDCONF_READ_ONLY == 0 */ + diff --git a/core/driver/volume.c b/core/driver/volume.c new file mode 100644 index 0000000..56b2a0b --- /dev/null +++ b/core/driver/volume.c @@ -0,0 +1,460 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements core volume operations. +*/ +#include +#include +#include + + +static bool MetarootIsValid(METAROOT *pMR, bool *pfSectorCRCIsValid); +#ifdef REDCONF_ENDIAN_SWAP +static void MetaRootEndianSwap(METAROOT *pMetaRoot); +#endif + + +/** @brief Mount a file system volume. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. +*/ +REDSTATUS RedVolMount(void) +{ + REDSTATUS ret; + + #if REDCONF_READ_ONLY == 0 + ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDWR); + #else + ret = RedOsBDevOpen(gbRedVolNum, BDEV_O_RDONLY); + #endif + + if(ret == 0) + { + ret = RedVolMountMaster(); + + if(ret == 0) + { + ret = RedVolMountMetaroot(); + } + + if(ret != 0) + { + (void)RedOsBDevClose(gbRedVolNum); + } + } + + return ret; +} + + +/** @brief Mount the master block. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO Master block missing, corrupt, or inconsistent with the + compile-time driver settings. +*/ +REDSTATUS RedVolMountMaster(void) +{ + REDSTATUS ret; + MASTERBLOCK *pMB; + + /* Read the master block, to ensure that the disk was formatted with + Reliance Edge. + */ + ret = RedBufferGet(0U, BFLAG_META_MASTER, CAST_VOID_PTR_PTR(&pMB)); + + if(ret == 0) + { + /* Verify that the driver was compiled with the same settings that + the disk was formatted with. If not, the user has made a + mistake: either the driver settings are wrong, or the disk needs + to be reformatted. + */ + if( (pMB->ulVersion != RED_DISK_LAYOUT_VERSION) + || (pMB->ulInodeCount != gpRedVolConf->ulInodeCount) + || (pMB->ulBlockCount != gpRedVolume->ulBlockCount) + || (pMB->uMaxNameLen != REDCONF_NAME_MAX) + || (pMB->uDirectPointers != REDCONF_DIRECT_POINTERS) + || (pMB->uIndirectPointers != REDCONF_INDIRECT_POINTERS) + || (pMB->bBlockSizeP2 != BLOCK_SIZE_P2) + || (((pMB->bFlags & MBFLAG_API_POSIX) != 0U) != (REDCONF_API_POSIX == 1)) + || (((pMB->bFlags & MBFLAG_INODE_TIMESTAMPS) != 0U) != (REDCONF_INODE_TIMESTAMPS == 1)) + || (((pMB->bFlags & MBFLAG_INODE_BLOCKS) != 0U) != (REDCONF_INODE_BLOCKS == 1))) + { + ret = -RED_EIO; + } + #if REDCONF_API_POSIX == 1 + else if(((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) != (REDCONF_API_POSIX_LINK == 1)) + { + ret = -RED_EIO; + } + #else + else if((pMB->bFlags & MBFLAG_INODE_NLINK) != 0U) + { + ret = -RED_EIO; + } + #endif + else + { + /* Master block configuration is valid. + */ + gpRedVolume->ullSequence = pMB->hdr.ullSequence; + } + + RedBufferPut(pMB); + } + + return ret; +} + + +/** @brief Mount the latest metaroot. + + This function also populates the volume contexts. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO Both metaroots are missing or corrupt. +*/ +REDSTATUS RedVolMountMetaroot(void) +{ + REDSTATUS ret; + + ret = RedIoRead(gbRedVolNum, 1U, 1U, &gpRedCoreVol->aMR[0U]); + + if(ret == 0) + { + ret = RedIoRead(gbRedVolNum, 2U, 1U, &gpRedCoreVol->aMR[1U]); + } + + /* Determine which metaroot is the most recent copy that was written + completely. + */ + if(ret == 0) + { + uint8_t bMR = UINT8_MAX; + bool fSectorCRCIsValid; + + if(MetarootIsValid(&gpRedCoreVol->aMR[0U], &fSectorCRCIsValid)) + { + bMR = 0U; + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap(&gpRedCoreVol->aMR[0U]); + #endif + } + else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid) + { + ret = -RED_EIO; + } + else + { + /* Metaroot is not valid, so it is ignored and there's nothing + to do here. + */ + } + + if(ret == 0) + { + if(MetarootIsValid(&gpRedCoreVol->aMR[1U], &fSectorCRCIsValid)) + { + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap(&gpRedCoreVol->aMR[1U]); + #endif + + if((bMR != 0U) || (gpRedCoreVol->aMR[1U].hdr.ullSequence > gpRedCoreVol->aMR[0U].hdr.ullSequence)) + { + bMR = 1U; + } + } + else if(gpRedVolConf->fAtomicSectorWrite && !fSectorCRCIsValid) + { + ret = -RED_EIO; + } + else + { + /* Metaroot is not valid, so it is ignored and there's nothing + to do here. + */ + } + } + + if(ret == 0) + { + if(bMR == UINT8_MAX) + { + /* Neither metaroot was valid. + */ + ret = -RED_EIO; + } + else + { + gpRedCoreVol->bCurMR = bMR; + gpRedMR = &gpRedCoreVol->aMR[bMR]; + } + } + } + + if(ret == 0) + { + /* Normally the metaroot contains the highest sequence number, but the + master block is the last block written during format, so on a + freshly formatted volume the master block sequence number (stored in + gpRedVolume->ullSequence) will be higher than that in the metaroot. + */ + if(gpRedMR->hdr.ullSequence > gpRedVolume->ullSequence) + { + gpRedVolume->ullSequence = gpRedMR->hdr.ullSequence; + } + + gpRedVolume->fMounted = true; + #if REDCONF_READ_ONLY == 0 + gpRedVolume->fReadOnly = false; + #endif + + #if RESERVED_BLOCKS > 0U + gpRedCoreVol->fUseReservedBlocks = false; + #endif + gpRedCoreVol->ulAlmostFreeBlocks = 0U; + + gpRedCoreVol->aMR[1U - gpRedCoreVol->bCurMR] = *gpRedMR; + gpRedCoreVol->bCurMR = 1U - gpRedCoreVol->bCurMR; + gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; + } + + return ret; +} + + +/** @brief Determine whether the metaroot is valid. + + @param pMR The metaroot buffer. + @param pfSectorCRCIsValid Populated with whether the first sector of the + metaroot buffer is valid. + + @return Whether the metaroot is valid. + + @retval true The metaroot buffer is valid. + @retval false The metaroot buffer is invalid. +*/ +static bool MetarootIsValid( + METAROOT *pMR, + bool *pfSectorCRCIsValid) +{ + bool fRet; + const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMR); + uint32_t ulSectorCRC = pMR->ulSectorCRC; + uint32_t ulCRC; + + #ifdef REDCONF_ENDIAN_SWAP + ulSectorCRC = RedRev32(ulSectorCRC); + #endif + + /* The sector CRC was zero when the CRC was computed during the + transaction, so it must be zero here. + */ + pMR->ulSectorCRC = 0U; + + ulCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U); + + fRet = ulCRC == ulSectorCRC; + *pfSectorCRCIsValid = fRet; + + if(fRet) + { + if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE) + { + ulCRC = RedCrc32Update(ulCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize); + } + + #ifdef REDCONF_ENDIAN_SWAP + ulCRC = RedRev32(ulCRC); + #endif + + fRet = ulCRC == pMR->hdr.ulCRC; + } + + return fRet; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Commit a transaction point. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedVolTransact(void) +{ + REDSTATUS ret = 0; + + REDASSERT(!gpRedVolume->fReadOnly); /* Should be checked by caller. */ + + if(gpRedCoreVol->fBranched) + { + gpRedMR->ulFreeBlocks += gpRedCoreVol->ulAlmostFreeBlocks; + gpRedCoreVol->ulAlmostFreeBlocks = 0U; + + ret = RedBufferFlush(0U, gpRedVolume->ulBlockCount); + + if(ret == 0) + { + const uint8_t *pbMR = CAST_VOID_PTR_TO_CONST_UINT8_PTR(gpRedMR); + uint32_t ulSectorCRC; + + gpRedMR->hdr.ulSignature = META_SIG_METAROOT; + gpRedMR->hdr.ullSequence = gpRedVolume->ullSequence; + + gpRedVolume->ullSequence++; + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap(gpRedMR); + #endif + + gpRedMR->ulSectorCRC = 0U; + + ulSectorCRC = RedCrc32Update(0U, &pbMR[8U], gpRedVolConf->ulSectorSize - 8U); + + if(gpRedVolConf->ulSectorSize < REDCONF_BLOCK_SIZE) + { + gpRedMR->hdr.ulCRC = RedCrc32Update(ulSectorCRC, &pbMR[gpRedVolConf->ulSectorSize], REDCONF_BLOCK_SIZE - gpRedVolConf->ulSectorSize); + } + else + { + gpRedMR->hdr.ulCRC = ulSectorCRC; + } + + gpRedMR->ulSectorCRC = ulSectorCRC; + + #ifdef REDCONF_ENDIAN_SWAP + gpRedMR->hdr.ulCRC = RedRev32(gpRedMR->hdr.ulCRC); + gpRedMR->ulSectorCRC = RedRev32(gpRedMR->ulSectorCRC); + #endif + + /* Flush the block device before writing the metaroot, so that all + previously written blocks are guaranteed to be on the media before + the metaroot is written. Otherwise, if the block device reorders + the writes, the metaroot could reach the media before metadata it + points at, creating a window for disk corruption if power is lost. + */ + ret = RedIoFlush(gbRedVolNum); + } + + if(ret == 0) + { + ret = RedIoWrite(gbRedVolNum, 1UL + gpRedCoreVol->bCurMR, 1U, gpRedMR); + + #ifdef REDCONF_ENDIAN_SWAP + MetaRootEndianSwap(gpRedMR); + #endif + } + + /* Flush the block device to force the metaroot write to the media. This + guarantees the transaction point is really complete before we return. + */ + if(ret == 0) + { + ret = RedIoFlush(gbRedVolNum); + } + + /* Toggle to the other metaroot buffer. The working state and committed + state metaroot buffers exchange places. + */ + if(ret == 0) + { + uint8_t bNextMR = 1U - gpRedCoreVol->bCurMR; + + gpRedCoreVol->aMR[bNextMR] = *gpRedMR; + gpRedCoreVol->bCurMR = bNextMR; + + gpRedMR = &gpRedCoreVol->aMR[gpRedCoreVol->bCurMR]; + + gpRedCoreVol->fBranched = false; + } + + CRITICAL_ASSERT(ret == 0); + } + + return ret; +} +#endif + + +#ifdef REDCONF_ENDIAN_SWAP +static void MetaRootEndianSwap( + METAROOT *pMetaRoot) +{ + pMetaRoot->ulSectorCRC = RedRev32(pMetaRoot->ulSectorCRC); + pMetaRoot->ulFreeBlocks = RedRev32(pMetaRoot->ulFreeBlocks); + #if REDCONF_API_POSIX == 1 + pMetaRoot->ulFreeInodes = RedRev32(pMetaRoot->ulFreeInodes); + #endif + pMetaRoot->ulAllocNextBlock = RedRev32(pMetaRoot->ulAllocNextBlock); +} +#endif + + +/** @brief Process a critical file system error. + + @param pszFileName The file in which the error occurred. + @param ulLineNum The line number at which the error occurred. +*/ +void RedVolCriticalError( + const char *pszFileName, + uint32_t ulLineNum) +{ + #if REDCONF_OUTPUT == 1 + #if REDCONF_READ_ONLY == 0 + if(!gpRedVolume->fReadOnly) + { + RedOsOutputString("Critical file system error in Reliance Edge, setting volume to READONLY\n"); + } + else + #endif + { + RedOsOutputString("Critical file system error in Reliance Edge (volume already READONLY)\n"); + } + #endif + + #if REDCONF_READ_ONLY == 0 + gpRedVolume->fReadOnly = true; + #endif + + #if REDCONF_ASSERTS == 1 + RedOsAssertFail(pszFileName, ulLineNum); + #else + (void)pszFileName; + (void)ulLineNum; + #endif +} + diff --git a/core/include/redcore.h b/core/include/redcore.h new file mode 100644 index 0000000..43961f8 --- /dev/null +++ b/core/include/redcore.h @@ -0,0 +1,221 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDCORE_H +#define REDCORE_H + + +#include +#include "rednodes.h" +#include "redcoremacs.h" +#include "redcorevol.h" +#include "redexclude.h" + + +#define META_SIG_MASTER (0x5453414DU) /* 'MAST' */ +#define META_SIG_METAROOT (0x4154454DU) /* 'META' */ +#define META_SIG_IMAP (0x50414D49U) /* 'IMAP' */ +#define META_SIG_INODE (0x444F4E49U) /* 'INOD' */ +#define META_SIG_DINDIR (0x494C4244U) /* 'DBLI' */ +#define META_SIG_INDIR (0x49444E49U) /* 'INDI' */ + + +REDSTATUS RedIoRead(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedIoWrite(uint8_t bVolNum, uint32_t ulBlockStart, uint32_t ulBlockCount, const void *pBuffer); +REDSTATUS RedIoFlush(uint8_t bVolNum); +#endif + + +#define BFLAG_DIRTY ((uint16_t) 0x0001U) +#define BFLAG_NEW ((uint16_t) 0x0002U) +#define BFLAG_META_MASTER ((uint16_t)(0x0004U | BFLAG_META)) +#define BFLAG_META_IMAP ((uint16_t)(0x0008U | BFLAG_META)) +#define BFLAG_META_INODE ((uint16_t)(0x0010U | BFLAG_META)) +#define BFLAG_META_INDIR ((uint16_t)(0x0020U | BFLAG_META)) +#define BFLAG_META_DINDIR ((uint16_t)(0x0040U | BFLAG_META)) +#define BFLAG_META ((uint16_t) 0x8000U) + + +void RedBufferInit(void); +REDSTATUS RedBufferGet(uint32_t ulBlock, uint16_t uFlags, void **ppBuffer); +void RedBufferPut(const void *pBuffer); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedBufferFlush(uint32_t ulBlockStart, uint32_t ulBlockCount); +void RedBufferDirty(const void *pBuffer); +void RedBufferBranch(const void *pBuffer, uint32_t ulBlockNew); +#if (REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1) +void RedBufferDiscard(const void *pBuffer); +#endif +#endif +REDSTATUS RedBufferDiscardRange(uint32_t ulBlockStart, uint32_t ulBlockCount); + + +/** @brief Allocation state of a block. +*/ +typedef enum +{ + ALLOCSTATE_FREE, /**< Free and may be allocated; writeable. */ + ALLOCSTATE_USED, /**< In-use and transacted; not writeable. */ + ALLOCSTATE_NEW, /**< In-use but not transacted; writeable. */ + ALLOCSTATE_AFREE /**< Will become free after a transaction; not writeable. */ +} ALLOCSTATE; + +REDSTATUS RedImapBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedImapBlockSet(uint32_t ulBlock, bool fAllocated); +REDSTATUS RedImapAllocBlock(uint32_t *pulBlock); +#endif +REDSTATUS RedImapBlockState(uint32_t ulBlock, ALLOCSTATE *pState); + +#if REDCONF_IMAP_INLINE == 1 +REDSTATUS RedImapIBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); +REDSTATUS RedImapIBlockSet(uint32_t ulBlock, bool fAllocated); +#endif + +#if REDCONF_IMAP_EXTERNAL == 1 +REDSTATUS RedImapEBlockGet(uint8_t bMR, uint32_t ulBlock, bool *pfAllocated); +REDSTATUS RedImapEBlockSet(uint32_t ulBlock, bool fAllocated); +uint32_t RedImapNodeBlock(uint8_t bMR, uint32_t ulImapNode); +#endif + + +/** @brief Cached inode structure. +*/ +typedef struct +{ + uint32_t ulInode; /**< The inode number of the cached inode. */ + bool fDirectory; /**< True if the inode is a directory. */ + #if REDCONF_READ_ONLY == 0 + bool fWriteable; /**< True if the inode is writeable. */ + bool fDirty; /**< True if the inode buffer is dirty. */ + #endif + bool fCoordInited; /**< True after the first seek. */ + + INODE *pBuffer; /**< Pointer to the inode buffer. */ + #if DINDIR_POINTERS > 0U + DINDIR *pDindir; /**< Pointer to the double indirect node buffer. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + INDIR *pIndir; /**< Pointer to the indirect node buffer. */ + #endif + uint8_t *pbData; /**< Pointer to the data block buffer. */ + + uint32_t ulLogicalBlock; /**< Logical block offset into the inode. */ + #if DINDIR_POINTERS > 0U + uint32_t ulDindirBlock; /**< Physical block number of the double indirect node. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint32_t ulIndirBlock; /**< Physical block number of the indirect node. */ + #endif + uint32_t ulDataBlock; /**< Physical block number of the file data block. */ + + uint16_t uInodeEntry; /**< Which inode entry to traverse to reach ulLogicalBlock. */ + #if DINDIR_POINTERS > 0U + uint16_t uDindirEntry; /**< Which double indirect entry to traverse to reach ulLogicalBlock. */ + #endif + #if REDCONF_DIRECT_POINTERS < INODE_ENTRIES + uint16_t uIndirEntry; /**< Which indirect entry to traverse to reach ulLogicalBlock. */ + #endif +} CINODE; + + +#define IPUT_UPDATE_ATIME (0x01U) +#define IPUT_UPDATE_MTIME (0x02U) +#define IPUT_UPDATE_CTIME (0x04U) +#define IPUT_UPDATE_MASK (IPUT_UPDATE_ATIME|IPUT_UPDATE_MTIME|IPUT_UPDATE_CTIME) + + +REDSTATUS RedInodeMount(CINODE *pInode, FTYPE type, bool fBranch); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedInodeBranch(CINODE *pInode); +#endif +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1)) +REDSTATUS RedInodeCreate(CINODE *pInode, uint32_t ulPInode, uint16_t uMode); +#endif +#if DELETE_SUPPORTED +REDSTATUS RedInodeDelete(CINODE *pInode); +REDSTATUS RedInodeLinkDec(CINODE *pInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +REDSTATUS RedInodeFree(CINODE *pInode); +#endif +void RedInodePut(CINODE *pInode, uint8_t bTimeFields); +void RedInodePutCoord(CINODE *pInode); +#if DINDIR_POINTERS > 0U +void RedInodePutDindir(CINODE *pInode); +#endif +#if REDCONF_DIRECT_POINTERS < INODE_ENTRIES +void RedInodePutIndir(CINODE *pInode); +#endif +void RedInodePutData(CINODE *pInode); +#if ((REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX == 1) || (REDCONF_IMAGE_BUILDER == 1))) || (REDCONF_CHECKER == 1) +REDSTATUS RedInodeIsFree(uint32_t ulInode, bool *pfFree); +#endif +REDSTATUS RedInodeBitGet(uint8_t bMR, uint32_t ulInode, uint8_t bWhich, bool *pfAllocated); + +REDSTATUS RedInodeDataRead(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedInodeDataWrite(CINODE *pInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); +#if DELETE_SUPPORTED || TRUNCATE_SUPPORTED +REDSTATUS RedInodeDataTruncate(CINODE *pInode, uint64_t ullSize); +#endif +#endif +REDSTATUS RedInodeDataSeekAndRead(CINODE *pInode, uint32_t ulBlock); +REDSTATUS RedInodeDataSeek(CINODE *pInode, uint32_t ulBlock); + +#if REDCONF_API_POSIX == 1 +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedDirEntryCreate(CINODE *pPInode, const char *pszName, uint32_t ulInode); +#endif +#if DELETE_SUPPORTED +REDSTATUS RedDirEntryDelete(CINODE *pPInode, uint32_t ulDeleteIdx); +#endif +REDSTATUS RedDirEntryLookup(CINODE *pPInode, const char *pszName, uint32_t *pulEntryIdx, uint32_t *pulInode); +#if (REDCONF_API_POSIX_READDIR == 1) || (REDCONF_CHECKER == 1) +REDSTATUS RedDirEntryRead(CINODE *pPInode, uint32_t *pulIdx, char *pszName, uint32_t *pulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) +REDSTATUS RedDirEntryRename(CINODE *pSrcPInode, const char *pszSrcName, CINODE *pSrcInode, CINODE *pDstPInode, const char *pszDstName, CINODE *pDstInode); +#endif +#endif + +REDSTATUS RedVolMount(void); +REDSTATUS RedVolMountMaster(void); +REDSTATUS RedVolMountMetaroot(void); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedVolTransact(void); +#endif +void RedVolCriticalError(const char *pszFileName, uint32_t ulLineNum); + + +#if (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) +REDSTATUS RedVolFormat(void); +#endif + + +#endif + diff --git a/core/include/redcoremacs.h b/core/include/redcoremacs.h new file mode 100644 index 0000000..daff730 --- /dev/null +++ b/core/include/redcoremacs.h @@ -0,0 +1,97 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDCOREMACS_H +#define REDCOREMACS_H + + +#define BLOCK_SPARSE (0U) + +#define DINDIR_POINTERS ((INODE_ENTRIES - REDCONF_DIRECT_POINTERS) - REDCONF_INDIRECT_POINTERS) +#define DINDIR_DATA_BLOCKS (INDIR_ENTRIES * INDIR_ENTRIES) + +#define INODE_INDIR_BLOCKS (REDCONF_INDIRECT_POINTERS * INDIR_ENTRIES) +#define INODE_DINDIR_BLOCKS (DINDIR_POINTERS * DINDIR_DATA_BLOCKS) +#define INODE_DATA_BLOCKS (REDCONF_DIRECT_POINTERS + INODE_INDIR_BLOCKS + INODE_DINDIR_BLOCKS) +#define INODE_SIZE_MAX (1ULL * REDCONF_BLOCK_SIZE * INODE_DATA_BLOCKS) + + +#define INODE_FIRST_VALID (INODE_ROOTDIR) /* First valid inode number. */ + +/* First inode number than can be allocated. +*/ +#if REDCONF_API_POSIX == 1 +#define INODE_FIRST_FREE (INODE_FIRST_VALID + 1U) +#else +#define INODE_FIRST_FREE (INODE_FIRST_VALID) +#endif + +/** @brief Determine if an inode number is valid. + + All usages of this macro deviate from MISRA-C:2012 Directive 4.9 (advisory). + To reduce code duplication while maintaining portability and efficiency, a + function-like macro is used instead of a static inline function. + + As Directive 4.9 is advisory, a deviation record is not required. This + notice and the PC-Lint error inhibition option are the only records of the + deviation. +*/ +#define INODE_IS_VALID(INODENUM) (((INODENUM) >= INODE_FIRST_VALID) && ((INODENUM) < (INODE_FIRST_VALID + gpRedVolConf->ulInodeCount))) + + +/* The number of blocks reserved to allow a truncate or delete operation to + complete when the disk is otherwise full. + + The more expensive of the two operations is delete, which has to actually + write to a file data block to remove the directory entry. +*/ +#if (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) + #if DINDIR_POINTERS > 0U + #define RESERVED_BLOCKS 3U + #elif REDCONF_INDIRECT_POINTERS > 0U + #define RESERVED_BLOCKS 2U + #else + #define RESERVED_BLOCKS 1U + #endif +#elif ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1)) + #if DINDIR_POINTERS > 0U + #define RESERVED_BLOCKS 2U + #elif REDCONF_INDIRECT_POINTERS > 0U + #define RESERVED_BLOCKS 1U + #else + #define RESERVED_BLOCKS 0U + #endif +#else + #define RESERVED_BLOCKS 0U +#endif + + +#define CRITICAL_ASSERT(EXP) ((EXP) ? (void)0 : CRITICAL_ERROR()) +#define CRITICAL_ERROR() RedVolCriticalError(__FILE__, __LINE__) + + +#endif + diff --git a/core/include/redcorevol.h b/core/include/redcorevol.h new file mode 100644 index 0000000..0d21aa8 --- /dev/null +++ b/core/include/redcorevol.h @@ -0,0 +1,95 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDCOREVOL_H +#define REDCOREVOL_H + + +/** @brief Per-volume run-time data specific to the core. +*/ +typedef struct +{ + /** Whether this volume uses the inline imap (true) or external imap + (false). Computed at initialization time based on the block count. + */ + bool fImapInline; + +#if REDCONF_IMAP_EXTERNAL == 1 + /** First block number of the on-disk imap. Valid only when fImapInline + is false. + */ + uint32_t ulImapStartBN; + + /** The number of double-allocated imap nodes that make up the imap. + */ + uint32_t ulImapNodeCount; +#endif + + /** Block number where the inode table starts. + */ + uint32_t ulInodeTableStartBN; + + /** First block number that can be allocated. + */ + uint32_t ulFirstAllocableBN; + + /** The two metaroot structures, committed and working state. + */ + METAROOT aMR[2U]; + + /** The index of the current metaroot; must be 0 or 1. + */ + uint8_t bCurMR; + + /** Whether the volume has been branched or not. + */ + bool fBranched; + + /** The number of blocks which will become free after the next transaction. + */ + uint32_t ulAlmostFreeBlocks; + + #if RESERVED_BLOCKS > 0U + /** Whether to use the blocks reserved for operations that create free + space. + */ + bool fUseReservedBlocks; + #endif +} COREVOLUME; + +/* Pointer to the core volume currently being accessed; populated during + RedCoreVolSetCurrent(). +*/ +extern COREVOLUME *gpRedCoreVol; + +/* Pointer to the metaroot currently being accessed; populated during + RedCoreVolSetCurrent() and RedCoreVolTransact(). +*/ +extern METAROOT *gpRedMR; + + +#endif + diff --git a/core/include/redexclude.h b/core/include/redexclude.h new file mode 100644 index 0000000..ffbc073 --- /dev/null +++ b/core/include/redexclude.h @@ -0,0 +1,47 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDEXCLUDE_H +#define REDEXCLUDE_H + + +#define DELETE_SUPPORTED \ + ( \ + (REDCONF_READ_ONLY == 0) \ + && ( (REDCONF_API_POSIX == 1) \ + && ( (REDCONF_API_POSIX_RMDIR == 1) \ + || (REDCONF_API_POSIX_UNLINK == 1) \ + || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))))) + +#define TRUNCATE_SUPPORTED \ + ( \ + (REDCONF_READ_ONLY == 0) \ + && ( ((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1)) \ + || ((REDCONF_API_FSE == 1) && (REDCONF_API_FSE_TRUNCATE == 1)))) + + +#endif + diff --git a/core/include/rednodes.h b/core/include/rednodes.h new file mode 100644 index 0000000..8d8d01c --- /dev/null +++ b/core/include/rednodes.h @@ -0,0 +1,195 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDNODES_H +#define REDNODES_H + + +#define NODEHEADER_SIZE (16U) +#define NODEHEADER_OFFSET_SIG (0U) +#define NODEHEADER_OFFSET_CRC (4U) +#define NODEHEADER_OFFSET_SEQ (8U) + +/** @brief Common header for all metadata nodes. +*/ +typedef struct +{ + uint32_t ulSignature; /**< Value which uniquely identifies the metadata node type. */ + uint32_t ulCRC; /**< CRC-32 checksum of the node contents, starting after the CRC. */ + uint64_t ullSequence; /**< Current sequence number at the time the node was written to disk. */ +} NODEHEADER; + + +/** Compile-time boolean which corresponds to REDCONF_API_POSIX == 1. */ +#define MBFLAG_API_POSIX (0x01U) + +/** Compile-time boolean which corresponds to REDCONF_INODE_TIMESTAMPS == 1. */ +#define MBFLAG_INODE_TIMESTAMPS (0x02U) + +/** Compile-time boolean which corresponds to REDCONF_INODE_BLOCKS == 1. */ +#define MBFLAG_INODE_BLOCKS (0x04U) + +/** Compile-time boolean which corresponds to REDCONF_API_POSIX == REDCONF_API_POSIX_LINK == 1. */ +#define MBFLAG_INODE_NLINK (0x08U) + + +/** @brief Node which identifies the volume and stores static volume information. +*/ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulVersion; /**< On-disk layout version number. */ + char acBuildNum[8U]; /**< Build number of the product (not null terminated). */ + uint32_t ulFormatTime; /**< Date and time the volume was formatted. */ + uint32_t ulInodeCount; /**< Compile-time configured number of inodes. */ + uint32_t ulBlockCount; /**< Compile-time configured number of logical blocks. */ + uint16_t uMaxNameLen; /**< Compile-time configured maximum file name length. */ + uint16_t uDirectPointers; /**< Compile-time configured number of direct pointers per inode. */ + uint16_t uIndirectPointers; /**< Compile-time configured number of indirect pointers per inode. */ + uint8_t bBlockSizeP2; /**< Compile-time configured block size, expressed as a power of two. */ + uint8_t bFlags; /**< Compile-time booleans which affect on-disk structures. */ +} MASTERBLOCK; + + +#if REDCONF_API_POSIX == 1 +#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 16U) /* Size in bytes of the metaroot header fields. */ +#else +#define METAROOT_HEADER_SIZE (NODEHEADER_SIZE + 12U) /* Size in bytes of the metaroot header fields. */ +#endif +#define METAROOT_ENTRY_BYTES (REDCONF_BLOCK_SIZE - METAROOT_HEADER_SIZE) /* Number of bytes remaining in the metaroot block for entries. */ +#define METAROOT_ENTRIES (METAROOT_ENTRY_BYTES * 8U) + +/** @brief Metadata root node; each volume has two. +*/ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulSectorCRC; /**< CRC-32 checksum of the first sector. */ + uint32_t ulFreeBlocks; /**< Number of allocable blocks that are free. */ + #if REDCONF_API_POSIX == 1 + uint32_t ulFreeInodes; /**< Number of inode slots that are free. */ + #endif + uint32_t ulAllocNextBlock; /**< Forward allocation pointer. */ + + /** Imap bitmap. With inline imaps, this is the imap bitmap that indicates + which inode blocks are used and which allocable blocks are used. + Otherwise, this bitmap toggles nodes in the external imap between one + of two possible block locations. + */ + uint8_t abEntries[METAROOT_ENTRY_BYTES]; +} METAROOT; + + +#if REDCONF_IMAP_EXTERNAL == 1 +#define IMAPNODE_HEADER_SIZE (NODEHEADER_SIZE) /* Size in bytes of the imap node header fields. */ +#define IMAPNODE_ENTRY_BYTES (REDCONF_BLOCK_SIZE - IMAPNODE_HEADER_SIZE) /* Number of bytes remaining in the imap node for entries. */ +#define IMAPNODE_ENTRIES (IMAPNODE_ENTRY_BYTES * 8U) + +/** @brief One node of the external imap. +*/ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + /** Bitmap which indicates which inode blocks are used and which allocable + blocks are used. + */ + uint8_t abEntries[IMAPNODE_ENTRY_BYTES]; +} IMAPNODE; +#endif + + +#define INODE_HEADER_SIZE (NODEHEADER_SIZE + 8U + ((REDCONF_INODE_BLOCKS == 1) ? 4U : 0U) + \ + ((REDCONF_INODE_TIMESTAMPS == 1) ? 12U : 0U) + 4U + ((REDCONF_API_POSIX == 1) ? 4U : 0U)) +#define INODE_ENTRIES ((REDCONF_BLOCK_SIZE - INODE_HEADER_SIZE) / 4U) + +#if (REDCONF_DIRECT_POINTERS < 0) || (REDCONF_DIRECT_POINTERS > (INODE_ENTRIES - REDCONF_INDIRECT_POINTERS)) + #error "Configuration error: invalid value of REDCONF_DIRECT_POINTERS" +#endif +#if (REDCONF_INDIRECT_POINTERS < 0) || (REDCONF_INDIRECT_POINTERS > (INODE_ENTRIES - REDCONF_DIRECT_POINTERS)) + #error "Configuration error: invalid value of REDCONF_INDIRECT_POINTERS" +#endif + +/** @brief Stores metadata for a file or directory. +*/ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint64_t ullSize; /**< Size of the inode, in bytes. */ +#if REDCONF_INODE_BLOCKS == 1 + uint32_t ulBlocks; /**< Total number file data blocks allocated to the inode. */ +#endif +#if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t ulATime; /**< Time of last access (seconds since January 1, 1970). */ + uint32_t ulMTime; /**< Time of last modification (seconds since January 1, 1970). */ + uint32_t ulCTime; /**< Time of last status change (seconds since January 1, 1970). */ +#endif + uint16_t uMode; /**< Inode type (file or directory) and permissions (reserved). */ +#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) + uint16_t uNLink; /**< Link count, number of names pointing to the inode. */ +#else + uint8_t abPadding[2]; /**< Padding to 32-bit align the next member. */ +#endif +#if REDCONF_API_POSIX == 1 + uint32_t ulPInode; /**< Parent inode number. Only guaranteed to be accurate for directories. */ +#endif + + /** Block numbers for lower levels of the file metadata structure. Some + fraction of these entries are for direct pointers (file data block + numbers), some for indirect pointers, some for double-indirect + pointers; the number allocated to each is static but user-configurable. + For all types, an array slot is zero if the range is sparse or beyond + the end of file. + */ + uint32_t aulEntries[INODE_ENTRIES]; +} INODE; + + +#define INDIR_HEADER_SIZE (NODEHEADER_SIZE + 4U) +#define INDIR_ENTRIES ((REDCONF_BLOCK_SIZE - INDIR_HEADER_SIZE) / 4U) + +/** @brief Node for storing block pointers. +*/ +typedef struct +{ + NODEHEADER hdr; /**< Common node header. */ + + uint32_t ulInode; /**< Inode which owns this indirect or double indirect. */ + + /** For indirect nodes, stores block numbers of file data. For double + indirect nodes, stores block numbers of indirect nodes. An array + slot is zero if the corresponding block or indirect range is beyond + the end of file or entirely sparse. + */ + uint32_t aulEntries[INDIR_ENTRIES]; +} INDIR, DINDIR; + + +#endif + diff --git a/doc/coding_style.txt b/doc/coding_style.txt new file mode 100644 index 0000000..569c04e --- /dev/null +++ b/doc/coding_style.txt @@ -0,0 +1,389 @@ +Datalight Coding Style +====================== + +This is a description of the Datalight Coding Style intended for third parties +who want to contribute code to Reliance Edge. This document is derived from the +DDSS Coding Guidelines, but only contains a subset of the content which is most +likely to be relevant to third party contributors. + +Reliance Edge complies with the MISRA-C:2012 coding guidelines, which includes +many rules that affect coding style. Unfortunately the MISRA-C:2012 document is +not freely available, and is much too long to be effectively summarized, but if +you are familiar with the rules, adhere to them. A few important rules of +thumb: avoid the goto and continue keywords; avoid using more than one break +in a loop; and avoid having more than one return from a function (single point +of exit); default cases in every switch statement; avoid recursion; and make +generous use of parentheses. Outside of the file system driver, in tests and +host tools, the MISRA-C rules are relaxed. + +Beyond MISRA-C, Datalight has a standard coding style. Most aspects of this +style are matters of preference, but when contributing code to Datalight an +effort should be made to use this style for the sake of consistency. + +Below is an example function, which illustrates several key points of Datalight +Coding Style: + +/** @brief One-sentence description of what this function does. + + Additional description. + + @param ulFirstParameter Description of the parameter. + @param pszPointer Description of the parameter. + + @return Describe the return value. + + @retval true Optional description of specific return value. + @retval false Optional description of specific return value. +*/ +bool ExampleFunction( + uint32_t ulFirstParameter, + char *pszPointer) +{ + bool fStatus = true; + + /* This is a single-line comment. + */ + if(ulFirstParameter > 0U) + { + /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit + amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt + ut labore et dolore magna aliqua. + */ + FunctionCall(); + + while(fStatus) + { + fStatus = AnotherFunction(ulFirstParameter, pszPointer); + } + } + + return fStatus; +} + +Tab Stop Conventions +-------------------- + +In all C code (.c/.h), use a tab width of four spaces, and use soft tabs (in +other words, tabs are expanded to spaces). In Makefiles, use hard tabs and a +tab width of 8. + +Naming +------ + +Datalight uses CamelCase for functions and variables. Type names are generally +UPPERCASE, except for standard types like uint32_t. Preprocessor macros are +UPPERCASE, with words separated by underscores (for example, INODE_INVALID). + +Doxygen Documentation +--------------------- + +Doxygen is used to document functions (including static functions), along with +types, structures, files, etc. For Doxygen tags, use '@' instead of a backslash +(thus "@param" not "\param"). + +Function Declarations +--------------------- + +Multi-line function declarations are preferred, as they tend to be more +readable. Use the following form: + +static bool ExampleFunctionDeclaration( + uint32_t ulFirstParameter, + char *pszPointer, + uint8_t **ppbBuffer) +{ + uint16_t uLocalVar; /* descriptive comment */ + uint8_t *pbBuffer = NULL; /* descriptive comment */ + + Function body... +} + +The following guidelines should be used: + +- Align both the data-type and the variable names, for parameters and locals, at + the same level if practical. +- For pointer types, the '*' belongs to the variable name---it's not part of the + data-type, so keep it with the variable name. +- If useful, single line comments may be used to describe local variables (not + a requirement). +- For functions with no parameters, the "void" declaration does not need to be + on a separate line. +- Generally each variable should be declared on a separate line. This promotes + readability, and facilitates having a comment for each variable. + +Function declarations should be spaced apart by two blank lines between the +closing brace which ends a function and the Doxygen comment which starts the +next. + +Curly Braces +------------ + +Datalight lines up all curly braces vertically. As per MISRA-C, curly braces +are never omitted, even if the braces contain only a single statement. + +For consistency, even structure declarations and initializations should use the +same style, with the curly braces lined up vertically. One exception is for +structure initializations where both the opening and closing curly braces can +fit on the same line. If so, do it. + +Code Comments +------------- + +Datalight uses the standard C style /* comments */. C++ style comments (//) are +never used. The Datalight standard comment style is shown below. This style +applies to all general comments within the code. + +/* This is a single-line comment. +*/ +if(ulFirstParameter > 0U) +{ + /* This is a multi-line comment. Filler text: Lorem ipsum dolor sit amet, + consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore + et dolore magna aliqua. + */ + while(fStatus) + { + } +} + +Note the characteristics: + +- The /* and */ align with the natural 4 character indentation. +- The comment text is exactly indented another 4 characters. +- The comment text starts on the same line as the opening /*. +- The terminating */ is on its own line. +- There is usually a single blank line preceding the comment, however if the + preceding line is an opening curly brace, then an extra blank line is not + necessary. +- There is usually no blank line after the comment, but rather the closing */ + "attaches" the comment to the code about which the comment refers. +- These comments should always fit with the standard 80 character margin. + +Comments where the /* and */ are on the same line may be used in a few places: + +- For variable or parameter descriptions, where the comment fits on the same + line as the declaration. +- For structure member declarations, where the comment fits on the same line as + the declaration. +- For macros or preprocessor logic, where the comment fits on the same line. + +It is OK for such comments to exceed the 80 character margin by a small amount, +if necessary, as this sometimes promotes code readability. + +Indentation Style +----------------- + +The general paradigm used in Datalight code is that curly braces line up +vertically, and everything in between them is indented. This should include all +comments, labels, and preprocessor symbols. The only things which are aligned +at the left-most columns are: + +- Symbols, variables, declarations, and preprocessor logic which are at the + module-scope (outside of a function) +- Comments which are outside of a function +- Function declarations +- Function open and closing curly braces + +Typically comments are always lined up directly with the code to which they +apply. + +Labels (when used; gotos are disallowed in driver code) are lined up two +characters to the left of the code they reside in, to make them stand out, while +as the same time, still remaining subservient to the level of curly braces in +which they reside. For example: + +bool ExampleLabelUsage(void) +{ + MutexLock(); + + Lots of complicated code... + + Unlock: + + MutexUnlock(); + + return fSuccess; +} + +Preprocessor logic, such as controlling features which are conditionally +compiled in or out, should not disrupt the flow of the code, but rather should +be indented in similar fashion to the code it controls, but positioned two +characters to the left. For example, consider the following code snippet. The +preprocessor conditions are both indented relative to the outer curly braces, +but do not disrupt the normal code flow. + +int32_t red_statvfs( + const char *pszVolume, + REDSTATFS *pStatvfs) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolStat(pStatvfs); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + +Note that, like anything else between curly brackets, the contents of a switch +statement are indented: + +switch(ulSignature) +{ + case META_SIG_MASTER: + fValid = (uFlags == BFLAG_META_MASTER); + break; + case META_SIG_IMAP: + fValid = (uFlags == BFLAG_META_IMAP); + break; + case META_SIG_INODE: + fValid = (uFlags == BFLAG_META_INODE); + break; + case META_SIG_DINDIR: + fValid = (uFlags == BFLAG_META_DINDIR); + break; + case META_SIG_INDIR: + fValid = (uFlags == BFLAG_META_INDIR); + break; + default: + fValid = false; + break; +} + +Maximum Line Length +------------------- + +The maximum line length for code need not be rigidly limited to the traditional +80 characters. Nevertheless the line lengths should be kept reasonable. +Anything longer than 100 to 120 characters should probably be broken up. The +most important consideration is readability---fitting on the screen is important +for readability, but equally important is facilitating an easy understanding of +the logical code flow. + +There are a few exceptions on both sides of the issue. Generally comments +should be limited to 80 characters always. Some lines of code may exceed the +120 character length by a large margin, if it makes the code more understandable +and maintainable. This is especially true when dealing with code that generates +output which needs to be lined up. + +Regardless of everything else, no lines should exceed 250 characters because +some editors cannot handle anything larger. + +Maximum Display Output Line Length +---------------------------------- + +Any code which displays TTY style output, whether on a screen or a terminal, +should be constructed so the output is readable and wraps properly on an 80 +character wide display. This primarily applies to the "standard" output from +various tests and tools as well as syntax output for those tests and tools; +debug output can violate this rule. + +Preprocessor Notation +--------------------- + +Don't use preprocessor notation where the # is separated from the keyword by one +or more white spaces. For example, don't do: + +#ifndef SYMBOL1 +# define SYMBOL1 +#endif + +Instead, do: + +#ifndef SYMBOL1 + #define SYMBOL1 +#endif + +Hexadecimal Notation +-------------------- + +Use uppercase for any alphabetic hexadecimal digits, and lower case for the +notational element. For example: + +#define HEXNUM 0x123abd /* Bad */ +#define HEXNUM 0X123ABD /* Bad */ +#define HEXNUM 0x123ABD /* Good */ + +Hungarian Notation +------------------ + +Datalight uses Hungarian notation. The following type prefixes are used: + +Type Prefix | Meaning +----------- | ------- +c | char +uc | unsigned char +i | int +n | unsigned int or size_t +b | uint8_t +u | uint16_t +ul | uint32_t +ull | uint64_t +sz | array of char that will be null-terminated +f | bool +h | A handle +fn | A function (always used with the "p" modifier) + +There is no official Hungarian for int8_t, int16_t, int32_t, or int64_t, +although some code uses unofficial variants (like "ll" for int64_t). + +The following modifiers may be used in combination with the type prefixes +defined above, or in combination with other types: + +Modifier | Meaning +-------- | ------- +a | An array +p | A pointer +g | A global variable + +Notes: + +- There is no standard Hungarian for structure declarations, however the use of + the "a" and "p" modifiers is completely appropriate (and expected). +- For those data types which do not have any standard defined Hungarian prefix, + using none is preferable to misusing another prefix which would lead to + confusion. +- The "p" pointer modifier must be used such that a variable which is a pointer + to a pointer uses multiple "p" prefixes. A general rule-of-thumb is that the + variable name should have the same number of "p" prefixes as the declaration + has asterisks. This allows pointer expressions to be easily decoded using + cancellation. + +Variable Scope +-------------- + +Declare a variable in the narrowest scope in which it is meaningful. +Unnecessarily declaring all variables at the beginning of a function, where they +may be physically far from where they are actually used, makes the code harder +to maintain. + +When multiple blocks of code share a variable, but not its value, declare the +variable separately for each code block. + +For example, if two separate blocks contain loops indexed by a variable ulIndex +declare it separately in each block rather than declaring it once in a wider +scope and using it in both places. + +Using distinct declarations in the two blocks allows the compiler to check for +failure to initialize the variable in the second block. If there is a single +declaration, the (now meaningless) value left over from the first block can be +used erroneously in the second block. + diff --git a/doc/release_notes.md b/doc/release_notes.md new file mode 100644 index 0000000..b165f6d --- /dev/null +++ b/doc/release_notes.md @@ -0,0 +1,20 @@ +# Reliance Edge Release Notes + +This file contains a list of updates made to Reliance Edge over the course of +recent releases and a list of known issues. + +## Release History and Changes + +### Reliance Edge v0.9 (Beta), April 2015 + +First public release. + +## Known Issues + +### Visual Studio 2005 + +The Reliance Edge Win32 port (used for the host tools and the Win32 test +project) cannot be compiled by Visual Studio 2005. This is not going to be +fixed since VS2005 is an old toolset. Newer versions of Visual Studio, starting +with Visual Studio 2008, work just fine. + diff --git a/doc/release_notes.txt b/doc/release_notes.txt new file mode 100644 index 0000000..7b6194c --- /dev/null +++ b/doc/release_notes.txt @@ -0,0 +1,24 @@ + + +RELIANCE EDGE RELEASE NOTES + + +This file contains a list of updates made to Reliance Edge over the +course of recent releases and a list of known issues. + + +Release History and Changes + +Reliance Edge v0.9 (Beta), April 2015 + +First public release. + + +Known Issues + +Visual Studio 2005 + +The Reliance Edge Win32 port (used for the host tools and the Win32 test +project) cannot be compiled by Visual Studio 2005. This is not going to +be fixed since VS2005 is an old toolset. Newer versions of Visual +Studio, starting with Visual Studio 2008, work just fine. diff --git a/fse/fse.c b/fse/fse.c new file mode 100644 index 0000000..f71966c --- /dev/null +++ b/fse/fse.c @@ -0,0 +1,647 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implementation of the Reliance Edge FSE API. +*/ +#include + +#if REDCONF_API_FSE == 1 + +/** @defgroup red_group_fse The File System Essentials Interface + @{ +*/ + +#include +#include +#include + + +static REDSTATUS FseEnter(uint8_t bVolNum); +static void FseLeave(void); + + +static bool gfFseInited; /* Whether driver is initialized. */ + + +/** @brief Initialize the Reliance Edge file system driver. + + Prepares the Reliance Edge file system driver to be used. Must be the first + Reliance Edge function to be invoked: no volumes can be mounted until the + driver has been initialized. + + If this function is called when the Reliance Edge driver is already + initialized, it does nothing and returns success. + + This function is not thread safe: attempting to initialize from multiple + threads could leave things in a bad state. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedFseInit(void) +{ + REDSTATUS ret; + + if(gfFseInited) + { + ret = 0; + } + else + { + ret = RedCoreInit(); + + if(ret == 0) + { + gfFseInited = true; + } + } + + return ret; +} + + +/** @brief Uninitialize the Reliance Edge file system driver. + + Tears down the Reliance Edge file system driver. Cannot be used until all + Reliance Edge volumes are unmounted. A subsequent call to RedFseInit() + will initialize the driver again. + + If this function is called when the Reliance Edge driver is already + uninitialized, it does nothing and returns success. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBUSY At least one volume is still mounted. +*/ +REDSTATUS RedFseUninit(void) +{ + REDSTATUS ret = 0; + + if(!gfFseInited) + { + ret = 0; + } + else + { + uint8_t bVolNum; + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + #endif + + for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) + { + if(gaRedVolume[bVolNum].fMounted) + { + ret = -RED_EBUSY; + break; + } + } + + if(ret == 0) + { + gfFseInited = false; + } + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + + if(ret == 0) + { + ret = RedCoreUninit(); + } + } + + return ret; +} + + +/** @brief Mount a file system volume. + + Prepares the file system volume to be accessed. Mount will fail if the + volume has never been formatted, or if the on-disk format is inconsistent + with the compile-time configuration. + + If the volume is already mounted, this function does nothing and returns + success. + + @param bVolNum The volume number of the volume to be mounted. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is + uninitialized. + @retval -RED_EIO Volume not formatted, improperly formatted, or corrupt. +*/ +REDSTATUS RedFseMount( + uint8_t bVolNum) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + if(!gaRedVolume[bVolNum].fMounted) + { + ret = RedCoreVolMount(); + } + + FseLeave(); + } + + return ret; +} + + +/** @brief Unmount a file system volume. + + This function discards the in-memory state for the file system and marks it + as unmounted. Subsequent attempts to access the volume will fail until the + volume is mounted again. + + If unmount automatic transaction points are enabled, this function will + commit a transaction point prior to unmounting. If unmount automatic + transaction points are disabled, this function will unmount without + transacting, effectively discarding the working state. + + Before unmounting, this function will wait for any active file system + thread to complete by acquiring the FS mutex. The volume will be marked as + unmounted before the FS mutex is released, so subsequent FS threads will + possibly block and then see an error when attempting to access a volume + which is unmounting or unmounted. + + If the volume is already unmounted, this function does nothing and returns + success. + + @param bVolNum The volume number of the volume to be unmounted. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number; or the driver is + uninitialized. + @retval -RED_EIO I/O error during unmount automatic transaction point. +*/ +REDSTATUS RedFseUnmount( + uint8_t bVolNum) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + if(gaRedVolume[bVolNum].fMounted) + { + ret = RedCoreVolUnmount(); + } + + FseLeave(); + } + + return ret; +} + + +/** @brief Read from a file. + + Data which has not yet been written, but which is before the end-of-file + (sparse data), shall read as zeroes. A short read -- where the number of + bytes read is less than requested -- indicates that the requested read was + partially or, if zero bytes were read, entirely beyond the end-of-file. + + If @p ullFileOffset is at or beyond the maximum file size, it is treated + like any other read entirely beyond the end-of-file: no data is read and + zero is returned. + + @param bVolNum The volume number of the file to read. + @param ulFileNum The file number of the file to read. + @param ullFileOffset The file offset to read from. + @param ulLength The number of bytes to read. + @param pBuffer The buffer to populate with the data read. Must be + at least ulLength bytes in size. + + @return The number of bytes read (nonnegative) or a negated ::REDSTATUS + code indicating the operation result (negative). + + @retval >=0 The number of bytes read from the file. + @retval -RED_EBADF @p ulFileNum is not a valid file number. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + or @p pBuffer is `NULL`; or @p ulLength exceeds + INT32_MAX and cannot be returned properly. + @retval -RED_EIO A disk I/O error occurred. +*/ +int32_t RedFseRead( + uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + void *pBuffer) +{ + int32_t ret; + + if(ulLength > (uint32_t)INT32_MAX) + { + ret = -RED_EINVAL; + } + else + { + ret = FseEnter(bVolNum); + } + + if(ret == 0) + { + uint32_t ulReadLen = ulLength; + + ret = RedCoreFileRead(ulFileNum, ullFileOffset, &ulReadLen, pBuffer); + + FseLeave(); + + if(ret == 0) + { + ret = (int32_t)ulReadLen; + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write to a file. + + If the write extends beyond the end-of-file, the file size will be + increased. + + A short write -- where the number of bytes written is less than requested + -- indicates either that the file system ran out of space but was still + able to write some of the request; or that the request would have caused + the file to exceed the maximum file size, but some of the data could be + written prior to the file size limit. + + If an error is returned (negative return), either none of the data was + written or a critical error occurred (like an I/O error) and the file + system volume will be read-only. + + @param bVolNum The volume number of the file to write. + @param ulFileNum The file number of the file to write. + @param ullFileOffset The file offset to write at. + @param ulLength The number of bytes to write. + @param pBuffer The buffer containing the data to be written. Must + be at least ulLength bytes in size. + + @return The number of bytes written (nonnegative) or a negated ::REDSTATUS + code indicating the operation result (negative). + + @retval >0 The number of bytes written to the file. + @retval -RED_EBADF @p ulFileNum is not a valid file number. + @retval -RED_EFBIG No data can be written to the given file offset since + the resulting file size would exceed the maximum file + size. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + or @p pBuffer is `NULL`; or @p ulLength exceeds + INT32_MAX and cannot be returned properly. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC No data can be written because there is insufficient + free space. + @retval -RED_EROFS The file system volume is read-only. +*/ +int32_t RedFseWrite( + uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullFileOffset, + uint32_t ulLength, + const void *pBuffer) +{ + int32_t ret; + + if(ulLength > (uint32_t)INT32_MAX) + { + ret = -RED_EINVAL; + } + else + { + ret = FseEnter(bVolNum); + } + + if(ret == 0) + { + uint32_t ulWriteLen = ulLength; + + ret = RedCoreFileWrite(ulFileNum, ullFileOffset, &ulWriteLen, pBuffer); + + FseLeave(); + + if(ret == 0) + { + ret = (int32_t)ulWriteLen; + } + } + + return ret; +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1) +/** @brief Truncate a file (set the file size). + + Allows the file size to be increased, decreased, or to remain the same. If + the file size is increased, the new area is sparse (will read as zeroes). + If the file size is decreased, the data beyond the new end-of-file will + return to free space once it is no longer part of the committed state + (either immediately or after the next transaction point). + + This function can fail when the disk is full if @p ullNewFileSize is + non-zero. If decreasing the file size, this can be fixed by transacting and + trying again: Reliance Edge guarantees that it is possible to perform a + truncate of at least one file that decreases the file size after a + transaction point. If disk full transactions are enabled, this will happen + automatically. + + @param bVolNum The volume number of the file to truncate. + @param ulFileNum The file number of the file to truncate. + @param ullNewFileSize The new file size, in bytes. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulFileNum is not a valid file number. + @retval -RED_EFBIG @p ullNewFileSize exceeds the maximum file size. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOSPC Insufficient free space to perform the truncate. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedFseTruncate( + uint8_t bVolNum, + uint32_t ulFileNum, + uint64_t ullNewFileSize) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + ret = RedCoreFileTruncate(ulFileNum, ullNewFileSize); + + FseLeave(); + } + + return ret; +} +#endif + + +/** @brief Retrieve the size of a file. + + @param bVolNum The volume number of the file whose size is being read. + @param ulFileNum The file number of the file whose size is being read. + + @return The size of the file (nonnegative) or a negated ::REDSTATUS code + indicating the operation result (negative). + + @retval >=0 The size of the file. + @retval -RED_EBADF @p ulFileNum is not a valid file number. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + @retval -RED_EIO A disk I/O error occurred. +*/ +int64_t RedFseSizeGet( + uint8_t bVolNum, + uint32_t ulFileNum) +{ + int64_t ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + uint64_t ullSize; + + ret = RedCoreFileSizeGet(ulFileNum, &ullSize); + + if(ret == 0) + { + /* Unless there is an on-disk format change, the maximum file size + is guaranteed to be less than INT64_MAX, and so it can be safely + returned in an int64_t. + */ + REDASSERT(ullSize < INT64_MAX); + + ret = (int64_t)ullSize; + } + + FseLeave(); + } + + return ret; +} + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1) +/** @brief Update the transaction mask. + + The following events are available: + + - #RED_TRANSACT_UMOUNT + - #RED_TRANSACT_WRITE + - #RED_TRANSACT_TRUNCATE + - #RED_TRANSACT_VOLFULL + + The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask of + all transaction flags, excluding those representing excluded functionality. + + Attempting to enable events for excluded functionality will result in an + error. + + @param bVolNum The volume number of the volume whose transaction mask + is being changed. + @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + be set as the current transaction mode. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + or @p ulEventMask contains invalid bits. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedFseTransMaskSet( + uint8_t bVolNum, + uint32_t ulEventMask) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + ret = RedCoreTransMaskSet(ulEventMask); + + FseLeave(); + } + + return ret; +} +#endif + + +#if REDCONF_API_FSE_TRANSMASKGET == 1 +/** @brief Read the transaction mask. + + If the volume is read-only, the returned event mask is always zero. + + @param bVolNum The volume number of the volume whose transaction mask + is being retrieved. + @param pulEventMask Populated with a bitwise-OR'd mask of automatic + transaction events which represent the current + transaction mode for the volume. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted; + or @p pulEventMask is `NULL`. +*/ +REDSTATUS RedFseTransMaskGet( + uint8_t bVolNum, + uint32_t *pulEventMask) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + ret = RedCoreTransMaskGet(pulEventMask); + + FseLeave(); + } + + return ret; +} +#endif + + +#if REDCONF_READ_ONLY == 0 +/** @brief Commit a transaction point. + + Reliance Edge is a transactional file system. All modifications, of both + metadata and filedata, are initially working state. A transaction point + is a process whereby the working state atomically becomes the committed + state, replacing the previous committed state. Whenever Reliance Edge is + mounted, including after power loss, the state of the file system after + mount is the most recent committed state. Nothing from the committed + state is ever missing, and nothing from the working state is ever included. + + @param bVolNum The volume number of the volume to transact. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number or not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The file system volume is read-only. +*/ +REDSTATUS RedFseTransact( + uint8_t bVolNum) +{ + REDSTATUS ret; + + ret = FseEnter(bVolNum); + + if(ret == 0) + { + ret = RedCoreVolTransact(); + + FseLeave(); + } + + return ret; +} +#endif + +/** @} */ + +/** @brief Enter the file system driver. + + @param bVolNum The volume to be accessed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The file system driver is uninitialized; or @p bVolNum + is not a valid volume number. +*/ +static REDSTATUS FseEnter( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(gfFseInited) + { + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + #endif + + ret = RedCoreVolSetCurrent(bVolNum); + + #if REDCONF_TASK_COUNT > 1U + if(ret != 0) + { + RedOsMutexRelease(); + } + #endif + } + else + { + ret = -RED_EINVAL; + } + + return ret; +} + + +/** @brief Leave the file system driver. +*/ +static void FseLeave(void) +{ + REDASSERT(gfFseInited); + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif +} + + +#endif /* REDCONF_API_FSE == 1 */ + diff --git a/include/redapimacs.h b/include/redapimacs.h new file mode 100644 index 0000000..cb3bd4a --- /dev/null +++ b/include/redapimacs.h @@ -0,0 +1,112 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines macros used to interact with the Reliance Edge API. +*/ +#ifndef REDAPIMAC_H +#define REDAPIMAC_H + + +/** Clear all events: manual transactions only. */ +#define RED_TRANSACT_MANUAL 0x00000000U + +/** Transact prior to unmounting in red_umount() or RedFseUnmount(). */ +#define RED_TRANSACT_UMOUNT 0x00000001U + +/** Transact after a successful red_open() which created a file. */ +#define RED_TRANSACT_CREAT 0x00000002U + +/** Transact after a successful red_unlink() or red_rmdir(). */ +#define RED_TRANSACT_UNLINK 0x00000004U + +/** Transact after a successful red_mkdir(). */ +#define RED_TRANSACT_MKDIR 0x00000008U + +/** Transact after a successful red_rename(). */ +#define RED_TRANSACT_RENAME 0x00000010U + +/** Transact after a successful red_link(). */ +#define RED_TRANSACT_LINK 0x00000020U + +/** Transact after a successful red_close(). */ +#define RED_TRANSACT_CLOSE 0x00000040U + +/** Transact after a successful red_write() or RedFseWrite(). */ +#define RED_TRANSACT_WRITE 0x00000080U + +/** Transact after a successful red_fsync(). */ +#define RED_TRANSACT_FSYNC 0x00000100U + +/** Transact after a successful red_ftruncate(), RedFseTruncate(), or red_open() with RED_O_TRUNC that actually truncates. */ +#define RED_TRANSACT_TRUNCATE 0x00000200U + +/** Transact to free space in disk full situations. */ +#define RED_TRANSACT_VOLFULL 0x00000400U + +#if REDCONF_READ_ONLY == 1 + +/** Mask of all supported automatic transaction events. */ +#define RED_TRANSACT_MASK 0U + +#elif REDCONF_API_POSIX == 1 + +/** @brief Mask of all supported automatic transaction events. +*/ +#define RED_TRANSACT_MASK \ +( \ + RED_TRANSACT_UMOUNT | \ + RED_TRANSACT_CREAT | \ + ((REDCONF_API_POSIX_UNLINK == 1) ? RED_TRANSACT_UNLINK : 0U) | \ + ((REDCONF_API_POSIX_MKDIR == 1) ? RED_TRANSACT_MKDIR : 0U) | \ + ((REDCONF_API_POSIX_RENAME == 1) ? RED_TRANSACT_RENAME : 0U) | \ + ((REDCONF_API_POSIX_LINK == 1) ? RED_TRANSACT_LINK : 0U) | \ + RED_TRANSACT_CLOSE | \ + RED_TRANSACT_WRITE | \ + RED_TRANSACT_FSYNC | \ + ((REDCONF_API_POSIX_FTRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \ + RED_TRANSACT_VOLFULL \ +) + +#else /* REDCONF_API_FSE == 1 */ + +/** @brief Mask of all supported automatic transaction events. +*/ +#define RED_TRANSACT_MASK \ +( \ + RED_TRANSACT_UMOUNT | \ + RED_TRANSACT_WRITE | \ + ((REDCONF_API_FSE_TRUNCATE == 1) ? RED_TRANSACT_TRUNCATE : 0U) | \ + RED_TRANSACT_VOLFULL \ +) + +#endif /* REDCONF_READ_ONLY */ + +#if (REDCONF_TRANSACT_DEFAULT & RED_TRANSACT_MASK) != REDCONF_TRANSACT_DEFAULT +#error "Configuration error: invalid value of REDCONF_TRANSACT_DEFAULT" +#endif + + +#endif + diff --git a/include/redconfigchk.h b/include/redconfigchk.h new file mode 100644 index 0000000..1e77b52 --- /dev/null +++ b/include/redconfigchk.h @@ -0,0 +1,299 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Compile-time validity checks for the REDCONF macros. +*/ +#ifndef REDCONFIGCHK_H +#define REDCONFIGCHK_H + +#ifndef REDCONF_READ_ONLY + #error "Configuration error: REDCONF_READ_ONLY must be defined." +#endif +#ifndef REDCONF_API_POSIX + #error "Configuration error: REDCONF_API_POSIX must be defined." +#endif +#ifndef REDCONF_API_FSE + #error "Configuration error: REDCONF_API_FSE must be defined." +#endif + +#if REDCONF_API_POSIX == 1 + #ifndef REDCONF_API_POSIX_FORMAT + #error "Configuration error: REDCONF_API_POSIX_FORMAT must be defined." + #endif + #ifndef REDCONF_API_POSIX_UNLINK + #error "Configuration error: REDCONF_API_POSIX_UNLINK must be defined." + #endif + #ifndef REDCONF_API_POSIX_MKDIR + #error "Configuration error: REDCONF_API_POSIX_MKDIR must be defined." + #endif + #ifndef REDCONF_API_POSIX_RMDIR + #error "Configuration error: REDCONF_API_POSIX_RMDIR must be defined." + #endif + #ifndef REDCONF_API_POSIX_RENAME + #error "Configuration error: REDCONF_API_POSIX_RENAME must be defined." + #endif + #ifndef REDCONF_API_POSIX_LINK + #error "Configuration error: REDCONF_API_POSIX_LINK must be defined." + #endif + #ifndef REDCONF_API_POSIX_FTRUNCATE + #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be defined." + #endif + #ifndef REDCONF_API_POSIX_READDIR + #error "Configuration error: REDCONF_API_POSIX_READDIR must be defined." + #endif + #ifndef REDCONF_NAME_MAX + #error "Configuration error: REDCONF_NAME_MAX must be defined." + #endif + #ifndef REDCONF_PATH_SEPARATOR + #error "Configuration error: REDCONF_PATH_SEPARATOR must be defined." + #endif + #ifndef REDCONF_RENAME_ATOMIC + #error "Configuration error: REDCONF_RENAME_ATOMIC must be defined." + #endif + #ifndef REDCONF_HANDLE_COUNT + #error "Configuration error: REDCONF_HANDLE_COUNT must be defined." + #endif +#else + #ifndef REDCONF_API_FSE_TRUNCATE + #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be defined." + #endif + #ifndef REDCONF_API_FSE_TRANSMASKSET + #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be defined." + #endif + #ifndef REDCONF_API_FSE_TRANSMASKGET + #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be defined." + #endif +#endif + +#ifndef REDCONF_TASK_COUNT + #error "Configuration error: REDCONF_TASK_COUNT must be defined." +#endif +#ifndef REDCONF_ENDIAN_BIG + #error "Configuration error: REDCONF_ENDIAN_BIG must be defined." +#endif +#ifndef REDCONF_ALIGNMENT_SIZE + #error "Configuration error: REDCONF_ALIGNMENT_SIZE must be defined." +#endif +#ifndef REDCONF_CRC_ALGORITHM + #error "Configuration error: REDCONF_CRC_ALGORITHM must be defined." +#endif +#ifndef REDCONF_INODE_TIMESTAMPS + #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be defined." +#endif +#ifndef REDCONF_ATIME + #error "Configuration error: REDCONF_ATIME must be defined." +#endif +#ifndef REDCONF_DIRECT_POINTERS + #error "Configuration error: REDCONF_DIRECT_POINTERS must be defined." +#endif +#ifndef REDCONF_INDIRECT_POINTERS + #error "Configuration error: REDCONF_INDIRECT_POINTERS must be defined." +#endif +#ifndef REDCONF_INODE_BLOCKS + #error "Configuration error: REDCONF_INODE_BLOCKS must be defined." +#endif +#ifndef REDCONF_IMAP_EXTERNAL + #error "Configuration error: REDCONF_IMAP_EXTERNAL must be defined." +#endif +#ifndef REDCONF_IMAP_INLINE + #error "Configuration error: REDCONF_IMAP_INLINE must be defined." +#endif +#ifndef REDCONF_OUTPUT + #error "Configuration error: REDCONF_OUTPUT must be defined." +#endif +#ifndef REDCONF_ASSERTS + #error "Configuration error: REDCONF_ASSERTS must be defined." +#endif +#ifndef REDCONF_TRANSACT_DEFAULT + #error "Configuration error: REDCONF_TRANSACT_DEFAULT must be defined." +#endif +#ifndef REDCONF_BUFFER_COUNT + #error "Configuration error: REDCONF_BUFFER_COUNT must be defined." +#endif +#ifndef REDCONF_BLOCK_SIZE + #error "Configuration error: REDCONF_BLOCK_SIZE must be defined." +#endif +#ifndef REDCONF_VOLUME_COUNT + #error "Configuration error: REDCONF_VOLUME_COUNT must be defined." +#endif +#ifndef REDCONF_IMAGE_BUILDER + #error "Configuration error: REDCONF_IMAGE_BUILDER must be defined." +#endif +#ifndef REDCONF_CHECKER + #error "Configuration error: REDCONF_CHECKER must be defined." +#endif + + +#if (REDCONF_READ_ONLY != 0) && (REDCONF_READ_ONLY != 1) + #error "Configuration error: REDCONF_READ_ONLY must be either 0 or 1" +#endif + +#if REDCONF_API_POSIX == 1 + #if REDCONF_API_FSE != 0 + #error "Configuration error: REDCONF_API_FSE must be 0 if REDCONF_API_POSIX is 1" + #endif + + #if (REDCONF_API_POSIX_FORMAT != 0) && (REDCONF_API_POSIX_FORMAT != 1) + #error "Configuration error: REDCONF_API_POSIX_FORMAT must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_UNLINK != 0) && (REDCONF_API_POSIX_UNLINK != 1) + #error "Configuration error: REDCONF_API_POSIX_UNLINK must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_MKDIR != 0) && (REDCONF_API_POSIX_MKDIR != 1) + #error "Configuration error: REDCONF_API_POSIX_MKDIR must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_RMDIR != 0) && (REDCONF_API_POSIX_RMDIR != 1) + #error "Configuration error: REDCONF_API_POSIX_RMDIR must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_RENAME != 0) && (REDCONF_API_POSIX_RENAME != 1) + #error "Configuration error: REDCONF_API_POSIX_RENAME must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_LINK != 0) && (REDCONF_API_POSIX_LINK != 1) + #error "Configuration error: REDCONF_API_POSIX_LINK must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_FTRUNCATE != 0) && (REDCONF_API_POSIX_FTRUNCATE != 1) + #error "Configuration error: REDCONF_API_POSIX_FTRUNCATE must be either 0 or 1." + #endif + + #if (REDCONF_API_POSIX_READDIR != 0) && (REDCONF_API_POSIX_READDIR != 1) + #error "Configuration error: REDCONF_API_POSIX_READDIR must be either 0 or 1." + #endif + + #if (REDCONF_NAME_MAX < 1) || (REDCONF_NAME_MAX > (REDCONF_BLOCK_SIZE - 4)) + #error "Configuration error: invalid value of REDCONF_NAME_MAX" + #endif + + #if (REDCONF_PATH_SEPARATOR < 1) || (REDCONF_PATH_SEPARATOR > 127) + #error "Configuration error: invalid value of REDCONF_PATH_SEPARATOR" + #endif + + #if (REDCONF_RENAME_ATOMIC != 0) && (REDCONF_RENAME_ATOMIC != 1) + #error "Configuration error: REDCONF_RENAME_ATOMIC must be either 0 or 1." + #endif + + #if (REDCONF_HANDLE_COUNT < 1U) || (REDCONF_HANDLE_COUNT > 4096U) + #error "Configuration error: invalid value of REDCONF_HANDLE_COUNT" + #endif + +#elif REDCONF_API_POSIX == 0 + #if REDCONF_API_FSE != 1 + #error "Configuration error: REDCONF_API_FSE must be 1 if REDCONF_API_POSIX is 0" + #endif + + #if (REDCONF_API_FSE_TRUNCATE != 0) && (REDCONF_API_FSE_TRUNCATE != 1) + #error "Configuration error: REDCONF_API_FSE_TRUNCATE must be either 0 or 1." + #endif + + #if (REDCONF_API_FSE_TRANSMASKSET != 0) && (REDCONF_API_FSE_TRANSMASKSET != 1) + #error "Configuration error: REDCONF_API_FSE_TRANSMASKSET must be either 0 or 1." + #endif + + #if (REDCONF_API_FSE_TRANSMASKGET != 0) && (REDCONF_API_FSE_TRANSMASKGET != 1) + #error "Configuration error: REDCONF_API_FSE_TRANSMASKGET must be either 0 or 1." + #endif + +#else + #error "REDCONF_API_POSIX" +#endif + +#if REDCONF_TASK_COUNT < 1U + #error "Configuration error: invalid value of REDCONF_TASK_COUNT" +#endif + +#if (REDCONF_ENDIAN_BIG != 0) && (REDCONF_ENDIAN_BIG != 1) + #error "Configuration error: REDCONF_ENDIAN_BIG must be either 0 or 1." +#endif + +#if (REDCONF_ALIGNMENT_SIZE != 1U) && (REDCONF_ALIGNMENT_SIZE != 2U) && (REDCONF_ALIGNMENT_SIZE != 4U) && (REDCONF_ALIGNMENT_SIZE != 8U) + #error "Configuration error: invalid value REDCONF_ALIGNMENT_SIZE" +#endif + +/* REDCONF_CRC_ALGORITHM checked in crc.c +*/ + +#if (REDCONF_INODE_TIMESTAMPS != 0) && (REDCONF_INODE_TIMESTAMPS != 1) + #error "Configuration error: REDCONF_INODE_TIMESTAMPS must be either 0 or 1." +#endif + +#if (REDCONF_ATIME != 0) && (REDCONF_ATIME != 1) + #error "Configuration error: REDCONF_ATIME must be either 0 or 1." +#endif + +/* REDCONF_DIRECT_POINTERS and REDCONF_INDIRECT_POINTERS checked in rednodes.h +*/ + +#if (REDCONF_INODE_BLOCKS != 0) && (REDCONF_INODE_BLOCKS != 1) + #error "Configuration error: REDCONF_INODE_BLOCKS must be either 0 or 1." +#endif + +/* Further validity checking of imap specs done in RelCoreInit() +*/ +#if (REDCONF_IMAP_EXTERNAL != 0) && (REDCONF_IMAP_EXTERNAL != 1) + #error "Configuration error: REDCONF_IMAP_EXTERNAL must be either 0 or 1." +#endif +#if (REDCONF_IMAP_INLINE != 0) && (REDCONF_IMAP_INLINE != 1) + #error "Configuration error: REDCONF_IMAP_INLINE must be either 0 or 1." +#endif +#if (REDCONF_IMAP_INLINE == 0) && (REDCONF_IMAP_EXTERNAL == 0) + #error "Configuration error: At least one of REDCONF_IMAP_INLINE and REDCONF_IMAP_EXTERNAL must be set" +#endif + +#if (REDCONF_OUTPUT != 0) && (REDCONF_OUTPUT != 1) + #error "Configuration error: REDCONF_OUTPUT must be either 0 or 1." +#endif + +#if (REDCONF_ASSERTS != 0) && (REDCONF_ASSERTS != 1) + #error "Configuration error: REDCONF_ASSERTS must be either 0 or 1." +#endif + +/* REDCONF_BLOCK_SIZE checked in redmacs.h +*/ + +#if (REDCONF_VOLUME_COUNT < 1U) || (REDCONF_VOLUME_COUNT > 255U) + #error "REDCONF_VOLUME_COUNT must be an integer between 1 and 255" +#endif + +/* REDCONF_BUFFER_COUNT lower limit checked in buffer.c +*/ +#if REDCONF_BUFFER_COUNT > 255U + #error "REDCONF_BUFFER_COUNT cannot be greater than 255" +#endif + +#if (REDCONF_IMAGE_BUILDER != 0) && (REDCONF_IMAGE_BUILDER != 1) + #error "Configuration error: REDCONF_IMAGE_BUILDER must be either 0 or 1." +#endif + +#if (REDCONF_CHECKER != 0) && (REDCONF_CHECKER != 1) + #error "Configuration error: REDCONF_CHECKER must be either 0 or 1." +#endif + + +#endif diff --git a/include/redcoreapi.h b/include/redcoreapi.h new file mode 100644 index 0000000..1e3e101 --- /dev/null +++ b/include/redcoreapi.h @@ -0,0 +1,97 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDCOREAPI_H +#define REDCOREAPI_H + + +#include + + +REDSTATUS RedCoreInit(void); +REDSTATUS RedCoreUninit(void); + +REDSTATUS RedCoreVolSetCurrent(uint8_t bVolNum); + +#if (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) +REDSTATUS RedCoreVolFormat(void); +#endif +#if REDCONF_CHECKER == 1 +REDSTATUS RedCoreVolCheck(void); +#endif +REDSTATUS RedCoreVolMount(void); +REDSTATUS RedCoreVolUnmount(void); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedCoreVolTransact(void); +#endif +#if REDCONF_API_POSIX == 1 +REDSTATUS RedCoreVolStat(REDSTATFS *pStatFS); +#endif + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_FSE == 0) || (REDCONF_API_FSE_TRANSMASKSET == 1)) +REDSTATUS RedCoreTransMaskSet(uint32_t ulEventMask); +#endif +#if (REDCONF_API_FSE == 0) || (REDCONF_API_FSE_TRANSMASKGET == 1) +REDSTATUS RedCoreTransMaskGet(uint32_t *pulEventMask); +#endif + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) +REDSTATUS RedCoreCreate(uint32_t ulPInode, const char *pszName, bool fDir, uint32_t *pulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_LINK == 1) +REDSTATUS RedCoreLink(uint32_t ulPInode, const char *pszName, uint32_t ulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) +REDSTATUS RedCoreUnlink(uint32_t ulPInode, const char *pszName); +#endif +#if REDCONF_API_POSIX == 1 +REDSTATUS RedCoreLookup(uint32_t ulPInode, const char *pszName, uint32_t *pulInode); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_RENAME == 1) +REDSTATUS RedCoreRename(uint32_t ulSrcPInode, const char *pszSrcName, uint32_t ulDstPInode, const char *pszDstName); +#endif +#if REDCONF_API_POSIX == 1 +REDSTATUS RedCoreStat(uint32_t ulInode, REDSTAT *pStat); +#endif +#if REDCONF_API_FSE == 1 +REDSTATUS RedCoreFileSizeGet(uint32_t ulInode, uint64_t *pullSize); +#endif + +REDSTATUS RedCoreFileRead(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedCoreFileWrite(uint32_t ulInode, uint64_t ullStart, uint32_t *pulLen, const void *pBuffer); +#endif +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_FSE == 0) || (REDCONF_API_FSE_TRUNCATE == 1)) && ((REDCONF_API_POSIX == 0) || (REDCONF_API_POSIX_FTRUNCATE == 1)) +REDSTATUS RedCoreFileTruncate(uint32_t ulInode, uint64_t ullSize); +#endif + +#if (REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_READDIR == 1) +REDSTATUS RedCoreDirRead(uint32_t ulInode, uint32_t *pulPos, char *pszName, uint32_t *pulInode); +#endif + + +#endif + diff --git a/include/rederrno.h b/include/rederrno.h new file mode 100644 index 0000000..9f462f7 --- /dev/null +++ b/include/rederrno.h @@ -0,0 +1,114 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Error values for Reliance Edge APIs +*/ +#ifndef REDERRNO_H +#define REDERRNO_H + + +/** @brief Return type for Reliance Edge error values. +*/ +typedef int32_t REDSTATUS; + + +/* The errno numbers are the same as Linux. +*/ + +/** Operation not permitted. */ +#define RED_EPERM 1 + +/** No such file or directory. */ +#define RED_ENOENT 2 + +/** I/O error. */ +#define RED_EIO 5 + +/** Bad file number. */ +#define RED_EBADF 9 + +/** Out of memory */ +#define RED_ENOMEM 12 + +/** Device or resource busy. */ +#define RED_EBUSY 16 + +/** File exists. */ +#define RED_EEXIST 17 + +/** Cross-device link. */ +#define RED_EXDEV 18 + +/** Not a directory. */ +#define RED_ENOTDIR 20 + +/** Is a directory. */ +#define RED_EISDIR 21 + +/** Invalid argument. */ +#define RED_EINVAL 22 + +/** File table overflow. */ +#define RED_ENFILE 23 + +/** Too many open files. */ +#define RED_EMFILE 24 + +/** File too large. */ +#define RED_EFBIG 27 + +/** No space left on device. */ +#define RED_ENOSPC 28 + +/** Read-only file system. */ +#define RED_EROFS 30 + +/** Too many links. */ +#define RED_EMLINK 31 + +/** Math result not representable. */ +#define RED_ERANGE 34 + +/** File name too long. */ +#define RED_ENAMETOOLONG 36 + +/** Function not implemented. */ +#define RED_ENOSYS 38 + +/** Directory not empty. */ +#define RED_ENOTEMPTY 39 + +/** No data available. */ +#define RED_ENODATA 61 + +/** Too many users. */ +#define RED_EUSERS 87 + +/** Nothing will be okay ever again. */ +#define RED_EFUBAR RED_EINVAL + + +#endif + diff --git a/include/redfs.h b/include/redfs.h new file mode 100644 index 0000000..74ed95f --- /dev/null +++ b/include/redfs.h @@ -0,0 +1,44 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDFS_H +#define REDFS_H + + +#include +#include "redconfigchk.h" +#include +#include "rederrno.h" +#include "redmacs.h" +#include "redapimacs.h" +#include "redutils.h" +#include "redosserv.h" +#include "redmisc.h" +#include "redver.h" + + +#endif + diff --git a/include/redfse.h b/include/redfse.h new file mode 100644 index 0000000..39886ca --- /dev/null +++ b/include/redfse.h @@ -0,0 +1,102 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Interface for the Reliance Edge FSE API. + + The FSE (File Systems Essentials) API is a minimalist file system API + intended for simple use cases with a fixed number of statically-defined + files. It does not support creating or deleting files dynamically. Files + are referenced by a fixed file number, rather than by name; there are no + file names and no directories. There are also no file handles: files are + not opened or closed, and file offsets are given explicitly. + + If the FSE API is too limited to meet the needs of your application, + consider using the more feature-rich POSIX-like file system API instead. +*/ +#ifndef REDFSE_H +#define REDFSE_H + +/* This header is intended for application use; some applications are written + in C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if REDCONF_API_FSE == 1 + +#include +#include +#include "rederrno.h" + + +/** @brief First valid file number. + + This macro can be used to statically define file numbers for given files, + as in the below example: + + ~~~{.c} + #define LOG_FILE (RED_FILENUM_FIRST_VALID) + #define DATABASE_FILE (RED_FILENUM_FIRST_VALID + 1U) + #define ICON1_FILE (RED_FILENUM_FIRST_VALID + 2U) + #define ICON2_FILE (RED_FILENUM_FIRST_VALID + 3U) + ~~~ +*/ +#define RED_FILENUM_FIRST_VALID (2U) + + +REDSTATUS RedFseInit(void); +REDSTATUS RedFseUninit(void); +REDSTATUS RedFseMount(uint8_t bVolNum); +REDSTATUS RedFseUnmount(uint8_t bVolNum); +int32_t RedFseRead(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +int32_t RedFseWrite(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullFileOffset, uint32_t ulLength, const void *pBuffer); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRUNCATE == 1) +REDSTATUS RedFseTruncate(uint8_t bVolNum, uint32_t ulFileNum, uint64_t ullNewFileSize); +#endif +int64_t RedFseSizeGet(uint8_t bVolNum, uint32_t ulFileNum); +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_FSE_TRANSMASKSET == 1) +REDSTATUS RedFseTransMaskSet(uint8_t bVolNum, uint32_t ulEventMask); +#endif +#if REDCONF_API_FSE_TRANSMASKGET == 1 +REDSTATUS RedFseTransMaskGet(uint8_t bVolNum, uint32_t *pulEventMask); +#endif +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedFseTransact(uint8_t bVolNum); +#endif + +#endif /* REDCONF_API_FSE == 1 */ + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/redmacs.h b/include/redmacs.h new file mode 100644 index 0000000..4fd4b37 --- /dev/null +++ b/include/redmacs.h @@ -0,0 +1,160 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDMACS_H +#define REDMACS_H + + +#ifndef NULL +#define NULL ((void *)0) +#endif + +#ifndef UINT8_MAX +#define UINT8_MAX (0xFFU) +#endif +#ifndef UINT16_MAX +#define UINT16_MAX (0xFFFFU) +#endif +#ifndef UINT32_MAX +#define UINT32_MAX (0xFFFFFFFFU) +#endif +#ifndef INT32_MAX +#define INT32_MAX (0x7FFFFFFF) +#endif +#ifndef INT64_MAX +#define INT64_MAX (0x7FFFFFFFFFFFFFFFULL) +#endif + +#ifndef true +#define true (1) +#endif +#ifndef false +#define false (0) +#endif + +#if REDCONF_BLOCK_SIZE == 256U +#define BLOCK_SIZE_P2 8U +#elif REDCONF_BLOCK_SIZE == 512U +#define BLOCK_SIZE_P2 9U +#elif REDCONF_BLOCK_SIZE == 1024U +#define BLOCK_SIZE_P2 10U +#elif REDCONF_BLOCK_SIZE == 2048U +#define BLOCK_SIZE_P2 11U +#elif REDCONF_BLOCK_SIZE == 4096U +#define BLOCK_SIZE_P2 12U +#elif REDCONF_BLOCK_SIZE == 8192U +#define BLOCK_SIZE_P2 13U +#elif REDCONF_BLOCK_SIZE == 16384U +#define BLOCK_SIZE_P2 14U +#elif REDCONF_BLOCK_SIZE == 32768U +#define BLOCK_SIZE_P2 15U +#elif REDCONF_BLOCK_SIZE == 65536U +#define BLOCK_SIZE_P2 16U +#else +#error "REDCONF_BLOCK_SIZE must be a power of two value between 256 and 65536" +#endif + +#define REDMIN(a, b) (((a) < (b)) ? (a) : (b)) + + +/** @brief Cast a pointer to a const uint8_t pointer. + + All usages of this macro deviate from MISRA-C:2012 Rule 11.5 (advisory). + Because there are no alignment requirements for a uint8_t pointer, this is + safe. However, it is technically a deviation from the rule. + + As Rule 11.5 is advisory, a deviation record is not required. This notice + and the PC-Lint error inhibition option are the only records of the + deviation. +*/ +#define CAST_VOID_PTR_TO_CONST_UINT8_PTR(PTR) ((const uint8_t *)(PTR)) + + +/** @brief Cast a pointer to a uint8_t pointer. + + All usages of this macro deviate from MISRA-C:2012 Rule 11.5 (advisory). + Because there are no alignment requirements for a uint8_t pointer, this is + safe. However, it is technically a deviation from the rule. + + As Rule 11.5 is advisory, a deviation record is not required. This notice + and the PC-Lint error inhibition option are the only records of the + deviation. +*/ +#define CAST_VOID_PTR_TO_UINT8_PTR(PTR) ((uint8_t *)(PTR)) + + +/** @brief Cast a pointer to a const uint32_t pointer. + + Usages of this macro may deviate from MISRA-C:2012 Rule 11.5 (advisory). + It is only used in cases where the pointer is known to be aligned, and thus + it is safe to do so. + + As Rule 11.5 is advisory, a deviation record is not required. This notice + and the PC-Lint error inhibition option are the only records of the + deviation. + + Usages of this macro may deviate from MISRA-C:2012 Rule 11.3 (required). + As Rule 11.3 is required, a separate deviation record is required. +*/ +#define CAST_CONST_UINT32_PTR(PTR) ((const uint32_t *)(const void *)(PTR)) + + +/** @brief Cast a pointer to a pointer, to (void **). + + Usages of this macro deviate from MISRA-C:2012 Rule 11.3 (required). + It is only used for populating a node structure pointer with a buffer + pointer. Buffer pointers are 8-byte aligned, thus it is safe to do so. + + As Rule 11.3 is required, a separate deviation record is required. +*/ +#define CAST_VOID_PTR_PTR(PTRPTR) ((void **)(PTRPTR)) + + +/** @brief Create a two-dimensional byte array which is safely aligned. + + Usages of this macro deviate from MISRA-C:2012 Rule 19.2 (advisory). + A union is required to force alignment of the block buffers, which are used + to access metadata nodes, which must be safely aligned for 64-bit types. + + As rule 19.2 is advisory, a deviation record is not required. This notice + and the PC-Lint error inhibition option are the only records of the + deviation. +*/ +#define ALIGNED_2D_BYTE_ARRAY(un, nam, size1, size2) \ + union \ + { \ + uint8_t nam[size1][size2]; \ + uint64_t DummyAlign; \ + } un + + + +#define INODE_INVALID (0U) /* General-purpose invalid inode number. */ +#define INODE_ROOTDIR (2U) /* Inode number of the root directory. */ + + +#endif + diff --git a/include/redmisc.h b/include/redmisc.h new file mode 100644 index 0000000..018ba04 --- /dev/null +++ b/include/redmisc.h @@ -0,0 +1,48 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDMISC_H +#define REDMISC_H + + +/** @brief Type of an inode or handle. + + Used to indicate the actual or expected type of an inode or handle. +*/ +typedef enum +{ + FTYPE_FILE, /**< Type is file. */ + FTYPE_DIR, /**< Type is directory. */ + + /** Type is either file or directory: used only to indicate an expected + type, never as an actual type. + */ + FTYPE_EITHER +} FTYPE; + + +#endif + diff --git a/include/redosserv.h b/include/redosserv.h new file mode 100644 index 0000000..77ecc02 --- /dev/null +++ b/include/redosserv.h @@ -0,0 +1,86 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDOSSERV_H +#define REDOSSERV_H + + +#include + + +/** @brief Type of access requested when opening a block device. +*/ +typedef enum +{ + BDEV_O_RDONLY, /**< Open block device for read access. */ + BDEV_O_WRONLY, /**< Open block device for write access. */ + BDEV_O_RDWR /**< Open block device for read and write access. */ +} BDEVOPENMODE; + +REDSTATUS RedOsBDevOpen(uint8_t bVolNum, BDEVOPENMODE mode); +REDSTATUS RedOsBDevClose(uint8_t bVolNum); +REDSTATUS RedOsBDevRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); + +#if REDCONF_READ_ONLY == 0 +REDSTATUS RedOsBDevWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); +REDSTATUS RedOsBDevFlush(uint8_t bVolNum); +#endif + +/* Non-standard API: for host machines only. +*/ +REDSTATUS RedOsBDevConfig(uint8_t bVolNum, const char *pszBDevSpec); + + +#if REDCONF_TASK_COUNT > 1U +REDSTATUS RedOsMutexInit(void); +REDSTATUS RedOsMutexUninit(void); +void RedOsMutexAcquire(void); +void RedOsMutexRelease(void); +#endif +#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) +uint32_t RedOsTaskId(void); +#endif + +REDSTATUS RedOsClockInit(void); +REDSTATUS RedOsClockUninit(void); +uint32_t RedOsClockGetTime(void); + +REDSTATUS RedOsTimestampInit(void); +REDSTATUS RedOsTimestampUninit(void); +REDTIMESTAMP RedOsTimestamp(void); +uint64_t RedOsTimePassed(REDTIMESTAMP tsSince); + +#if REDCONF_OUTPUT == 1 +void RedOsOutputString(const char *pszString); +#endif + +#if REDCONF_ASSERTS == 1 +void RedOsAssertFail(const char *pszFileName, uint32_t ulLineNum); +#endif + + +#endif + diff --git a/include/redposix.h b/include/redposix.h new file mode 100644 index 0000000..98979a1 --- /dev/null +++ b/include/redposix.h @@ -0,0 +1,196 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Interface for the Reliance Edge POSIX-like API. + + The POSIX-like file system API is the primary file system API for + Reliance Edge, which supports the full functionality of the file system. + This API aims to be compatible with POSIX where reasonable, but it is + simplified considerably to meet the needs of resource-constrained embedded + systems. The API has also been extended to provide access to the unique + features of Reliance Edge, and to cover areas (like mountins and formatting) + which do not have APIs in the POSIX specification. +*/ +#ifndef REDPOSIX_H +#define REDPOSIX_H + +/* This header is intended for application use; some applications are written + in C++. +*/ +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if REDCONF_API_POSIX == 1 + +#include +#include +#include "rederrno.h" +#include "redstat.h" + +/** Open for reading only. */ +#define RED_O_RDONLY 0x00000001U + +/** Open for writing only. */ +#define RED_O_WRONLY 0x00000002U + +/** Open for reading and writing. */ +#define RED_O_RDWR 0x00000004U + +/** File offset for all writes is end-of-file. */ +#define RED_O_APPEND 0x00000008U + +/** Create the file. */ +#define RED_O_CREAT 0x00000010U + +/** Error if path already exists. */ +#define RED_O_EXCL 0x00000020U + +/** Truncate file to size zero. */ +#define RED_O_TRUNC 0x00000040U + + +/** @brief Last file system error (errno). + + Under normal circumstances, each task using the file system has an + independent `red_errno` value. Applications do not need to worry about + one task obliterating an error value that another task needed to read. The + value is initially zero. When one of the POSIX-like APIs return an + indication of error, `red_errno` is set to an error value. + + In some circumstances, `red_errno` will be a global errno location which + is shared by multiple tasks. If the calling task is not registered as a + file system user and all of the task slots are full, there can be no + task-specific errno, so the global errno is used. Likewise, if the file + system driver is uninitialized, there are no registered file system users + and `red_errno` always refers to the global errno. Under these + circumstances, multiple tasks manipulating `red_errno` could be + problematic. When the task count is set to one, `red_errno` always refers + to the global errno. + + Note that `red_errno` is usable as an lvalue; i.e., in addition to reading + the error value, the error value can be set: + + ~~~{.c} + red_errno = 0; + ~~~ +*/ +#define red_errno (*red_errnoptr()) + + +/** @brief Positions from which to seek within a file. +*/ +typedef enum +{ + /* 0/1/2 are the traditional values for SET/CUR/END, respectively. Prior + to the release of Unix System V in 1983, the SEEK_* symbols did not + exist and C programs hard-coded the 0/1/2 values with those meanings. + */ + RED_SEEK_SET = 0, /**< Set file offset to given offset. */ + RED_SEEK_CUR = 1, /**< Set file offset to current offset plus signed offset. */ + RED_SEEK_END = 2 /**< Set file offset to EOF plus signed offset. */ +} REDWHENCE; + + +#if REDCONF_API_POSIX_READDIR == 1 +/** @brief Opaque directory handle. +*/ +typedef struct sREDHANDLE REDDIR; + + +/** @brief Directory entry information. +*/ +typedef struct +{ + uint32_t d_ino; /**< File serial number (inode number). */ + char d_name[REDCONF_NAME_MAX+1U]; /**< Name of entry. */ + REDSTAT d_stat; /**< File information (POSIX extension). */ +} REDDIRENT; +#endif + + +int32_t red_init(void); +int32_t red_uninit(void); +int32_t red_mount(const char *pszVolume); +int32_t red_umount(const char *pszVolume); +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) +int32_t red_format(const char *pszVolume); +#endif +#if REDCONF_READ_ONLY == 0 +int32_t red_transact(const char *pszVolume); +#endif +#if REDCONF_READ_ONLY == 0 +int32_t red_settransmask(const char *pszVolume, uint32_t ulEventMask); +#endif +int32_t red_gettransmask(const char *pszVolume, uint32_t *pulEventMask); +int32_t red_statvfs(const char *pszVolume, REDSTATFS *pStatvfs); +int32_t red_open(const char *pszPath, uint32_t ulOpenMode); +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1) +int32_t red_unlink(const char *pszPath); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1) +int32_t red_mkdir(const char *pszPath); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1) +int32_t red_rmdir(const char *pszPath); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) +int32_t red_rename(const char *pszOldPath, const char *pszNewPath); +#endif +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1) +int32_t red_link(const char *pszPath, const char *pszHardLink); +#endif +int32_t red_close(int32_t iFildes); +int32_t red_read(int32_t iFildes, void *pBuffer, uint32_t ulLength); +#if REDCONF_READ_ONLY == 0 +int32_t red_write(int32_t iFildes, const void *pBuffer, uint32_t ulLength); +#endif +#if REDCONF_READ_ONLY == 0 +int32_t red_fsync(int32_t iFildes); +#endif +int64_t red_lseek(int32_t iFildes, int64_t llOffset, REDWHENCE whence); +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) +int32_t red_ftruncate(int32_t iFildes, uint64_t ullSize); +#endif +int32_t red_fstat(int32_t iFildes, REDSTAT *pStat); +#if REDCONF_API_POSIX_READDIR == 1 +REDDIR *red_opendir(const char *pszPath); +REDDIRENT *red_readdir(REDDIR *pDirStream); +void red_rewinddir(REDDIR *pDirStream); +int32_t red_closedir(REDDIR *pDirStream); +#endif +REDSTATUS *red_errnoptr(void); + +#endif /* REDCONF_API_POSIX */ + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/include/redstat.h b/include/redstat.h new file mode 100644 index 0000000..dbbdca3 --- /dev/null +++ b/include/redstat.h @@ -0,0 +1,94 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDSTAT_H +#define REDSTAT_H + + +/** Mode bit for a directory. */ +#define RED_S_IFDIR 0x4000U + +/** Mode bit for a regular file. */ +#define RED_S_IFREG 0x8000U + +/** @brief Test for a directory. +*/ +#define RED_S_ISDIR(m) (((m) & RED_S_IFDIR) != 0U) + +/** @brief Test for a regular file. +*/ +#define RED_S_ISREG(m) (((m) & RED_S_IFREG) != 0U) + + +/** File system is read-only. */ +#define RED_ST_RDONLY 0x00000001U + +/** File system ignores suid and sgid bits. */ +#define RED_ST_NOSUID 0x00000002U + + +/** @brief Status information on an inode. +*/ +typedef struct +{ + uint8_t st_dev; /**< Volume number of volume containing file. */ + uint32_t st_ino; /**< File serial number (inode number). */ + uint16_t st_mode; /**< Mode of file. */ + uint16_t st_nlink; /**< Number of hard links to the file. */ + uint64_t st_size; /**< File size in bytes. */ + #if REDCONF_INODE_TIMESTAMPS == 1 + uint32_t st_atime; /**< Time of last access (seconds since 01-01-1970). */ + uint32_t st_mtime; /**< Time of last data modification (seconds since 01-01-1970). */ + uint32_t st_ctime; /**< Time of last status change (seconds since 01-01-1970). */ + #endif + #if REDCONF_INODE_BLOCKS == 1 + uint32_t st_blocks; /**< Number of blocks allocated for this object. */ + #endif +} REDSTAT; + + +/** @brief Status information on a file system volume. +*/ +typedef struct +{ + uint32_t f_bsize; /**< File system block size. */ + uint32_t f_frsize; /**< Fundamental file system block size. */ + uint32_t f_blocks; /**< Total number of blocks on file system in units of f_frsize. */ + uint32_t f_bfree; /**< Total number of free blocks. */ + uint32_t f_bavail; /**< Number of free blocks available to non-privileged process. */ + uint32_t f_files; /**< Total number of file serial numbers. */ + uint32_t f_ffree; /**< Total number of free file serial numbers. */ + uint32_t f_favail; /**< Number of file serial numbers available to non-privileged process. */ + uint32_t f_fsid; /**< File system ID (useless, populated with zero). */ + uint32_t f_flag; /**< Bit mask of f_flag values. Includes read-only file system flag. */ + uint32_t f_namemax; /**< Maximum filename length. */ + uint64_t f_maxfsize; /**< Maximum file size (POSIX extension). */ + uint32_t f_dev; /**< Volume number (POSIX extension). */ +} REDSTATFS; + + +#endif + diff --git a/include/redtests.h b/include/redtests.h new file mode 100644 index 0000000..38e1636 --- /dev/null +++ b/include/redtests.h @@ -0,0 +1,80 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Prototypes for Reliance Edge test entry points. +*/ +#ifndef REDTESTS_H +#define REDTESTS_H + +#include +#include "redtestutils.h" +#include "redver.h" + +/* This macro is only defined by the error injection project. +*/ +#ifdef REDCONF_ERROR_INJECTION +#include +#endif + +#define FSSTRESS_SUPPORTED \ + ( ((RED_KIT == RED_KIT_GPL) || (RED_KIT == RED_KIT_SANDBOX)) \ + && (REDCONF_API_POSIX == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1) \ + && (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) && (REDCONF_API_POSIX_RENAME == 1) \ + && (REDCONF_API_POSIX_LINK == 1) && (REDCONF_API_POSIX_FTRUNCATE == 1) && (REDCONF_API_POSIX_READDIR == 1)) + +#define FSE_STRESS_TEST_SUPPORTED \ + ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ + && (REDCONF_API_FSE == 1) && (REDCONF_READ_ONLY == 0)) + +#define POSIX_API_TEST_SUPPORTED \ + ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ + && (REDCONF_API_POSIX == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1)) + +#define STOCH_POSIX_TEST_SUPPORTED \ + ( ((RED_KIT == RED_KIT_COMMERCIAL) || (RED_KIT == RED_KIT_SANDBOX)) \ + && (REDCONF_API_POSIX == 1) && (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) \ + && (REDCONF_API_POSIX_READDIR == 1) && (REDCONF_API_POSIX_MKDIR == 1) && (REDCONF_API_POSIX_RMDIR == 1) \ + && (REDCONF_API_POSIX_UNLINK == 1)) + + +#if FSSTRESS_SUPPORTED +int fsstress_main(int argc, char **argv); +#endif + +#if STOCH_POSIX_TEST_SUPPORTED +int RedStochPosix(int argc, char ** argv); +#endif + +#if FSE_STRESS_TEST_SUPPORTED +void RedFseStressTest(void); +#endif + +#if POSIX_API_TEST_SUPPORTED +int RedTestPosixMain(int argc, char * argv[]); +#endif + + +#endif + diff --git a/include/redtestutils.h b/include/redtestutils.h new file mode 100644 index 0000000..01990cd --- /dev/null +++ b/include/redtestutils.h @@ -0,0 +1,47 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Reliance Edge utilities only needed for tests. +*/ +#ifndef REDTESTUTILS_H +#define REDTESTUTILS_H + + +void RedRandSeed(uint64_t ullSeed); +uint64_t RedRand64(uint64_t *pullSeed); +uint32_t RedRand32(uint32_t *pulSeed); + +#include + +#if REDCONF_OUTPUT == 1 +void RedPrintf(const char *pszFormat, ...); +void RedVPrintf(const char *pszFormat, va_list arglist); +#endif +int32_t RedSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, ...); +int32_t RedVSNPrintf(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, va_list arglist); + + +#endif + diff --git a/include/redutils.h b/include/redutils.h new file mode 100644 index 0000000..a2f2518 --- /dev/null +++ b/include/redutils.h @@ -0,0 +1,87 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDUTILS_H +#define REDUTILS_H + + +#define REDASSERT(EXP) ((EXP) ? (void)0 : REDERROR()) + +#if REDCONF_ASSERTS == 1 +#define REDERROR() RedOsAssertFail(__FILE__, __LINE__) +#else +#define REDERROR() ((void)0) +#endif + + +#ifndef RedMemCpy +void RedMemCpy(void *pDest, const void *pSrc, uint32_t ulLen); +#endif +#ifndef RedMemMove +void RedMemMove(void *pDest, const void *pSrc, uint32_t ulLen); +#endif +#ifndef RedMemSet +void RedMemSet(void *pDest, uint8_t bVal, uint32_t ulLen); +#endif +#ifndef RedMemCmp +int32_t RedMemCmp(const void *pMem1, const void *pMem2, uint32_t ulLen); +#endif + +#ifndef RedStrLen +uint32_t RedStrLen(const char *pszStr); +#endif +#ifndef RedStrCmp +int32_t RedStrCmp(const char *pszStr1, const char *pszStr2); +#endif +#ifndef RedStrNCmp +int32_t RedStrNCmp(const char *pszStr1, const char *pszStr2, uint32_t ulLen); +#endif +#ifndef RedStrNCpy +void RedStrNCpy(char *pszDst, const char *pszSrc, uint32_t ulLen); +#endif + +uint32_t RedCrc32Update(uint32_t ulInitCrc32, const void *pBuffer, uint32_t ulLength); +uint32_t RedCrcNode(const void *pBuffer); + +#if REDCONF_API_POSIX == 1 +uint32_t RedNameLen(const char *pszName); +#endif + +bool RedBitGet(const uint8_t *pbBitmap, uint32_t ulBit); +void RedBitSet(uint8_t *pbBitmap, uint32_t ulBit); +void RedBitClear(uint8_t *pbBitmap, uint32_t ulBit); + +#ifdef REDCONF_ENDIAN_SWAP +uint64_t RedRev64(uint64_t ullToRev); +uint32_t RedRev32(uint32_t ulToRev); +uint16_t RedRev16(uint16_t uToRev); +#endif + +void RedSignOn(void); + + +#endif + diff --git a/include/redver.h b/include/redver.h new file mode 100644 index 0000000..9bfefba --- /dev/null +++ b/include/redver.h @@ -0,0 +1,118 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Macros for version numbers, build number, and product information. +*/ +#ifndef REDVER_H +#define REDVER_H + + +/** @brief Consecutive number assigned to each automated build. + + +*/ +#define RED_BUILD_NUMBER "329" + +/** @brief Date of the last automated build. + + +*/ +#define RED_BUILD_DATE "04/29/15" + +/** @brief Time of the last automated build. + + +*/ +#define RED_BUILD_TIME "16:53:33" + +#define RED_KIT_GPL 0U /* Open source GPL kit. */ +#define RED_KIT_COMMERCIAL 1U /* Commercially-licensed kit. */ +#define RED_KIT_SANDBOX 2U /* Not a kit: developer sandbox. */ + +/** @brief Indicates the Reliance Edge kit. + + +*/ +#define RED_KIT RED_KIT_GPL + + +/** @brief Version number to display in output. +*/ +#define RED_VERSION "v0.9" + + +/** @brief On-disk version number. + + This is incremented only when the on-disk layout is updated in such a way + which is incompatible with previously released versions of the file system. +*/ +#define RED_DISK_LAYOUT_VERSION 1U + + +/** @brief Base name of the file system product. +*/ +#define RED_PRODUCT_BASE_NAME "Reliance Edge" + + +/* Specifies whether the product is in alpha stage, beta stage, or neither. +*/ +#if 1 + #if 0 + #define ALPHABETA " (Alpha)" + #else + #define ALPHABETA " (Beta)" + #endif +#else + #define ALPHABETA "" +#endif + +/** @brief Full product name and version. +*/ +#define RED_PRODUCT_NAME "Datalight "RED_PRODUCT_BASE_NAME" "RED_VERSION" Build "RED_BUILD_NUMBER ALPHABETA + + +/** @brief Product copyright. +*/ +#define RED_PRODUCT_LEGAL "Copyright (c) 2014-2015 Datalight, Inc. All Rights Reserved Worldwide." + + +/** @brief Product patents. +*/ +#define RED_PRODUCT_PATENT "Patents: US#7284101." + + +/** @brief Product edition. +*/ +#if RED_KIT == RED_KIT_GPL +#define RED_PRODUCT_EDITION "Open-Source GPLv2 Edition -- Compiled "__DATE__" at "__TIME__ +#elif RED_KIT == RED_KIT_COMMERCIAL +#define RED_PRODUCT_EDITION "Commercial Edition -- Compiled "__DATE__" at "__TIME__ +#else +#define RED_PRODUCT_EDITION "Developer Sandbox -- Compiled "__DATE__" at "__TIME__ +#endif + + +#endif + diff --git a/include/redvolume.h b/include/redvolume.h new file mode 100644 index 0000000..3d08348 --- /dev/null +++ b/include/redvolume.h @@ -0,0 +1,134 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDVOLUME_H +#define REDVOLUME_H + + +/** @brief Per-volume configuration structure. + + Contains the configuration values that may differ between volumes. Must be + declared in an array in redconf.c in the Reliance Edge project directory and + statically initialized with values representing the volume configuration of + the target system. +*/ +typedef struct +{ + /** The sector size for the block device underlying the volume: the basic + unit for reading and writing to the storage media. Commonly ranges + between 512 and 4096, but any power-of-two value not greater than the + block size will work. + */ + uint32_t ulSectorSize; + + /** The number of sectors in this file system volume. + */ + uint64_t ullSectorCount; + + /** Whether a sector write on the block device underlying the volume is + atomic. It is atomic if when the sector write is interrupted, the + contents of the sector are guaranteed to be either all of the new data, + or all of the old data. If unsure, leave as false. + */ + bool fAtomicSectorWrite; + + /** This is the maximum number of inodes (files and directories). This + number includes the root directory inode (inode 2; created during + format), but does not include inodes 0 or 1, which do not exist on + disk. The number of inodes cannot be less than 1. + */ + uint32_t ulInodeCount; + + #if REDCONF_API_POSIX == 1 + /** The path prefix for the volume; for example, "VOL1:", "FlashDisk", etc. + */ + const char *pszPathPrefix; + #endif +} VOLCONF; + +extern const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT]; +extern const VOLCONF *gpRedVolConf; + + +/** @brief Per-volume run-time data. +*/ +typedef struct +{ + /** Whether the volume is currently mounted. + */ + bool fMounted; + + #if REDCONF_READ_ONLY == 0 + /** Whether the volume is read-only. + */ + bool fReadOnly; + + /** The active automatic transaction mask. + */ + uint32_t ulTransMask; + #endif + + /** The power of 2 difference between sector size and block size. + */ + uint8_t bBlockSectorShift; + + /** The number of logical blocks in this file system volume. The unit here + is the global block size. + */ + uint32_t ulBlockCount; + + /** The total number of allocable blocks; Also the maximum count of free + blocks. + */ + uint32_t ulBlocksAllocable; + + /** The maximum number of bytes that an inode is capable of addressing. + */ + uint64_t ullMaxInodeSize; + + /** The current metadata sequence number. This value is included in all + metadata nodes and incremented every time a metadata node is written. + It is assumed to never wrap around. + */ + uint64_t ullSequence; +} VOLUME; + +/* Array of VOLUME structures, populated at during RedCoreInit(). +*/ +extern VOLUME gaRedVolume[REDCONF_VOLUME_COUNT]; + +/* Volume number currently being accessed; populated during + RedCoreVolSetCurrent(). +*/ +extern uint8_t gbRedVolNum; + +/* Pointer to the volume currently being accessed; populated during + RedCoreVolSetCurrent(). +*/ +extern VOLUME *gpRedVolume; + +#endif + diff --git a/os/freertos/include/ostypes.h b/os/freertos/include/ostypes.h new file mode 100644 index 0000000..1601392 --- /dev/null +++ b/os/freertos/include/ostypes.h @@ -0,0 +1,39 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef OSTYPES_H +#define OSTYPES_H + + +/** @brief Implementation-defined timestamp type. + + This can be an integer, a structure, or a pointer: anything that is + convenient for the implementation. Since the underlying type is not fixed, + common code should treat this as an opaque type. +*/ +typedef uint32_t REDTIMESTAMP; + + +#endif + diff --git a/os/freertos/services/osassert.c b/os/freertos/services/osassert.c new file mode 100644 index 0000000..b400db4 --- /dev/null +++ b/os/freertos/services/osassert.c @@ -0,0 +1,59 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements assertion handling. +*/ +#include + +#if REDCONF_ASSERTS == 1 + +#include + + +/** @brief Invoke the native assertion handler. + + @param pszFileName Null-terminated string containing the name of the file + where the assertion fired. + @param ulLineNum Line number in @p pszFileName where the assertion + fired. +*/ +void RedOsAssertFail( + const char *pszFileName, + uint32_t ulLineNum) +{ + #if REDCONF_OUTPUT == 1 + printf("Assertion failed in \"%s\" at line %u\n\r", pszFileName, (unsigned)ulLineNum); + #else + (void)pszFileName; + (void)ulLineNum; + #endif + + while(true) + { + } +} + +#endif + diff --git a/os/freertos/services/osbdev.c b/os/freertos/services/osbdev.c new file mode 100644 index 0000000..d31e33f --- /dev/null +++ b/os/freertos/services/osbdev.c @@ -0,0 +1,1205 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements block device I/O. +*/ +#include + +#include +#include + + +/*------------------------------------------------------------------------------ + Porting Note: + + Several example implementations of this module for FreeRTOS are available. + If you are lucky, you can use one of these implementations; otherwise, these + can serve as examples of how to implement this service. +------------------------------------------------------------------------------*/ + +/** @brief The F_DRIVER example implementation. + + This implementation is designed to reuse an existing block device driver + that was written for FreeRTOS+FAT SL. If you have such a driver, with + little work it can be "dropped in" and used for Reliance Edge. The only + customization required is that gpfnRedOsBDevInit needs to be defined and + pointed at the F_DRIVERINIT function. This can be done in this module or in + another C file. + + The disadantage of using the FreeRTOS F_DRIVER functions is that they only + support single-sector reads and writes. Reliance Edge will issue + multi-sector requests, and servicing these one sector at a time will + significantly slow down the file system. +*/ +#define BDEV_F_DRIVER 0U + +/** @brief The FatFs example implementation. + + This implementation is designed to reuse an existing block device driver + that was written for FatFs. If you have such a driver, it can be linked + in and used immediately. The FatFs `diskio.h` header must be in the include + directory path. +*/ +#define BDEV_FATFS 1U + +/** @brief The Atmel Studio Framework SD/MMC driver example implementation. + + This implementation uses a modified version of the open source SD/MMC driver + included in the Atmel Studio Framework (ASF) and will work as-is for many + varieties of Atmel hardware. This example assumes relatively minor + modifications to the ASF SD/MMC driver to make it support multi-sector read + and write requests, which greatly improves performance. The modified driver + is distributed with Reliance Edge and is included in FreeRTOS Atmel projects + (such as in projects/freertos/atmel/sam4e-ek/src/ASF). + + This example can easily be modified to work with an unmodified version of + the ASF SD/MMC driver. Simply replace sd_mmc_mem_2_ram_multi() and + sd_mmc_ram_2_mem_multi() with sd_mmc_mem_2_ram() and sd_mmc_ram_2_mem() + respectively, and add a for loop to loop over each sector in the request. + However, as described in the manual, there are considerable performance + advantages to issuing real multi-sector requests, so using the modified + driver is recommended. +*/ +#define BDEV_ATMEL_SDMMC 2U + +/** @brief The RAM disk example implementation. + + This implementation uses a RAM disk. It will allow you to compile and test + Reliance Edge even if your storage driver is not yet ready. On typical + target hardware, the amount of spare RAM will be limited so generally only + very small disks will be available. +*/ +#define BDEV_RAM_DISK 3U + +/** @brief Pick which example implementation is compiled. + + Must be one of: + - #BDEV_F_DRIVER + - #BDEV_FATFS + - #BDEV_ATMEL_SDMMC + - #BDEV_RAM_DISK +*/ +#define BDEV_EXAMPLE_IMPLEMENTATION BDEV_ATMEL_SDMMC + + +static REDSTATUS DiskOpen(uint8_t bVolNum, BDEVOPENMODE mode); +static REDSTATUS DiskClose(uint8_t bVolNum); +static REDSTATUS DiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS DiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); +static REDSTATUS DiskFlush(uint8_t bVolNum); +#endif + + +/** @brief Initialize a block device. + + This function is called when the file system needs access to a block + device. + + Upon successful return, the block device should be fully initialized and + ready to service read/write/flush/close requests. + + The behavior of calling this function on a block device which is already + open is undefined. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskOpen(bVolNum, mode); + } + + return ret; +} + + +/** @brief Uninitialize a block device. + + This function is called when the file system no longer needs access to a + block device. If any resource were allocated by RedOsBDevOpen() to service + block device requests, they should be freed at this time. + + Upon successful return, the block device must be in such a state that it + can be opened again. + + The behavior of calling this function on a block device which is already + closed is undefined. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. +*/ +REDSTATUS RedOsBDevClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskClose(bVolNum); + } + + return ret; +} + + +/** @brief Read sectors from a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_WRONLY. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret = 0; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret = 0; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + This function must synchronously flush all software and hardware caches + beneath the file system, ensuring that all sectors written previously are + committed to permanent storage. + + If the environment has no caching beneath the file system, the + implementation of this function can do nothing and return success. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + ret = DiskFlush(bVolNum); + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#if BDEV_EXAMPLE_IMPLEMENTATION == BDEV_F_DRIVER + +#include + + +/* This must be declared and initialized elsewere (e.g., in project code) to + point at the initialization function for the F_DRIVER block device. +*/ +extern const F_DRIVERINIT gpfnRedOsBDevInit; + +static F_DRIVER *gapFDriver[REDCONF_VOLUME_COUNT]; + + +/** @brief Initialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret; + + (void)mode; + + if((gpfnRedOsBDevInit == NULL) || (gapFDriver[bVolNum] != NULL)) + { + ret = -RED_EINVAL; + } + else + { + F_DRIVER *pDriver; + + pDriver = gpfnRedOsBDevInit(bVolNum); + if(pDriver != NULL) + { + F_PHY geom; + int iErr; + + /* Validate that the geometry is consistent with the volume + configuration. + */ + iErr = pDriver->getphy(pDriver, &geom); + if(iErr == 0) + { + if( (geom.bytes_per_sector != gaRedVolConf[bVolNum].ulSectorSize) + || (geom.number_of_sectors < gaRedVolConf[bVolNum].ullSectorCount)) + { + ret = -RED_EINVAL; + } + else + { + gapFDriver[bVolNum] = pDriver; + ret = 0; + } + } + else + { + ret = -RED_EIO; + } + + if(ret != 0) + { + pDriver->release(pDriver); + } + } + else + { + ret = -RED_EIO; + } + } + + return ret; +} + + +/** @brief Uninitialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(gapFDriver[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + gapFDriver[bVolNum]->release(gapFDriver[bVolNum]); + gapFDriver[bVolNum] = NULL; + + ret = 0; + } + + return ret; +} + + +/** @brief Read sectors from a disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret = 0; + F_DRIVER *pDriver = gapFDriver[bVolNum]; + + if(pDriver == NULL) + { + ret = -RED_EINVAL; + } + else + { + uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulSectorIdx; + int iErr; + + for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) + { + iErr = pDriver->readsector(pDriver, &pbBuffer[ulSectorIdx * ulSectorSize], + (unsigned long)(ullSectorStart + ulSectorCount)); + if(iErr != 0) + { + ret = -RED_EIO; + break; + } + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The block device is not open. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret = 0; + F_DRIVER *pDriver = gapFDriver[bVolNum]; + + if(pDriver == NULL) + { + ret = -RED_EINVAL; + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulSectorIdx; + int iErr; + + for(ulSectorIdx = 0U; ulSectorIdx < ulSectorCount; ulSectorIdx++) + { + /* We have to cast pbBuffer to non-const since the writesector + prototype is flawed, using a non-const pointer for the buffer. + */ + iErr = pDriver->writesector(pDriver, (uint8_t *)&pbBuffer[ulSectorIdx * ulSectorSize], + (unsigned long)(ullSectorStart + ulSectorCount)); + if(iErr != 0) + { + ret = -RED_EIO; + break; + } + } + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(gapFDriver[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + /* The F_DRIVER interface does not include a flush function, so to be + reliable the F_DRIVER implementation must use synchronous writes. + */ + ret = 0; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_FATFS + +#include +#include + +/* disk_read() and disk_write() use an unsigned 8-bit value to specify the + sector count, so no transfer can be larger than 255 sectors. +*/ +#define MAX_SECTOR_TRANSFER UINT8_MAX + + +/** @brief Initialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + DSTATUS status; + uint32_t ulTries; + REDSTATUS ret = 0; + + /* Assuming that the volume number is also the correct drive number. If + this is not the case in your environment, a static constant array can be + declared to map volume numbers to the correct driver number. + */ + for(ulTries = 0U; ulTries < 20U; ulTries++) + { + status = disk_initialize(bVolNum); + if(status == 0) + { + break; + } + + vTaskDelay(500U / portTICK_PERIOD_MS); + } + + if(status != 0) + { + ret = -RED_EIO; + } + + /* Retrieve the sector size and sector count to ensure they are compatible + with our compile-time geometry. + */ + if(ret == 0) + { + WORD wSectorSize; + DWORD dwSectorCount; + DRESULT result; + + result = disk_ioctl(bVolNum, GET_SECTOR_SIZE, &wSectorSize); + if(result == RES_OK) + { + result = disk_ioctl(bVolNum, GET_SECTOR_COUNT, &dwSectorCount); + if(result == RES_OK) + { + if( (wSectorSize != gaRedVolConf[bVolNum].ulSectorSize) + || (dwSectorCount < gaRedVolConf[bVolNum].ullSectorCount)) + { + ret = -RED_EINVAL; + } + } + else + { + ret = -RED_EIO; + } + } + else + { + ret = -RED_EIO; + } + } + + return ret; +} + + +/** @brief Uninitialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskClose( + uint8_t bVolNum) +{ + (void)bVolNum; + return 0; +} + + +/** @brief Read sectors from a disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); + + while(ulSectorIdx < ulSectorCount) + { + uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); + DRESULT result; + + result = disk_read(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer); + if(result != RES_OK) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + + while(ulSectorIdx < ulSectorCount) + { + uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); + DRESULT result; + + result = disk_write(bVolNum, &pbBuffer[ulSectorIdx * ulSectorSize], (DWORD)(ullSectorStart + ulSectorIdx), (BYTE)ulTransfer); + if(result != RES_OK) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + DRESULT result; + + result = disk_ioctl(bVolNum, CTRL_SYNC, NULL); + if(result == RES_OK) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_ATMEL_SDMMC + +#include + +#include +#include +#include +#include + +/* sd_mmc_mem_2_ram_multi() and sd_mmc_ram_2_mem_multi() use an unsigned + 16-bit value to specify the sector count, so no transfer can be larger + than UINT16_MAX sectors. +*/ +#define MAX_SECTOR_TRANSFER UINT16_MAX + + +/** @brief Initialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The device is read-only media and write access was + requested. +*/ +static REDSTATUS DiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret = 0; + uint32_t ulTries; + Ctrl_status cs; + + /* Note: Assuming the volume number is the same as the SD card slot. The + ASF SD/MMC driver supports two SD slots. This implementation will need + to be modified if multiple volumes share a single SD card. + */ + + /* The first time the disk is opened, the SD card can take a while to get + ready, in which time sd_mmc_test_unit_ready() returns either CTRL_BUSY + or CTRL_NO_PRESENT. Try numerous times, waiting half a second after + each failure. Empirically, this has been observed to succeed on the + second try, so trying 10x more than that provides a margin of error. + */ + for(ulTries = 0U; ulTries < 20U; ulTries++) + { + cs = sd_mmc_test_unit_ready(bVolNum); + if((cs != CTRL_NO_PRESENT) && (cs != CTRL_BUSY)) + { + break; + } + + vTaskDelay(500U / portTICK_PERIOD_MS); + } + + if(cs == CTRL_GOOD) + { + #if REDCONF_READ_ONLY == 0 + if(mode != BDEV_O_RDONLY) + { + if(sd_mmc_wr_protect(bVolNum)) + { + ret = -RED_EROFS; + } + } + + if(ret == 0) + #endif + { + uint32_t ulSectorLast; + + (void)sd_mmc_read_capacity(bVolNum, &ulSectorLast); + + /* The ASF SD/MMC driver only supports 512-byte sectors. + */ + if( (gaRedVolConf[bVolNum].ulSectorSize != 512U) + || ((ulSectorLast + 1U) < gaRedVolConf[bVolNum].ullSectorCount)) + { + ret = -RED_EINVAL; + } + } + } + else + { + ret = -RED_EIO; + } + + return ret; +} + + +/** @brief Uninitialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskClose( + uint8_t bVolNum) +{ + (void)bVolNum; + return 0; +} + + +/** @brief Read sectors from a disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + uint8_t *pbBuffer = CAST_VOID_PTR_TO_UINT8_PTR(pBuffer); + + while(ulSectorIdx < ulSectorCount) + { + uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); + Ctrl_status cs; + + cs = sd_mmc_mem_2_ram_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx), + (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]); + if(cs != CTRL_GOOD) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret = 0; + uint32_t ulSectorIdx = 0U; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + + while(ulSectorIdx < ulSectorCount) + { + uint32_t ulTransfer = REDMIN(ulSectorCount - ulSectorIdx, MAX_SECTOR_TRANSFER); + Ctrl_status cs; + + cs = sd_mmc_ram_2_mem_multi(bVolNum, (uint32_t)(ullSectorStart + ulSectorIdx), + (uint16_t)ulTransfer, &pbBuffer[ulSectorIdx * ulSectorSize]); + if(cs != CTRL_GOOD) + { + ret = -RED_EIO; + break; + } + + ulSectorIdx += ulTransfer; + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + Ctrl_status cs; + + /* The ASF SD/MMC driver appears to write sectors synchronously, so it + should be fine to do nothing and return success. However, Atmel's + implementation of the FatFs diskio.c file does the equivalent of the + below when the disk is flushed. Just in case this is important for some + non-obvious reason, do the same. + */ + cs = sd_mmc_test_unit_ready(bVolNum); + if(cs == CTRL_GOOD) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#elif BDEV_EXAMPLE_IMPLEMENTATION == BDEV_RAM_DISK + +#include /* For calloc(). */ + + +static uint8_t *gapbRamDisk[REDCONF_VOLUME_COUNT]; + + +/** @brief Initialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS DiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret = 0; + + (void)mode; + + if(gapbRamDisk[bVolNum] == NULL) + { + gapbRamDisk[bVolNum] = calloc(gaRedVolume[bVolNum].ulBlockCount, REDCONF_BLOCK_SIZE); + if(gapbRamDisk[bVolNum] == NULL) + { + ret = -RED_EIO; + } + } + + return ret; +} + + +/** @brief Uninitialize a disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(gapbRamDisk[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + /* This implementation uses dynamically allocated memory, but must + retain previously written data after the block device is closed, and + thus the memory cannot be freed and will remain allocated until + reboot. + */ + ret = 0; + } + + return ret; +} + + +/** @brief Read sectors from a disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret; + + if(gapbRamDisk[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; + + memcpy(pBuffer, &gapbRamDisk[bVolNum][ullByteOffset], ulByteCount); + + ret = 0; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret; + + if(gapbRamDisk[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; + + memcpy(&gapbRamDisk[bVolNum][ullByteOffset], pBuffer, ulByteCount); + + ret = 0; + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS DiskFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(gapbRamDisk[bVolNum] == NULL) + { + ret = -RED_EINVAL; + } + else + { + ret = 0; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +#else + +#error "Invalid BDEV_EXAMPLE_IMPLEMENTATION value" + +#endif /* BDEV_EXAMPLE_IMPLEMENTATION == ... */ + diff --git a/os/freertos/services/osclock.c b/os/freertos/services/osclock.c new file mode 100644 index 0000000..aaaf20c --- /dev/null +++ b/os/freertos/services/osclock.c @@ -0,0 +1,79 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements real-time clock functions. +*/ +#include + + +/** @brief Initialize the real time clock. + + The behavior of calling this function when the RTC is already initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockInit(void) +{ + return 0; +} + + +/** @brief Uninitialize the real time clock. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockUninit(void) +{ + return 0; +} + + +/** @brief Get the date/time. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return The number of seconds since January 1, 1970 excluding leap seconds + (in other words, standard Unix time). If the resolution or epoch + of the RTC is different than this, the implementation must convert + it to the expected representation. +*/ +uint32_t RedOsClockGetTime(void) +{ + /* FreeRTOS does not provide an RTC abstraction since most of the systems + it targets have no RTC hardware. If your hardware includes an RTC that + you would like to use, this function must be customized. + */ + return 0; +} + diff --git a/os/freertos/services/osmutex.c b/os/freertos/services/osmutex.c new file mode 100644 index 0000000..f617949 --- /dev/null +++ b/os/freertos/services/osmutex.c @@ -0,0 +1,120 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a synchronization object to provide mutual exclusion. +*/ +#include +#include + +#include + +#if REDCONF_TASK_COUNT > 1U + + +static SemaphoreHandle_t xMutex; + + +/** @brief Initialize the mutex. + + After initialization, the mutex is in the released state. + + The behavior of calling this function when the mutex is still initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexInit(void) +{ + REDSTATUS ret; + + xMutex = xSemaphoreCreateMutex(); + if(xMutex != NULL) + { + ret = 0; + } + else + { + ret = -RED_ENOMEM; + } + + return ret; +} + + +/** @brief Uninitialize the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of uninitializing the mutex when it is + in the acquired state is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexUninit(void) +{ + vSemaphoreDelete(xMutex); + xMutex = NULL; + + return 0; +} + + +/** @brief Acquire the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of recursively acquiring the mutex is + undefined. +*/ +void RedOsMutexAcquire(void) +{ + while(xSemaphoreTake(xMutex, portMAX_DELAY) != pdTRUE) + { + } +} + + +/** @brief Release the mutex. + + The behavior is undefined in the following cases: + + - Releasing the mutex when the mutex is not initialized. + - Releasing the mutex when it is not in the acquired state. + - Releasing the mutex from a task or thread other than the one which + acquired the mutex. +*/ +void RedOsMutexRelease(void) +{ + BaseType_t xSuccess; + + xSuccess = xSemaphoreGive(xMutex); + REDASSERT(xSuccess == pdTRUE); + (void)xSuccess; +} + +#endif + diff --git a/os/freertos/services/osoutput.c b/os/freertos/services/osoutput.c new file mode 100644 index 0000000..a7824ec --- /dev/null +++ b/os/freertos/services/osoutput.c @@ -0,0 +1,63 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements outputting a character string. +*/ +#include + +#if REDCONF_OUTPUT == 1 + +#include + + +/** @brief Write a string to a user-visible output location. + + Write a null-terminated string to the serial port, console, terminal, or + other display device, such that the text is visible to the user. + + @param pszString A null-terminated string. +*/ +void RedOsOutputString( + const char *pszString) +{ + uint32_t ulIdx = 0U; + + while(pszString[ulIdx] != '\0') + { + putchar(pszString[ulIdx]); + + /* Serial output often requires a \r to print newlines correctly. + */ + if(pszString[ulIdx] == '\n') + { + putchar('\r'); + } + + ulIdx++; + } +} + +#endif + diff --git a/os/freertos/services/ostask.c b/os/freertos/services/ostask.c new file mode 100644 index 0000000..23ed1f4 --- /dev/null +++ b/os/freertos/services/ostask.c @@ -0,0 +1,66 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements task functions. +*/ +#include +#include + +#include + +#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) + + +/** @brief Get the current task ID. + + This task ID must be unique for all tasks using the file system. + + @return The task ID. Must not be 0. +*/ +uint32_t RedOsTaskId(void) +{ + #if INCLUDE_xTaskGetCurrentTaskHandle == 1 + /* Simply casting the xTaskGetCurrentTaskHandle() return value results in + warnings from some compilers, so use variables. + */ + TaskHandle_t xTask = xTaskGetCurrentTaskHandle(); + uintptr_t taskptr = (uintptr_t)xTask; + uint32_t ulTaskPtr = (uint32_t)taskptr; + + /* Assert no information was lost casting from uintptr_t to uint32_t. + */ + REDASSERT(ulTaskPtr == taskptr); + + /* NULL is a valid task handle in FreeRTOS, so add one to all task IDs. + */ + REDASSERT((ulTaskPtr + 1U) != 0U); + return ulTaskPtr + 1U; + #else + #error "INCLUDE_xTaskGetCurrentTaskHandle must be 1 when REDCONF_TASK_COUNT > 1" + #endif +} + +#endif + diff --git a/os/freertos/services/ostimestamp.c b/os/freertos/services/ostimestamp.c new file mode 100644 index 0000000..56734dd --- /dev/null +++ b/os/freertos/services/ostimestamp.c @@ -0,0 +1,178 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements timestamp functions. + + The functionality implemented herein is not needed for the file system + driver, only to provide accurate results with performance tests. +*/ +#include +#include + +#include + +#if configUSE_TIMERS == 1 + + +/* configTICK_RATE_HZ is almost always 100, 250, 500, or 1000. If + 1000000U % configTICK_RATE_HZ != 0, then RedOsTimePassed() will be a + little inaccurate. +*/ +#define MICROSECS_PER_TICK (1000000U / configTICK_RATE_HZ) + + +/** @brief Initialize the timestamp service. + + The behavior of invoking this function when timestamps are already + initialized is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENOSYS The timestamp service has not been implemented. +*/ +REDSTATUS RedOsTimestampInit(void) +{ + return 0; +} + + +/** @brief Uninitialize the timestamp service. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsTimestampUninit(void) +{ + return 0; +} + + +/** @brief Retrieve a timestamp. + + The behavior of invoking this function when timestamps are not initialized + is undefined + + @return A timestamp which can later be passed to RedOsTimePassed() to + determine the amount of time which passed between the two calls. +*/ +REDTIMESTAMP RedOsTimestamp(void) +{ + return xTaskGetTickCount(); +} + + +/** @brief Determine how much time has passed since a timestamp was retrieved. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @param tsSince A timestamp acquired earlier via RedOsTimestamp(). + + @return The number of microseconds which have passed since @p tsSince. +*/ +uint64_t RedOsTimePassed( + REDTIMESTAMP tsSince) +{ + /* This works even if the tick count has wrapped around, provided it has + only wrapped around once. + */ + uint32_t ulTicksPassed = (uint32_t)xTaskGetTickCount() - tsSince; + uint64_t ullMicrosecs = (uint64_t)ulTicksPassed * MICROSECS_PER_TICK; + + return ullMicrosecs; +} + +#else + +/** @brief Initialize the timestamp service. + + The behavior of invoking this function when timestamps are already + initialized is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENOSYS The timestamp service has not been implemented. +*/ +REDSTATUS RedOsTimestampInit(void) +{ + return -RED_ENOSYS; +} + + +/** @brief Uninitialize the timestamp service. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsTimestampUninit(void) +{ + return -RED_ENOSYS; +} + + +/** @brief Retrieve a timestamp. + + The behavior of invoking this function when timestamps are not initialized + is undefined + + @return A timestamp which can later be passed to RedOsTimePassed() to + determine the amount of time which passed between the two calls. +*/ +REDTIMESTAMP RedOsTimestamp(void) +{ + REDERROR(); + return 0U; +} + + +/** @brief Determine how much time has passed since a timestamp was retrieved. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @param tsSince A timestamp acquired earlier via RedOsTimestamp(). + + @return The number of microseconds which have passed since @p tsSince. +*/ +uint64_t RedOsTimePassed( + REDTIMESTAMP tsSince) +{ + (void)tsSince; + REDERROR(); + return 0U; +} + +#endif /* configUSE_TIMERS == 1 */ + diff --git a/os/stub/include/ostypes.h b/os/stub/include/ostypes.h new file mode 100644 index 0000000..d48ba89 --- /dev/null +++ b/os/stub/include/ostypes.h @@ -0,0 +1,41 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef OSTYPES_H +#define OSTYPES_H + + +/** @brief Implementation-defined timestamp type. + + This can be an integer, a structure, or a pointer: anything that is + convenient for the implementation. Since the underlying type is not fixed, + common code should treat this as an opaque type. +*/ +typedef uint64_t REDTIMESTAMP; + + +#endif + diff --git a/os/stub/services/osassert.c b/os/stub/services/osassert.c new file mode 100644 index 0000000..f8639a4 --- /dev/null +++ b/os/stub/services/osassert.c @@ -0,0 +1,53 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements assertion handling. +*/ +#include + +#if REDCONF_ASSERTS == 1 + + +/** @brief Invoke the native assertion handler. + + @param pszFileName Null-terminated string containing the name of the file + where the assertion fired. + @param ulLineNum Line number in @p pszFileName where the assertion + fired. +*/ +void RedOsAssertFail( + const char *pszFileName, + uint32_t ulLineNum) +{ + (void)pszFileName; + (void)ulLineNum; + + while(true) + { + } +} + +#endif + diff --git a/os/stub/services/osbdev.c b/os/stub/services/osbdev.c new file mode 100644 index 0000000..e51aa82 --- /dev/null +++ b/os/stub/services/osbdev.c @@ -0,0 +1,241 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements block device I/O. +*/ +#include +#include + + +/** @brief Initialize a block device. + + This function is called when the file system needs access to a block + device. + + Upon successful return, the block device should be fully initialized and + ready to service read/write/flush/close requests. + + The behavior of calling this function on a block device which is already + open is undefined. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + (void)mode; + + ret = -RED_ENOSYS; + } + + return ret; +} + + +/** @brief Uninitialize a block device. + + This function is called when the file system no longer needs access to a + block device. If any resource were allocated by RedOsBDevOpen() to service + block device requests, they should be freed at this time. + + Upon successful return, the block device must be in such a state that it + can be opened again. + + The behavior of calling this function on a block device which is already + closed is undefined. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. +*/ +REDSTATUS RedOsBDevClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + REDERROR(); + ret = -RED_ENOSYS; + } + + return ret; +} + + +/** @brief Read sectors from a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_WRONLY. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret = 0; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + REDERROR(); + ret = -RED_ENOSYS; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret = 0; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + REDERROR(); + ret = -RED_ENOSYS; + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + This function must synchronously flush all software and hardware caches + beneath the file system, ensuring that all sectors written previously are + committed to permanent storage. + + If the environment has no caching beneath the file system, the + implementation of this function can do nothing and return success. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + ret = -RED_EINVAL; + } + else + { + REDERROR(); + ret = -RED_ENOSYS; + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + diff --git a/os/stub/services/osclock.c b/os/stub/services/osclock.c new file mode 100644 index 0000000..2980c0c --- /dev/null +++ b/os/stub/services/osclock.c @@ -0,0 +1,75 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements real-time clock functions. +*/ +#include + + +/** @brief Initialize the real time clock. + + The behavior of calling this function when the RTC is already initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockInit(void) +{ + return 0; +} + + +/** @brief Uninitialize the real time clock. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockUninit(void) +{ + return 0; +} + + +/** @brief Get the date/time. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return The number of seconds since January 1, 1970 excluding leap seconds + (in other words, standard Unix time). If the resolution or epoch + of the RTC is different than this, the implementation must convert + it to the expected representation. +*/ +uint32_t RedOsClockGetTime(void) +{ + return 0; +} + diff --git a/os/stub/services/osmutex.c b/os/stub/services/osmutex.c new file mode 100644 index 0000000..32fc576 --- /dev/null +++ b/os/stub/services/osmutex.c @@ -0,0 +1,102 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a synchronization object to provide mutual exclusion. +*/ +#include + +#if REDCONF_TASK_COUNT > 1U + + +/** @brief Initialize the mutex. + + After initialization, the mutex is in the released state. + + The behavior of calling this function when the mutex is still initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexInit(void) +{ + REDSTATUS ret; + + ret = -RED_ENOSYS; + + return ret; +} + + +/** @brief Uninitialize the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of uninitializing the mutex when it is + in the acquired state is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexUninit(void) +{ + REDSTATUS ret; + + REDERROR(); + ret = -RED_ENOSYS; + + return ret; +} + + +/** @brief Acquire the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of recursively acquiring the mutex is + undefined. +*/ +void RedOsMutexAcquire(void) +{ + REDERROR(); +} + + +/** @brief Release the mutex. + + The behavior is undefined in the following cases: + + - Releasing the mutex when the mutex is not initialized. + - Releasing the mutex when it is not in the acquired state. + - Releasing the mutex from a task or thread other than the one which + acquired the mutex. +*/ +void RedOsMutexRelease(void) +{ + REDERROR(); +} + +#endif + diff --git a/os/stub/services/osoutput.c b/os/stub/services/osoutput.c new file mode 100644 index 0000000..c15c4d0 --- /dev/null +++ b/os/stub/services/osoutput.c @@ -0,0 +1,48 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements outputting a character string. +*/ +#include + +#if REDCONF_OUTPUT == 1 + + +/** @brief Write a string to a user-visible output location. + + Write a null-terminated string to the serial port, console, terminal, or + other display device, such that the text is visible to the user. + + @param pszString A null-terminated string. +*/ +void RedOsOutputString( + const char *pszString) +{ + (void)pszString; + REDERROR(); +} + +#endif + diff --git a/os/stub/services/ostask.c b/os/stub/services/ostask.c new file mode 100644 index 0000000..abe44d9 --- /dev/null +++ b/os/stub/services/ostask.c @@ -0,0 +1,46 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements task functions. +*/ +#include + +#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) + + +/** @brief Get the current task ID. + + This task ID must be unique for all tasks using the file system. + + @return The task ID. Must not be 0. +*/ +uint32_t RedOsTaskId(void) +{ + REDERROR(); + return 1U; +} + +#endif + diff --git a/os/stub/services/ostimestamp.c b/os/stub/services/ostimestamp.c new file mode 100644 index 0000000..c964cbb --- /dev/null +++ b/os/stub/services/ostimestamp.c @@ -0,0 +1,105 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements timestamp functions. + + The functionality implemented herein is not needed for the file system + driver, only to provide accurate results with performance tests. +*/ +#include + + +/** @brief Initialize the timestamp service. + + The behavior of invoking this function when timestamps are already + initialized is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENOSYS The timestamp service has not been implemented. +*/ +REDSTATUS RedOsTimestampInit(void) +{ + REDSTATUS ret; + + ret = -RED_ENOSYS; + + return ret; +} + + +/** @brief Uninitialize the timestamp service. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsTimestampUninit(void) +{ + REDSTATUS ret; + + REDERROR(); + ret = -RED_ENOSYS; + + return ret; +} + + +/** @brief Retrieve a timestamp. + + The behavior of invoking this function when timestamps are not initialized + is undefined + + @return A timestamp which can later be passed to RedOsTimePassed() to + determine the amount of time which passed between the two calls. +*/ +REDTIMESTAMP RedOsTimestamp(void) +{ + REDERROR(); + return 0U; +} + + +/** @brief Determine how much time has passed since a timestamp was retrieved. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @param tsSince A timestamp acquired earlier via RedOsTimestamp(). + + @return The number of microseconds which have passed since @p tsSince. +*/ +uint64_t RedOsTimePassed( + REDTIMESTAMP tsSince) +{ + REDERROR(); + (void)tsSince; + return 0U; +} + diff --git a/os/win32/build/host.mk b/os/win32/build/host.mk new file mode 100644 index 0000000..9aa882b --- /dev/null +++ b/os/win32/build/host.mk @@ -0,0 +1,66 @@ +CC=cl +P_OS ?= win32 +B_OBJEXT ?= obj + +INCLUDES= \ + /I $(P_PROJDIR) \ + /I $(P_BASEDIR)/include \ + /I $(P_BASEDIR)/core/include \ + /I $(P_BASEDIR)/os/win32/include + +EXTRA_CFLAGS += /W3 /D_CRT_SECURE_NO_WARNINGS +ifeq ($(B_DEBUG),0) +EXTRA_CFLAGS += /O2 /Ot /Ox +else +EXTRA_CFLAGS += /Od /D_DEBUG /MTd /Od /Zi /RTC1 +endif + +all: redfmt redimgbld + +%.obj: %.c + $(CC) $(EXTRA_CFLAGS) $(INCLUDES) $< /c /Fo$@ + +# The redconf.h for the tools #includes the redconf.h from the parent project +# to inherit its settings, so add it as a dependency. +REDPROJHDR=$(P_CONFDIR)/redconf.h + +include $(P_BASEDIR)/build/reliance.mk + +IMGBLDHDR= \ + $(P_BASEDIR)/os/win32/tools/imgbld/ibheader.h \ + $(P_BASEDIR)/os/win32/tools/wintlcmn.h +IMGBLDOBJ= \ + $(P_BASEDIR)/os/win32/tools/imgbld/ibcommon.obj \ + $(P_BASEDIR)/os/win32/tools/imgbld/ibfse.obj \ + $(P_BASEDIR)/os/win32/tools/imgbld/ibposix.obj \ + $(P_BASEDIR)/os/win32/tools/imgbld/imgbld.obj \ + $(P_BASEDIR)/os/win32/tools/wintlcmn.obj +REDPROJOBJ= \ + $(IMGBLDOBJ) \ + $(P_BASEDIR)/os/win32/tools/imgcopy.obj \ + $(P_BASEDIR)/os/win32/tools/winchk.obj \ + $(P_BASEDIR)/os/win32/tools/winfmt.obj + +$(P_BASEDIR)/os/win32/tools/imgbld/ibcommon.obj: $(P_BASEDIR)/os/win32/tools/imgbld/ibcommon.c $(IMGBLDHDR) +$(P_BASEDIR)/os/win32/tools/imgbld/ibfse.obj: $(P_BASEDIR)/os/win32/tools/imgbld/ibfse.c $(IMGBLDHDR) +$(P_BASEDIR)/os/win32/tools/imgbld/ibposix.obj: $(P_BASEDIR)/os/win32/tools/imgbld/ibposix.c $(IMGBLDHDR) +$(P_BASEDIR)/os/win32/tools/imgbld/imgbld.obj: $(P_BASEDIR)/os/win32/tools/imgbld/imgbld.c $(IMGBLDHDR) +$(P_BASEDIR)/os/win32/tools/winfmt.obj: $(P_BASEDIR)/os/win32/tools/winfmt.c $(P_BASEDIR)/os/win32/tools/wintlcmn.h +$(P_BASEDIR)/os/win32/tools/wintlcmn.obj: $(P_BASEDIR)/os/win32/tools/wintlcmn.c $(P_BASEDIR)/os/win32/tools/wintlcmn.h + +# The redconf.c for the tools #includes the redconf.c from the parent project +# to inherit its settings, so add it as a dependency. +$(P_PROJDIR)/redconf.obj: $(P_CONFDIR)/redconf.c + + +redfmt: $(P_BASEDIR)/os/win32/tools/winfmt.obj $(P_BASEDIR)/os/win32/tools/wintlcmn.obj $(REDDRIVOBJ) $(REDTOOLOBJ) + $(CC) $(EXTRA_CFLAGS) $^ /Fe$@.exe + +redimgbld: $(IMGBLDOBJ) $(REDDRIVOBJ) $(REDTOOLOBJ) + $(CC) $(EXTRA_CFLAGS) $^ /Fe$@.exe + +.phony: clean +clean: + del /f /q $(subst /,\,$(REDDRIVOBJ) $(REDTOOLOBJ) $(REDPROJOBJ)) 2>NUL + del /f /q *.ilk *.pdb *.obj *.exe *.suo *.sln 2>NUL + diff --git a/os/win32/include/ostypes.h b/os/win32/include/ostypes.h new file mode 100644 index 0000000..edfcdb7 --- /dev/null +++ b/os/win32/include/ostypes.h @@ -0,0 +1,39 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef OSTYPES_H +#define OSTYPES_H + + +/** @brief Implementation-defined timestamp type. + + This can be an integer, a structure, or a pointer: anything that is + convenient for the implementation. Since the underlying type is not fixed, + common code should treat this as an opaque type. +*/ +typedef uint64_t REDTIMESTAMP; + + +#endif + diff --git a/os/win32/services/osassert.c b/os/win32/services/osassert.c new file mode 100644 index 0000000..4910222 --- /dev/null +++ b/os/win32/services/osassert.c @@ -0,0 +1,58 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements assertion handling. +*/ +#include + +#if REDCONF_ASSERTS == 1 + +#include +#include + + +/** @brief Invoke the native assertion handler. + + @param pszFileName Null-terminated string containing the name of the file + where the assertion fired. + @param ulLineNum Line number in @p pszFileName where the assertion + fired. +*/ +void RedOsAssertFail( + const char *pszFileName, + uint32_t ulLineNum) +{ + #if REDCONF_OUTPUT == 1 + fprintf(stderr, "Assertion failed in \"%s\" at line %u\n", pszFileName, (unsigned)ulLineNum); + #else + (void)pszFileName; + (void)ulLineNum; + #endif + + DebugBreak(); +} + +#endif + diff --git a/os/win32/services/osbdev.c b/os/win32/services/osbdev.c new file mode 100644 index 0000000..4c784c1 --- /dev/null +++ b/os/win32/services/osbdev.c @@ -0,0 +1,1172 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements block device I/O. +*/ +#include + +#include +#include + +#include +#include + + +typedef enum +{ + BDEVTYPE_RAM_DISK = 0, /* Default: must be zero. */ + BDEVTYPE_FILE_DISK = 1, + BDEVTYPE_RAW_DISK = 2 +} BDEVTYPE; + +typedef struct +{ + bool fOpen; /* The block device is open. */ + BDEVOPENMODE mode; /* Acess mode. */ + BDEVTYPE type; /* Disk type: ram disk, file disk, raw disk. */ + uint8_t *pbRamDisk; /* Buffer for RAM disks. */ + const char *pszSpec; /* Path for file and raw disks. */ + HANDLE hDevice; /* Handle for file and raw disks. */ +} WINBDEV; + + +static bool IsDriveSpec(const char *pszPathSpec); +static REDSTATUS RamDiskOpen(uint8_t bVolNum, BDEVOPENMODE mode); +static REDSTATUS RamDiskClose(uint8_t bVolNum); +static REDSTATUS RamDiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS RamDiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); +static REDSTATUS RamDiskFlush(uint8_t bVolNum); +#endif +static REDSTATUS FileDiskOpen(uint8_t bVolNum, BDEVOPENMODE mode); +static REDSTATUS FileDiskClose(uint8_t bVolNum); +static REDSTATUS FileDiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS FileDiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); +static REDSTATUS FileDiskFlush(uint8_t bVolNum); +#endif +static REDSTATUS RawDiskOpen(uint8_t bVolNum, BDEVOPENMODE mode); +static REDSTATUS RawDiskClose(uint8_t bVolNum); +static REDSTATUS RawDiskRead(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, void *pBuffer); +#if REDCONF_READ_ONLY == 0 +static REDSTATUS RawDiskWrite(uint8_t bVolNum, uint64_t ullSectorStart, uint32_t ulSectorCount, const void *pBuffer); +static REDSTATUS RawDiskFlush(uint8_t bVolNum); +#endif + + +static WINBDEV gaDisk[REDCONF_VOLUME_COUNT]; + + +/** @brief Configure a block device. + + @note This is a non-standard block device API! The standard block device + APIs are designed for implementations running on targets with block + devices that are known in advance and can be statically defined by + the implementation. However, this implementation is intended for + host systems, and it needs to support writing to raw disks (like + "H:" etc.) and file disks which are supplied on the command line. + + @param bVolNum The volume number of the volume to configure. + @param pszBDevSpec Drive or file to associate with the volume. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is not a valid volume number; or + @p pszBDevSpec is `NULL` or an empty string. +*/ +REDSTATUS RedOsBDevConfig( + uint8_t bVolNum, + const char *pszBDevSpec) +{ + REDSTATUS ret; + + if((bVolNum >= REDCONF_VOLUME_COUNT) || gaDisk[bVolNum].fOpen || (pszBDevSpec == NULL) || (pszBDevSpec[0U] == '\0')) + { + ret = -RED_EINVAL; + } + else + { + RedMemSet(&gaDisk[bVolNum], 0U, sizeof(gaDisk[bVolNum])); + + gaDisk[bVolNum].pszSpec = pszBDevSpec; + + if(IsDriveSpec(pszBDevSpec)) + { + gaDisk[bVolNum].type = BDEVTYPE_RAW_DISK; + } + else + { + gaDisk[bVolNum].type = BDEVTYPE_FILE_DISK; + } + + ret = 0; + } + + return ret; +} + + +/** Determine whether a path names a drive or disk device. + + Drive paths are expected to use the Win32 device namespace; "C:" by itself + would not be recognized as a drive, but "\\.\C:" would. + + @param pszPathSpec The path to examine. + + @return Whether @p pszPathSpec appears to name a drive or disk device. +*/ +static bool IsDriveSpec( + const char *pszPathSpec) +{ + bool fIsDrive = false; + + /* The "\\.\" prefix indicates the Win32 device namespace. + */ + if(RedStrNCmp("\\\\.\\", pszPathSpec, 4U) == 0) + { + const char *pszDevice = &pszPathSpec[4U]; + + /* Subsequent to the prefix, look for a drive spec like "X:" or a disk + spec like "PhysicalDriveX". + */ + if( ( ((pszDevice[0U] >= 'A') && (pszDevice[0U] <= 'Z')) + || ((pszDevice[0U] >= 'a') && (pszDevice[0U] <= 'z'))) + && (pszDevice[1U] == ':') + && (pszDevice[2U] == '\0')) + { + fIsDrive = true; + } + else if((_strnicmp(pszDevice, "PhysicalDrive", 13U) == 0) && (pszDevice[13U] != '\0')) + { + const char *pszDiskNum = &pszDevice[13U]; + + /* Manually verify that pszDiskNum starts with a number, since + strtol() will skip over leading white space. + */ + if((pszDiskNum[0U] >= '0') && (pszDiskNum[0U] <= '9')) + { + const char *pszEndPtr; + long lDiskNum; + + lDiskNum = strtol(pszDiskNum, (char **)&pszEndPtr, 10); + if(lDiskNum == 0) + { + /* strtol() returns zero when no conversion could be + performed, but zero is also a valid disk number, so + check if pszDiskNum is "0". + */ + if((pszDiskNum[0U] == '0') && (pszDiskNum[1U] == '\0')) + { + fIsDrive = true; + } + } + else if((lDiskNum > 0) && (lDiskNum != LONG_MAX) && (pszEndPtr[0U] == '\0')) + { + fIsDrive = true; + } + else + { + /* Characters subsequent to "PhysicalDrive" are not a valid + integer, so the string is not a drive path. + */ + } + } + } + else + { + /* Characters subsequent to the "\\.\" prefix do not appear to name + a disk, so the string is not a drive path. + */ + } + } + + return fIsDrive; +} + + +/** @brief Initialize a block device. + + This function is called when the file system needs access to a block + device. + + Upon successful return, the block device should be fully initialized and + ready to service read/write/flush/close requests. + + The behavior of calling this function on a block device which is already + open is undefined. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret; + + if((bVolNum >= REDCONF_VOLUME_COUNT) || gaDisk[bVolNum].fOpen) + { + ret = -RED_EINVAL; + } + else + { + switch(gaDisk[bVolNum].type) + { + case BDEVTYPE_RAM_DISK: + ret = RamDiskOpen(bVolNum, mode); + break; + + case BDEVTYPE_FILE_DISK: + ret = FileDiskOpen(bVolNum, mode); + break; + + case BDEVTYPE_RAW_DISK: + ret = RawDiskOpen(bVolNum, mode); + break; + + default: + REDERROR(); + ret = -RED_EINVAL; + break; + } + + if(ret == 0) + { + gaDisk[bVolNum].fOpen = true; + gaDisk[bVolNum].mode = mode; + } + } + + return ret; +} + + +/** @brief Uninitialize a block device. + + This function is called when the file system no longer needs access to a + block device. If any resource were allocated by RedOsBDevOpen() to service + block device requests, they should be freed at this time. + + Upon successful return, the block device must be in such a state that it + can be opened again. + + The behavior of calling this function on a block device which is already + closed is undefined. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. +*/ +REDSTATUS RedOsBDevClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if((bVolNum >= REDCONF_VOLUME_COUNT) || !gaDisk[bVolNum].fOpen) + { + ret = -RED_EINVAL; + } + else + { + switch(gaDisk[bVolNum].type) + { + case BDEVTYPE_RAM_DISK: + ret = RamDiskClose(bVolNum); + break; + + case BDEVTYPE_FILE_DISK: + ret = FileDiskClose(bVolNum); + break; + + case BDEVTYPE_RAW_DISK: + ret = RawDiskClose(bVolNum); + break; + + default: + REDERROR(); + ret = -RED_EINVAL; + break; + } + + if(ret == 0) + { + gaDisk[bVolNum].fOpen = false; + } + } + + return ret; +} + + +/** @brief Read sectors from a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_WRONLY. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + REDSTATUS ret; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || !gaDisk[bVolNum].fOpen + || (gaDisk[bVolNum].mode == BDEV_O_WRONLY) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + switch(gaDisk[bVolNum].type) + { + case BDEVTYPE_RAM_DISK: + ret = RamDiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + case BDEVTYPE_FILE_DISK: + ret = FileDiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + case BDEVTYPE_RAW_DISK: + ret = RawDiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + default: + REDERROR(); + ret = -RED_EINVAL; + break; + } + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a physical block device. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number, @p pBuffer is + `NULL`, or @p ullStartSector and/or @p ulSectorCount + refer to an invalid range of sectors. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + REDSTATUS ret; + + if( (bVolNum >= REDCONF_VOLUME_COUNT) + || !gaDisk[bVolNum].fOpen + || (gaDisk[bVolNum].mode == BDEV_O_RDONLY) + || (ullSectorStart >= gaRedVolConf[bVolNum].ullSectorCount) + || ((gaRedVolConf[bVolNum].ullSectorCount - ullSectorStart) < ulSectorCount) + || (pBuffer == NULL)) + { + ret = -RED_EINVAL; + } + else + { + switch(gaDisk[bVolNum].type) + { + case BDEVTYPE_RAM_DISK: + ret = RamDiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + case BDEVTYPE_FILE_DISK: + ret = FileDiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + case BDEVTYPE_RAW_DISK: + ret = RawDiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); + break; + + default: + REDERROR(); + ret = -RED_EINVAL; + break; + } + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + This function must synchronously flush all software and hardware caches + beneath the file system, ensuring that all sectors written previously are + committed to permanent storage. + + If the environment has no caching beneath the file system, the + implementation of this function can do nothing and return success. + + The behavior of calling this function is undefined if the block device is + closed or if it was opened with ::BDEV_O_RDONLY. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p bVolNum is an invalid volume number. + @retval -RED_EIO A disk I/O error occurred. +*/ +REDSTATUS RedOsBDevFlush( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if((bVolNum >= REDCONF_VOLUME_COUNT) || !gaDisk[bVolNum].fOpen || (gaDisk[bVolNum].mode == BDEV_O_RDONLY)) + { + ret = -RED_EINVAL; + } + else + { + switch(gaDisk[bVolNum].type) + { + case BDEVTYPE_RAM_DISK: + ret = RamDiskFlush(bVolNum); + break; + + case BDEVTYPE_FILE_DISK: + ret = FileDiskFlush(bVolNum); + break; + + case BDEVTYPE_RAW_DISK: + ret = RawDiskFlush(bVolNum); + break; + + default: + REDERROR(); + ret = -RED_EINVAL; + break; + } + } + + return ret; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Initialize a RAM disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS RamDiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + REDSTATUS ret = 0; + + (void)mode; + + if(gaDisk[bVolNum].pbRamDisk == NULL) + { + gaDisk[bVolNum].pbRamDisk = calloc(gaRedVolume[bVolNum].ulBlockCount, REDCONF_BLOCK_SIZE); + if(gaDisk[bVolNum].pbRamDisk == NULL) + { + ret = -RED_EIO; + } + } + + return ret; +} + + +/** @brief Uninitialize a RAM disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS RamDiskClose( + uint8_t bVolNum) +{ + /* This implementation uses dynamically allocated memory, but must retain + previously written data after the block device is closed, and thus the + memory cannot be freed and will remain allocated until the program + exits. + */ + return 0; +} + + +/** @brief Read sectors from a RAM disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS RamDiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; + + memcpy(pBuffer, &gaDisk[bVolNum].pbRamDisk[ullByteOffset], ulByteCount); + + return 0; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a RAM disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS RamDiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + uint64_t ullByteOffset = ullSectorStart * gaRedVolConf[bVolNum].ulSectorSize; + uint32_t ulByteCount = ulSectorCount * gaRedVolConf[bVolNum].ulSectorSize; + + memcpy(&gaDisk[bVolNum].pbRamDisk[ullByteOffset], pBuffer, ulByteCount); + + return 0; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +static REDSTATUS RamDiskFlush( + uint8_t bVolNum) +{ + return 0; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Initialize a file disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EROFS The file disk is a preexisting read-only file and write + access was requested. +*/ +static REDSTATUS FileDiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + WINBDEV *pDisk = &gaDisk[bVolNum]; + REDSTATUS ret = 0; + + if(mode != BDEV_O_RDONLY) + { + DWORD dwAttr; + + /* The media needs to be writeable. + */ + dwAttr = GetFileAttributesA(pDisk->pszSpec); + if((dwAttr != INVALID_FILE_ATTRIBUTES) && ((dwAttr & FILE_ATTRIBUTE_READONLY) != 0U)) + { + ret = -RED_EROFS; + } + } + + if(ret == 0) + { + DWORD dwDesiredAccess = GENERIC_READ; + DWORD dwCreationDisposition = OPEN_EXISTING; + + #if REDCONF_READ_ONLY == 0 + if(mode != BDEV_O_RDONLY) + { + /* Open with GENERIC_READ, even if mode is BDEV_O_WRONLY, to avoid + failures that sometimes happen when opening write-only. + */ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + dwCreationDisposition = OPEN_ALWAYS; + } + #endif + + pDisk->hDevice = CreateFileA(pDisk->pszSpec, dwDesiredAccess, FILE_SHARE_READ, + NULL, dwCreationDisposition, 0U, NULL); + + if(pDisk->hDevice == INVALID_HANDLE_VALUE) + { + ret = -RED_EIO; + } + else + { + ret = 0; + } + } + + return ret; +} + + +/** @brief Uninitialize a file disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS FileDiskClose( + uint8_t bVolNum) +{ + REDSTATUS ret = 0; + + /* Flush before closing. This is primarily for the tools, so that all the + data is really committed to the media when the tool exits. + */ + if(gaDisk[bVolNum].mode != BDEV_O_RDONLY) + { + if(!FlushFileBuffers(gaDisk[bVolNum].hDevice)) + { + ret = -RED_EIO; + } + } + + if(ret == 0) + { + if(!CloseHandle(gaDisk[bVolNum].hDevice)) + { + ret = -RED_EIO; + } + } + + return ret; +} + + +/** @brief Read sectors from a file disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS FileDiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + ULARGE_INTEGER position; + OVERLAPPED overlap = {{0}}; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + DWORD dwRead; + BOOL fResult; + REDSTATUS ret; + + position.QuadPart = ullSectorStart * ulSectorSize; + overlap.Offset = position.LowPart; + overlap.OffsetHigh = position.HighPart; + + fResult = ReadFile(gaDisk[bVolNum].hDevice, pBuffer, (uint64_t)ulSectorCount * ulSectorSize, &dwRead, &overlap); + if(fResult && (dwRead == ((uint64_t)ulSectorCount * ulSectorSize))) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a file disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS FileDiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + ULARGE_INTEGER position; + OVERLAPPED overlap = {{0}}; + uint32_t ulSectorSize = gaRedVolConf[bVolNum].ulSectorSize; + DWORD dwWritten; + BOOL fResult; + REDSTATUS ret; + + position.QuadPart = ullSectorStart * ulSectorSize; + overlap.Offset = position.LowPart; + overlap.OffsetHigh = position.HighPart; + + fResult = WriteFile(gaDisk[bVolNum].hDevice, pBuffer, (uint64_t)ulSectorCount * ulSectorSize, &dwWritten, &overlap); + if(fResult && (dwWritten == ((uint64_t)ulSectorCount * ulSectorSize))) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS FileDiskFlush( + uint8_t bVolNum) +{ + /* In theory, we could flush the file disk, but there isn't a strong need. + File disks are used for two things: the image builder and tests. The + host Windows system is not expected to crash, and if it does, the image + builder or tests will be starting over anyway. + + The downside to flushing is that when testing a file disk, it makes the + tests much slower since it generates lots of disk I/O on the host hard + drive. + */ + return 0; +} +#endif /* REDCONF_READ_ONLY == 0 */ + + +/** @brief Initialize a raw disk. + + @param bVolNum The volume number of the volume whose block device is being + initialized. + @param mode The open mode, indicating the type of access required. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EBUSY The device could not be locked. + @retval -RED_EROFS The device is read-only media and write access was + requested. +*/ +static REDSTATUS RawDiskOpen( + uint8_t bVolNum, + BDEVOPENMODE mode) +{ + uint32_t ulTry; + DWORD dwUnused; + WINBDEV *pDisk = &gaDisk[bVolNum]; + REDSTATUS ret = 0; + DWORD dwDesiredAccess = GENERIC_READ; + + #if REDCONF_READ_ONLY == 0 + if(mode != BDEV_O_RDONLY) + { + /* Open with GENERIC_READ, even if mode is BDEV_O_WRONLY, to avoid + failures that sometimes happen when opening write-only. + */ + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + } + #endif + + for(ulTry = 0U; ulTry <= 20U; ulTry++) + { + /* Disable caching. It would be preferable to flush the block device + handle when needed, but attempting to do so results in an error. + + Enable both FILE_FLAG_WRITE_THROUGH and FILE_FLAG_NO_BUFFERING, so + that system caching is not in effect, then the data is immediately + flushed to disk without going through the Windows system cache. + The operating system also requests a write-through of the disk's + local hardware cache to persistent media. + */ + pDisk->hDevice = CreateFileA(pDisk->pszSpec, dwDesiredAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL); + + if(pDisk->hDevice != INVALID_HANDLE_VALUE) + { + break; + } + + Sleep(500U); + } + + if(pDisk->hDevice == INVALID_HANDLE_VALUE) + { + ret = -RED_EIO; + } + + if(ret == 0) + { + /* Lock the volume for exclusive use. We are purposely ignoring + errors here, the lock volume may fail if there are open handles to + the volume, however, the dismount of the volume will force those + handles invalid if possible. If the volume dismount fails, an + application is holding a lock on the disk and we should fail. + + Note that after the dismount of the volume, the validity of the + handle is at discretion of the original file system so we must + clear up any ambiguity with a second call to open the volume while + there is no file system mounted. + */ + (void)DeviceIoControl(pDisk->hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwUnused, NULL); + if(!DeviceIoControl(pDisk->hDevice, FSCTL_DISMOUNT_VOLUME, NULL, 0, NULL, 0, &dwUnused, NULL)) + { + ret = -RED_EBUSY; + } + } + + if(ret == 0) + { + /* Close and reopen the handle, since the dismount may have invalidated + the original handle. + */ + (void)CloseHandle(pDisk->hDevice); + + for(ulTry = 0U; ulTry <= 20U; ulTry++) + { + pDisk->hDevice = CreateFileA(pDisk->pszSpec, dwDesiredAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, + FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH, NULL); + + if(pDisk->hDevice != INVALID_HANDLE_VALUE) + { + break; + } + + Sleep(500U); + } + } + + if(ret == 0) + { + bool fLocked = false; + + /* This has been observed to fail on the first attempt and succeed on + a subsequent attempt. + */ + for(ulTry = 0U; ulTry <= 20U; ulTry++) + { + if(DeviceIoControl(pDisk->hDevice, FSCTL_LOCK_VOLUME, NULL, 0, NULL, 0, &dwUnused, NULL)) + { + fLocked = true; + break; + } + + Sleep(500U); + } + + if(!fLocked) + { + ret = -RED_EBUSY; + } + } + + if(ret == 0) + { + DISK_GEOMETRY_EX geo; + + if(!DeviceIoControl(pDisk->hDevice, IOCTL_DISK_GET_DRIVE_GEOMETRY_EX, NULL, 0, &geo, sizeof(geo), &dwUnused, NULL)) + { + ret = -RED_EIO; + } + else + { + uint64_t ullTotalSectors; + + /* NOTE: There are issues with both methods of calculating the + sector count. + + The first method may result in a sector count which + exceeds the number of sectors Windows thinks the media + has. When these purportedly non-existent sectors are read + or written, the I/O operation fails with a bad parameter + error. This behavior has shown up on numerous flash + drives and SD cards. + + The second (and original) method is not known to result in + any I/O failures, but it can result in a sector count + which renders the disk much smaller than it should be; + this is known to have affected partitioned media. + */ + #if 0 + ullTotalSectors = geo.DiskSize.QuadPart; + ullTotalSectors /= geo.Geometry.BytesPerSector; + #else + ullTotalSectors = geo.Geometry.Cylinders.QuadPart; + ullTotalSectors *= geo.Geometry.TracksPerCylinder; + ullTotalSectors *= geo.Geometry.SectorsPerTrack; + #endif + + /* Error if the disk is smaller than the configuration says it was. + + Currently the code expects the sector size to be accurate. It + would be possible to update the code to be forgiving of an + incorrect configuration sector size, but that would involve more + conversions. + */ + if( (ullTotalSectors < gaRedVolConf[bVolNum].ullSectorCount) + || (geo.Geometry.BytesPerSector != gaRedVolConf[bVolNum].ulSectorSize)) + { + ret = -RED_EINVAL; + } + } + } + + #if REDCONF_READ_ONLY == 0 + if(ret == 0) + { + bool fWriteProtected = false; + + if(!DeviceIoControl(pDisk->hDevice, IOCTL_DISK_IS_WRITABLE, NULL, 0, NULL, 0, &dwUnused, NULL)) + { + DWORD dwError = GetLastError(); + + if(dwError == ERROR_WRITE_PROTECT) + { + fWriteProtected = true; + } + else + { + ret = -RED_EIO; + } + } + + if((ret == 0) && fWriteProtected && (mode != BDEV_O_RDONLY)) + { + ret = -RED_EROFS; + } + } + #endif + + if((ret != 0) && (pDisk->hDevice != INVALID_HANDLE_VALUE)) + { + (void)CloseHandle(pDisk->hDevice); + } + + return ret; +} + + +/** @brief Uninitialize a raw disk. + + @param bVolNum The volume number of the volume whose block device is being + uninitialized. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS RawDiskClose( + uint8_t bVolNum) +{ + REDSTATUS ret; + + if(CloseHandle(gaDisk[bVolNum].hDevice)) + { + ret = 0; + } + else + { + ret = -RED_EIO; + } + + return ret; +} + + +/** @brief Read sectors from a raw disk. + + @param bVolNum The volume number of the volume whose block device + is being read from. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to read. + @param pBuffer The buffer into which to read the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS RawDiskRead( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + void *pBuffer) +{ + return FileDiskRead(bVolNum, ullSectorStart, ulSectorCount, pBuffer); +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write sectors to a raw disk. + + @param bVolNum The volume number of the volume whose block device + is being written to. + @param ullSectorStart The starting sector number. + @param ulSectorCount The number of sectors to write. + @param pBuffer The buffer from which to write the sector data. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS RawDiskWrite( + uint8_t bVolNum, + uint64_t ullSectorStart, + uint32_t ulSectorCount, + const void *pBuffer) +{ + return FileDiskWrite(bVolNum, ullSectorStart, ulSectorCount, pBuffer); +} + + +/** @brief Flush any caches beneath the file system. + + @param bVolNum The volume number of the volume whose block device is being + flushed. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS RawDiskFlush( + uint8_t bVolNum) +{ + /* Caching is disabled, nothing to flush. + */ + return 0; +} +#endif /* REDCONF_READ_ONLY == 0 */ + diff --git a/os/win32/services/osclock.c b/os/win32/services/osclock.c new file mode 100644 index 0000000..871ca26 --- /dev/null +++ b/os/win32/services/osclock.c @@ -0,0 +1,79 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements real-time clock functions. +*/ +#include + +#include + + +/** @brief Initialize the real time clock. + + The behavior of calling this function when the RTC is already initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockInit(void) +{ + return 0; +} + + +/** @brief Uninitialize the real time clock. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsClockUninit(void) +{ + return 0; +} + + +/** @brief Get the date/time. + + The behavior of calling this function when the RTC is not initialized is + undefined. + + @return The number of seconds since January 1, 1970 excluding leap seconds + (in other words, standard Unix time). If the resolution or epoch + of the RTC is different than this, the implementation must convert + it to the expected representation. +*/ +uint32_t RedOsClockGetTime(void) +{ + /* Due to the signedness of time_t, this will break in 2038. + */ + return (uint32_t)time(NULL); +} + diff --git a/os/win32/services/osmutex.c b/os/win32/services/osmutex.c new file mode 100644 index 0000000..d7b6ee1 --- /dev/null +++ b/os/win32/services/osmutex.c @@ -0,0 +1,102 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a synchronization object to provide mutual exclusion. +*/ +#include + +#if REDCONF_TASK_COUNT > 1U + +#include + + +static CRITICAL_SECTION gCritSec; + + +/** @brief Initialize the mutex. + + After initialization, the mutex is in the released state. + + The behavior of calling this function when the mutex is still initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexInit(void) +{ + InitializeCriticalSection(&gCritSec); + + return 0; +} + + +/** @brief Uninitialize the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of uninitializing the mutex when it is + in the acquired state is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsMutexUninit(void) +{ + DeleteCriticalSection(&gCritSec); + + return 0; +} + + +/** @brief Acquire the mutex. + + The behavior of calling this function when the mutex is not initialized is + undefined; likewise, the behavior of recursively acquiring the mutex is + undefined. +*/ +void RedOsMutexAcquire(void) +{ + EnterCriticalSection(&gCritSec); +} + + +/** @brief Release the mutex. + + The behavior is undefined in the following cases: + + - Releasing the mutex when the mutex is not initialized. + - Releasing the mutex when it is not in the acquired state. + - Releasing the mutex from a task or thread other than the one which + acquired the mutex. +*/ +void RedOsMutexRelease(void) +{ + LeaveCriticalSection(&gCritSec); +} + +#endif + diff --git a/os/win32/services/osoutput.c b/os/win32/services/osoutput.c new file mode 100644 index 0000000..aa96b30 --- /dev/null +++ b/os/win32/services/osoutput.c @@ -0,0 +1,49 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements outputting a character string. +*/ +#include + +#if REDCONF_OUTPUT == 1 + +#include + + +/** @brief Write a string to a user-visible output location. + + Write a null-terminated string to the serial port, console, terminal, or + other display device, such that the text is visible to the user. + + @param pszString A null-terminated string. +*/ +void RedOsOutputString( + const char *pszString) +{ + printf("%s", pszString); +} + +#endif + diff --git a/os/win32/services/ostask.c b/os/win32/services/ostask.c new file mode 100644 index 0000000..b5a6fd8 --- /dev/null +++ b/os/win32/services/ostask.c @@ -0,0 +1,47 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements task functions. +*/ +#include + +#if (REDCONF_TASK_COUNT > 1U) && (REDCONF_API_POSIX == 1) + +#include + + +/** @brief Get the current task ID. + + This task ID must be unique for all tasks using the file system. + + @return The task ID. Must not be 0. +*/ +uint32_t RedOsTaskId(void) +{ + return GetCurrentThreadId(); +} + +#endif + diff --git a/os/win32/services/ostimestamp.c b/os/win32/services/ostimestamp.c new file mode 100644 index 0000000..480af05 --- /dev/null +++ b/os/win32/services/ostimestamp.c @@ -0,0 +1,149 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements timestamp functions. + + The functionality implemented herein is not needed for the file system + driver, only to provide accurate results with performance tests. +*/ +#include + +#include + +static uint64_t ullMultiplier; +static uint64_t ullDivisor; + + +/** @brief Initialize the timestamp service. + + The behavior of invoking this function when timestamps are already + initialized is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_ENOSYS The timestamp service has not been implemented. +*/ +REDSTATUS RedOsTimestampInit(void) +{ + REDSTATUS ret; + LARGE_INTEGER freq; + + if(QueryPerformanceFrequency(&freq)) + { + if(freq.QuadPart < 1000000U) + { + ullMultiplier = 1000000U / freq.QuadPart; + ullDivisor = 1; + } + else + { + ullMultiplier = 1; + ullDivisor = freq.QuadPart / 1000000U; + } + + ret = 0; + } + else + { + ret = -RED_ENOSYS; + } + + return ret; +} + + +/** @brief Uninitialize the timestamp service. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. +*/ +REDSTATUS RedOsTimestampUninit(void) +{ + return 0; +} + + +/** @brief Retrieve a timestamp. + + The behavior of invoking this function when timestamps are not initialized + is undefined + + @return A timestamp which can later be passed to RedOsTimePassed() to + determine the amount of time which passed between the two calls. +*/ +REDTIMESTAMP RedOsTimestamp(void) +{ + REDTIMESTAMP ret = 0U; + LARGE_INTEGER now; + + if(QueryPerformanceCounter(&now)) + { + ret = now.QuadPart; + } + else + { + REDERROR(); + } + + return ret; +} + + +/** @brief Determine how much time has passed since a timestamp was retrieved. + + The behavior of invoking this function when timestamps are not initialized + is undefined. + + @param tsSince A timestamp acquired earlier via RedOsTimestamp(). + + @return The number of microseconds which have passed since @p tsSince. +*/ +uint64_t RedOsTimePassed( + REDTIMESTAMP tsSince) +{ + uint64_t ullTimePassed = 0U; + LARGE_INTEGER now; + + if(QueryPerformanceCounter(&now)) + { + uint64_t ullTicksPassed = now.QuadPart - tsSince; + + /* Add half the divisor to round up when appropriate. + */ + ullTimePassed = ((ullTicksPassed * ullMultiplier) + (ullDivisor / 2)) / ullDivisor; + } + else + { + REDERROR(); + } + + return ullTimePassed; +} + diff --git a/os/win32/tools/config/allsettings.cpp b/os/win32/tools/config/allsettings.cpp new file mode 100644 index 0000000..e810c71 --- /dev/null +++ b/os/win32/tools/config/allsettings.cpp @@ -0,0 +1,809 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "allsettings.h" +#include "volumesettings.h" + + +// Private helpers +static QString outputLine(const QString ¯oName, const QString &value, + const QString &comment = QString::null); +static QString outputIfNotBlank(const QString ¯oName, const QString &value, + const QString &comment = QString::null); +template +static void parseToSetting(const QString &text, Setting *setting, + QStringList ¬Found, QStringList ¬Parsed, + const QString &humanName = QString::null); +static void parseMemSetting(const QString &text, StrSetting *setting); +static void parseToEnabledDisabledSetting(const QString &text, + StrSetting *setting, + const QString &strTrue, + const QString &strFalse, + QStringList ¬Found, + QStringList ¬Parsed, + const QString &humanName = QString::null); +static void parseToTrSetting(const QString &text, BoolSetting *setting); +static QString findValue(const QString &text, const QString ¯oName, bool &found); + +// Constant strings to save some malloc's and code duplicaiton +const QString str1 = QString("1"), + str0 = QString("0"), + strU = QString("U"); + +// Private inline helpers for FormatHeaderOutput. These process +// a given setting and append C preprocessor code to outputString +// as specified by the setting. + +static inline void addBoolSetting(QString &outputString, BoolSetting *boolSetting) +{ + outputString += outputLine(boolSetting->GetMacroName(), + (boolSetting->GetValue() ? str1 : str0)); +} + +static inline void addIntSetting(QString &outputString, IntSetting *intSetting) +{ + outputString += outputLine(intSetting->GetMacroName(), + QString::number(intSetting->GetValue()) + strU); +} + +// Add a transaction point to the mask at the end of outputString +// if trSetting is set to true. +// Trasnaction point will be exluded without evaluating trSetting +// if override is set to false. Evaluated normally if override +// is true or unspecified. +static inline void addTrIfChecked(QString &outputString, BoolSetting *trSetting, + bool override = true) +{ + if(override && trSetting->GetValue()) + { + // Essential to end with the pipe char; overwritten + // after final trSetting is evaluated. + outputString += QString(" ") + trSetting->GetMacroName() + QString(" |"); + } +} + +// Takes a pointer to a pointer; deletes the *item +// and sets it to NULL +template +static inline void deleteAndNullify(T **item) +{ + delete *item; + *item = NULL; +} + +QString AllSettings::FormatHeaderOutput() +{ + QString toReturn = QString("/** @file\n*/\n#ifndef REDCONF_H\n#define REDCONF_H\n\n\n"); + QString currValue; + + // Assert one setting. Assume the others. + Q_ASSERT(allSettings.cbsReadonly != NULL); + Q_ASSERT(volumeSettings != NULL); + + // Add include statement at the top + currValue = allSettings.lesInclude->GetValue(); + if(!currValue.isNull() && !currValue.isEmpty()) + { + toReturn += QString("#include ") + currValue + QString("\n\n"); + } + + addBoolSetting(toReturn, allSettings.cbsReadonly); + + bool posix = allSettings.rbtnsUsePosix->GetValue(); + + addBoolSetting(toReturn, allSettings.rbtnsUsePosix); + addBoolSetting(toReturn, allSettings.rbtnsUseFse); + + // Set POSIX calls to true if selected and POSIX is enabled + toReturn += outputLine(allSettings.cbsPosixFormat->GetMacroName(), + (posix && allSettings.cbsPosixFormat->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixLink->GetMacroName(), + (posix && allSettings.cbsPosixLink->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixUnlink->GetMacroName(), + (posix && allSettings.cbsPosixUnlink->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixMkdir->GetMacroName(), + (posix && allSettings.cbsPosixMkdir->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixRmdir->GetMacroName(), + (posix && allSettings.cbsPosixRmdir->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixRename->GetMacroName(), + (posix && allSettings.cbsPosixRename->GetValue() ? str1 : str0)); + // Greyed out if cbPosixRename not selected + toReturn += outputLine(allSettings.cbsPosixAtomicRename->GetMacroName(), + (posix && allSettings.cbsPosixRename->GetValue() + && allSettings.cbsPosixAtomicRename->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixFtruncate->GetMacroName(), + (posix && allSettings.cbsPosixFtruncate->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsPosixDirOps->GetMacroName(), + (posix && allSettings.cbsPosixDirOps->GetValue() ? str1 : str0)); + + addIntSetting(toReturn, allSettings.sbsMaxNameLen); + + QString pathSepChar = allSettings.pssPathSepChar->GetValue(); + + // Handle special case characters here + if(QString::compare(pathSepChar, "\\") == 0) + { + pathSepChar = "\\\\"; //Double-escaped backslash + } + else if (QString::compare(pathSepChar, "'") == 0) + { + pathSepChar = "\\'"; + } + else if (QString::compare(pathSepChar, "\t") == 0) + { + pathSepChar = "\\t"; + } + + currValue = QString("'") + pathSepChar + QString("'"); + toReturn += outputLine(macroNamePathSepChar, currValue); + + addIntSetting(toReturn, allSettings.sbsTaskCount); + addIntSetting(toReturn, allSettings.sbsHandleCount); + + // Set FSE calls to true if selected and POSIX is disabled + toReturn += outputLine(allSettings.cbsFseTruncate->GetMacroName(), + (!posix && allSettings.cbsFseTruncate->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsFseGetMask->GetMacroName(), + (!posix && allSettings.cbsFseGetMask->GetValue() ? str1 : str0)); + toReturn += outputLine(allSettings.cbsFseSetMask->GetMacroName(), + (!posix && allSettings.cbsFseSetMask->GetValue() ? str1 : str0)); + + addBoolSetting(toReturn, allSettings.cbsDebugEnableOutput); + addBoolSetting(toReturn, allSettings.cbsDebugProcesAsserts); + + // "Volumes" tab + + addIntSetting(toReturn, allSettings.cmisBlockSize); + + addIntSetting(toReturn, volumeSettings->GetStVolumeCount()); + + // "Data" tab + + currValue = (allSettings.cmssByteOrder->GetValue().startsWith("big", Qt::CaseInsensitive) + ? "1" : "0"); + toReturn += outputLine(macroNameByteOrder, currValue); + + addIntSetting(toReturn, allSettings.cmisNativeAlignment); + + currValue = (allSettings.cmssCrc->GetValue().startsWith("bitwise", Qt::CaseInsensitive) + ? crcBitwise : (allSettings.cmssCrc->GetValue().startsWith("sarwate", Qt::CaseInsensitive) + ? crcSarwate : crcSlice)); + toReturn += outputLine(macroNameCrc, currValue); + + addBoolSetting(toReturn, allSettings.cbsInodeCount); + addBoolSetting(toReturn, allSettings.cbsInodeTimestamps); + + // Greyed out if cbInodeTimestamps is not selected + toReturn += outputLine(allSettings.cbsUpdateAtime->GetMacroName(), + ((allSettings.cbsInodeTimestamps->GetValue() + && allSettings.cbsUpdateAtime->GetValue()) + ? str1 : str0)); + + addIntSetting(toReturn, allSettings.sbsDirectPtrs); + addIntSetting(toReturn, allSettings.sbsIndirectPtrs); + + addIntSetting(toReturn, allSettings.sbsAllocatedBuffers); + + toReturn += outputIfNotBlank(macroNameMemcpy, allSettings.lesMemcpy->GetValue()); + toReturn += outputIfNotBlank(macroNameMemmov, allSettings.lesMemmov->GetValue()); + toReturn += outputIfNotBlank(macroNameMemset, allSettings.lesMemset->GetValue()); + toReturn += outputIfNotBlank(macroNameMemcmp, allSettings.lesMemcmp->GetValue()); + toReturn += outputIfNotBlank(macroNameStrlen, allSettings.lesStrlen->GetValue()); + toReturn += outputIfNotBlank(macroNameStrcmp, allSettings.lesStrcmp->GetValue()); + toReturn += outputIfNotBlank(macroNameStrncmp, allSettings.lesStrncmp->GetValue()); + toReturn += outputIfNotBlank(macroNameStrncpy, allSettings.lesStrncpy->GetValue()); + + // Transaction points + if(allSettings.cbsTrManual->GetValue()) + { + currValue = QString("(") + macroNameTrManual + QString(")"); + } + else + { + currValue = QString("(("); + QString rememberCurrVal = currValue; + + // Add each transaction point if checked and if corresponding + // API call is enabled + + addTrIfChecked(currValue, allSettings.cbsTrFileCreat, posix); + addTrIfChecked(currValue, allSettings.cbsTrDirCreat, + posix && allSettings.cbsPosixMkdir->GetValue()); + addTrIfChecked(currValue, allSettings.cbsTrRename, + posix && allSettings.cbsPosixRename->GetValue()); + addTrIfChecked(currValue, allSettings.cbsTrLink, + posix && allSettings.cbsPosixLink->GetValue()); + addTrIfChecked(currValue, allSettings.cbsTrUnlink, + posix && allSettings.cbsPosixUnlink->GetValue()); + addTrIfChecked(currValue, allSettings.cbsTrWrite); + addTrIfChecked(currValue, allSettings.cbsTrTruncate, + (posix && allSettings.cbsPosixFtruncate->GetValue()) + || (!posix && allSettings.cbsFseTruncate->GetValue())); + addTrIfChecked(currValue, allSettings.cbsTrSync, posix); + addTrIfChecked(currValue, allSettings.cbsTrClose, posix); + addTrIfChecked(currValue, allSettings.cbsTrVolFull); + addTrIfChecked(currValue, allSettings.cbsTrUmount); + + // Ensure some flags were added (currValue was changed) + if(currValue != rememberCurrVal) + { + // Overwrite the final pipe character + currValue[currValue.length() - 1] = ')'; + currValue += " & RED_TRANSACT_MASK)"; + } + else + { + currValue = QString("(") + macroNameTrManual + QString(")"); + } + } + toReturn += outputLine(macroNameTrDefault, currValue); + + bool imapInline; + bool imapExternal; + volumeSettings->GetImapRequirements(imapInline, imapExternal); + + toReturn += QString("#define ") + macroNameInlineImap + + (imapInline ? QString(" 1\n\n") : QString(" 0\n\n")) + + QString("#define ") + macroNameExternalImap + + (imapExternal ? QString(" 1\n\n") : QString(" 0\n\n")); + + toReturn += QString("#define REDCONF_IMAGE_BUILDER 0\n\n"); + toReturn += QString("#define REDCONF_CHECKER 0\n\n"); + + toReturn += QString("#endif\n"); //close ifndef REDCONF_H + + return toReturn; +} + +// Formats the given arguments and returns a C #define statement +// based on them +QString outputLine(const QString ¯oName, const QString &value, + const QString &comment) +{ + return QString("#define ") + + macroName + + QString(" ") + + value + + (comment.isNull() ? QString("") : QString(" /* ") + + comment + + QString(" */")) + + QString("\n\n"); +} + +// Wraps outputLine, but returns an empty string if the given +// string value is null, empty, or whitespace. +QString outputIfNotBlank(const QString ¯oName, const QString &value, + const QString &comment) +{ + if(value.isNull() || value.isEmpty() || value.trimmed().isEmpty()) + { + return ""; + } + else + { + return outputLine(macroName, value, comment); + } +} + +QString AllSettings::FormatCodefileOutput() +{ + Q_ASSERT(volumeSettings != NULL); + return volumeSettings->FormatCodefileOutput(); +} + +void AllSettings::GetErrors(QStringList &errors, QStringList &warnings) +{ + // All CheckError calls in this function are parallel. + + // "General" tab + AllSettings::CheckError(allSettings.cbsReadonly, errors, warnings); + AllSettings::CheckError(allSettings.rbtnsUsePosix, errors, warnings); + AllSettings::CheckError(allSettings.rbtnsUseFse, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixFormat, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixLink, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixUnlink, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixMkdir, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixRmdir, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixRename, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixAtomicRename, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixFtruncate, errors, warnings); + AllSettings::CheckError(allSettings.cbsPosixDirOps, errors, warnings); + AllSettings::CheckError(allSettings.sbsMaxNameLen, errors, warnings); + AllSettings::CheckError(allSettings.pssPathSepChar, errors, warnings); + AllSettings::CheckError(allSettings.sbsTaskCount, errors, warnings); + AllSettings::CheckError(allSettings.sbsHandleCount, errors, warnings); + AllSettings::CheckError(allSettings.cbsFseTruncate, errors, warnings); + AllSettings::CheckError(allSettings.cbsFseGetMask, errors, warnings); + AllSettings::CheckError(allSettings.cbsFseSetMask, errors, warnings); + AllSettings::CheckError(allSettings.cbsDebugEnableOutput, errors, warnings); + AllSettings::CheckError(allSettings.cbsDebugProcesAsserts, errors, warnings); + + // "Volumes" tab + AllSettings::CheckError(allSettings.cmisBlockSize, errors, warnings); + + // "Data" tab + AllSettings::CheckError(allSettings.cmssByteOrder, errors, warnings); + AllSettings::CheckError(allSettings.cmisNativeAlignment, errors, warnings); + AllSettings::CheckError(allSettings.cmssCrc, errors, warnings); + AllSettings::CheckError(allSettings.cbsInodeCount, errors, warnings); + AllSettings::CheckError(allSettings.cbsInodeTimestamps, errors, warnings); + AllSettings::CheckError(allSettings.cbsUpdateAtime, errors, warnings); + AllSettings::CheckError(allSettings.sbsDirectPtrs, errors, warnings); + AllSettings::CheckError(allSettings.sbsIndirectPtrs, errors, warnings); + + // "Memory" tab + AllSettings::CheckError(allSettings.sbsAllocatedBuffers, errors, warnings); + AllSettings::CheckError(allSettings.lesMemcpy, errors, warnings); + AllSettings::CheckError(allSettings.lesMemmov, errors, warnings); + AllSettings::CheckError(allSettings.lesMemset, errors, warnings); + AllSettings::CheckError(allSettings.lesMemcmp, errors, warnings); + AllSettings::CheckError(allSettings.lesStrlen, errors, warnings); + AllSettings::CheckError(allSettings.lesStrcmp, errors, warnings); + AllSettings::CheckError(allSettings.lesStrncmp, errors, warnings); + AllSettings::CheckError(allSettings.lesStrncpy, errors, warnings); + AllSettings::CheckError(allSettings.lesInclude, errors, warnings); + + // "Transactions" tab + AllSettings::CheckError(allSettings.cbsTrManual, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrFileCreat, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrDirCreat, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrRename, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrLink, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrUnlink, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrWrite, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrTruncate, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrSync, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrClose, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrVolFull, errors, warnings); + AllSettings::CheckError(allSettings.cbsTrUmount, errors, warnings); + + Q_ASSERT(volumeSettings != NULL); + volumeSettings->GetErrors(errors, warnings); +} + +void AllSettings::CheckError(SettingBase *setting, + QStringList &errors, QStringList &warnings) +{ + Q_ASSERT(setting != NULL); + QString msg; + Validity v = setting->RecheckValid(msg); + switch(v) + { + case Invalid: + errors.append(msg); + break; + case Warning: + warnings.append(msg); + break; + //default: valid. Do nothing. + } +} + +void AllSettings::ParseHeaderToSettings(const QString &text, + QStringList ¬Found,QStringList ¬Parsed) +{ + QRegularExpression inclExp("#include ((\".*\")|(\\<.*\\>))\\s*?\\n"); + QRegularExpressionMatch inclMatch = inclExp.match(text); + if(inclMatch.hasMatch()) + { + if(inclMatch.lastCapturedIndex() < 1) + { + notParsed += "Included header"; + } + else + { + allSettings.lesInclude->SetValue(inclMatch.captured(1)); + } + } + else + { + allSettings.lesInclude->SetValue(""); + } + + parseToSetting(text, allSettings.cbsReadonly, notFound, notParsed); + parseToSetting(text, allSettings.rbtnsUsePosix, notFound, notParsed); + parseToSetting(text, allSettings.rbtnsUseFse, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixFormat, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixLink, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixUnlink, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixMkdir, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixRmdir, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixRename, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixAtomicRename, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixFtruncate, notFound, notParsed); + parseToSetting(text, allSettings.cbsPosixDirOps, notFound, notParsed); + parseToSetting(text, allSettings.sbsMaxNameLen, notFound, notParsed); + parseToSetting(text, allSettings.pssPathSepChar, notFound, notParsed); + parseToSetting(text, allSettings.sbsTaskCount, notFound, notParsed); + parseToSetting(text, allSettings.sbsHandleCount, notFound, notParsed); + parseToSetting(text, allSettings.cbsFseTruncate, notFound, notParsed); + parseToSetting(text, allSettings.cbsFseGetMask, notFound, notParsed); + parseToSetting(text, allSettings.cbsFseSetMask, notFound, notParsed); + parseToSetting(text, allSettings.cbsDebugEnableOutput, notFound, notParsed); + parseToSetting(text, allSettings.cbsDebugProcesAsserts, notFound, notParsed); + + // "Volumes" tab + parseToSetting(text, allSettings.cmisBlockSize, notFound, notParsed); + + // "Data Storage" tab + parseToEnabledDisabledSetting(text, allSettings.cmssByteOrder, "Big endian", "Little endian", + notFound, notParsed); + + parseToSetting(text, allSettings.cmisNativeAlignment, notFound, notParsed); + + //special case: CRC name must be translated into expected UI string + bool crcFound; + QString crcStrValue = findValue(text, allSettings.cmssCrc->GetMacroName(), crcFound); + if(crcFound && !crcStrValue.isNull()) + { + if(QString::compare(crcStrValue, crcBitwise) == 0) + { + allSettings.cmssCrc->SetValue("Bitwise - smallest, slowest"); + } + else if(QString::compare(crcStrValue, crcSarwate) == 0) + { + allSettings.cmssCrc->SetValue("Sarwate - midsized, fast"); + } + else if(QString::compare(crcStrValue, crcSlice) == 0) + { + allSettings.cmssCrc->SetValue("Slice by 8 - largest, fastest"); + } + else + { + notParsed += macroNameCrc; + } + } + else + { + notFound += macroNameCrc; + } + + parseToSetting(text, allSettings.cbsInodeCount, notFound, notParsed); + parseToSetting(text, allSettings.cbsInodeTimestamps, notFound, notParsed); + parseToSetting(text, allSettings.cbsUpdateAtime, notFound, notParsed); + parseToSetting(text, allSettings.sbsDirectPtrs, notFound, notParsed); + parseToSetting(text, allSettings.sbsIndirectPtrs, notFound, notParsed); + + // "Memory" tab + parseToSetting(text, allSettings.sbsAllocatedBuffers, notFound, notParsed); + + // Don't warn on these if not found; they will not be found + // if use Reliance memory mngmnt fns was selected. + parseMemSetting(text, allSettings.lesMemcpy); + parseMemSetting(text, allSettings.lesMemmov); + parseMemSetting(text, allSettings.lesMemset); + parseMemSetting(text, allSettings.lesMemcmp); + parseMemSetting(text, allSettings.lesStrlen); + parseMemSetting(text, allSettings.lesStrcmp); + parseMemSetting(text, allSettings.lesStrncmp); + parseMemSetting(text, allSettings.lesStrncpy); + + // Transaction point settings. Special case: if the transaction + // name is found within the #define statement, then it is set true. + // Otherwise it is set false. + + QRegularExpression trSearchExp(QString("#define[ \\t]+") + + macroNameTrDefault + //Capture all lines of value + + QString("([^\\\\]*(\\\\\\s*[^\\\\]*)*)")); + QRegularExpressionMatch rem = trSearchExp.match(text); + if(rem.hasMatch() && rem.lastCapturedIndex() >= 1) + { + QString trText = rem.captured(1); + + parseToTrSetting(trText, allSettings.cbsTrManual); + parseToTrSetting(trText, allSettings.cbsTrFileCreat); + parseToTrSetting(trText, allSettings.cbsTrDirCreat); + parseToTrSetting(trText, allSettings.cbsTrRename); + parseToTrSetting(trText, allSettings.cbsTrLink); + parseToTrSetting(trText, allSettings.cbsTrUnlink); + parseToTrSetting(trText, allSettings.cbsTrWrite); + parseToTrSetting(trText, allSettings.cbsTrTruncate); + parseToTrSetting(trText, allSettings.cbsTrSync); + parseToTrSetting(trText, allSettings.cbsTrClose); + parseToTrSetting(trText, allSettings.cbsTrVolFull); + parseToTrSetting(trText, allSettings.cbsTrUmount); + } + else //no matches + { + notFound += macroNameTrDefault; + } +} + +// Searches for the the given setting in the given tex. Parses the +// value and loads it into setting. Appends humanName to notFound +// or to notParsed if the setting was not found or could not be +// parsed. Appends the setting's macro name if humanName is not +// specified. +template +void parseToSetting(const QString &text, Setting *setting, + QStringList ¬Found, QStringList ¬Parsed, + const QString &humanName) +{ + Q_ASSERT(setting != NULL); + + QString label = (humanName.isNull() ? setting->GetMacroName() : humanName); + bool found = false, parseSuccess = false; + + QString strValue = findValue(text, setting->GetMacroName(), found); + if(found && !strValue.isNull()) + { + T value; + parseSuccess = setting->TryParse(strValue, value); + if(parseSuccess) + { + setting->SetValue(value); + } + else + { + notParsed += label; + } + } + else + { + notFound += label; + } +} + +// Searches for the given setting in the given text. If the macro +// is found, its value is parsed and loads it into setting. +// Otherwise the given setting is set to an empty string. +void parseMemSetting(const QString &text, StrSetting *setting) +{ + Q_ASSERT(setting != NULL); + bool found = false; + QString strValue = findValue(text, setting->GetMacroName(), found); + if(found && !strValue.isNull()) + { + setting->SetValue(strValue); + } + else + { + setting->SetValue(""); + } +} + +// For settings that represent boolean entities with strings. +// Sets setting to strTrue or strFalse if the macro is is found +// in text and can be parsed; otherwise appends humanName to +// notFound or to notParsed. If humanName is not specified, the +// setting's macro name is appended. +void parseToEnabledDisabledSetting(const QString &text, StrSetting *setting, + const QString &strTrue, const QString &strFalse, + QStringList ¬Found, QStringList ¬Parsed, + const QString &humanName) +{ + QString label = (humanName.isNull() ? setting->GetMacroName() : humanName); + bool found = false; + + QString strValue = findValue(text, setting->GetMacroName(), found); + if(found && !strValue.isNull()) + { + if(QString::compare(strValue, "0") == 0 + || QString::compare(strValue, "false", Qt::CaseInsensitive) == 0) + { + setting->SetValue(strFalse); + } + else if(QString::compare(strValue, "1") == 0 + || QString::compare(strValue, "true", Qt::CaseInsensitive) == 0) + { + setting->SetValue(strTrue); + } + else + { + notParsed += label; + } + } + else + { + notFound += label; + } +} + +// Searches for the given setting's macro name in the given text. +// Sets the setting to true if it is found, false otherwise. +void parseToTrSetting(const QString &text, BoolSetting *setting) +{ + Q_ASSERT(setting != NULL); + QRegularExpression searchExp(setting->GetMacroName()); + QRegularExpressionMatch rem = searchExp.match(text); + setting->SetValue(rem.hasMatch()); +} + +// Locates the given macroName in the given text. Sets found to +// true and returns the macro's value if it is found; otherwise +// sets found to false and returns QString::null. +QString findValue(const QString &text, const QString ¯oName, bool &found) +{ + QRegularExpression searchExp(QString("#define[ \\t]+") + + macroName + // Capture value. Capture group 1 may contain + // more than one word, but will not start or + // end with whitespace. + + QString("[ \\t]+(\\S([ \\t]*\\S)*)")); + QRegularExpressionMatch rem = searchExp.match(text); + found = rem.hasMatch() && rem.lastCapturedIndex() > 0; + if(!found) + { + return QString::null; + } + return rem.captured(1); +} + +void AllSettings::ParseCodefileToSettings(const QString &text, + QStringList ¬Found, + QStringList ¬Parsed) +{ + Q_ASSERT(volumeSettings != NULL); + volumeSettings->ParseCodefile(text, notFound, notParsed); +} + +void AllSettings::DeleteAll() +{ + deleteAndNullify(&allSettings.cbsReadonly); + deleteAndNullify(&allSettings.rbtnsUsePosix); + deleteAndNullify(&allSettings.rbtnsUseFse); + deleteAndNullify(&allSettings.cbsPosixFormat); + deleteAndNullify(&allSettings.cbsPosixLink); + deleteAndNullify(&allSettings.cbsPosixUnlink); + deleteAndNullify(&allSettings.cbsPosixMkdir); + deleteAndNullify(&allSettings.cbsPosixRmdir); + deleteAndNullify(&allSettings.cbsPosixRename); + deleteAndNullify(&allSettings.cbsPosixAtomicRename); + deleteAndNullify(&allSettings.cbsPosixFtruncate); + deleteAndNullify(&allSettings.cbsPosixDirOps); + deleteAndNullify(&allSettings.sbsMaxNameLen); + deleteAndNullify(&allSettings.pssPathSepChar); + deleteAndNullify(&allSettings.sbsTaskCount); + deleteAndNullify(&allSettings.sbsHandleCount); + deleteAndNullify(&allSettings.cbsFseTruncate); + deleteAndNullify(&allSettings.cbsFseGetMask); + deleteAndNullify(&allSettings.cbsFseSetMask); + deleteAndNullify(&allSettings.cbsDebugEnableOutput); + deleteAndNullify(&allSettings.cbsDebugProcesAsserts); + + // "Volumes" tab (Note: most settings handled by VolumeSettings) + deleteAndNullify(&allSettings.cmisBlockSize); + + // "Data" tab + deleteAndNullify(&allSettings.cmssByteOrder); + deleteAndNullify(&allSettings.cmisNativeAlignment); + deleteAndNullify(&allSettings.cmssCrc); + deleteAndNullify(&allSettings.cbsInodeCount); + deleteAndNullify(&allSettings.cbsInodeTimestamps); + deleteAndNullify(&allSettings.cbsUpdateAtime); + deleteAndNullify(&allSettings.sbsDirectPtrs); + deleteAndNullify(&allSettings.sbsIndirectPtrs); + + // "Memory" tab + deleteAndNullify(&allSettings.sbsAllocatedBuffers); + deleteAndNullify(&allSettings.lesMemcpy); + deleteAndNullify(&allSettings.lesMemmov); + deleteAndNullify(&allSettings.lesMemset); + deleteAndNullify(&allSettings.lesMemcmp); + deleteAndNullify(&allSettings.lesStrlen); + deleteAndNullify(&allSettings.lesStrcmp); + deleteAndNullify(&allSettings.lesStrncmp); + deleteAndNullify(&allSettings.lesStrncpy); + deleteAndNullify(&allSettings.lesInclude); + + // "Transactions" tab + deleteAndNullify(&allSettings.cbsTrManual); + deleteAndNullify(&allSettings.cbsTrFileCreat); + deleteAndNullify(&allSettings.cbsTrDirCreat); + deleteAndNullify(&allSettings.cbsTrRename); + deleteAndNullify(&allSettings.cbsTrLink); + deleteAndNullify(&allSettings.cbsTrUnlink); + deleteAndNullify(&allSettings.cbsTrWrite); + deleteAndNullify(&allSettings.cbsTrTruncate); + deleteAndNullify(&allSettings.cbsTrSync); + deleteAndNullify(&allSettings.cbsTrClose); + deleteAndNullify(&allSettings.cbsTrVolFull); + deleteAndNullify(&allSettings.cbsTrUmount); +} + + +const QString macroNameReadonly = "REDCONF_READ_ONLY"; +const QString macroNameUsePosix = "REDCONF_API_POSIX"; +const QString macroNameUseFse = "REDCONF_API_FSE"; +const QString macroNamePosixFormat = "REDCONF_API_POSIX_FORMAT"; +const QString macroNamePosixLink = "REDCONF_API_POSIX_LINK"; +const QString macroNamePosixUnlink = "REDCONF_API_POSIX_UNLINK"; +const QString macroNamePosixMkdir = "REDCONF_API_POSIX_MKDIR"; +const QString macroNamePosixRmdir = "REDCONF_API_POSIX_RMDIR"; +const QString macroNamePosixRename = "REDCONF_API_POSIX_RENAME"; +const QString macroNamePosixRenameAtomic = "REDCONF_RENAME_ATOMIC"; +const QString macroNamePosixFtruncate = "REDCONF_API_POSIX_FTRUNCATE"; +const QString macroNamePosixDirOps = "REDCONF_API_POSIX_READDIR"; +const QString macroNameMaxNameLen = "REDCONF_NAME_MAX"; +const QString macroNamePathSepChar = "REDCONF_PATH_SEPARATOR"; +const QString macroNameTaskCount = "REDCONF_TASK_COUNT"; +const QString macroNameHandleCount = "REDCONF_HANDLE_COUNT"; +const QString macroNameFseTruncate = "REDCONF_API_FSE_TRUNCATE"; +const QString macroNameFseGetMask = "REDCONF_API_FSE_TRANSMASKGET"; +const QString macroNameFseSetMask = "REDCONF_API_FSE_TRANSMASKSET"; +const QString macroNameDebugEnableOutput = "REDCONF_OUTPUT"; +const QString macroNameDebugProcesAsserts = "REDCONF_ASSERTS"; + +// "Volumes" tab +const QString macroNameBlockSize = "REDCONF_BLOCK_SIZE"; +const QString macroNameVolumeCount = "REDCONF_VOLUME_COUNT"; + +// "Data" tab +const QString macroNameByteOrder = "REDCONF_ENDIAN_BIG"; +const QString macroNameNativeAlignment = "REDCONF_ALIGNMENT_SIZE"; +const QString macroNameCrc = "REDCONF_CRC_ALGORITHM"; +const QString macroNameInodeCount = "REDCONF_INODE_BLOCKS"; +const QString macroNameInodeTimestamps = "REDCONF_INODE_TIMESTAMPS"; +const QString macroNameUpdateAtime = "REDCONF_ATIME"; +const QString macroNameDirectPtrs = "REDCONF_DIRECT_POINTERS"; +const QString macroNameIndirectPtrs = "REDCONF_INDIRECT_POINTERS"; + +// Not in UI +const QString macroNameInlineImap = "REDCONF_IMAP_INLINE"; +const QString macroNameExternalImap = "REDCONF_IMAP_EXTERNAL"; + +// "Memory" tab +const QString macroNameAllocatedBuffers = "REDCONF_BUFFER_COUNT"; +const QString macroNameMemcpy = "RedMemCpy"; +const QString macroNameMemmov = "RedMemMove"; +const QString macroNameMemset = "RedMemSet"; +const QString macroNameMemcmp = "RedMemCmp"; +const QString macroNameStrlen = "RedStrLen"; +const QString macroNameStrcmp = "RedStrCmp"; +const QString macroNameStrncmp = "RedStrNCmp"; +const QString macroNameStrncpy = "RedStrNCpy"; + +// "Transactions" tab +const QString macroNameTrDefault = "REDCONF_TRANSACT_DEFAULT"; //Not in UI +const QString macroNameTrManual = "RED_TRANSACT_MANUAL"; +const QString macroNameTrFileCreat = "RED_TRANSACT_CREAT"; +const QString macroNameTrDirCreat = "RED_TRANSACT_MKDIR"; +const QString macroNameTrRename = "RED_TRANSACT_RENAME"; +const QString macroNameTrLink = "RED_TRANSACT_LINK"; +const QString macroNameTrUnlink = "RED_TRANSACT_UNLINK"; +const QString macroNameTrWrite = "RED_TRANSACT_WRITE"; +const QString macroNameTrTruncate = "RED_TRANSACT_TRUNCATE"; +const QString macroNameTrSync = "RED_TRANSACT_FSYNC"; +const QString macroNameTrClose = "RED_TRANSACT_CLOSE"; +const QString macroNameTrVolFull = "RED_TRANSACT_VOLFULL"; +const QString macroNameTrUmount = "RED_TRANSACT_UMOUNT"; + +// Mem & str management function names +const QString cstdMemcpy = "memcpy"; +const QString cstdMemmov = "memmove"; +const QString cstdMemset = "memset"; +const QString cstdMemcmp = "memcmp"; +const QString cstdStrlen = "(uint32_t) strlen"; +const QString cstdStrcmp = "strcmp"; +const QString cstdStrncmp = "strncmp"; +const QString cstdStrncpy = "strncpy"; +const QString cstdStringH = ""; + +const QString crcBitwise = "CRC_BITWISE"; +const QString crcSarwate = "CRC_SARWATE"; +const QString crcSlice = "CRC_SLICEBY8"; + +// Extern global allSettings instance +AllSettings allSettings; diff --git a/os/win32/tools/config/allsettings.h b/os/win32/tools/config/allsettings.h new file mode 100644 index 0000000..03be34a --- /dev/null +++ b/os/win32/tools/config/allsettings.h @@ -0,0 +1,244 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef ALLSETTINGS_H +#define ALLSETTINGS_H + +#include "CbSetting.h" +#include "cmbintsetting.h" +#include "cmbstrsetting.h" +#include "pathsepsetting.h" +#include "rbtnsetting.h" +#include "sbsetting.h" +#include "lesetting.h" + +/// +/// \brief Structure containing public settings pointers for global access. +/// Instantiated globally in ::allSettings +/// +struct AllSettings +{ + /// + /// \brief Formats a string for output to a redconf.h file. Uses the values + /// in the global variables ::allSettings and ::volumeSettings to + /// fill in values. Assumes that all values are valid. + /// + static QString FormatHeaderOutput(); + + /// + /// \brief Fills errors and warnings with any errors and warnings found in + /// current settings + /// + /// \param errors List to which to add any error messages + /// \param warnings List to which to add any warning messages + /// + static void GetErrors(QStringList &errors, QStringList &warnings); + + /// + /// \brief Wrapper function for VolumeSettings::FormatCodefileOutput + /// + static QString FormatCodefileOutput(); + + /// + /// \brief Looks for settings in the given string \p text. The macro names + /// of any missing values are added to \p notFound and the macro + /// names of any unparseable values are added to \p notParsed. + /// + static void ParseHeaderToSettings(const QString &text, + QStringList ¬Found, + QStringList ¬Parsed); + + /// + /// \brief Wrapper function for VolumeSettings::ParseCodefile + /// + static void ParseCodefileToSettings(const QString &text, + QStringList ¬Found, + QStringList ¬Parsed); + + /// + /// \brief Checks for validity of \p setting, appending any message to + /// \p errors or \p warnings. + /// + static void CheckError(SettingBase *setting, + QStringList &errors, QStringList &warnings); + + /// + /// \brief Deletes all members of ::allSettings and sets them to NULL + /// + static void DeleteAll(); + + // "General" tab + CbSetting *cbsReadonly; + RbtnSetting *rbtnsUsePosix; + RbtnSetting *rbtnsUseFse; + CbSetting *cbsPosixFormat; + CbSetting *cbsPosixLink; + CbSetting *cbsPosixUnlink; + CbSetting *cbsPosixMkdir; + CbSetting *cbsPosixRmdir; + CbSetting *cbsPosixRename; + CbSetting *cbsPosixAtomicRename; + CbSetting *cbsPosixFtruncate; + CbSetting *cbsPosixDirOps; + SbSetting *sbsMaxNameLen; + PathSepSetting *pssPathSepChar; + SbSetting *sbsTaskCount; + SbSetting *sbsHandleCount; + CbSetting *cbsFseTruncate; + CbSetting *cbsFseGetMask; + CbSetting *cbsFseSetMask; + CbSetting *cbsDebugEnableOutput; + CbSetting *cbsDebugProcesAsserts; + + // "Volumes" tab (Note: most settings handled by VolumeSettings) + CmbIntSetting *cmisBlockSize; + + // "Data" tab + CmbStrSetting *cmssByteOrder; + CmbIntSetting *cmisNativeAlignment; + CmbStrSetting *cmssCrc; + CbSetting *cbsInodeCount; + CbSetting *cbsInodeTimestamps; + CbSetting *cbsUpdateAtime; + SbSetting *sbsDirectPtrs; + SbSetting *sbsIndirectPtrs; + + // "Memory" tab + SbSetting *sbsAllocatedBuffers; + LeSetting *lesMemcpy; + LeSetting *lesMemmov; + LeSetting *lesMemset; + LeSetting *lesMemcmp; + LeSetting *lesStrlen; + LeSetting *lesStrcmp; + LeSetting *lesStrncmp; + LeSetting *lesStrncpy; + LeSetting *lesInclude; + + // "Transactions" tab + CbSetting *cbsTrManual; + CbSetting *cbsTrFileCreat; + CbSetting *cbsTrDirCreat; + CbSetting *cbsTrRename; + CbSetting *cbsTrLink; + CbSetting *cbsTrUnlink; + CbSetting *cbsTrWrite; + CbSetting *cbsTrTruncate; + CbSetting *cbsTrSync; + CbSetting *cbsTrClose; + CbSetting *cbsTrVolFull; + CbSetting *cbsTrUmount; +}; + +extern const QString macroNameReadonly; +extern const QString macroNameUsePosix; +extern const QString macroNameUseFse; +extern const QString macroNamePosixFormat; +extern const QString macroNamePosixLink; +extern const QString macroNamePosixUnlink; +extern const QString macroNamePosixMkdir; +extern const QString macroNamePosixRmdir; +extern const QString macroNamePosixRename; +extern const QString macroNamePosixRenameAtomic; +extern const QString macroNamePosixFtruncate; +extern const QString macroNamePosixDirOps; +extern const QString macroNameMaxNameLen; +extern const QString macroNamePathSepChar; +extern const QString macroNameTaskCount; +extern const QString macroNameHandleCount; +extern const QString macroNameFseTruncate; +extern const QString macroNameFseGetMask; +extern const QString macroNameFseSetMask; +extern const QString macroNameDebugEnableOutput; +extern const QString macroNameDebugProcesAsserts; + +// "Volumes" tab +extern const QString macroNameBlockSize; +extern const QString macroNameVolumeCount; + +// "Data Storage" tab +extern const QString macroNameByteOrder; +extern const QString macroNameNativeAlignment; +extern const QString macroNameCrc; +extern const QString macroNameInodeCount; +extern const QString macroNameInodeTimestamps; +extern const QString macroNameUpdateAtime; +extern const QString macroNameDirectPtrs; +extern const QString macroNameIndirectPtrs; + +// Not in UI: +extern const QString macroNameInlineImap; +extern const QString macroNameExternalImap; + +// "Memory" tab +extern const QString macroNameAllocatedBuffers; +extern const QString macroNameMemcpy; +extern const QString macroNameMemmov; +extern const QString macroNameMemset; +extern const QString macroNameMemcmp; +extern const QString macroNameStrlen; +extern const QString macroNameStrcmp; +extern const QString macroNameStrncmp; +extern const QString macroNameStrncpy; + +// "Transaction Points" tab +extern const QString macroNameTrDefault; //Not in UI +extern const QString macroNameTrManual; +extern const QString macroNameTrFileCreat; +extern const QString macroNameTrDirCreat; +extern const QString macroNameTrRename; +extern const QString macroNameTrLink; +extern const QString macroNameTrUnlink; +extern const QString macroNameTrWrite; +extern const QString macroNameTrTruncate; +extern const QString macroNameTrSync; +extern const QString macroNameTrClose; +extern const QString macroNameTrVolFull; +extern const QString macroNameTrUmount; + +// Mem & str management function names +extern const QString cstdMemcpy; +extern const QString cstdMemmov; +extern const QString cstdMemset; +extern const QString cstdMemcmp; +extern const QString cstdStrlen; +extern const QString cstdStrcmp; +extern const QString cstdStrncmp; +extern const QString cstdStrncpy; +extern const QString cstdStringH; + +// Enum-like macro values +extern const QString crcBitwise; +extern const QString crcSarwate; +extern const QString crcSlice; + +/// +/// \brief Global ::AllSettings object. +/// +/// Accessed by validators, ::Input, ::Output, etc. Initialized in +/// ::ConfigWindow constructor. +/// +extern AllSettings allSettings; + +#endif // ALLSETTINGS_H diff --git a/os/win32/tools/config/application.cpp b/os/win32/tools/config/application.cpp new file mode 100644 index 0000000..bb60b7a --- /dev/null +++ b/os/win32/tools/config/application.cpp @@ -0,0 +1,136 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include +#include + +#include "application.h" + +Application::Application(int &argc, char *argv[]) + : QApplication(argc, argv), + configWindow(NULL), + output(NULL), + input(NULL), + messageBox(NULL) +{ +} + +Application::~Application() +{ + if(configWindow != NULL) + { + delete configWindow; + } + if(output != NULL) + { + delete output; + } + if(input != NULL) + { + delete input; + } + // MessageBox deleted by configWindow +} + +int Application::Run() +{ + if(configWindow != NULL) + { + Q_ASSERT(false); + return 1; //Error: already running + } + + configWindow = new ConfigWindow(); + output = new Output(configWindow); + input = new Input(configWindow); + messageBox = new QMessageBox(configWindow); + + messageBox->setText("Error"); + messageBox->setIcon(QMessageBox::Critical); + messageBox->setStandardButtons(QMessageBox::Ok); + + connect(configWindow, SIGNAL(saveClicked()), + this, SLOT(TrySave())); + connect(output, SIGNAL(results(Output::Result)), + this, SLOT(output_results(Output::Result))); + connect(configWindow, SIGNAL(loadClicked()), + this, SLOT(TryLoad())); + connect(input, SIGNAL(results(Input::Result)), + this, SLOT(input_results(Input::Result))); + connect(configWindow, SIGNAL(warningBtnClicked()), + this, SLOT(ShowErrors())); + + // Pass control to configWindow. + configWindow->show(); + return exec(); +} + +void Application::TrySave() +{ + output->TrySave(); + // Result handled by output_results +} + +void Application::TryLoad() +{ + input->TryLoad(); + // Result handled by input_results +} + +void Application::ShowErrors() +{ + // Show error dialog, even if there are no errors. + output->ShowErrors(true); +} + +void Application::output_results(Output::Result r) +{ + if(r == Output::OutResultFileError) + { + messageBox->setInformativeText("Error saving configuration files. Try saving to a different directory."); + messageBox->exec(); + } + configWindow->activateWindow(); + +} + +void Application::input_results(Input::Result r) +{ + if(r == Input::InResultFileError) + { + messageBox->setInformativeText("Error loading selected configuration files."); + messageBox->exec(); + } + else if (r == Input::InResultErrorHugeFile) + { + messageBox->setInformativeText("Unreasonably large file. Please select valid configuration files."); + messageBox->exec(); + } + else if (r == Input::InResultSuccess) + { + configWindow->SetMemRbtnSelection(ConfigWindow::Customize); + output->ShowErrors(false); + } + configWindow->activateWindow(); +} diff --git a/os/win32/tools/config/application.h b/os/win32/tools/config/application.h new file mode 100644 index 0000000..4c3a1e0 --- /dev/null +++ b/os/win32/tools/config/application.h @@ -0,0 +1,89 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef APPLICATION_H +#define APPLICATION_H + +#include +#include +#include + +#include "configwindow.h" +#include "output.h" +#include "input.h" + +/// +/// \brief The Application class is a child class of QApplication. It runs the +/// program and owns instances of the ConfigWindow, Output, and Input +/// classes. +/// +class Application : protected QApplication +{ + Q_OBJECT +public: + /// + /// \brief Instantiates an Application + /// + /// \param argc Passed to QApplication constructor + /// \param argv Passed to QApplication constructor + /// + Application(int &argc, char *argv[]); + + ~Application(); + + /// + /// \brief Runs the configuration utility + /// + /// \return Returns 0 if success or non-zero if error + /// + int Run(); + +private: + ConfigWindow *configWindow; + Output *output; + Input *input; + QMessageBox *messageBox; + +public slots: + /// + /// \brief Calls Output::TrySave and handles results + /// + void TrySave(); + + /// + /// \brief Calls Output::TryLoad and handles results + /// + void TryLoad(); + + /// + /// \brief Calls Output::ShowErrors + /// + void ShowErrors(); + +private slots: + void output_results(Output::Result r); + void input_results(Input::Result r); +}; + +#endif // APPLICATION_H diff --git a/os/win32/tools/config/boolsetting.cpp b/os/win32/tools/config/boolsetting.cpp new file mode 100644 index 0000000..df42eb6 --- /dev/null +++ b/os/win32/tools/config/boolsetting.cpp @@ -0,0 +1,75 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ + +#include + +#include + +#include "boolsetting.h" + +BoolSetting::BoolSetting(QString macroName, bool defaultValue, + std::function validator, + WarningBtn * btnWarn) + : Setting(macroName, defaultValue, validator), + btnWarning(btnWarn) +{ +} + +void BoolSetting::ProcessInput(bool input) +{ + QString msg; + checkValue(input, msg); + SetValue(input, false); +} + +Validity BoolSetting::checkValue(bool value, QString &msg) +{ + Validity v = CheckValid(value, msg); + if(btnWarning) + { + btnWarning->Set(v, msg); + } + return v; +} + +bool BoolSetting::TryParse(const QString &toParse, bool & out) +{ + // Currently 0 and 1 are the only values used for boolean + // REDCONF settings, but support true and false for common + // sense reasons. + if(QString::compare(toParse, "1") == 0 + || QString::compare(toParse, "true", Qt::CaseInsensitive) == 0) + { + out = true; + return true; + } + else if (QString::compare(toParse, "0") == 0 + || QString::compare(toParse, "false", Qt::CaseInsensitive) == 0) + { + out = false; + return true; + } + else return false; +} diff --git a/os/win32/tools/config/boolsetting.h b/os/win32/tools/config/boolsetting.h new file mode 100644 index 0000000..7496926 --- /dev/null +++ b/os/win32/tools/config/boolsetting.h @@ -0,0 +1,73 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef BOOLSETTING_H +#define BOOLSETTING_H + +#include + +#include "Setting.h" +#include "WarningBtn.h" + + + +/// +/// \brief Class for settings that may be represented using a Boolean type. +/// Inherits from QObject and Setting, where `T` is set to `bool` +/// +class BoolSetting : public QObject, public Setting + //Qt moc expects first inheritance to be from a QObject type. +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param btnWarn Optional: the warning button associated with this + /// setting + /// + BoolSetting(QString macroName, bool defaultValue, + std::function validator, + WarningBtn * btnWarn = 0); + + bool TryParse(const QString &toParse, bool & out) override; + + /// + /// \brief Sets the value of this setting, checking validity and setting + /// any associated warning button + /// + /// \param input The value to set + /// + void ProcessInput(bool input); + +protected: + Validity checkValue(bool value, QString &msg) override; + + WarningBtn *btnWarning; +}; + +#endif // BOOLSETTING_H diff --git a/os/win32/tools/config/cbsetting.cpp b/os/win32/tools/config/cbsetting.cpp new file mode 100644 index 0000000..2fda8b7 --- /dev/null +++ b/os/win32/tools/config/cbsetting.cpp @@ -0,0 +1,69 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include + +#include "CbSetting.h" + +CbSetting::CbSetting(QString macroName, bool defaultValue, + std::function validator, + QCheckBox * cb, + WarningBtn * btnWarn) + : BoolSetting(macroName, defaultValue, validator, btnWarn), + checkBox(cb) +{ + if(!cb) + { + throw new std::invalid_argument("cb cannot be null"); + } + + setUi(); + connect(cb, SIGNAL(stateChanged(int)), + this, SLOT(checkBox_stateChanged(int))); +} + +void CbSetting::setUi() +{ + checkBox->setChecked(value); +} + +void CbSetting::checkBox_stateChanged(int state) +{ + bool bstate; + if(state == Qt::Checked) + { + bstate = true; + } + else if (state == Qt::Unchecked) + { + bstate = false; + } + else { + // Halt: bool checkboxes should be two-state only. + Q_ASSERT(false); + } + ProcessInput(bstate); +} diff --git a/os/win32/tools/config/cbsetting.h b/os/win32/tools/config/cbsetting.h new file mode 100644 index 0000000..5620ec2 --- /dev/null +++ b/os/win32/tools/config/cbsetting.h @@ -0,0 +1,65 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef CBSETTING_H +#define CBSETTING_H + +#include +#include + +#include "BoolSetting.h" + +/// +/// \brief The CbSetting class manages settings that use a QCheckBox for user +/// input and hold a Boolean value. +/// +class CbSetting : public BoolSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param cb The QCheckBox associated with this setting + /// \param btnWarn Optional: passed to the BoolSetting constructor + /// + CbSetting(QString macroName, bool defaultValue, + std::function validator, + QCheckBox *cb, + WarningBtn * btnWarn = 0); + +protected: + virtual void setUi() override; + +private: + QCheckBox * checkBox; + +private slots: + void checkBox_stateChanged(int state); +}; + +#endif // CBSETTING_H diff --git a/os/win32/tools/config/cmbintsetting.cpp b/os/win32/tools/config/cmbintsetting.cpp new file mode 100644 index 0000000..b925635 --- /dev/null +++ b/os/win32/tools/config/cmbintsetting.cpp @@ -0,0 +1,56 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "cmbintsetting.h" + +CmbIntSetting::CmbIntSetting(QString macroName, unsigned long defaultValue, + std::function validator, + QComboBox *cmb, + WarningBtn * btnWarn) + : IntSetting(macroName, defaultValue, validator, btnWarn), + comboBox(cmb) +{ + if(!cmb) + { + throw new std::invalid_argument("cmb cannot be null"); + } + + setUi(); + connect(cmb, SIGNAL(currentIndexChanged(QString)), + this, SLOT(combobox_currentIndexChanged(QString))); +} + +void CmbIntSetting::setUi() +{ + // Use QLocale to add commas; e.g. 32768 -> 32,768 + static const QLocale l(QLocale::English, QLocale::UnitedStates); + comboBox->setCurrentText(l.toString((qulonglong) value)); +} + +void CmbIntSetting::combobox_currentIndexChanged(const QString & text) +{ + ProcessInput(text); +} diff --git a/os/win32/tools/config/cmbintsetting.h b/os/win32/tools/config/cmbintsetting.h new file mode 100644 index 0000000..12598a0 --- /dev/null +++ b/os/win32/tools/config/cmbintsetting.h @@ -0,0 +1,65 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef CMBINTSETTING_H +#define CMBINTSETTING_H + +#include +#include + +#include "intsetting.h" +#include "WarningBtn.h" + +/// +/// \brief The CmbStrSetting class manages settings that use a QComboBox for +/// user input and hold an unsigned integer value. +/// +class CmbIntSetting : public IntSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param cmb The QComboBox associated with this setting + /// \param btnWarn Optional: passed to the IntSetting constructor + /// + CmbIntSetting(QString macroName, unsigned long defaultValue, + std::function validator, + QComboBox *cmb, + WarningBtn * btnWarn = 0); + +protected: + virtual void setUi() override; + +private: + QComboBox *comboBox; + +private slots: + void combobox_currentIndexChanged(const QString & text); +}; +#endif // CMBINTSETTING_H diff --git a/os/win32/tools/config/cmbstrsetting.cpp b/os/win32/tools/config/cmbstrsetting.cpp new file mode 100644 index 0000000..acbd25d --- /dev/null +++ b/os/win32/tools/config/cmbstrsetting.cpp @@ -0,0 +1,54 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "cmbstrsetting.h" + +CmbStrSetting::CmbStrSetting(QString macroName, QString defaultValue, + std::function validator, + QComboBox *cmb, + WarningBtn * btnWarn) + : StrSetting(macroName, defaultValue, validator, btnWarn), + comboBox(cmb) +{ + if(!cmb) + { + throw new std::invalid_argument("cmb cannot be null"); + } + + setUi(); + connect(cmb, SIGNAL(currentIndexChanged(QString)), + this, SLOT(combobox_currentIndexChanged(QString))); +} + +void CmbStrSetting::setUi() +{ + comboBox->setCurrentText(value); +} + +void CmbStrSetting::combobox_currentIndexChanged(const QString & text) +{ + ProcessInput(text); +} diff --git a/os/win32/tools/config/cmbstrsetting.h b/os/win32/tools/config/cmbstrsetting.h new file mode 100644 index 0000000..729e1ab --- /dev/null +++ b/os/win32/tools/config/cmbstrsetting.h @@ -0,0 +1,66 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef CMBSETTING_H +#define CMBSETTING_H + +#include +#include + +#include "StrSetting.h" +#include "WarningBtn.h" +/// +/// \brief The CmbStrSetting class manages settings that use a QComboBox for +/// user input and hold a string value. This includes settings that +/// output an enum-like macro. +/// +class CmbStrSetting : public StrSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param cmb The QComboBox associated with this setting + /// \param btnWarn Optional: passed to the StrSetting constructor + /// + CmbStrSetting(QString macroName, QString defaultValue, + std::function validator, + QComboBox *cmb, + WarningBtn * btnWarn = 0); + +protected: + virtual void setUi() override; + +private: + QComboBox *comboBox; + +private slots: + void combobox_currentIndexChanged(const QString & text); +}; + +#endif // CMBSETTING_H diff --git a/os/win32/tools/config/configwindow.cpp b/os/win32/tools/config/configwindow.cpp new file mode 100644 index 0000000..b9c0725 --- /dev/null +++ b/os/win32/tools/config/configwindow.cpp @@ -0,0 +1,370 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "configwindow.h" +#include "ui_configwindow.h" +#include "allsettings.h" +#include "validators.h" +#include "output.h" + +ConfigWindow::ConfigWindow(QWidget *parent) : + QMainWindow(parent), + ui(new Ui::ConfigWindow) +{ + ui->setupUi(this); + + // Instantiate allSettings + + // "General" tab + allSettings.cbsReadonly = new CbSetting(macroNameReadonly, false, emptyBoolValidator, ui->cbReadonly); + allSettings.rbtnsUsePosix = new RbtnSetting(macroNameUsePosix, true, validateUsePosixApi, ui->rbtnUsePosix, ui->wbtnApiRbtns); + allSettings.rbtnsUseFse = new RbtnSetting(macroNameUseFse, false, validateUseFseApi, ui->rbtnUseFse, ui->wbtnApiRbtns); + allSettings.cbsPosixFormat = new CbSetting(macroNamePosixFormat, true, emptyBoolValidator, ui->cbPosixFormat); + allSettings.cbsPosixLink = new CbSetting(macroNamePosixLink, true, emptyBoolValidator, ui->cbPosixLink); + allSettings.cbsPosixUnlink = new CbSetting(macroNamePosixUnlink, true, emptyBoolValidator, ui->cbPosixUnlink); + allSettings.cbsPosixMkdir = new CbSetting(macroNamePosixMkdir, true, emptyBoolValidator, ui->cbPosixMkdir); + allSettings.cbsPosixRmdir = new CbSetting(macroNamePosixRmdir, true, emptyBoolValidator, ui->cbPosixRmDir); + allSettings.cbsPosixRename = new CbSetting(macroNamePosixRename, false, emptyBoolValidator, ui->cbPosixRename); + allSettings.cbsPosixAtomicRename = new CbSetting(macroNamePosixRenameAtomic, false, emptyBoolValidator, ui->cbPosixAtomicRename); + allSettings.cbsPosixFtruncate = new CbSetting(macroNamePosixFtruncate, true, emptyBoolValidator, ui->cbPosixFtruncate); + allSettings.cbsPosixDirOps = new CbSetting(macroNamePosixDirOps, true, emptyBoolValidator, ui->cbPosixDirOps); + allSettings.sbsMaxNameLen = new SbSetting(macroNameMaxNameLen, 12, validateMaxNameLen, ui->sbFileNameLen, ui->wbtnFileNameLen); + allSettings.pssPathSepChar = new PathSepSetting(macroNamePathSepChar, "/", validatePathSepChar, ui->cmbPathChar, ui->lePathCharCustom, ui->wbtnPathChar); + allSettings.cbsFseTruncate = new CbSetting(macroNameFseTruncate, true, emptyBoolValidator, ui->cbFseTruncate); + allSettings.sbsTaskCount = new SbSetting(macroNameTaskCount, 10, validateTaskCount, ui->sbTaskCount, ui->wbtnTaskCount); + allSettings.sbsHandleCount = new SbSetting(macroNameHandleCount, 10, validateHandleCount, ui->sbHandleCount, ui->wbtnHandleCount); + allSettings.cbsFseGetMask = new CbSetting(macroNameFseGetMask, true, emptyBoolValidator, ui->cbFseGetMask); + allSettings.cbsFseSetMask = new CbSetting(macroNameFseSetMask, true, emptyBoolValidator, ui->cbFseSetMask); + allSettings.cbsDebugEnableOutput = new CbSetting(macroNameDebugEnableOutput, false, emptyBoolValidator, ui->cbEnableOutput); + allSettings.cbsDebugProcesAsserts = new CbSetting(macroNameDebugProcesAsserts, false, emptyBoolValidator, ui->cbProcessAsserts); + + // "Volumes" tab (Note: most settings handled + // by VolumeSettings + allSettings.cmisBlockSize = new CmbIntSetting(macroNameBlockSize, 512, validateBlockSize, ui->cmbBlockSize, ui->wbtnBlockSize); + + // "Data Storage" tab + allSettings.cmssByteOrder = new CmbStrSetting(macroNameByteOrder, "Little endian", validateByteOrder, ui->cmbByteOrder, ui->wbtnByteOrder); + allSettings.cmisNativeAlignment = new CmbIntSetting(macroNameNativeAlignment, 4, validateAlignmentSize, ui->cmbAlignmentSize, ui->wbtnAlignmentSize); + allSettings.cmssCrc = new CmbStrSetting(macroNameCrc, "Slice by 8 - largest, fastest", validateCrc, ui->cmbCrc, ui->wbtnCrc); + allSettings.cbsInodeCount = new CbSetting(macroNameInodeCount, true, emptyBoolValidator, ui->cbInodeBlockCount); + allSettings.cbsInodeTimestamps = new CbSetting(macroNameInodeTimestamps, true, emptyBoolValidator, ui->cbInodeTimestamps); + allSettings.cbsUpdateAtime = new CbSetting(macroNameUpdateAtime, false, emptyBoolValidator, ui->cbUpdateAtime); + allSettings.sbsDirectPtrs = new SbSetting(macroNameDirectPtrs, 4, validateDirectPointers, ui->sbDirectPointers, ui->wbtnDirectPointers); + allSettings.sbsIndirectPtrs = new SbSetting(macroNameIndirectPtrs, 32, validateIndirectPointers, ui->sbIndirectPointers, ui->wbtnIndirectPointers); + + // "Memory" tab + allSettings.sbsAllocatedBuffers = new SbSetting(macroNameAllocatedBuffers, 8, validateAllocatedBuffers, ui->sbAllocatedBuffers, ui->wbtnAllocatedBuffers); + allSettings.lesMemcpy = new LeSetting(macroNameMemcpy, cstdMemcpy, emptyStringValidator, ui->leMemcpy); + allSettings.lesMemmov = new LeSetting(macroNameMemmov, cstdMemmov, emptyStringValidator, ui->leMemmov); + allSettings.lesMemset = new LeSetting(macroNameMemset, cstdMemset, emptyStringValidator, ui->leMemset); + allSettings.lesMemcmp = new LeSetting(macroNameMemcmp, cstdMemcmp, emptyStringValidator, ui->leMemcmp); + allSettings.lesStrlen = new LeSetting(macroNameStrlen, cstdStrlen, emptyStringValidator, ui->leStrlen); + allSettings.lesStrcmp = new LeSetting(macroNameStrcmp, cstdStrcmp, emptyStringValidator, ui->leStrcmp); + allSettings.lesStrncmp = new LeSetting(macroNameStrncmp, cstdStrncmp, emptyStringValidator, ui->leStrncmp); + allSettings.lesStrncpy = new LeSetting(macroNameStrncpy, cstdStrncpy, emptyStringValidator, ui->leStrncpy); + allSettings.lesInclude = new LeSetting("", cstdStringH, validateMemInclude, ui->leIncludeFile, ui->wbtnIncludeFile); + + // "Transaction Points" tab + allSettings.cbsTrManual = new CbSetting(macroNameTrManual, false, validateTransactManual,ui->cbTransactManual, ui->wbtnTransactManual); + allSettings.cbsTrFileCreat = new CbSetting(macroNameTrFileCreat, true, emptyBoolValidator, ui->cbTransactFileCreate); + allSettings.cbsTrDirCreat = new CbSetting(macroNameTrDirCreat, true, emptyBoolValidator, ui->cbTransactDirCreate); + allSettings.cbsTrRename = new CbSetting(macroNameTrRename, true, emptyBoolValidator, ui->cbTransactRename); + allSettings.cbsTrLink = new CbSetting(macroNameTrLink, true, emptyBoolValidator, ui->cbTransactLink); + allSettings.cbsTrUnlink = new CbSetting(macroNameTrUnlink, true, emptyBoolValidator, ui->cbTransactUnlink); + allSettings.cbsTrWrite = new CbSetting(macroNameTrWrite, false, emptyBoolValidator, ui->cbTransactWrite); + allSettings.cbsTrTruncate = new CbSetting(macroNameTrTruncate, false, emptyBoolValidator, ui->cbTransactTruncate); + allSettings.cbsTrSync = new CbSetting(macroNameTrSync, true, emptyBoolValidator, ui->cbTransactFSync); + allSettings.cbsTrClose = new CbSetting(macroNameTrClose, true, emptyBoolValidator, ui->cbTransactClose); + allSettings.cbsTrVolFull = new CbSetting(macroNameTrVolFull, true, validateTransactVolFull, ui->cbTransactVolFull, ui->wbtnTransactVolFull); + allSettings.cbsTrUmount = new CbSetting(macroNameTrUmount, true, emptyBoolValidator, ui->cbTransactVolUnmount); + + allSettings.cbsInodeCount->notifyList.append(allSettings.sbsDirectPtrs); + allSettings.cbsInodeCount->notifyList.append(allSettings.sbsIndirectPtrs); + allSettings.cbsInodeTimestamps->notifyList.append(allSettings.sbsDirectPtrs); + allSettings.cbsInodeTimestamps->notifyList.append(allSettings.sbsIndirectPtrs); + allSettings.rbtnsUsePosix->notifyList.append(allSettings.sbsDirectPtrs); + allSettings.rbtnsUsePosix->notifyList.append(allSettings.sbsIndirectPtrs); + allSettings.cmisBlockSize->notifyList.append(allSettings.sbsDirectPtrs); + allSettings.cmisBlockSize->notifyList.append(allSettings.sbsIndirectPtrs); + allSettings.sbsIndirectPtrs->notifyList.append(allSettings.sbsDirectPtrs); + allSettings.sbsDirectPtrs->notifyList.append(allSettings.sbsIndirectPtrs); + + // The following settings are dependent + allSettings.cbsInodeCount->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.cbsInodeTimestamps->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.rbtnsUsePosix->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.cmisBlockSize->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.sbsIndirectPtrs->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.sbsDirectPtrs->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.rbtnsUsePosix->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.cbsPosixRename->notifyList.append(allSettings.sbsAllocatedBuffers); + allSettings.cbsPosixAtomicRename->notifyList.append(allSettings.sbsAllocatedBuffers); + + // Simulate toggling to init which transaction flags + // are available + rbtnUsePosix_toggled(allSettings.rbtnsUsePosix->GetValue()); + ui->cbPosixAtomicRename->setEnabled(allSettings.cbsPosixRename->GetValue()); + + // Must be initialized after allSettings.cmisBlockSize + volumeSettings = new VolumeSettings(ui->lePathPrefix, + ui->cmbSectorSize, + ui->sbVolSize, + ui->labelVolSizeBytes, + ui->sbInodeCount, + ui->cmbAtomicWrite, + ui->btnAddVol, + ui->btnRemoveCurrVol, + ui->listVolumes, + ui->wbtnVolumeCtrls, + ui->wbtnPathPrefix, + ui->wbtnSectorSize, + ui->wbtnVolSize, + ui->wbtnInodeCount, + ui->wbtnAtomicWrite); + + wbtns.append(ui->wbtnTransactVolFull); + wbtns.append(ui->wbtnTransactManual); + wbtns.append(ui->wbtnAllocatedBuffers); + wbtns.append(ui->wbtnIndirectPointers); + wbtns.append(ui->wbtnDirectPointers); + wbtns.append(ui->wbtnCrc); + wbtns.append(ui->wbtnAlignmentSize); + wbtns.append(ui->wbtnByteOrder); + wbtns.append(ui->wbtnVolumeCtrls); + wbtns.append(ui->wbtnSectorSize); + wbtns.append(ui->wbtnVolSize); + wbtns.append(ui->wbtnAtomicWrite); + wbtns.append(ui->wbtnInodeCount); + wbtns.append(ui->wbtnPathPrefix); + wbtns.append(ui->wbtnBlockSize); + wbtns.append(ui->wbtnHandleCount); + wbtns.append(ui->wbtnTaskCount); + wbtns.append(ui->wbtnPathChar); + wbtns.append(ui->wbtnFileNameLen); + wbtns.append(ui->wbtnApiRbtns); + wbtns.append(ui->wbtnIncludeFile); + + for(int i = 0; i < wbtns.count(); i++) + { + connect(wbtns[i], SIGNAL(clicked()), + this, SIGNAL(warningBtnClicked())); + } + connect(ui->cbReadonly, SIGNAL(toggled(bool)), + this, SLOT(cbReadonly_toggled(bool))); + connect(ui->rbtnUsePosix, SIGNAL(toggled(bool)), + this, SLOT(rbtnUsePosix_toggled(bool))); + connect(ui->cbPosixRename, SIGNAL(toggled(bool)), + this, SLOT(cbPosixRename_toggled(bool))); + connect(ui->cbPosixMkdir, SIGNAL(toggled(bool)), + this, SLOT(cbPosixMkdir_toggled(bool))); + connect(ui->cbPosixLink, SIGNAL(toggled(bool)), + this, SLOT(cbPosixLink_toggled(bool))); + connect(ui->cbPosixUnlink, SIGNAL(toggled(bool)), + this, SLOT(cbPosixUnlink_toggled(bool))); + connect(ui->cbPosixFtruncate, SIGNAL(toggled(bool)), + this, SLOT(cbPosixFtruncate_toggled(bool))); + connect(ui->cbFseTruncate, SIGNAL(toggled(bool)), + this, SLOT(cbFseTruncate_toggled(bool))); + connect(ui->cbInodeTimestamps, SIGNAL(toggled(bool)), + this, SLOT(cbInodeTimestamps_toggled(bool))); + connect(ui->rbtnMemUseCStd, SIGNAL(toggled(bool)), + this, SLOT(rbtnMemUseCStd_toggled(bool))); + connect(ui->rbtnMemUseReliance, SIGNAL(toggled(bool)), + this, SLOT(rbtnMemUseReliance_toggled(bool))); + connect(ui->rbtnMemCustomize, SIGNAL(toggled(bool)), + this, SLOT(rbtnMemCustomize_toggled(bool))); + connect(ui->cbTransactManual, SIGNAL(toggled(bool)), + this, SLOT(cbTransactManual_toggled(bool))); + + // Forwarded signals + connect(ui->actionSave, SIGNAL(triggered()), + this, SIGNAL(saveClicked())); + connect(ui->actionLoad, SIGNAL(triggered()), + this, SIGNAL(loadClicked())); + + // Hide settings for unused API + if(allSettings.rbtnsUsePosix->GetValue()) + { + ui->frameFseOps->setVisible(false); + } + else + { + ui->framePosixOps->setVisible(false); + } + + // Not controlled by a Setting object, so set it here. + ui->rbtnMemUseCStd->setChecked(true); + + limitReporter = new LimitReporter(ui->lFsizeBytes, ui->lVsizeBytes); +} + +ConfigWindow::~ConfigWindow() +{ + delete ui; + delete volumeSettings; + volumeSettings = NULL; + + AllSettings::DeleteAll(); + + delete limitReporter; +} + +void ConfigWindow::SetMemRbtnSelection(MemFnSet mfs) +{ + switch(mfs) + { + case UseCStd: + ui->rbtnMemUseCStd->setChecked(true); + break; + + case UseReliance: + ui->rbtnMemUseReliance->setChecked(true); + break; + + case Customize: + ui->rbtnMemCustomize->setChecked(true); + break; + } +} + +void ConfigWindow::cbReadonly_toggled(bool selected) +{ + ui->cbPosixFormat->setEnabled(!selected); + ui->cbPosixLink->setEnabled(!selected); + ui->cbPosixUnlink->setEnabled(!selected); + ui->cbPosixMkdir->setEnabled(!selected); + ui->cbPosixRmDir->setEnabled(!selected); + ui->framePosixRenames->setEnabled(!selected); + ui->cbPosixFtruncate->setEnabled(!selected); + + ui->cbFseSetMask->setEnabled(!selected); + ui->cbFseTruncate->setEnabled(!selected); + + ui->cbUpdateAtime->setEnabled(!selected && ui->cbInodeTimestamps->isChecked()); + + ui->tabTransactionPts->setEnabled(!selected); + // Disable tr settings tab + ui->tabWidget->setTabEnabled(ui->tabWidget->count() - 1, !selected); +} + +void ConfigWindow::rbtnUsePosix_toggled(bool selected) +{ + ui->framePosixOps->setVisible(selected); + ui->frameFseOps->setVisible(!selected); + + ui->cbTransactFileCreate->setEnabled(selected); + ui->cbTransactDirCreate->setEnabled(selected && ui->cbPosixMkdir->isChecked()); + ui->cbTransactRename->setEnabled(selected && ui->cbPosixRename->isChecked()); + ui->cbTransactLink->setEnabled(selected && ui->cbPosixLink->isChecked()); + ui->cbTransactUnlink->setEnabled(selected && ui->cbPosixUnlink->isChecked()); + ui->cbTransactFSync->setEnabled(selected); + ui->cbTransactClose->setEnabled(selected); + + ui->cbTransactTruncate->setEnabled( + selected && ui->cbPosixFtruncate->isChecked() + || !selected && ui->cbFseTruncate->isChecked()); +} + +void ConfigWindow::cbPosixRename_toggled(bool selected) +{ + ui->cbPosixAtomicRename->setEnabled(selected); + ui->cbTransactRename->setEnabled(selected); +} + +void ConfigWindow::cbPosixMkdir_toggled(bool selected) +{ + ui->cbTransactDirCreate->setEnabled(selected); +} + +void ConfigWindow::cbPosixLink_toggled(bool selected) +{ + ui->cbTransactLink->setEnabled(selected); +} + +void ConfigWindow::cbPosixUnlink_toggled(bool selected) +{ + ui->cbTransactUnlink->setEnabled(selected); +} + +void ConfigWindow::cbPosixFtruncate_toggled(bool selected) +{ + ui->cbTransactTruncate->setEnabled(selected); +} + +void ConfigWindow::cbFseTruncate_toggled(bool selected) +{ + ui->cbTransactTruncate->setEnabled(selected); +} + +void ConfigWindow::cbInodeTimestamps_toggled(bool selected) +{ + ui->cbUpdateAtime->setEnabled(selected && !ui->cbReadonly->isChecked()); +} + +void ConfigWindow::rbtnMemUseCStd_toggled(bool selected) +{ + if(selected) + { + ui->frameMemFnsCust->setEnabled(false); + ui->leMemcpy->setText(cstdMemcpy); + ui->leMemmov->setText(cstdMemmov); + ui->leMemset->setText(cstdMemset); + ui->leMemcmp->setText(cstdMemcmp); + ui->leStrlen->setText(cstdStrlen); + ui->leStrcmp->setText(cstdStrcmp); + ui->leStrncmp->setText(cstdStrncmp); + ui->leStrncpy->setText(cstdStrncpy); + ui->leIncludeFile->setText(cstdStringH); + } +} + +void ConfigWindow::rbtnMemUseReliance_toggled(bool selected) +{ + if(selected) + { + ui->frameMemFnsCust->setEnabled(false); + ui->leMemcpy->clear(); + ui->leMemmov->clear(); + ui->leMemset->clear(); + ui->leMemcmp->clear(); + ui->leStrlen->clear(); + ui->leStrcmp->clear(); + ui->leStrncmp->clear(); + ui->leStrncpy->clear(); + ui->leIncludeFile->clear(); + } +} + +void ConfigWindow::rbtnMemCustomize_toggled(bool selected) +{ + if(selected) + { + ui->frameMemFnsCust->setEnabled(true); + } +} + +void ConfigWindow::cbTransactManual_toggled(bool selected) +{ + ui->frameAutomaticTransactions->setEnabled(!selected); +} diff --git a/os/win32/tools/config/configwindow.h b/os/win32/tools/config/configwindow.h new file mode 100644 index 0000000..9830250 --- /dev/null +++ b/os/win32/tools/config/configwindow.h @@ -0,0 +1,109 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef CONFIGWINDOW_H +#define CONFIGWINDOW_H + +#include +#include + +#include "volumesettings.h" +#include "limitreporter.h" + +namespace Ui { +class ConfigWindow; +} + +class ConfigWindow : public QMainWindow +{ + Q_OBJECT +public: + + /// + /// \brief Represents the radio button options under Memory Management + /// Methods + /// + enum MemFnSet + { + UseCStd, + UseReliance, + Customize + }; + + /// + /// \brief Constructs a ConfigWindow, Also initializing allSettings and + /// volumeSettings + /// + explicit ConfigWindow(QWidget *parent = 0); + + ~ConfigWindow(); + + /// + /// \brief Sets the current selection for memory management methods. Used + /// to select "Customize" after loading settings. + /// + /// \param mfs The option to set + /// + void SetMemRbtnSelection(MemFnSet mfs); + +private: + void updateLimits(); + + Ui::ConfigWindow *ui; + QList wbtns; + LimitReporter *limitReporter; + +signals: + /// + /// \brief Invoked when File -> Save is selected + /// + void saveClicked(); + + /// + /// \brief Invoked when File -> Load is selected + /// + void loadClicked(); + + /// + /// \brief Invoked when a warning button is clicked + /// + void warningBtnClicked(); + +private slots: + void cbReadonly_toggled(bool selected); + void rbtnUsePosix_toggled(bool selected); + void cbPosixRename_toggled(bool selected); + void cbPosixMkdir_toggled(bool selected); + void cbPosixLink_toggled(bool selected); + void cbPosixUnlink_toggled(bool selected); + void cbPosixFtruncate_toggled(bool selected); + void cbFseTruncate_toggled(bool selected); + void cbInodeTimestamps_toggled(bool selected); + void rbtnMemUseCStd_toggled(bool selected); + void rbtnMemUseReliance_toggled(bool selected); + void rbtnMemCustomize_toggled(bool selected); + void cbTransactManual_toggled(bool selected); +}; + +#endif // CONFIGWINDOW_H diff --git a/os/win32/tools/config/configwindow.ui b/os/win32/tools/config/configwindow.ui new file mode 100644 index 0000000..5c8bb7b --- /dev/null +++ b/os/win32/tools/config/configwindow.ui @@ -0,0 +1,2866 @@ + + + ConfigWindow + + + + 0 + 0 + 370 + 553 + + + + + 0 + 0 + + + + Reliance Edge Configuration Utility + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + QTabWidget::Rounded + + + 0 + + + + General + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + -73 + 345 + 591 + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + Readonly + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + Enable readonly configuration + + + + + + + + + + + 0 + 0 + + + + File Access API + + + + + + + + Use POSIX API + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 4 + 20 + + + + + + + + Use File System Essentials API + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + true + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + Enabled operations: + + + + + + + + + + + + + format + + + + + + + + + + + link + + + + + + + + + + + unlink + + + + + + + + + + + mkdir + + + + + + + + + + + rmdir + + + + + + + + + + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + rename + + + + + + + + + 0 + + + 20 + + + + + atomic rename + + + + + + + + + + + + + + ftruncate + + + + + + + + + + + Directory operations + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 10 + 17 + + + + + + + + + + + + + 0 + 10 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Maximum file name length: + + + + + + + 65535 + + + + + + + chars + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 18 + + + + + 18 + 18 + + + + + + + + + + + + 0 + 10 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Path separator character: + + + + + + + + / + + + + + \ + + + + + Custom + + + + + + + + true + + + + 1 + 0 + + + + + 40 + 0 + + + + + 40 + 16777215 + + + + + + + 6 + + + + + + + Qt::Horizontal + + + QSizePolicy::Expanding + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 18 + + + + + 18 + 18 + + + + + + + + + + + + 0 + 10 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Handle count: + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + 1 + + + 4096 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 18 + + + + + 18 + 18 + + + + + + + + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + Enabled operations: + + + + + + + Truncate + + + + + + + Get transaction mask + + + + + + + Set transaction mask + + + + + + + + + + + + + File Access Tasks + + + + + + + 0 + 0 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Maximum task count: + + + + + + + + 0 + 0 + + + + + 90 + 0 + + + + 1 + + + 2147483647 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 18 + + + + + 18 + 18 + + + + + + + + + + + + + + Debugging + + + + + + Enable text output + + + + + + + Process asserts + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Volumes + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 362 + 518 + + + + + + + Global Settings + + + + + + + + Block size: + + + + + + + + 256 + + + + + 512 + + + + + 1,024 + + + + + 2,048 + + + + + 4,096 + + + + + 8,192 + + + + + 16,384 + + + + + 32,768 + + + + + 65,536 + + + + + + + + bytes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + + + + 0 + 0 + + + + + 80 + 0 + + + + + 140 + 16777215 + + + + + + + + + + + + Volume name (path prefix): + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + Sector size: + + + + + + + + 1 + + + + + 2 + + + + + 4 + + + + + 8 + + + + + 16 + + + + + 32 + + + + + 64 + + + + + 128 + + + + + 256 + + + + + 512 + + + + + 1,024 + + + + + 2,048 + + + + + 4,096 + + + + + 8,192 + + + + + 16,384 + + + + + 32,768 + + + + + 65,536 + + + + + + + + bytes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + 0 + + + + + + + Volume size: + + + + + + + + 1 + 0 + + + + + 120 + 0 + + + + 5 + + + 2147483647 + + + + + + + sectors + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + = + + + + + + + 0 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + + + Atomic sector write: + + + + + + + + 70 + 0 + + + + + Supported + + + + + Unsupported + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + Inode count: + + + + + + + + 1 + 0 + + + + + 120 + 0 + + + + 1 + + + 2147483647 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 16777215 + 16777215 + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + Add Volume + + + + + + + Remove Selected + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + + + Data + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 362 + 518 + + + + + + + Data Storage Format + + + + + + + + System byte order: + + + + + + + + 90 + 0 + + + + + Big endian + + + + + Little endian + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + Native alignment size: + + + + + + + + 0 + 0 + + + + + 1 + + + + + 2 + + + + + 4 + + + + + 8 + + + + + + + + bytes + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + CRC algorithm: + + + + + + + + Bitwise - smallest, slowest + + + + + Sarwate - midsized, fast + + + + + Slice by 8 - largest, fastest + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + Inode Settings + + + + + + Enable inode block count + + + + + + + Enable inode timestamps + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + Update atime on read + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + + Direct pointers per inode: + + + + + + + 65536 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + Indirect pointers per inode: + + + + + + + 65536 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Memory + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 362 + 518 + + + + + + + + 0 + 0 + + + + + 0 + 50 + + + + Buffers + + + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter + + + + + + + 0 + 10 + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Allocated buffers: + + + + + + + 255 + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 0 + 0 + + + + + 18 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + + + 0 + 0 + + + + Memory Management Methods + + + + + + Use C standard library functions + + + + + + + Use Reliance functions + + + + + + + Customize + + + + + + + QFrame::StyledPanel + + + QFrame::Raised + + + + 0 + + + 0 + + + + + + + Copy memory: + + + + + + + + + + + + + + + + + + Move memory: + + + + + + + + + + + + + + Set memory: + + + + + + + + + + + + + + Compare memory: + + + + + + + + + + + + + + String length: + + + + + + + + + + + + + + String compare: + + + + + + + + + + + + + + Bounded string compare: + + + + + + + + + + + + + + Bounded string copy: + + + + + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 5 + + + + + + + + + + Header file to include: + + + + + + + + + + + 0 + 0 + + + + + 0 + 0 + + + + + 18 + 16777215 + + + + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Transactions + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 362 + 518 + + + + + + + Transaction Settings + + + + + + + + Manual transactions only + + + + + + + + 0 + 0 + + + + + 18 + 0 + + + + + 18 + 16777215 + + + + + + + + + + Automatic transaction points: + + + + + + + + 10 + + + 0 + + + + + File creation + + + + + + + Directory creation + + + + + + + Rename + + + + + + + Link + + + + + + + Unlink + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 6 + + + + + + + + Write + + + + + + + Truncate + + + + + + + File sync + + + + + + + Close + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 20 + 6 + + + + + + + + + + Volume full + + + + + + + + 0 + 0 + + + + + 18 + 0 + + + + + 18 + 16777215 + + + + + + + + + + Volume unmount + + + + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + Limits + + + + 0 + + + 0 + + + 0 + + + 0 + + + 0 + + + + + true + + + + + 0 + 0 + 362 + 518 + + + + + + + Maximum File Size + + + + + + The maximum file size at current settings is: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + 0 MB (0 bytes) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + The maximum file size is determined by the following values: + + + true + + + + + + + - Block size + - Block count enabled + - Inode timestamps enabled + - Selected API + - Direct pointer count + - Indirect pointer count + + + false + + + + + + + For more details, see the "By the Numbers" section of the Reliance Edge documentation. + + + true + + + + + + + + + + Maximum Volume Size + + + + + + The maximum file size at current settings is: + + + + + + + + + Qt::Horizontal + + + QSizePolicy::Fixed + + + + 10 + 20 + + + + + + + + 0 MB (0 bytes) + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + The maximum volume is primarily determined by the selected block size. The selected API has a small effect on the maximum volume size as well. + + + true + + + + + + + For more details, see the "By the Numbers" section of the Reliance Edge documentation. + + + true + + + + + + + + + + Qt::Vertical + + + + 20 + 40 + + + + + + + + + + + + + + + + + + 0 + 0 + 370 + 21 + + + + + File + + + + + + + + + Save... + + + + + Load... + + + + + + + WarningBtn + QWidget +
WarningBtn.h
+ 1 +
+
+ + +
diff --git a/os/win32/tools/config/d-ic.ico b/os/win32/tools/config/d-ic.ico new file mode 100644 index 0000000000000000000000000000000000000000..2751595abab4f682a51a091d543b7f1a5da1930e GIT binary patch literal 82726 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 DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef DEBUG_H +#define DEBUG_H + +#include + +#ifndef QT_NO_DEBUG + #define PRINTDBG(MSG) (qDebug() << (MSG)) +#else + #define PRINTDBG(MSG) ((void)0) +#endif + +#endif // DEBUG_H + diff --git a/os/win32/tools/config/errordialog.cpp b/os/win32/tools/config/errordialog.cpp new file mode 100644 index 0000000..31d7908 --- /dev/null +++ b/os/win32/tools/config/errordialog.cpp @@ -0,0 +1,121 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include +#include + +#include "errordialog.h" +#include "ui_errordialog.h" + +ErrorDialog::ErrorDialog(QWidget *parent) : + QDialog(parent, Qt::WindowCloseButtonHint), + ui(new Ui::ErrorDialog) +{ + ui->setupUi(this); + + connect(ui->btnOk, SIGNAL(clicked()), + this, SLOT(btnOk_clicked())); + connect(ui->btnContinue, SIGNAL(clicked()), + this, SLOT(btnContinue_clicked())); + connect(ui->btnCancel, SIGNAL(clicked()), + this, SLOT(btnCancel_clicked())); +} + +ErrorDialog::~ErrorDialog() +{ + delete ui; + +} + +void ErrorDialog::SetErrorText(const QString &text) +{ + ui->label->setText(text); +} + +void ErrorDialog::ShowErrorsInfo(QStringList errors, QStringList warnings) +{ + setModal(false); // Non-blocking UI + + ui->btnOk->setVisible(true); + ui->btnCancel->setVisible(false); + ui->btnContinue->setVisible(false); + + ui->btnOk->setDefault(true); + + showErrors(errors, warnings); +} + +void ErrorDialog::ShowErrorsAction(QStringList errors, QStringList warnings) +{ + setModal(true); // UI blocks parent windows + + ui->btnContinue->setVisible(true); + ui->btnCancel->setVisible(true); + ui->btnOk->setVisible(false); + + ui->btnContinue->setDefault(true); + + showErrors(errors, warnings); +} + +void ErrorDialog::showErrors(QStringList errors, QStringList warnings) +{ + QIcon iconError(":/icons/error.png"); + QIcon iconWarn(":/icons/warn.png"); + QListWidgetItem *lwi; + + // Clear and repopulate the list of error messages + ui->listErrors->clear(); + for(int i = 0; i < errors.length(); i++) + { + lwi = new QListWidgetItem(iconError, errors[i]); + ui->listErrors->addItem(lwi); + } + for(int i = 0; i < warnings.length(); i++) + { + lwi = new QListWidgetItem(iconWarn, warnings[i]); + ui->listErrors->addItem(lwi); + } + + show(); + activateWindow(); +} + +void ErrorDialog::btnOk_clicked() +{ + close(); + emit results(EdResultOk); +} + +void ErrorDialog::btnContinue_clicked() +{ + close(); + emit results(EdResultContinue); +} + +void ErrorDialog::btnCancel_clicked() +{ + close(); + emit results(EdResultCancel); +} diff --git a/os/win32/tools/config/errordialog.h b/os/win32/tools/config/errordialog.h new file mode 100644 index 0000000..b08872c --- /dev/null +++ b/os/win32/tools/config/errordialog.h @@ -0,0 +1,121 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef ERRORDIALOG_H +#define ERRORDIALOG_H + +#include +#include +#include + +namespace Ui { +class ErrorDialog; +} + +/// +/// \brief An ::ErrorDialog is a dialog with a list of errors and/or warnings +/// to be shown to the user. +/// +/// The dialog may block user action and require a decision to be made +/// (see ErrorDialog::ShowErrorsAction) or it may allow a user to +/// continue working with the parent window (see +/// ErrorDialog::ShowErrorsInfo) +/// +class ErrorDialog : public QDialog +{ + Q_OBJECT +public: + /// + /// \brief Represents the user choice that terminates an ErrorDialog. + /// + enum Result { + /// User has chosen to continue the operation. + EdResultContinue = 0, + + /// User has chosen to cancel the operation. + EdResultCancel = 1, + + /// User has chosen the only available option + EdResultOk = 2 + }; + + explicit ErrorDialog(QWidget *parent = 0); + + ~ErrorDialog(); + + /// + /// \brief Sets the message that is displayed above the list of errors and + /// warnings. + /// + /// \param text The text to use for the message. + /// + void SetErrorText(const QString &text); + + /// + /// \brief Opens this ::ErrorDialog and shows the given errors and + /// warnings. Does not block user from continuing to interact with + /// the open ::ConfigWindow. Only the "Continue" button is made + /// available to the user. + /// + /// \param errors The list of error messages to show. Shown at the top, + /// with a red icon beside each entry. + /// \param warnings The list of warning messages to show. Shown below any + /// error messages, with a yellow icon beside each entry. + /// + void ShowErrorsInfo(QStringList errors, QStringList warnings = QStringList()); + + + /// + /// \brief Opens this ::ErrorDialog and shows the given errors and + /// warnings. The user is given the option to continue or to cancel. + /// The open ::ConfigWindow is blocked until the user clicks one of + /// the options. + /// + /// \param errors The list of error messages to show. Shown at the top, + /// with a red icon beside each entry. + /// \param warnings The list of warning messages to show. Shown below any + /// error messages, with a yellow icon beside each entry. + /// + void ShowErrorsAction(QStringList errors, QStringList warnings); + +signals: + /// + /// \brief Called when the user presses the button and the dialog box + /// closes + /// \param r Describes the user selection + /// + void results(ErrorDialog::Result r); + +private: + void showErrors(QStringList errors, QStringList warnings); + + Ui::ErrorDialog *ui; + +private slots: + void btnOk_clicked(); + void btnContinue_clicked(); + void btnCancel_clicked(); +}; + +#endif // ERRORDIALOG_H diff --git a/os/win32/tools/config/errordialog.ui b/os/win32/tools/config/errordialog.ui new file mode 100644 index 0000000..32a329e --- /dev/null +++ b/os/win32/tools/config/errordialog.ui @@ -0,0 +1,88 @@ + + + ErrorDialog + + + true + + + + 0 + 0 + 498 + 263 + + + + Reliance Edge Configuration Utility + + + + + + The following errors must be corrected before proceding. + + + true + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Continue + + + + + + + Cancel + + + + + + + OK + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + + + diff --git a/os/win32/tools/config/filedialog.cpp b/os/win32/tools/config/filedialog.cpp new file mode 100644 index 0000000..3efcb89 --- /dev/null +++ b/os/win32/tools/config/filedialog.cpp @@ -0,0 +1,103 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "filedialog.h" + +QString FileDialog::defaultDir = QDir::homePath(); + +FileDialog::FileDialog(QWidget *parentWindow, AcceptMode amode, FileMode fmode) + : QFileDialog(parentWindow), + acceptMode(amode) +{ + codefileNameFilters += "Config code file (redconf.c)"; + codefileNameFilters += "C code files (*.c)"; + codefileNameFilters += "All files(*.*)"; + + headerNameFilters += "Config header file (redconf.h)"; + headerNameFilters += "C header files (*.h)"; + headerNameFilters += "All files (*.*)"; + + setFileMode(fmode); + setAcceptMode(amode); + setDirectory(defaultDir); +} + +QString FileDialog::ShowGetHeader() +{ + if(acceptMode == AcceptSave) + { + setWindowTitle("Save Configuration Header As (1 of 2)"); + } + else + { + Q_ASSERT(acceptMode == AcceptOpen); + setWindowTitle("Open Configuration Header (1 of 2)"); + } + + setDefaultSuffix("h"); + selectFile("redconf.h"); + setNameFilters(headerNameFilters); + + return showFileDialog(); +} + +QString FileDialog::ShowGetCodefile() +{ + if(acceptMode == AcceptSave) + { + setWindowTitle("Save Configuration Code File As (2 of 2)"); + } + else + { + Q_ASSERT(acceptMode == AcceptOpen); + setWindowTitle("Open Configuration Code File (2 of 2)"); + } + + setDefaultSuffix("c"); + selectFile("redconf.c"); + setNameFilters(codefileNameFilters); + + return showFileDialog(); +} + +// Shows fileDialog and returns the path to the file chosen by the user. +// Returns QString::null if no file is selected. +QString FileDialog::showFileDialog() +{ + if(!exec()) + { + return QString::null; + } + + defaultDir = directory().path(); + QStringList strList = selectedFiles(); + + Q_ASSERT(strList.count() == 1); //Should give us one file + if(strList.count() == 0) //But just in case it doesn't + { + return QString::null; + } + + return strList.at(0); +} diff --git a/os/win32/tools/config/filedialog.h b/os/win32/tools/config/filedialog.h new file mode 100644 index 0000000..ef6b3be --- /dev/null +++ b/os/win32/tools/config/filedialog.h @@ -0,0 +1,81 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef FILEDIALOG_H +#define FILEDIALOG_H + +#include + +/// +/// \brief A child of QFileDialog designed for saving and loading configuration +/// files. +/// +class FileDialog : protected QFileDialog +{ + Q_OBJECT +public: + /// + /// \brief Constructs a ::FileDialog. + /// + /// \param parentWindow A pointer to the parent ::ConfigWindow + /// \param amode Must be one of AcceptMode::AcceptSave or + /// AcceptMode::AcceptOpen. Specifies whether this + /// ::FileDialog will select files to open or locations + /// to save files. + /// \param fmode The FileMode to use for this ::FileDialog. Passed to + /// QFileDialog::setFileMode. + /// + FileDialog(QWidget *parentWindow, AcceptMode amode, FileMode fmode); + + /// + /// \brief Shows this ::FileDialog, asking the user to choose a redconf.h + /// file. + /// + /// \return Returns the path to the file chosen by the user, or + /// QString::null if no file was selected. + /// + QString ShowGetHeader(); + + /// + /// \brief Shows this ::FileDialog, asking the user to choose a redconf.c + /// file. + /// + /// \return Returns the path to the file chosen by the user, or + /// QString::null if no file was selected. + /// + QString ShowGetCodefile(); + +private: + QString showFileDialog(); + + QStringList codefileNameFilters; + QStringList headerNameFilters; + AcceptMode acceptMode; + + // Used to open every FileDialog to the last used location. + // Initialized to the user's home directory. + static QString defaultDir; +}; + +#endif // FILEDIALOG_H diff --git a/os/win32/tools/config/ic.rc b/os/win32/tools/config/ic.rc new file mode 100644 index 0000000..bbb2761 --- /dev/null +++ b/os/win32/tools/config/ic.rc @@ -0,0 +1 @@ + IDI_ICON1 ICON DISCARDABLE "d-ic.ico" \ No newline at end of file diff --git a/os/win32/tools/config/icon-error-16.png b/os/win32/tools/config/icon-error-16.png new file mode 100644 index 0000000000000000000000000000000000000000..9b31ca44cb002956af295ae6936c262f3bbe8728 GIT binary patch literal 448 zcmV;x0YCnUP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0aZyvK~y+TrIWEr z13?gmXVw%77CwNGPSa^2m@bu%U}5Jgh>ee6CwT)Qg^dp(*d%CS6$}J4ViT~iNF#*& z&ObLfvoY7`2Ya(KxAX7b?40};4O@a%tA_F0sQ`!e_CO#tvro3Pr)lF_`~68Qbut0$ z)Eh{8W5N9hWkBTBo+s&f)Q!-OfG4XysLE!9nD9w!i?%#q05VmZo>!7fzvD%>3JjZ#2+h0U=myW|LW3H4rZ0d`o? zBugm9K9=zQn69-sFB@srs5h6Phm{-r0g-QA+j**uLldR|0000*dV-WQ8EaPWK=n5nQLQ(TT~_JTuxd#c0tbhEKruW>zLD>$3~McPZ2P4AqYm%ZdF zznUg=<;3l0>!#N9Y2*iNvEFbem05q{)a=hZUGj~$YyEm_N+d;^4m^H$t5NDokc-lz zvgi9hs(iY3ylv49k0$QC5VPRN?Dy7}bbdS#Rew`lKFV`Vr{w?Dzz|^YboFyt=akR{ E0BWq4VgLXD literal 0 HcmV?d00001 diff --git a/os/win32/tools/config/icons.qrc b/os/win32/tools/config/icons.qrc new file mode 100644 index 0000000..ec763ce --- /dev/null +++ b/os/win32/tools/config/icons.qrc @@ -0,0 +1,6 @@ + + + icon-error-16.png + icon-warning-16.png + + diff --git a/os/win32/tools/config/input.cpp b/os/win32/tools/config/input.cpp new file mode 100644 index 0000000..1e5cd3e --- /dev/null +++ b/os/win32/tools/config/input.cpp @@ -0,0 +1,153 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "input.h" +#include "allsettings.h" + +Input::Input(QWidget *parentWin) + : fileDialog(NULL), + parentWindow(parentWin), + messageBox(new QMessageBox(parentWin)) +{ +} + +void Input::TryLoad() +{ + QString headerText, codefileText; + + if(fileDialog == NULL) + { + fileDialog = new FileDialog(parentWindow, + QFileDialog::AcceptOpen, + QFileDialog::ExistingFile); + } + + QString headerPath = fileDialog->ShowGetHeader(); + if(headerPath.isNull() || headerPath.isEmpty()) + { + emit results(InResultUserCancelled); + return; + } + + QString codefilePath = fileDialog->ShowGetCodefile(); + if(codefilePath.isNull() || codefilePath.isEmpty()) + { + emit results(InResultUserCancelled); + return; + } + + if(!getFile(headerPath, headerText)) + { + return; //results() already emitted by getFile + } + if(!getFile(codefilePath, codefileText)) + { + return; + } + + QStringList notFound; + QStringList notParsed; + AllSettings::ParseHeaderToSettings(headerText, notFound, notParsed); + AllSettings::ParseCodefileToSettings(codefileText, notFound, notParsed); + + if(notFound.count() > 0 || notParsed.count() > 0) + { + QString report; + + if(notFound.count() > 0) + { + report += "The following settings were not found in the selected configuration files: \n\n"; + for(int i = 0; i < notFound.count(); i++) + { + report += QString(" - ") + notFound[i] + QString("\n"); + } + if(notParsed.count() > 0) + { + report += "\n"; + } + } + if(notParsed.count() > 0) + { + report += "The following settings were located in the selected configuration files but could not be parsed: \n\n"; + for(int i = 0; i < notParsed.count(); i++) + { + report += QString(" - ") + notParsed[i] + QString("\n"); + } + } + + messageBox->setText("Some settings could not be loaded."); + messageBox->setInformativeText("Press \"Show Details\" to view which values were not loaded properly."); + messageBox->setDetailedText(report); + messageBox->setIcon(QMessageBox::Warning); + messageBox->setStandardButtons(QMessageBox::Ok); + + messageBox->exec(); + } + + emit results(InResultSuccess); +} + +// Helper method for TryLoad: takes a path to a text file +// filePath and fills fileContents with its text. If an +// error is encountered, emits results() with the appropriate +// Result and returns false +bool Input::getFile(const QString &filePath, QString &fileContent) +{ + bool success = true; + QFile file(filePath); + if(!file.open(QIODevice::ReadOnly | QIODevice::Text)) + { + success = false; + } + else + { + if(file.size() > 1024 * 1024) + { + // Don't bother hanging the computer trying to read + // this file. It's way too big. + emit results(InResultErrorHugeFile); + return false; + } + + QTextStream stmIn(&file); + stmIn.setCodec("UTF-8"); + fileContent = stmIn.readAll(); + + if(stmIn.status() != QTextStream::Ok + || fileContent.isNull() + || fileContent.isEmpty()) + { + success = false; + } + } + + if(!success) + { + emit results(InResultFileError); + return false; + } + else return true; +} diff --git a/os/win32/tools/config/input.h b/os/win32/tools/config/input.h new file mode 100644 index 0000000..73c2343 --- /dev/null +++ b/os/win32/tools/config/input.h @@ -0,0 +1,88 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef INPUT_H +#define INPUT_H + +#include +#include +#include +#include + +#include "filedialog.h" + +/// +/// \brief The Input class controls the process of loading configuration files. +/// +class Input : public QObject +{ + Q_OBJECT +public: + /// + /// \brief Represents the result of a call to Input::TryLoad. + /// + enum Result { + /// Operation was successful + InResultSuccess, + + /// Operation was cancelled by the user (i.e. file dialog was closed + /// without selecting a file) + InResultUserCancelled, + + /// Operation was cancelled to avoid hanging the system because an + /// unreasonably large file was selected. + InResultErrorHugeFile, + + /// There was an error reading the file given by the user + InResultFileError + }; + + explicit Input(QWidget *parentWin); + + /// + /// \brief Prompts the user to select existing configuration files and + /// attempts to load them. + /// + /// The user is shown a ::FileDialog twice, once to select an + /// existing redconf.h file and again to select a redconf.c file. + /// If the user selects valid files, they are loaded into the + /// ::ConfigWindow UI. + /// + /// The result of this operation is emitted by the signal + /// Input::results. + /// + void TryLoad(); + +private: + bool getFile(const QString &filePath, QString &fileContent); + + FileDialog *fileDialog; + QWidget *parentWindow; + QMessageBox *messageBox; + +signals: + void results(Input::Result r); +}; + +#endif // INPUT_H diff --git a/os/win32/tools/config/intsetting.cpp b/os/win32/tools/config/intsetting.cpp new file mode 100644 index 0000000..c8be694 --- /dev/null +++ b/os/win32/tools/config/intsetting.cpp @@ -0,0 +1,88 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "intsetting.h" + +IntSetting::IntSetting(QString macroName, unsigned long defaultValue, + std::function validator, + WarningBtn * btnWarn) + : Setting(macroName, defaultValue, validator), + btnWarning(btnWarn) +{ +} + +void IntSetting::ProcessInput(const QString & text) +{ + unsigned long value; + bool success = TryParse(text, value); + if(!success) + { + if(btnWarning) + { + btnWarning->SetError("Error parsing selected value"); + } + throw new std::invalid_argument("Error parsing value"); + } + + QString msg; + checkValue(value, msg); + SetValue(value, false); +} + +Validity IntSetting::checkValue(unsigned long value, QString &msg) +{ + Validity v = CheckValid(value, msg); + if(btnWarning) + { + btnWarning->Set(v, msg); + } + return v; +} + +bool IntSetting::TryParse(const QString &toParse, unsigned long & out) +{ + if(toParse.isNull() || toParse.isEmpty()) + { + return false; + } + + QString strParsing = toParse; + strParsing.remove(','); //Allow comma-divided nums (e.g. 1,232,600) + strParsing.remove('U'); //Allow explicit unsigned notation + + bool success; + unsigned long result; + + // Second argument 0 -> "C language convention is used" + // according to qt-project docs. e.g. 0x___ read as hex + result = strParsing.toULong(&success, 0); + + if(success) + { + out = result; + } + return success; +} diff --git a/os/win32/tools/config/intsetting.h b/os/win32/tools/config/intsetting.h new file mode 100644 index 0000000..f7b2fab --- /dev/null +++ b/os/win32/tools/config/intsetting.h @@ -0,0 +1,71 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef INTSETTING_H +#define INTSETTING_H + +#include + +#include "Setting.h" +#include "WarningBtn.h" + +/// +/// \brief Class for settings that may be represented using a Boolean type. +/// Inherits from QObject and Setting, where `T` is set to +/// `unsigned long` +/// +class IntSetting : public QObject, public Setting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param btnWarn Optional: the warning button associated with this + /// setting + /// + IntSetting(QString macroName, unsigned long defaultValue, + std::function validator, + WarningBtn * btnWarn = 0); + + bool TryParse(const QString &toParse, unsigned long & out) override; + + /// + /// \brief Sets the value of this setting, checking validity and setting + /// any associated warning button + /// + /// \param input The value to parse and set + /// + void ProcessInput(const QString & text); + +protected: + Validity checkValue(unsigned long value, QString &msg) override; + + WarningBtn *btnWarning; +}; + +#endif // INTSETTING_H diff --git a/os/win32/tools/config/lesetting.cpp b/os/win32/tools/config/lesetting.cpp new file mode 100644 index 0000000..1c936e8 --- /dev/null +++ b/os/win32/tools/config/lesetting.cpp @@ -0,0 +1,54 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "lesetting.h" + +LeSetting::LeSetting(QString macroName, QString defaultValue, + std::function validator, + QLineEdit *le, + WarningBtn * btnWarn) + : StrSetting(macroName, defaultValue, validator, btnWarn), + lineEdit(le) +{ + if(!le) + { + throw new std::invalid_argument("le cannot be null"); + } + + setUi(); + connect(le, SIGNAL(textChanged(QString)), + this, SLOT(lineEdit_textChanged(QString))); +} + +void LeSetting::setUi() +{ + lineEdit->setText(value); +} + +void LeSetting::lineEdit_textChanged(const QString & text) +{ + ProcessInput(text); +} + + diff --git a/os/win32/tools/config/lesetting.h b/os/win32/tools/config/lesetting.h new file mode 100644 index 0000000..ada72d5 --- /dev/null +++ b/os/win32/tools/config/lesetting.h @@ -0,0 +1,66 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef LESETTING_H +#define LESETTING_H + +#include +#include + +#include "StrSetting.h" +#include "WarningBtn.h" + +/// +/// \brief The LeSetting class manages settings that use a QLineEdit for user +/// input and hold a QString value. +/// +class LeSetting : public StrSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param le The QLineEdit associated with this setting + /// \param btnWarn Optional: passed to the StrSetting constructor + /// + LeSetting(QString macroName, QString defaultValue, + std::function validator, + QLineEdit *le, + WarningBtn * btnWarn = 0); + +protected: + virtual void setUi() override; + +private: + QLineEdit * lineEdit; + +private slots: + void lineEdit_textChanged(const QString & text); +}; + +#endif // LESETTING_H diff --git a/os/win32/tools/config/limitreporter.cpp b/os/win32/tools/config/limitreporter.cpp new file mode 100644 index 0000000..ea13cd4 --- /dev/null +++ b/os/win32/tools/config/limitreporter.cpp @@ -0,0 +1,92 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "limitreporter.h" +#include "allsettings.h" +#include "validators.h" +#include "volumesettings.h" + +LimitReporter::LimitReporter(QLabel *fsizeMaxLabel, QLabel *vsizeMaxLabel) + : labelMaxFsize(fsizeMaxLabel), + labelMaxVsize(vsizeMaxLabel) +{ + // Assert this one, assume the others. + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + allSettings.cbsInodeCount->notifyList.append(this); + allSettings.cbsInodeTimestamps->notifyList.append(this); + allSettings.rbtnsUsePosix->notifyList.append(this); + allSettings.cmisBlockSize->notifyList.append(this); + allSettings.sbsDirectPtrs->notifyList.append(this); + allSettings.sbsIndirectPtrs->notifyList.append(this); + + // LimitReporter is deleted after allSettings, so there is + // no need to remove these on destruction. + + updateLimits(); +} + +void LimitReporter::Notify() +{ + updateLimits(); +} + +// Calculates upper limits of file size and volume size. Equations extracted +// from Reliance_Edge_Limits.xlsx. +void LimitReporter::updateLimits() +{ + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + unsigned long dirPointers = allSettings.sbsDirectPtrs->GetValue(); + unsigned long indirPointers = allSettings.sbsIndirectPtrs->GetValue(); + unsigned long blockSize = allSettings.cmisBlockSize->GetValue(); + unsigned long inodeEntries = getInodeEntries(); + + qlonglong doubleIndirs = inodeEntries - dirPointers - indirPointers; + qlonglong indirEntries = (blockSize - 20) / 4; + + // A negative value indicates an invalid setting. The settings will not + // be exportable until it is dealt with. In the mean time, do our best + // to show a reasonable value if a negative value is encountered. + if(indirEntries < 0) + { + indirEntries = 0; + } + if(doubleIndirs < 0) + { + doubleIndirs = 0; + } + + qulonglong inodeDataBlocks = + indirEntries * static_cast(indirPointers) // Inode indir blocks + + indirEntries * indirEntries // Dindir data blocks + + doubleIndirs * indirEntries * indirEntries; // Inode Dindir blocks + + qlonglong inodeSizeMax = inodeDataBlocks * static_cast(blockSize); + + labelMaxFsize->setText(VolumeSettings::FormatSize(inodeSizeMax)); + + labelMaxVsize->setText(VolumeSettings::FormatSize(getVolSizeMaxBytes())); + +} diff --git a/os/win32/tools/config/limitreporter.h b/os/win32/tools/config/limitreporter.h new file mode 100644 index 0000000..c8da748 --- /dev/null +++ b/os/win32/tools/config/limitreporter.h @@ -0,0 +1,61 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef LIMITREPORTER_H +#define LIMITREPORTER_H + +#include + +#include "notifiable.h" + +/// +/// \brief The LimitReporter class handles the UI components that show the +/// maximum file and volume size. +/// +/// This class is instantiated and deleted by the ::ConfigWindow +/// +class LimitReporter : public Notifiable +{ +public: + /// + /// \brief Constructor + /// + /// Requires that ::allSettings be initialized. + /// + /// \param sizeLabel The ::QLabel to which to print the maximum file size + /// \param detailLabel The ::QLabel to which to print information about the + /// settings that influence the maximum file size + /// + LimitReporter(QLabel *fsizeMaxLabel, QLabel *vsizeMaxLabel); + + void Notify() override; + +private: + QLabel *labelMaxFsize; + QLabel *labelMaxVsize; + + void updateLimits(); +}; + +#endif // LIMITREPORTER_H diff --git a/os/win32/tools/config/main.cpp b/os/win32/tools/config/main.cpp new file mode 100644 index 0000000..29743f4 --- /dev/null +++ b/os/win32/tools/config/main.cpp @@ -0,0 +1,35 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "application.h" + +/// +/// \brief Entry point for the configuration utility. Turns over program +/// control to an ::Application. +/// +int main(int argc, char *argv[]) +{ + Application a(argc, argv); + return a.Run(); +} diff --git a/os/win32/tools/config/notifiable.h b/os/win32/tools/config/notifiable.h new file mode 100644 index 0000000..144d151 --- /dev/null +++ b/os/win32/tools/config/notifiable.h @@ -0,0 +1,47 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef NOTIFIABLE_H +#define NOTIFIABLE_H + +/// +/// \brief The Notifiable class is an interface for objects to be notified of +/// changes to settings. This is an alternative to the Qt signal/slot +/// system which is required because the ::Setting class is not +/// allowed to inherit from QObject. +/// +class Notifiable +{ +public: + /// + /// \brief Notify of an event that requires this to reprocess information. + /// + /// In a normal ::Setting object, this redirects to + /// Setting::RecheckValid. + /// + virtual void Notify() = 0; +}; + +#endif // NOTIFIABLE_H + diff --git a/os/win32/tools/config/output.cpp b/os/win32/tools/config/output.cpp new file mode 100644 index 0000000..6a64e75 --- /dev/null +++ b/os/win32/tools/config/output.cpp @@ -0,0 +1,217 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "debug.h" +#include "output.h" +#include "errordialog.h" +#include "allsettings.h" +#include "volumesettings.h" + +Output::Output(QWidget *parentWin) + : parentWindow(parentWin), + fileDialog(NULL), + errorDialog(new ErrorDialog(parentWindow)), + isSaving(false) +{ + connect(errorDialog, SIGNAL(results(ErrorDialog::Result)), + this, SLOT(errorDialog_results(ErrorDialog::Result))); +} + +void Output::TrySave() +{ + Q_ASSERT(errorDialog != NULL); + + if(isSaving) + { + // Shouldn't be possible because the UI is blocked while + // isSaving is true. + Q_ASSERT(false); + emit results(OutResultErrorBusy); + } + + if(errorDialog->isVisible()) + { + errorDialog->close(); + } + + isSaving = true; + + QStringList errors; + QStringList warnings; + AllSettings::GetErrors(errors, warnings); + + if(errors.count() > 0 || warnings.count() > 0) + { + if(errors.count() > 0) + { + // No more chance of saving at this point. + isSaving = false; + errorDialog->SetErrorText("Please correct the following invalid values before continuing:"); + errorDialog->ShowErrorsInfo(errors, warnings); + } + else + { + errorDialog->SetErrorText("Continue despite the following warnings?"); + errorDialog->ShowErrorsAction(errors, warnings); + + // Resumes in errorDialog_results if the user chooses + // to continue + } + } + else + { + // No errors were found; go straight to output. + doOutput(); + isSaving = false; + } +} + +void Output::ShowErrors(bool showIfNoErrors) +{ + if(isSaving) + { + Q_ASSERT(false); //Don't want this happening. + emit results(OutResultErrorBusy); + } + Q_ASSERT(errorDialog != NULL); + + QStringList errors, warnings; + AllSettings::GetErrors(errors, warnings); + + if(errors.count() > 0 || warnings.count() > 0) + { + errorDialog->SetErrorText("The following errors and warnings were found:"); + errorDialog->ShowErrorsInfo(errors, warnings); + } + else if(showIfNoErrors) + { + errorDialog->SetErrorText("No errors or warnings found."); + errorDialog->ShowErrorsInfo(errors, warnings); + } + // else do nothing and return. +} + +void Output::doOutput() +{ + const QString headMessage = QString("\ +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION\n\ + UTILITY. DO NOT MODIFY.\n\ +*/\n"); + + if(fileDialog == NULL) + { + fileDialog = new FileDialog(parentWindow, + QFileDialog::AcceptSave, + QFileDialog::AnyFile); + } + + QString headerPath = fileDialog->ShowGetHeader(); + if(headerPath.isNull() || headerPath.isEmpty()) + { + emit results(OutResultUserCancelled); + return; + } + + QString codefilePath = fileDialog->ShowGetCodefile(); + if(codefilePath.isNull() || codefilePath.isEmpty()) + { + emit results(OutResultUserCancelled); + return; + } + + // Files are selected; open them and begin output. + + QFile fileHeader(headerPath), fileCodefile(codefilePath); + bool success = true; + + if(!fileHeader.open(QIODevice::WriteOnly | QIODevice::Text)) + { + success = false; + } + if(success) + { + QTextStream stmOut(&fileHeader); + stmOut.setCodec("UTF-8"); + stmOut << headMessage << AllSettings::FormatHeaderOutput(); + + if(stmOut.status() != QTextStream::Ok) + { + success = false; + } + } + + if(!fileCodefile.open(QIODevice::WriteOnly | QIODevice::Text)) + { + success = false; + } + if(success) + { + QTextStream stmOut(&fileCodefile); + stmOut.setCodec("UTF-8"); + stmOut << headMessage << AllSettings::FormatCodefileOutput(); + + if(stmOut.status() != QTextStream::Ok) + { + success = false; + } + } + + if(success) + { + emit results(OutResultSuccess); + } + else + { + emit results(OutResultFileError); + } + +} + +void Output::errorDialog_results(ErrorDialog::Result r) +{ + switch(r) + { + case ErrorDialog::EdResultCancel: + emit results(OutResultUserCancelled); + isSaving = false; + break; + + case ErrorDialog::EdResultOk: + if(isSaving) + { + isSaving = false; + emit results(OutResultInvalid); + } + else + { + emit results(OutResultInfoDismissed); + } + break; + + case ErrorDialog::EdResultContinue: + doOutput(); + isSaving = false; + break; + } +} diff --git a/os/win32/tools/config/output.h b/os/win32/tools/config/output.h new file mode 100644 index 0000000..9724cd9 --- /dev/null +++ b/os/win32/tools/config/output.h @@ -0,0 +1,125 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef OUTPUT_H +#define OUTPUT_H + +#include +#include +#include +#include + +#include "errordialog.h" +#include "settingbase.h" +#include "filedialog.h" + +/// +/// \brief The Output class controls the processes of reporting invalid values +/// to the user and saving configuration files +/// +class Output : public QObject +{ + Q_OBJECT +public: + /// + /// \brief Represents the result of a call to Output::TrySave or + /// Output::ShowErrors + /// + enum Result { + /// Operation was successful + OutResultSuccess, + + /// Operation cancelled because one or more values is invalid. + OutResultInvalid, + + /// Operation cancelled by the user + OutResultUserCancelled, + + /// The dialog shown by Output::ShowErrors has been dismissed + OutResultInfoDismissed, + + /// Operation cancelled because a save operation is already in progress. + /// This result is not expected to occur and may indicate an internal + /// error. + OutResultErrorBusy, + + /// Failure opening selected file or writing out information + OutResultFileError + }; + + Output(QWidget *parentWin); + + /// + /// \brief Checks for invalid values, prompts user to select a location to + /// save configuration files, and attempts to save them. + /// + /// The save operation first checks for invalid valid values. If any + /// invalid values are found, an ::ErrorDialog is displayed and then + /// the operation is cancelled. If warning values are found but no + /// errors, an ::ErrorDialog is shown prompting the user to continue + /// or cancel. + /// + /// The user is then shown a ::FileDialog twice to save the + /// relconf.h and relconf.c files. If valid file paths are selected, + /// then the settings are outputted to those files for use in + /// compiling the Reliance Edge source. + /// + /// The result of this operation is emitted by the signal + /// Output::results. + /// + void TrySave(); + + /// + /// \brief Checks for invalid and shows them to the user in a non-blocking + /// dialog. + /// + /// \param showIfNoErrors If specified and set to true, the dialog will be + /// shown even if no errors were found, reporting + /// that no errors were found. Otherwise the + /// function returns without showing the dialog if + /// no errors are found. + /// + void ShowErrors(bool showIfNoErrors = false); + +private: + // Called once settings validity is verified + void doOutput(); + + QWidget *parentWindow; + ErrorDialog *errorDialog; + FileDialog *fileDialog; + + // Set to true while the save operation is active. The ConfigWindow UI + // should be blocked while isSaving is true so that overlapping save + // calls are not possible. + bool isSaving; + +signals: + void results(Output::Result r); + +private slots: + void errorDialog_results(ErrorDialog::Result r); +}; + +#endif // OUTPUT_H diff --git a/os/win32/tools/config/pathsepsetting.cpp b/os/win32/tools/config/pathsepsetting.cpp new file mode 100644 index 0000000..6a7b415 --- /dev/null +++ b/os/win32/tools/config/pathsepsetting.cpp @@ -0,0 +1,112 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include "pathsepsetting.h" + +PathSepSetting::PathSepSetting(QString macroName, QString defaultValue, + std::function validator, + QComboBox *cmb, + QLineEdit *le, + WarningBtn *btnWarn) + : StrSetting(macroName, defaultValue, validator, btnWarn), + comboBox(cmb), + lineEdit(le) +{ + if(!cmb || !le) + { + throw new std::invalid_argument("cmb and le cannot be null"); + } + + setUi(); + connect(cmb, SIGNAL(currentIndexChanged(int)), + this, SLOT(comboBox_currentIndexChanged(int))); + connect(le, SIGNAL(textChanged(QString)), + this, SLOT(lineEdit_textChanged(QString))); +} + +bool PathSepSetting::TryParse(const QString &toParse, QString &out) +{ + QString substr = toParse; + if(toParse.startsWith('\'') && toParse.endsWith('\'')) + { + substr = toParse.mid(1, toParse.length() - 2); + } + + QString msg; + Validity v = CheckValid(substr, msg); + + if(v == Invalid) + { + return false; + } + else + { + out = substr; + return true; + } +} + +void PathSepSetting::comboBox_currentIndexChanged(int i) +{ + if(i == optionCustomIndex) + { + // Show line edit; don't do further processing + lineEdit->setVisible(true); + ProcessInput(lineEdit->text()); + } + else + { + lineEdit->setVisible(false); + ProcessInput(comboBox->currentText()); + } +} + +void PathSepSetting::setUi() +{ + if(QString::compare(value, "/") == 0) + { + comboBox->setCurrentText("/"); + lineEdit->setVisible(false); + } + else if(QString::compare(value, "\\") == 0 + || QString::compare(value, "\\\\") == 0) //double-escaped backslash + { + comboBox->setCurrentText("\\"); + lineEdit->setVisible(false); + } + else + { + // Set lineEdit text before setting comboBox index so as to avoid resetting + // value in comboBox_currentIndexChanged + lineEdit->setText(value); + comboBox->setCurrentIndex(optionCustomIndex); + lineEdit->setVisible(true); + } +} + +void PathSepSetting::lineEdit_textChanged(const QString &text) +{ + ProcessInput(text); +} + diff --git a/os/win32/tools/config/pathsepsetting.h b/os/win32/tools/config/pathsepsetting.h new file mode 100644 index 0000000..64aef31 --- /dev/null +++ b/os/win32/tools/config/pathsepsetting.h @@ -0,0 +1,76 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef PATHSEPSETTING_H +#define PATHSEPSETTING_H + +#include +#include +#include + +#include "StrSetting.h" +#include "WarningBtn.h" + +/// +/// \brief The CmbStrSetting class is a special case class that manages the +/// path separator character setting. It uses a QComboBox and a +/// QLineEdit for user input and holds a string value. +/// +class PathSepSetting : public StrSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param cmb The QComboBox associated with this setting + /// \param le The QLineEdit associated with this setting + /// \param btnWarn Optional: passed to the StrSetting constructor + /// + PathSepSetting(QString macroName, QString defaultValue, + std::function validator, + QComboBox *cmb, + QLineEdit *le, + WarningBtn * btnWarn = 0); + + bool TryParse(const QString &toParse, QString &out) override; + +protected: + virtual void setUi() override; + +private: + // The index of the "Custom" entry in comboBox + const static int optionCustomIndex = 2; + QComboBox *comboBox; + QLineEdit *lineEdit; + +private slots: + void comboBox_currentIndexChanged(int i); + void lineEdit_textChanged(const QString & text); +}; + +#endif // PATHSEPSETTING_H diff --git a/os/win32/tools/config/rbtnsetting.cpp b/os/win32/tools/config/rbtnsetting.cpp new file mode 100644 index 0000000..d860184 --- /dev/null +++ b/os/win32/tools/config/rbtnsetting.cpp @@ -0,0 +1,55 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "rbtnsetting.h" + +RbtnSetting::RbtnSetting(QString macroName, bool defaultValue, + std::function validator, + QRadioButton * rbtn, + WarningBtn * btnWarn) + : BoolSetting(macroName, defaultValue, validator, btnWarn), + radioButton(rbtn) +{ + if(!rbtn) + { + throw new std::invalid_argument("rbtn cannot be null"); + } + + setUi(); + connect(rbtn, SIGNAL(toggled(bool)), + this, SLOT(radioButton_toggled(bool))); +} + +void RbtnSetting::setUi() +{ + radioButton->setChecked(value); +} + +void RbtnSetting::radioButton_toggled(bool input) +{ + ProcessInput(input); +} + diff --git a/os/win32/tools/config/rbtnsetting.h b/os/win32/tools/config/rbtnsetting.h new file mode 100644 index 0000000..12f8295 --- /dev/null +++ b/os/win32/tools/config/rbtnsetting.h @@ -0,0 +1,64 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef RBTNSETTING_H +#define RBTNSETTING_H + +#include + +#include "boolsetting.h" + +/// +/// \brief The RbtnSetting class manages settings that use a QRadioButton for +/// user input and hold a Boolean value. +/// +class RbtnSetting : public BoolSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param rbtn The QRadioButton associated with this setting + /// \param btnWarn Optional: passed to the BoolSetting constructor + /// + RbtnSetting(QString macroName, bool defaultValue, + std::function validator, + QRadioButton * rbtn, + WarningBtn * btnWarn = 0); + +protected: + virtual void setUi() override; + +private: + QRadioButton *radioButton; + +private slots: + void radioButton_toggled(bool input); +}; + +#endif // RBTNSETTING_H diff --git a/os/win32/tools/config/redconfig.pro b/os/win32/tools/config/redconfig.pro new file mode 100644 index 0000000..c442756 --- /dev/null +++ b/os/win32/tools/config/redconfig.pro @@ -0,0 +1,75 @@ +#------------------------------------------------- +# +# Project created by QtCreator 2015-02-06T15:40:36 +# +#------------------------------------------------- + +QT += core gui + +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets + +TARGET = redconfig +TEMPLATE = app + +SOURCES += main.cpp\ + configwindow.cpp \ + cbsetting.cpp \ + warningbtn.cpp \ + cmbintsetting.cpp \ + cmbstrsetting.cpp \ + sbsetting.cpp \ + rbtnsetting.cpp \ + boolsetting.cpp \ + intsetting.cpp \ + strsetting.cpp \ + pathsepsetting.cpp \ + volumesettings.cpp \ + validators.cpp \ + allsettings.cpp \ + lesetting.cpp \ + output.cpp \ + errordialog.cpp \ + application.cpp \ + input.cpp \ + filedialog.cpp \ + limitreporter.cpp + +HEADERS += configwindow.h \ + setting.h \ + cbsetting.h \ + warningbtn.h \ + validity.h \ + cmbintsetting.h \ + cmbstrsetting.h \ + sbsetting.h \ + rbtnsetting.h \ + boolsetting.h \ + intsetting.h \ + strsetting.h \ + pathsepsetting.h \ + volumesettings.h \ + validators.h \ + debug.h \ + allsettings.h \ + lesetting.h \ + settingbase.h \ + output.h \ + errordialog.h \ + application.h \ + input.h \ + filedialog.h \ + notifiable.h \ + limitreporter.h + +FORMS += configwindow.ui \ + warningbtn.ui \ + errordialog.ui + +RESOURCES += \ + icons.qrc + +DISTFILES += \ + icon-error-16.png \ + icon-warning-16.png + + RC_FILE = ic.rc diff --git a/os/win32/tools/config/sbsetting.cpp b/os/win32/tools/config/sbsetting.cpp new file mode 100644 index 0000000..1ccdfe6 --- /dev/null +++ b/os/win32/tools/config/sbsetting.cpp @@ -0,0 +1,69 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "sbsetting.h" + +SbSetting::SbSetting(QString macroName, unsigned long defaultValue, + std::function validator, + QSpinBox *sb, + WarningBtn * btnWarn) + : IntSetting(macroName, defaultValue, validator, btnWarn), + spinbox(sb) +{ + if(!sb) + { + throw new std::invalid_argument("sb cannot be null"); + } + + setUi(); //important: before connections are made + connect(sb, SIGNAL(valueChanged(QString)), + this, SLOT(spinbox_valueChanged(QString))); +} + +bool SbSetting::TryParse(const QString &toParse, unsigned long &out) +{ + unsigned long result; + bool success = IntSetting::TryParse(toParse, result); + if(success && result < INT_MAX) + { + out = result; + return true; + } + return false; +} + +void SbSetting::setUi() +{ + // Should be safe to cast to int since values greater + // than INT_MAX cause parse failure; as long as default + // value is not greater than INT_MAX. + spinbox->setValue(static_cast(value)); +} + +void SbSetting::spinbox_valueChanged(const QString & text) +{ + ProcessInput(text); +} diff --git a/os/win32/tools/config/sbsetting.h b/os/win32/tools/config/sbsetting.h new file mode 100644 index 0000000..14946ca --- /dev/null +++ b/os/win32/tools/config/sbsetting.h @@ -0,0 +1,67 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef SPSETTING_H +#define SPSETTING_H + +#include +#include + +#include "intsetting.h" +#include "WarningBtn.h" + +/// +/// \brief The SbSetting class manages settings that use a QSpinBox for user +/// input and hold an unsigned integer value. +/// +class SbSetting : public IntSetting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param sb The QSpinBox associated with this setting + /// \param btnWarn Optional: passed to the IntSetting constructor + /// + SbSetting(QString macroName, unsigned long defaultValue, + std::function validator, + QSpinBox *sb, + WarningBtn * btnWarn = 0); + +protected: + virtual bool TryParse(const QString &toParse, unsigned long &out); + virtual void setUi() override; + +private: + QSpinBox *spinbox; + +private slots: + void spinbox_valueChanged(const QString & text); +}; + +#endif // SPSETTING_H diff --git a/os/win32/tools/config/setting.h b/os/win32/tools/config/setting.h new file mode 100644 index 0000000..54136ce --- /dev/null +++ b/os/win32/tools/config/setting.h @@ -0,0 +1,214 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef SETTINGS_H +#define SETTINGS_H + +#include +#include +#include + +#include +#include + +#include "settingbase.h" +#include "debug.h" +#include "validity.h" +#include "WarningBtn.h" + + +/// +/// \brief The Setting class is used to represent settings displayed by the UI. +/// This class controls validity checking and value storage; derrived +/// classes may also control user interface interaction. +/// +/// \tparam T The type which this setting holds +/// +template +class Setting : public SettingBase +{ +public: + /// + /// \brief Constructor + /// + /// \param macroName The C macro name associated with this setting. May + /// be null or empty if there is no associated macro. + /// \param defaultValue The initial value to which to set this setting + /// \param validator A function from validators.h to be used to validate + /// this setting + /// + Setting(QString macroName, T defaultValue, + std::function validator); + + /// + /// \brief CheckValid Checks whether the given value is valid for this + /// setting + /// + /// \param arg Value to check + /// \param msg Set to a human readable error or warning message if the + /// given value is not valid + /// + /// \return Returns one of Validity::Valid, Validity::Warning, or + /// Validity::Invalid + /// + Validity CheckValid(T arg, QString &msg); + + Validity RecheckValid(QString &msg) override; + + void Notify() override; + + /// + /// \brief Sets the value of this Setting. Does not test the validity of + /// the given value. + /// + /// \param arg Value to set + /// + /// \param updateUi If set to true or unspecified, any ui elements will be + /// updated after the value is set + /// + void SetValue(T arg, bool updateUi = true); + + /// + /// \brief Returns the current value held by this Setting + /// + T GetValue(void) + { + return value; + } + + /// + /// \brief Returns the macro name associated with this setting + /// + QString GetMacroName() + { + return name; + } + + /// + /// \brief Tries to parse the given string into a valid value for this + /// setting. + /// + /// \param toParse String data to parse + /// \param out Reference to be set to the parsed value. Indeterminate + /// if false is returned. + /// + /// \return True if successful, false if not. + /// + virtual bool TryParse(const QString &toParse, T &out) = 0; + +protected: + /// + /// \brief Verifies that given value value is valid. Returns the validity + /// and sets any warning UI elements accordingly. + /// + /// \param value Value to test + /// \param msg Will be set to a human readable message if the returned + /// value is not Validity::Valid + /// + /// \return Returns the validity of the given value + /// + virtual Validity checkValue(T value, QString &msg) = 0; + + /// + /// \brief setUi Sets any UI elements + /// + virtual void setUi(); + + const QString name; + const T defValue; + T value; + +private: + // Expected to be set to one of the functions declared in validators.h + // at initialization. + const std::function validateFn; +}; + + +template +Setting::Setting(QString macroName, T defaultValue, + std::function validator) + : name(macroName), + defValue(defaultValue), + value(defaultValue), + validateFn(validator) +{ + if(!validateFn) + { + throw new std::invalid_argument("Unassigned function pointer passed to Setting::Setting"); + } +} + +template +Validity Setting::CheckValid(T arg, QString &msg) +{ + return validateFn(arg, msg); +} + +template +Validity Setting::RecheckValid(QString &msg) +{ + return checkValue(value, msg); +} + +template +void Setting::Notify() +{ + QString msg; + checkValue(value, msg); +} + +template +void Setting::SetValue(T arg, bool updateUi) +{ + value = arg; + + // Recalculate validity for any Settings that are dependent + // on this one + if(!notifyList.isEmpty()) + { + for(QList::const_iterator i = notifyList.cbegin(); i < notifyList.cend(); ++i) + { + if(*i == NULL) + { + continue; + } + (*i)->Notify(); + } + } + + if(updateUi) + { + setUi(); + } +} + +// Blank method for Settings that have no UI components +template +void Setting::setUi() +{ + //Do nothing +} + +#endif // SETTINGS_H diff --git a/os/win32/tools/config/settingbase.h b/os/win32/tools/config/settingbase.h new file mode 100644 index 0000000..6e9807b --- /dev/null +++ b/os/win32/tools/config/settingbase.h @@ -0,0 +1,58 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef SETTINGBASE_H +#define SETTINGBASE_H + +#include + +#include "validity.h" +#include "notifiable.h" + +/// +/// \brief The SettingBase class is a base class for Setting, allowing +/// instances of Setting derrived classes to be treated as inheriting +/// from the same type. +/// +class SettingBase : public Notifiable +{ +public: + /// + /// \brief Checks whether the current value held by this Setting is valid; + /// sets any warnings in the user interface, and returns the + /// Validity. + /// + /// \param msg Set to a human readable error or warning message if + /// Validity::Invalid or Validity::Warning is returned + /// + virtual Validity RecheckValid(QString &msg) = 0; + + /// + /// \brief ::SettingBase objects added to this list will be notified when + /// any value held by this ::SettingBase + /// + QList notifyList; +}; + +#endif // SETTINGBASE_H diff --git a/os/win32/tools/config/strsetting.cpp b/os/win32/tools/config/strsetting.cpp new file mode 100644 index 0000000..0418954 --- /dev/null +++ b/os/win32/tools/config/strsetting.cpp @@ -0,0 +1,65 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "strsetting.h" + +StrSetting::StrSetting(QString macroName, QString defaultValue, + std::function validator, + WarningBtn * btnWarn) + : Setting(macroName, defaultValue, validator), + btnWarning(btnWarn) +{ +} + +void StrSetting::ProcessInput(const QString & text) +{ + QString msg; + checkValue(text, msg); + SetValue(text, false); +} + +Validity StrSetting::checkValue(QString value, QString &msg) +{ + Validity v = CheckValid(value, msg); + if(btnWarning) + { + btnWarning->Set(v, msg); + } + return v; +} + +bool StrSetting::TryParse(const QString &toParse, QString & out) +{ + if(toParse.isNull()) + { + return false; + } + else + { + out = toParse; + return true; + } +} diff --git a/os/win32/tools/config/strsetting.h b/os/win32/tools/config/strsetting.h new file mode 100644 index 0000000..f9e997d --- /dev/null +++ b/os/win32/tools/config/strsetting.h @@ -0,0 +1,70 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef STRSETTING_H +#define STRSETTING_H + +#include + +#include "Setting.h" +#include "WarningBtn.h" + +/// +/// \brief Class for settings that may be represented using a string type. +/// Inherits from QObject and Setting, where `T` is set to `QString` +/// +class StrSetting : public QObject, public Setting +{ + Q_OBJECT +public: + /// + /// \brief Constructor + /// + /// \param macroName Passed to Setting constructor + /// \param defaultValue Passed to Setting constructor + /// \param validator Passed to Setting constructor + /// \param btnWarn Optional: the warning button associated with this + /// setting + /// + StrSetting(QString macroName, QString defaultValue, + std::function validator, + WarningBtn * btnWarn = 0); + + bool TryParse(const QString &toParse, QString & out) override; + + /// + /// \brief Sets the value of this setting, checking validity and setting + /// any associated warning button + /// + /// \param input The value to set + /// + void ProcessInput(const QString & input); + +protected: + Validity checkValue(QString value, QString &msg); + + WarningBtn *btnWarning; +}; + +#endif // STRSETTING_H diff --git a/os/win32/tools/config/validators.cpp b/os/win32/tools/config/validators.cpp new file mode 100644 index 0000000..994e5ce --- /dev/null +++ b/os/win32/tools/config/validators.cpp @@ -0,0 +1,800 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/// +/// \file validators.h +/// \brief This header file defines all of the validation functions used for +/// the settings. +/// + +#include + +#include "validators.h" +#include "volumesettings.h" +#include "allsettings.h" + + +static bool isPowerOfTwo(unsigned long value); + + +/// +/// \brief Returns Valid no matter what is passed in. +/// +Validity emptyBoolValidator(bool value, QString &msg) +{ + (void)value; + (void)msg; + return Valid; +} + +/// +/// \brief Returns Valid no matter what is passed in. +/// +Validity emptyIntValidator(unsigned long value, QString &msg) +{ + (void)value; + (void)msg; + return Valid; +} + +/// +/// \brief Returns Valid no matter what is passed in. +/// +Validity emptyStringValidator(QString value, QString &msg) +{ + (void)value; + (void)msg; + return Valid; +} + +/// +/// \brief Validator for allSettings::rbtnsUsePosix. +/// +/// Requires that ::allSettings and ::volumeSettings be initialized. +/// +/// Side effect: calls ::volumeSettings->SetUsePosix. +/// +Validity validateUsePosixApi(bool value, QString &msg) +{ + Q_ASSERT(allSettings.rbtnsUseFse != NULL); + if(allSettings.rbtnsUseFse->GetValue() == value) + { + // At least on Windows, this happens when the rbtnUseFse is clicked: + // this value is changed to false before the Use FSE value is changed + // to true. This may be inverted, but either way the first + // validateUseXxxApi function will return Invalid and the second will + // return Valid in normal circumstances. + msg = "One API (POSIX or FSE) must be chosen but not both"; + return Invalid; + } + + Q_ASSERT(volumeSettings != NULL); + + // Following above comment, when the user selects a radio button this + // function call will be reached either here or in validateUseFseApi but not + // in both places, since the first called will return early above. + volumeSettings->SetUsePosix(value); + + return Valid; +} + +/// +/// \brief Validator for allSettings::rbtnsUseFse. +/// +/// Requires that ::allSettings and ::volumeSettings be initialized. +/// +/// Side effect: calls ::volumeSettings->SetUsePosix. +/// +Validity validateUseFseApi(bool value, QString &msg) +{ + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + if(allSettings.rbtnsUsePosix->GetValue() == value) + { + // See comments in validateUsePosixApi + msg = "One API (POSIX or FSE) must be chosen but not both"; + return Invalid; + } + + Q_ASSERT(volumeSettings != NULL); + volumeSettings->SetUsePosix(!value); + + return Valid; +} + +/// +/// \brief Validator for allSettings::sbsMaxNameLen. +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateMaxNameLen(unsigned long value, QString &msg) +{ + if(value < 1) + { + msg = "Max name length must be greater than 0"; + return Invalid; + } + + Q_ASSERT(allSettings.cmisBlockSize != NULL); + if(value > allSettings.cmisBlockSize->GetValue() - 4) + { + msg = "Max name length must be at least 4 lower than block size"; + return Invalid; + } + + if(value % 4 != 0) + { + msg = "Recommended: set name length maximum to a multiple of 4"; + return Warning; + } + + return Valid; +} + +/// +/// \brief Validator for allSettings::pssPathSepChar. +/// +Validity validatePathSepChar(QString value, QString &msg) +{ + if(value.isNull() || value.isEmpty()) + { + msg = "Path separator character cannot be empty."; + return Invalid; + } + + if(value.length() == 1) + { + char c = value[0].toLatin1(); + if(c <= 0 || c >= 127) + { + msg = "Path separator charactor must be a standard ASCII character."; + return Invalid; + } + return Valid; + } + + if(value.startsWith('\\')) + { + if(value.length() == 2 && + (value[1] == '\\' + || value[1] == 'a' + || value[1] == 'b' + || value[1] == 'f' + || value[1] == 'n' + || value[1] == 'r' + || value[1] == 't' + || value[1] == 'v' + || value[1] == '"' + || value[1] == '\'' + || value[1] == '?')) + { + return Valid; //Valid escape char + } + + int convertBase = 8; + int convertFrom = 1; //First expected numerical char + if(value[1] == 'x') + { + convertBase = 16; + convertFrom = 2; + } + bool success = false; + QString escapeSeq = value.mid(convertFrom, value.length() - 1); + unsigned short charCode = escapeSeq.toUShort(&success, convertBase); + + if(!success || charCode > 127) + { + msg = "Invalid escape sequence"; + return Invalid; + } + + if(charCode == 0) + { + msg = "Null character not valid for path separator"; + return Invalid; + } + + return Valid; + } + + msg = "Invalid character sequence. Must be single character or valid escape sequence"; + return Invalid; +} + +/// +/// \brief Validator for allSettings::sbsTaskCount +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateTaskCount(unsigned long value, QString &msg) +{ + if(value < 1) + { + msg = "Task count must be greater than 0"; + return Invalid; + } + + return Valid; +} +/// +/// \brief Validator for allSettings::sbsHandleCount +/// +Validity validateHandleCount(unsigned long value, QString &msg) +{ + if(value < 1 || value > 4096) + { + msg = "Handle count must be between 1 and 4096"; + return Invalid; + } + + return Valid; +} +/// +/// \brief Validator for allSettings::cmisBlockSize +/// +Validity validateBlockSize(unsigned long value, QString &msg) +{ + if(value < 256 || value > 65536) + { + msg = "Block size must be a power of 2 between 256 and 65536"; + return Invalid; + } + + if(!isPowerOfTwo(value)) + { + msg = "Block size must be a power of 2"; + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for the number of volumes added in the Volumes tab +/// +Validity validateVolumeCount(unsigned long value, QString &msg) +{ + if(value > 255) + { + msg = "No more than 255 volumes are allowed"; + return Invalid; + } + + if(value == 0) + { + msg = "At least one volume must be created"; + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for a VolumeSettings::Volume::stName +/// +/// Requires that ::allSettings be initialized. +/// +/// Returns Valid regardless of \p value if ::volumeSettings is not +/// initialized. This is necessary because the volume name is checked +/// for validity during the initialization of ::volumeSettings. +/// +/// This validator checks \p value against the names of other volumes. +/// It assumes that \p value is the name of the volume at the active +/// index in ::volumeSettings. If a volume name that is not at the +/// active index is checked with this validator, it will be checked +/// against itself and reported invalid because it appears to be a +/// duplicate. To avoid this, ensure volumeSettings::activeIndex refers +/// to the volume whose name is to be validated. +/// +Validity validateVolName(QString value, QString &msg) +{ + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + + if(!allSettings.rbtnsUsePosix->GetValue()) + { + return Valid; //Vol name doesn't matter in FSE + } + + if(value.isNull()) + { + Q_ASSERT(false); //Not expected + msg = "Volume name cannot be null"; + return Invalid; + } + + for(int i = 0; i < value.count(); i++) + { + if(value[i] == '\n' || value[i] == '\r') + { + msg = "Unexpected new line in volume name. Try using an escape sequence instead."; + return Invalid; + } + } + + // This evaluates to true when this function is called + // during the instantiation of volumeSettings. + if(volumeSettings == NULL) + { + PRINTDBG(QString("NULL volumeSettings; cannot validate: ") + value); + return Valid; //Assume that initial value is valid + } + + int ignoreIndex = volumeSettings->GetCurrentIndex(); + QList * const volumes + = volumeSettings->GetVolumes(); + + // Check for duplicates to this name + for(int i = 0; i < volumes->count(); i++) + { + if(i == ignoreIndex) continue; + if((*volumes)[i]->GetStName()->GetValue() == value) + { + msg = QString("Volume name must be unique. Duplicate volume name ") + value; + return Invalid; + } + } + + return Valid; +} + +/// +/// \brief Validator for a VolumeSettings::Volume::stSectorSize +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateVolSectorSize(unsigned long value, QString &msg) +{ + Q_ASSERT(allSettings.cmisBlockSize != NULL); + if(!isPowerOfTwo(value) + || value > 65536) // 2^16. Same max in block size + { + msg = "Sector size must be a power of 2 between 1 and 65536"; + return Invalid; + } + + if(value > allSettings.cmisBlockSize->GetValue()) + { + msg = "Sector size cannot be larger than block size"; + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for a VolumeSettings::Volume::stSectorCount. +/// +/// Assumes the validator is being run on the volume at +/// volumeSettings::activeIndex. Requires ::allSettings and +/// ::volumeSettings be initialized. +/// +Validity validateVolSectorCount(unsigned long value, QString &msg) +{ + + unsigned long sectorSize = volumeSettings + ->GetVolumes() + ->at(volumeSettings->GetCurrentIndex()) + ->GetStSectorSize() + ->GetValue(); + unsigned long blockSize = allSettings.cmisBlockSize->GetValue(); + + // Avoid division by 0 + if(blockSize == 0 || sectorSize == 0 || blockSize < sectorSize) + { + msg = "Invalid block or sector size; cannot validate volume size."; + return Warning; + } + + if((value / (blockSize / sectorSize)) < 5) + { + msg = "Volume must be the size of at least 5 blocks"; + return Invalid; + } + + Q_ASSERT(volumeSettings != NULL); + qulonglong maxSectors = getVolSizeMaxBytes() / sectorSize; + + if(static_cast(value) > maxSectors) + { + msg = "Volume size too large. Try selecting a higher block size. See Info tab for limits."; + return Invalid; + } + + else return Valid; +} + +/// +/// \brief Validator for a VolumeSettings::Volume::stInodeCount +/// +/// Assumes the validator is being run on the volume at +/// volumeSettings::activeIndex. Requires ::allSettings and +/// ::volumeSettings be initialized. +/// +Validity validateVolInodeCount(unsigned long value, QString &msg) +{ + if(value < 1) + { + msg = "Inode count must be 1 or above"; + return Invalid; + } + + VolumeSettings::Volume *currVolume = volumeSettings->GetVolumes()->at(volumeSettings->GetCurrentIndex()); + + bool imapExternal = currVolume->NeedsExternalImap(); + unsigned long sectorSize = currVolume->GetStSectorSize()->GetValue(); + unsigned long sectorCount = currVolume->GetStSectorCount()->GetValue(); + unsigned long blockSize = allSettings.cmisBlockSize->GetValue(); + unsigned long blockCount = sectorCount / (blockSize / sectorSize); + + // Number of bits in a block after subtracting the node header size. + unsigned long imapnodeEntries = (blockSize - 16) * 8; + + unsigned long inodeTableStartBN; // BN = Block Number + + if(imapExternal) + { + int imapNodeCount = 1; + while(((blockCount - 3) - (imapNodeCount * 2)) > (imapnodeEntries * imapNodeCount)) + { + imapNodeCount++; + } + + // Imap start block number + number of imap blocks + inodeTableStartBN = 3 + (imapNodeCount * 2); + } + else + { + inodeTableStartBN = 3; + } + + // Number of inode blocks past starting point must fit within block count + if((inodeTableStartBN + value * 2) > blockCount) + { + msg = QString("Inode count too high; limited by sector count. Current max: ") + + QString::number((blockCount - inodeTableStartBN) / 2); + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for a VolumeSettings::Volume::stAtomicWrite +/// +Validity validateVolAtomicWrite(QString value, QString &msg) +{ + if(QString::compare(value, gpszAtomicWrTrue, Qt::CaseInsensitive) == 0 + || QString::compare(value, gpszAtomicWrFalse, Qt::CaseInsensitive) == 0) + { + return Valid; + } + else + { + Q_ASSERT(false); // The associated QComboBox should not allow this. + msg = "Expected rename atomic to be either \"Supported\" or \"Unsupported\""; + return Invalid; + } +} + +/// +/// \brief Validator for allSettings::cmssByteOrder +/// +Validity validateByteOrder(QString value, QString &msg) +{ + if(value.startsWith("big", Qt::CaseInsensitive) + || value.startsWith("little", Qt::CaseInsensitive)) + { + return Valid; + } + else + { + Q_ASSERT(false); // The associated QComboBox should not allow this. + msg = "Byte order must be either big endian or little endian"; + return Invalid; + } + +} + +/// +/// \brief Validator for allSettings::sbsNativeAlignment +/// +Validity validateAlignmentSize(unsigned long value, QString &msg) +{ + if(value != 1 && value != 2 && value != 4 && value != 8) + { + msg = "Alignment size must be power of two between 1 and 8"; + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for allSettings::cmssCrc +/// +Validity validateCrc(QString value, QString &msg) +{ + if(QString::compare(value, crcBitwise) == 0 + || QString::compare(value, crcSarwate) == 0 + || QString::compare(value, crcSlice) == 0) + { + //Actual values + return Valid; + } + else if(value.startsWith("bitwise", Qt::CaseInsensitive) + || value.startsWith("sarwate", Qt::CaseInsensitive) + || value.startsWith("slice by 8", Qt::CaseInsensitive)) + { + //UI values + return Valid; + } + else + { + Q_ASSERT(false); // The associated QComboBox should not allow this. + msg = "CRC must be one of CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8"; + return Invalid; + } +} + +/// +/// \brief Validator for allSettings::sbsDirectPtrs +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateDirectPointers(unsigned long value, QString &msg) +{ + Q_ASSERT(allSettings.sbsIndirectPtrs != NULL); + unsigned long inodeEntries = getInodeEntries(); + + if(allSettings.sbsIndirectPtrs->GetValue() > inodeEntries) + { + msg = "Too many direct and indirect pointers."; + return Invalid; + } + + if(value > inodeEntries - allSettings.sbsIndirectPtrs->GetValue()) + { + msg = QString("Too many direct pointers. Current maximum based on other settings: ") + + QString::number(inodeEntries - allSettings.sbsIndirectPtrs->GetValue()) + + QString("."); + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for allSettings::sbsIndirectPtrs +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateIndirectPointers(unsigned long value, QString &msg) +{ + Q_ASSERT(allSettings.sbsDirectPtrs != NULL); + unsigned long inodeEntries = getInodeEntries(); + + if(allSettings.sbsDirectPtrs->GetValue() > inodeEntries) + { + msg = "Too many direct and indirect pointers."; + return Invalid; + } + + if(value > inodeEntries - allSettings.sbsDirectPtrs->GetValue()) + { + msg = QString("Too many indirect pointers. Current maximum based on other settings: ") + + QString::number(inodeEntries - allSettings.sbsDirectPtrs->GetValue()) + + QString("."); + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for allSettings::sbsAllocatedBuffers +/// +/// Requires that ::allSettings and ::volumeSettings be initialized. +/// +Validity validateAllocatedBuffers(unsigned long value, QString &msg) +{ + if(value > 255) + { + msg = "Buffer count must be less than 256"; + return Invalid; + } + + // Min buffer algorithm derrived from preprocessor logic in buffer.c + + ulong dindirPointers = (getInodeEntries() + - allSettings.sbsDirectPtrs->GetValue()) + - allSettings.sbsIndirectPtrs->GetValue(); + + ulong inodeMetaBuffers; + + if(dindirPointers > 0) + { + inodeMetaBuffers = 3; + } + else if(allSettings.sbsIndirectPtrs->GetValue() > 0) + { + inodeMetaBuffers = 2; + } + else + { + Q_ASSERT(allSettings.sbsDirectPtrs->GetValue() == getInodeEntries()); + inodeMetaBuffers = 1; + } + + ulong inodeBuffers = inodeMetaBuffers + 1; + + bool imapInline, imapExternal; + volumeSettings->GetImapRequirements(imapInline, imapExternal); + + ulong imapBuffers = (imapExternal ? 1 : 0); + + ulong minimumBufferCount; + + if(allSettings.cbsReadonly->GetValue() + || !allSettings.rbtnsUsePosix->GetValue()) + { + minimumBufferCount = inodeBuffers + imapBuffers; + } + else if(allSettings.cbsPosixRename->GetValue()) + { + if(allSettings.cbsPosixAtomicRename->GetValue()) + { + minimumBufferCount = inodeBuffers*2 + 3 + imapBuffers; + } + else + { + minimumBufferCount = inodeBuffers*2 + 2 + imapBuffers; + } + } + else //POSIX, but no rename + { + minimumBufferCount = inodeBuffers + 1 + imapBuffers; + } + + if(value < minimumBufferCount) + { + if(allSettings.cbsPosixRename->GetValue()) + { + msg = QString("Too few allocated buffers. Try disabling POSIX rename or increasing buffer count."); + } + else + { + msg = QString("Too few allocated buffers. Current minimum based on other settings: ") + + QString::number(minimumBufferCount); + } + return Invalid; + } + + return Valid; +} + +/// +/// \brief Validator for allSettings::lesInclude +/// +Validity validateMemInclude(QString value, QString &msg) +{ + if(value.isEmpty()) + { + return Valid; + } + if(value[0] == '<' && value[value.length() - 1] == '>' + || value[0] == '"' && value[value.length() - 1] == '"') + { + return Valid; + } + else + { + msg = "Invalid include file format: must be enclosed in quotation marks or angle brackets"; + return Invalid; + } +} + +/// +/// \brief Validator for allSettings::cbsTrManual +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateTransactManual(bool value, QString &msg) +{ + Q_ASSERT(allSettings.cbsReadonly != NULL); + if(value && !allSettings.cbsReadonly->GetValue()) + { + msg = "Automatic transaction on volume full recommended except in special cases"; + return Warning; + } + return Valid; +} + +/// +/// \brief Validator for allSettings::cbsTrVolFull +/// +/// Requires that ::allSettings be initialized. +/// +Validity validateTransactVolFull(bool value, QString &msg) +{ + Q_ASSERT(allSettings.cbsTrManual != NULL); + Q_ASSERT(allSettings.cbsReadonly != NULL); + if(!value && !allSettings.cbsTrManual->GetValue() + && !allSettings.cbsReadonly->GetValue()) + { + msg = "Automatic transaction on volume full recommended except in special cases"; + return Warning; + } + return Valid; +} + + +//Private method used to validate [in]direct pointer count +unsigned long getInodeEntries() +{ + Q_ASSERT(allSettings.cbsInodeCount != NULL); + Q_ASSERT(allSettings.cbsInodeTimestamps != NULL); + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + unsigned long inodeHeaderSize = 16 + 8 + + (allSettings.cbsInodeCount->GetValue() ? 4 : 0) + + (allSettings.cbsInodeTimestamps->GetValue() ? 12 : 0) + + 4 + + (allSettings.rbtnsUsePosix->GetValue() ? 4 : 0); + + return (allSettings.cmisBlockSize->GetValue() - inodeHeaderSize) / 4; +} + +qulonglong getVolSizeMaxBytes() +{ + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + qlonglong blockSize = allSettings.cmisBlockSize->GetValue(); + bool posix = allSettings.rbtnsUsePosix->GetValue(); + + qlonglong mrHeader = 28 + (posix ? 4 : 0); + qlonglong mrImapBits = (static_cast(blockSize) - mrHeader) * 8; + qlonglong imapBits = (static_cast(blockSize) - 16) * 8; + + qulonglong imapMax = mrImapBits * mrImapBits * static_cast(blockSize); + + if(mrImapBits < 0 || imapBits < 0) + { + imapMax = 0; + } + + qulonglong blockMax_32bit = 4294967296ULL * static_cast(blockSize); + + return (blockMax_32bit < imapMax) ? blockMax_32bit : imapMax; +} + +// Checks whether given value is a power of 2. +// Returns true for all powers of 2; false otherwise. +// Returns false for 0 as 0 is not considered to be +// a power of two. +// +// Code based on Stack Overflow: http://stackoverflow.com/questions/600293 +static bool isPowerOfTwo(unsigned long value) +{ + return (value != 0) && ((value & (value - 1)) == 0); +} diff --git a/os/win32/tools/config/validators.h b/os/win32/tools/config/validators.h new file mode 100644 index 0000000..f547f3a --- /dev/null +++ b/os/win32/tools/config/validators.h @@ -0,0 +1,83 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/// +/// \file validators.h +/// \brief This header file declares all of the validation functions used for +/// the settings. +/// +#ifndef VALIDATORS_H +#define VALIDATORS_H + +#include + +#include "validity.h" + +Validity emptyBoolValidator(bool value, QString &msg); +Validity emptyIntValidator(unsigned long value, QString &msg); +Validity emptyStringValidator(QString value, QString &msg); + +Validity validateUsePosixApi(bool value, QString &msg); +Validity validateUseFseApi(bool value, QString &msg); + +Validity validateMaxNameLen(unsigned long value, QString &msg); +Validity validatePathSepChar(QString value, QString &msg); +Validity validateTaskCount(unsigned long value, QString &msg); +Validity validateHandleCount(unsigned long value, QString &msg); + +Validity validateBlockSize(unsigned long value, QString &msg); +Validity validateVolumeCount(unsigned long value, QString &msg); + +Validity validateVolName(QString value, QString &msg); +Validity validateVolSectorSize(unsigned long value, QString &msg); +Validity validateVolSectorCount(unsigned long value, QString &msg); +Validity validateVolInodeCount(unsigned long value, QString &msg); +Validity validateVolAtomicWrite(QString value, QString &msg); + +Validity validateByteOrder(QString value, QString &msg); +Validity validateAlignmentSize(unsigned long value, QString &msg); +Validity validateCrc(QString value, QString &msg); +Validity validateDirectPointers(unsigned long value, QString &msg); +Validity validateIndirectPointers(unsigned long value, QString &msg); + +Validity validateAllocatedBuffers(unsigned long value, QString &msg); + +Validity validateMemInclude(QString value, QString &msg); + +Validity validateTransactManual(bool value, QString &msg); +Validity validateTransactVolFull(bool value, QString &msg); + +/// +/// \brief Gets the value of INODE_ENTRIES. Used in some validators and in +/// updating the max file size. +/// +unsigned long getInodeEntries(); + +/// +/// \brief Gets the maximum supported volume size in bytes based on current +/// settings. +/// +qulonglong getVolSizeMaxBytes(); + +#endif // VALIDATORS_H diff --git a/os/win32/tools/config/validity.h b/os/win32/tools/config/validity.h new file mode 100644 index 0000000..fbef80b --- /dev/null +++ b/os/win32/tools/config/validity.h @@ -0,0 +1,44 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef VALIDITY_H +#define VALIDITY_H + +/// +/// \brief Represents the validity of a setting +/// +enum Validity { + /// The value is valid + Valid, + + /// The value is valid but not recommended + Warning, + + /// The value is not valid + Invalid +}; + + +#endif // VALIDITY_H + diff --git a/os/win32/tools/config/volumesettings.cpp b/os/win32/tools/config/volumesettings.cpp new file mode 100644 index 0000000..6e16681 --- /dev/null +++ b/os/win32/tools/config/volumesettings.cpp @@ -0,0 +1,834 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "volumesettings.h" +#include "validators.h" +#include "allsettings.h" + +extern const char * const gpszAtomicWrTrue = "Supported"; +extern const char * const gpszAtomicWrFalse = "Unsupported"; + +VolumeSettings::Volume::Volume(QString name, + WarningBtn *wbtnPathPrefix, + WarningBtn *wbtnSectorSize, + WarningBtn *wbtnVolSize, + WarningBtn *wbtnInodeCount, + WarningBtn *wbtnAtomicWrite) + : stName("", name, validateVolName, wbtnPathPrefix), + stSectorSize("", 512, validateVolSectorSize, wbtnSectorSize), + stSectorCount("", 1024, validateVolSectorCount, wbtnVolSize), + stInodeCount("", 100, validateVolInodeCount, wbtnInodeCount), + stAtomicWrite("", gpszAtomicWrFalse, validateVolAtomicWrite, wbtnAtomicWrite) +{ + Q_ASSERT(allSettings.sbsAllocatedBuffers != NULL); + stSectorCount.notifyList.append(allSettings.sbsAllocatedBuffers); + stSectorSize.notifyList.append(&stSectorCount); + stSectorCount.notifyList.append(&stInodeCount); + stSectorSize.notifyList.append(&stInodeCount); +} + +StrSetting *VolumeSettings::Volume::GetStName() +{ + return &stName; +} + +IntSetting *VolumeSettings::Volume::GetStSectorSize() +{ + return &stSectorSize; +} + +IntSetting *VolumeSettings::Volume::GetStSectorCount() +{ + return &stSectorCount; +} + +IntSetting *VolumeSettings::Volume::GetStInodeCount() +{ + return &stInodeCount; +} + +StrSetting *VolumeSettings::Volume::GetStAtomicWrite() +{ + return &stAtomicWrite; +} + +bool VolumeSettings::Volume::NeedsExternalImap() +{ + // Formulas taken from RedCoreInit + + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + unsigned long metarootHeaderSize = 16 + + (allSettings.rbtnsUsePosix->GetValue() ? + 16 : 12); + unsigned long metarootEntries = + (allSettings.cmisBlockSize->GetValue() + - metarootHeaderSize) + * 8; + + unsigned volSectorShift = 0; + while((stSectorSize.GetValue() << volSectorShift) + < allSettings.cmisBlockSize->GetValue()) + { + volSectorShift++; + } + + unsigned long volBlockCount = stSectorCount.GetValue() >> volSectorShift; + + return (volBlockCount - 3 > metarootEntries); +} + + +VolumeSettings::VolumeSettings(QLineEdit *pathPrefixBox, + QComboBox *sectorSizeBox, + QSpinBox *volSizeBox, + QLabel *volSizeLabel, + QSpinBox *inodeCountBox, + QComboBox *atomicWriteBox, + QPushButton *addButton, + QPushButton *removeButton, + QListWidget *volumesList, + WarningBtn *volCountWarn, + WarningBtn *pathPrefixWarn, + WarningBtn *sectorSizeWarn, + WarningBtn *volSizeWarn, + WarningBtn *inodeCountWarn, + WarningBtn *atomicWriteWarn) + : stVolumeCount(macroNameVolumeCount, 1, validateVolumeCount), + lePathPrefix(pathPrefixBox), + sbVolSize(volSizeBox), + sbInodeCount(inodeCountBox), + labelVolSizeBytes(volSizeLabel), + cmbSectorSize(sectorSizeBox), + cmbAtomicWrite(atomicWriteBox), + btnAdd(addButton), + btnRemSelected(removeButton), + listVolumes(volumesList), + wbtnVolCount(volCountWarn), + wbtnPathPrefix(pathPrefixWarn), + wbtnSectorSize(sectorSizeWarn), + wbtnVolSize(volSizeWarn), + wbtnInodeCount(inodeCountWarn), + wbtnAtomicWrite(atomicWriteWarn), + volTick(0) +{ + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + usePosix = allSettings.rbtnsUsePosix->GetValue(); + + AddVolume(); + SetActiveVolume(volumes.count() - 1); + + connect(lePathPrefix, SIGNAL(textChanged(QString)), + this, SLOT(lePathPrefix_textChanged(QString))); + connect(sbVolSize, SIGNAL(valueChanged(QString)), + this, SLOT(sbVolSize_valueChanged(QString))); + connect(sbInodeCount, SIGNAL(valueChanged(QString)), + this, SLOT(sbInodeCount_valueChanged(QString))); + connect(cmbSectorSize, SIGNAL(currentIndexChanged(int)), + this, SLOT(cmbSectorSize_currentIndexChanged(int))); + connect(cmbAtomicWrite, SIGNAL(currentIndexChanged(int)), + this, SLOT(cmbAtomicWrite_currentIndexChanged(int))); + connect(listVolumes, SIGNAL(currentRowChanged(int)), + this, SLOT(listVolumes_currentRowChanged(int))); + connect(btnAdd, SIGNAL(clicked()), + this, SLOT(btnAdd_clicked())); + connect(btnRemSelected, SIGNAL(clicked()), + this, SLOT(btnRemSelected_clicked())); + + updateVolSizeBytes(); +} + +VolumeSettings::~VolumeSettings() +{ + clearVolumes(); +} + +IntSetting *VolumeSettings::GetStVolumeCount() +{ + return &stVolumeCount; +} + +QList *VolumeSettings::GetVolumes() +{ + return &volumes; +} + +int VolumeSettings::GetCurrentIndex() +{ + checkCurrentIndex(); + return activeIndex; +} + +void VolumeSettings::SetUsePosix(bool posix) +{ + usePosix = posix; + + if(posix) + { + lePathPrefix->setEnabled(true); + } + else + { + lePathPrefix->setEnabled(false); + } + + // Refresh UI list, since the entry names will change + // when usePosix changes. + refreshVolumeList(); +} + +void VolumeSettings::SetActiveVolume(int index) +{ + if(index < 0 || index >= volumes.count()) + { + throw new std::out_of_range( + "invalid index given to VolumeSettings::SetActiveVolume"); + } + + // Important: set activeIndex before changing UI elements, since + // some may try accessing volumes[activeIndex] on UI update + int rememberIndex = activeIndex; + activeIndex = index; + + // Update the UI fields to reflect the new active volume. + // + // Setting the UI values will trigger input processing, which + // will automatically check validity and set any needed + // warning icons. + + lePathPrefix->setText(volumes[index]->GetStName()->GetValue()); + + sbVolSize->setValue(volumes[index]->GetStSectorCount()->GetValue()); + + sbInodeCount->setValue(volumes[index]->GetStInodeCount()->GetValue()); + + // Volume size bytes label set by sbVolSize_valueChanged + + // Use QLocale to add comma separators + QLocale l(QLocale::English, QLocale::UnitedStates); + cmbSectorSize->setCurrentText(l.toString( + static_cast(volumes[index]->GetStSectorSize()->GetValue()))); + + cmbAtomicWrite->setCurrentText(volumes[index]->GetStAtomicWrite()->GetValue()); + + listVolumes->setCurrentRow(index); + + if(rememberIndex >= 0 && rememberIndex < volumes.count()) + { + deselectVolume(rememberIndex); + } + + allSettings.cmisBlockSize->notifyList.append(volumes[index]->GetStSectorSize()); + allSettings.cmisBlockSize->notifyList.append(volumes[index]->GetStSectorCount()); + allSettings.cmisBlockSize->notifyList.append(volumes[index]->GetStInodeCount()); + allSettings.rbtnsUsePosix->notifyList.append(volumes[index]->GetStInodeCount()); +} + +void VolumeSettings::AddVolume() +{ + QString name = QString("VOL") + QString::number(volTick) + QString(":"); + + volumes.append(new Volume(name, wbtnPathPrefix, wbtnSectorSize, wbtnVolSize, + wbtnInodeCount, wbtnAtomicWrite)); + volTick++; + + if(!usePosix) + { + name = QString("Volume ") + QString::number(volumes.count()); + } + // else leave 'name' unmodified for item label + + listVolumes->addItem(name); + + checkSetVolumeCount(); +} + +void VolumeSettings::RemoveActiveVolume() +{ + // Asserts activeIndex valid + if(!checkCurrentIndex()) return; + + Q_ASSERT(allSettings.cmisBlockSize != NULL); + + deselectVolume(activeIndex); + + delete volumes[activeIndex]; + volumes.removeAt(activeIndex); + + if(activeIndex >= volumes.count()) + { + if(volumes.count() == 0) + { + Q_ASSERT(false); // This was the last volume: should not happen. + + AddVolume(); // Add another volume if it does happen + return; + } + + // Select the last volume in the list + activeIndex = volumes.count() - 1; + } + + refreshVolumeList(); + checkSetVolumeCount(); +} + +void VolumeSettings::GetErrors(QStringList &errors, QStringList &warnings) +{ + int rememberIndex = activeIndex; + for(int i = 0; i < volumes.count(); i++) + { + // Artificially set activeIndex so that the volume name validator + // does not check volumes[i]'s name against itself and find a + // false duplicate. + activeIndex = i; + AllSettings::CheckError(volumes[i]->GetStName(), errors, warnings); + AllSettings::CheckError(volumes[i]->GetStSectorCount(), errors, warnings); + AllSettings::CheckError(volumes[i]->GetStInodeCount(), errors, warnings); + AllSettings::CheckError(volumes[i]->GetStSectorSize(), errors, warnings); + AllSettings::CheckError(volumes[i]->GetStAtomicWrite(), errors, warnings); + } + if(activeIndex != rememberIndex) + { + // Re-set warning buttons to the active volume + + activeIndex = rememberIndex; + checkCurrentIndex(); + volumes[activeIndex]->GetStName()->Notify(); + volumes[activeIndex]->GetStSectorCount()->Notify(); + volumes[activeIndex]->GetStInodeCount()->Notify(); + volumes[activeIndex]->GetStSectorSize()->Notify(); + volumes[activeIndex]->GetStAtomicWrite()->Notify(); + } +} + +void VolumeSettings::GetImapRequirements(bool &imapInline, bool &imapExternal) +{ + imapInline = false; + imapExternal = false; + + for(int i = 0; i < volumes.count(); i++) + { + if(volumes[i]->NeedsExternalImap()) + { + imapExternal = true; + } + else + { + imapInline = true; + } + + if(imapInline && imapExternal) + { + break; //No need to keep testing. + } + } +} + +QString VolumeSettings::FormatCodefileOutput() +{ + + QString toReturn = QString("\ +/** @file\n\ +*/\n\ +#include \n\ +#include \n\ +#include \n\ +#include \n\ +\n\n\ +const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] =\n\ +{\n"); + + for(int i = 0; i < volumes.count(); i++) + { + toReturn += QString(" { ") + + QString::number(volumes[i]->GetStSectorSize()->GetValue()) + + QString("U, ") + + QString::number(volumes[i]->GetStSectorCount()->GetValue()) + + QString("U, ") + + (QString::compare(volumes[i]->GetStAtomicWrite()->GetValue(), + gpszAtomicWrTrue, Qt::CaseInsensitive) == 0 + ? QString("true") : QString("false")) + + QString(", ") + + QString::number(volumes[i]->GetStInodeCount()->GetValue()) + + QString("U"); + + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + Q_ASSERT(allSettings.rbtnsUsePosix->GetValue() == usePosix); + + if(allSettings.rbtnsUsePosix->GetValue()) + { + QString volName = volumes[i]->GetStName()->GetValue(); + + // Add escape chars where necessary + volName.replace('\\', "\\\\"); + volName.replace('"', "\\\""); + + // Add as new entry, enclosed in quotation marks + toReturn += QString(", \"") + + volName + + QString("\""); + } + + if(i == volumes.count() - 1) + { + toReturn += QString("}\n"); + } + else + { + toReturn += QString("},\n"); + } + } + + toReturn += QString("};\n"); + return toReturn; +} + +void VolumeSettings::ParseCodefile(const QString &text, + QStringList ¬Found, + QStringList ¬Parsed) +{ + QRegularExpression exp("gaRedVolConf\\[.+?\\]\\s*=\\s*\\{([\\s\\S]*?)\\} *;"); + QRegularExpressionMatch rem = exp.match(text); + + if(!rem.hasMatch() || rem.lastCapturedIndex() < 1) + { + notFound += "Volume settings (gaRedVolConf)"; + return; + } + QString strVolumes = rem.captured(1); + + exp = QRegularExpression("\\{\\s*([\\s\\S]*?)\\s*\\}\\s*,?"); + + // Skip comment: (/\\*[\\s\\S]*?\\*/)? + // Capture value: (\\w*) + // Skip final whitespace: \\s* + QRegularExpression valueExp = QRegularExpression("(/\\*[\\s\\S]*?\\*/)?\\s*(\\w*),?\\s*"); + + // Same regex as valueExp, except value is enclosed in quotation marks + QRegularExpression pathPrefixEpx = QRegularExpression("(/\\*[\\s\\S]*?\\*/)?\"(.*?)\",?\\s*"); + + // The position in strVolumes to start looking for + // the next volume + int currPos = 0; + int currVolIndex = 0; + QList newVolumes; + bool failure = false; + + while(!failure) + { + rem = exp.match(strVolumes, currPos); + if(!rem.hasMatch() || rem.lastCapturedIndex() < 1) + { + break; + } + + // The initialization block of the current volume in gaRedVolConf + QString currStr = rem.captured(1); + currPos = rem.capturedEnd(0); + + // The position in currStr to start looking for the next value + int currVolPos = 0; + + // List of unparsed values of the settings of the current volume + QStringList strValues; + + for(int i = 0; i < 4; i++) + { + rem = valueExp.match(currStr, currVolPos); + if(!rem.hasMatch() || rem.lastCapturedIndex() < 2) + { + failure = true; + break; + } + strValues += rem.captured(2); + currVolPos = rem.capturedEnd(0); + } + if(failure) + { + break; + } + + QString pathPrefix; + + rem = pathPrefixEpx.match(currStr, currVolPos); + if(!rem.hasMatch() || rem.lastCapturedIndex() < 2) + { + // It's normal for this to be missing if the file + // was not exported in POSIX mode. Use a default + // name if not found. + pathPrefix = QString("VOL") + + QString::number(currVolIndex) + + QString(":"); + } + else + { + pathPrefix = rem.captured(2); + } + + Volume * newVol = new Volume(pathPrefix, + wbtnPathPrefix, + wbtnSectorSize, + wbtnVolSize, + wbtnInodeCount, + wbtnAtomicWrite); + + parseAndSet(newVol->GetStSectorSize(), strValues[0], notParsed, + pathPrefix + QString(" sector size")); + parseAndSet(newVol->GetStSectorCount(), strValues[1], notParsed, + pathPrefix + QString(" sector count")); + + // Special case parse and set + if(QString::compare(strValues[2], "true") == 0) + { + newVol->GetStAtomicWrite()->SetValue(gpszAtomicWrTrue); + } + else if(QString::compare(strValues[2], "false") == 0) + { + newVol->GetStAtomicWrite()->SetValue(gpszAtomicWrFalse); + } + else + { + notParsed += pathPrefix + QString(" atomic write supported"); + } + + parseAndSet(newVol->GetStInodeCount(), strValues[3], notParsed, + pathPrefix + QString(" inode count")); + + newVolumes.append(newVol); + currVolIndex++; + } + + if(failure || currVolIndex == 0) + { + if(failure) + { + for(int i = 0; i < newVolumes.count(); i++) + { + delete newVolumes[i]; + } + } + notParsed += "Volume settings (gaRedVolConf)"; + } + else + { + clearVolumes(); + + activeIndex = 0; + volumes = newVolumes; + Q_ASSERT(volumes.count() > 0); + + refreshVolumeList(); + checkSetVolumeCount(); + } +} + +QString VolumeSettings::FormatSize(qulonglong sizeInBytes) +{ + // Use QLocale to add comma separators + QLocale l(QLocale::English, QLocale::UnitedStates); + QString strBytes = l.toString((qulonglong) sizeInBytes) + QString(" bytes"); + + if(sizeInBytes < 1024ull) + { + return strBytes; + } + + double dbSize; + QString strSize; + + if(sizeInBytes < 1024ull * 1024ull) + { + dbSize = (double) sizeInBytes / 1024.0l; + strSize = QString::number(dbSize, 'f', 2) + + QString(" KB"); + } + else if(sizeInBytes < 1024ull * 1024ull * 1024ull) + { + dbSize = (double) sizeInBytes / 1024.0l / 1024.0l; + strSize = QString::number(dbSize, 'f', 2) + + QString(" MB"); + } + else if(sizeInBytes < 1024ull * 1024ull * 1024ull * 1024ull) + { + dbSize = (double) sizeInBytes / 1024.0l / 1024.0l / 1024.0l; + strSize = QString::number(dbSize, 'f', 2) + + QString(" GB"); + } + else if(sizeInBytes < 1024ull * 1024ull * 1024ull * 1024ull * 1024ull) + { + dbSize = (double) sizeInBytes / 1024.0l / 1024.0l / 1024.0l / 1024.0l; + strSize = QString::number(dbSize, 'f', 2) + + QString(" TB"); + } + else + { + dbSize = (double) sizeInBytes / 1024.0l / 1024.0l / 1024.0l / 1024.0l / 1024.0l; + strSize = QString::number(dbSize, 'f', 2) + + QString(" PB"); + } + + return strSize + QString(" (") + strBytes + QString(")"); +} + +// Deletes all entries from volumes +void VolumeSettings::clearVolumes() +{ + if(activeIndex >= 0 && activeIndex < volumes.count()) + { + // Remove references from other settings to avoid + // memory access errors + deselectVolume(activeIndex); + } + + for(int i = 0; i < volumes.count(); i++) + { + delete volumes[i]; + } +} + +// Remove references from allSettings members in order to avoid +// automatic re-checking (which would incorrectly set warning +// icons) and memory access violations if the volume is deleted. +void VolumeSettings::deselectVolume(int index) +{ + Q_ASSERT(allSettings.cmisBlockSize != NULL); + Q_ASSERT(allSettings.rbtnsUsePosix != NULL); + + allSettings.cmisBlockSize->notifyList + .removeOne(volumes[index]->GetStSectorSize()); + allSettings.cmisBlockSize->notifyList + .removeOne(volumes[index]->GetStSectorCount()); + allSettings.cmisBlockSize->notifyList + .removeOne(volumes[index]->GetStInodeCount()); + allSettings.rbtnsUsePosix->notifyList + .removeOne(volumes[index]->GetStInodeCount()); +} + +// Helper function for ParseCodeFile +template +void VolumeSettings::parseAndSet(Setting *setting, + const QString &strValue, + QStringList ¬Parsed, + const QString &humanName) +{ + T value; + bool success = setting->TryParse(strValue, value); + if(!success) + { + notParsed += humanName; + } + else + { + setting->SetValue(value); + } +} + +// Checks in the current number of volumes, setting any UI warnings +void VolumeSettings::checkSetVolumeCount() +{ + Q_ASSERT(listVolumes->count() == volumes.count()); + + // Can't use stVolumeCount.ProcessInput because we + // have an int already and not a QString + QString msg; + Validity v = stVolumeCount.CheckValid( + (unsigned long) volumes.count(), msg); + wbtnVolCount->Set(v, msg); + + stVolumeCount.SetValue((unsigned long) volumes.count()); + + if(volumes.count() <= 1) + { + btnRemSelected->setEnabled(false); + } + else + { + btnRemSelected->setEnabled(true); + } +} + +// Clears the volume list in the UI and repopulates it +void VolumeSettings::refreshVolumeList() +{ + listVolumes->clear(); + + if(usePosix) + { + for(int i = 0; i < volumes.count(); i++) + { + listVolumes->addItem(volumes[i]->GetStName()->GetValue()); + } + } + else + { + for(int i = 0; i < volumes.count(); i++) + { + listVolumes->addItem(QString("Volume ") + QString::number(i)); + } + } + + Q_ASSERT(activeIndex >= 0 && activeIndex < volumes.count()); + SetActiveVolume(activeIndex); +} + +// Asserts that activeIndex is valid. Takes steps to recover +// if it is not. +bool VolumeSettings::checkCurrentIndex() +{ + if(volumes.count() == 0) + { + Q_ASSERT(false); //Should never be 0 + AddVolume(); + return false; + } + else if(activeIndex < 0 || activeIndex >= volumes.count()) + { + Q_ASSERT(false); //Shouldn't happen + SetActiveVolume(0); + return false; + } + + return true; +} + +// Updates the label that reports the volume size in bytes. +void VolumeSettings::updateVolSizeBytes() +{ + labelVolSizeBytes->setText(FormatSize( + static_cast(volumes[activeIndex]->GetStSectorSize()->GetValue()) + * static_cast(volumes[activeIndex]->GetStSectorCount()->GetValue()))); +} + +void VolumeSettings::lePathPrefix_textChanged(const QString &text) +{ + // Asserts that the vol index is ok + if(!checkCurrentIndex()) return; + + volumes[activeIndex]->GetStName()->ProcessInput(text); + + if(usePosix) + { + listVolumes->item(activeIndex)->setText(text); + } + else + { + listVolumes->item(activeIndex)->setText(QString("Volume ") + + QString::number(activeIndex)); + } +} + +void VolumeSettings::cmbSectorSize_currentIndexChanged(int index) +{ + // Asserts that the vol index is ok + if(!checkCurrentIndex()) return; + + try { + volumes[activeIndex]->GetStSectorSize() + ->ProcessInput(cmbSectorSize->itemText(index)); + } + catch(std::invalid_argument) + { + Q_ASSERT(false); + return; + } + + updateVolSizeBytes(); +} + +void VolumeSettings::sbVolSize_valueChanged(const QString &value) +{ + // Asserts that the vol index is ok + if(!checkCurrentIndex()) return; + + try + { + volumes[activeIndex]->GetStSectorCount()->ProcessInput(value); + } + catch(std::invalid_argument) + { + Q_ASSERT(false); + return; + } + + updateVolSizeBytes(); +} + +void VolumeSettings::sbInodeCount_valueChanged(const QString &value) +{ + // Asserts that the vol index is ok + if(!checkCurrentIndex()) return; + + try { + volumes[activeIndex]->GetStInodeCount()->ProcessInput(value); + } + catch(std::invalid_argument) + { + Q_ASSERT(false); + return; + } +} + +void VolumeSettings::cmbAtomicWrite_currentIndexChanged(int index) +{ + // Asserts that the vol index is ok + if(!checkCurrentIndex()) return; + + try { + volumes[activeIndex]->GetStAtomicWrite() + ->ProcessInput(cmbAtomicWrite->itemText(index)); + } + catch(std::invalid_argument) + { + Q_ASSERT(false); + return; + } +} + +void VolumeSettings::listVolumes_currentRowChanged(int row) +{ + if(row < 0 || row >= volumes.count()) + { + return; + } + + SetActiveVolume(row); +} + +void VolumeSettings::btnAdd_clicked() +{ + AddVolume(); + Q_ASSERT(volumes.count() > 0); + SetActiveVolume(volumes.count() - 1); +} + +void VolumeSettings::btnRemSelected_clicked() +{ + RemoveActiveVolume(); +} + +VolumeSettings * volumeSettings = 0; diff --git a/os/win32/tools/config/volumesettings.h b/os/win32/tools/config/volumesettings.h new file mode 100644 index 0000000..f40c79c --- /dev/null +++ b/os/win32/tools/config/volumesettings.h @@ -0,0 +1,258 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef VOLUMESETTINGS_H +#define VOLUMESETTINGS_H + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "intsetting.h" +#include "strsetting.h" +#include "WarningBtn.h" + +extern const char * const gpszAtomicWrTrue; +extern const char * const gpszAtomicWrFalse; + +/// +/// \brief The VolumeSettings class handles basically everything associated +/// with the +/// +class VolumeSettings : QObject +{ + Q_OBJECT +public: + /// + /// \brief The Volume class ontains the Setting objects associated with a + /// volume. + /// + class Volume + { + public: + Volume(QString name, + WarningBtn *wbtnPathPrefix, + WarningBtn *wbtnSectorSize, + WarningBtn *wbtnVolSize, + WarningBtn *wbtnInodeCount, + WarningBtn *wbtnAtomicWrite); + StrSetting *GetStName(); + IntSetting *GetStSectorSize(); + IntSetting *GetStSectorCount(); + IntSetting *GetStInodeCount(); + StrSetting *GetStAtomicWrite(); + bool NeedsExternalImap(); + + private: + StrSetting stName; + IntSetting stSectorCount; + IntSetting stInodeCount; + IntSetting stSectorSize; + StrSetting stAtomicWrite; + }; + + /// + /// \brief Constructor + /// + /// Requires that ::allSettings be initialized. + /// + VolumeSettings(QLineEdit *pathPrefixBox, + QComboBox *sectorSizeBox, + QSpinBox *volSizeBox, + QLabel *volSizeLabel, + QSpinBox *inodeCountBox, + QComboBox *atomicWriteBox, + QPushButton *addButton, + QPushButton *removeButton, + QListWidget *volumesList, + WarningBtn *volCountWarn, + WarningBtn *pathPrefixWarn, + WarningBtn *sectorSizeWarn, + WarningBtn *volSizeWarn, + WarningBtn *inodeCountWarn, + WarningBtn *atomicWriteWarn); + ~VolumeSettings(); + + /// + /// \brief Gets the ::Setting for the number of volumes created + /// + IntSetting * GetStVolumeCount(); + + /// + /// \brief Gets the list of volumes created + /// + QList *GetVolumes(); + + /// + /// \brief Gets the index of the current active volume in + /// VolumeSettings::volumes + /// + int GetCurrentIndex(); + + /// + /// \brief Sets whether the configuration is for a POSIX or FSE API. + /// + /// Path prefixes (volume names) are only applicable to the POSIX + /// API. When ::usePosix is set to false, this setting becomes + /// unavailable. + /// + /// \param posix Specifies whether the POSIX API is enabled or not + /// + void SetUsePosix(bool posix); + + /// + /// \brief Sets the UI to edit the volume at the given index in volumes. + /// + /// Throws std::out_of_range if the given index is invalid. + /// + void SetActiveVolume(int index); + + /// + /// \brief Creates a new ::Volume + /// + /// Allocates a new volume and puts it in VolumeSettings::volumes. + /// + void AddVolume(); + + /// + /// \brief Removes and deletes the ::Volume at ::activeIndex. + /// + /// Requires that there be more than one volume and ::activeIndex + /// be valid. + /// + void RemoveActiveVolume(); + + /// + /// \brief Get any errors or warnings associated with the volume settings. + /// Called by AllSettings::GetErrors. + /// + void GetErrors(QStringList &errors, QStringList &warnings); + + /// + /// \brief Checks what configuration of imaps is required. + /// + /// \param imapInline Set to true if any volume requires an inline imap; + /// false otherwise. + /// \param imapExternal Set to true if any volume requires an external imap; + /// false otherwise. + /// + void GetImapRequirements(bool &imapInline, bool &imapExternal); + + /// + /// \brief Formats the volume settings as valid C code. + /// + /// \return A string of C code for a redconf.c file. + /// + QString FormatCodefileOutput(); + + /// + /// \brief Parse C code, loading volume settings. + /// + /// This function is only required to correctly load settings from + /// text that has been created by ::FormatCodefileOutput. It will + /// attempt to load settings from any + /// + /// \param text A string of C code from a redconf.c file. + /// \param notFound A list to which to append the name of any settings + /// that were expected but are not found. + /// \param notParsed A list to which to append the name of any settings + /// that were found but could not be parsed. + /// + void ParseCodefile(const QString &text, + QStringList ¬Found,QStringList ¬Parsed); + + /// + /// \brief Produces a human readable string from a number of bytes. The + /// format of the returned string is "xxx.xx MB (xx,xxx,xxx bytes)", + /// where MB could also by KB, GB, TB, or PB depending on the size. + /// If \p sizeInBytes is less than 1024, then the format of the + /// returned string is "x,xxx bytes" + /// + static QString FormatSize(qulonglong sizeInBytes); + +private: + void clearVolumes(); + void deselectVolume(int index); + template + void parseAndSet(Setting *setting, const QString &value, + QStringList ¬Parsed, const QString &humanName); + void refreshVolumeList(); + void checkSetVolumeCount(); + bool checkCurrentIndex(); + void updateVolSizeBytes(); + + // Getter: GetStNumVolumes + IntSetting stVolumeCount; + bool usePosix; + + // Keeps a record of how many volumes have been added. Used to create + // names of new volumes + unsigned volTick; + + // Getter: GetVolumes + QList volumes; + int activeIndex; + + QLineEdit *lePathPrefix; + QSpinBox *sbVolSize; + QSpinBox *sbInodeCount; + QLabel *labelVolSizeBytes; + QComboBox *cmbSectorSize; + QComboBox *cmbAtomicWrite; + QPushButton *btnAdd; + QPushButton *btnRemSelected; + QListWidget *listVolumes; + + WarningBtn *wbtnVolCount; + WarningBtn *wbtnPathPrefix; + WarningBtn *wbtnVolSize; + WarningBtn *wbtnInodeCount; + WarningBtn *wbtnSectorSize; + WarningBtn *wbtnAtomicWrite; + +private slots: + void lePathPrefix_textChanged(const QString &text); + void cmbSectorSize_currentIndexChanged(int index); + void sbVolSize_valueChanged(const QString &value); + void sbInodeCount_valueChanged(const QString &value); + void cmbAtomicWrite_currentIndexChanged(int index); + void listVolumes_currentRowChanged(int row); + void btnAdd_clicked(); + void btnRemSelected_clicked(); +}; + +/// +/// \brief Global ::VolumeSettings object. +/// +/// Accessed by validators, ::Input, ::Output, etc. Initialized in +/// ::ConfigWindow constructor after ::allSettings is initialized. +/// +extern VolumeSettings * volumeSettings; + +#endif // VOLUMESETTINGS_H diff --git a/os/win32/tools/config/warningbtn.cpp b/os/win32/tools/config/warningbtn.cpp new file mode 100644 index 0000000..a9fc593 --- /dev/null +++ b/os/win32/tools/config/warningbtn.cpp @@ -0,0 +1,115 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include "WarningBtn.h" +#include "ui_warningbtn.h" +#include "configwindow.h" + +// The icons used. These are set the first time the +// WarningBtn constructor is run +QIcon *WarningBtn::iconError = NULL; +QIcon *WarningBtn::iconWarn = NULL; + +WarningBtn::WarningBtn(QWidget *parent) : + QWidget(parent), + ui(new Ui::WarningBtn) +{ + ui->setupUi(this); + + if(!iconError || !iconWarn) + { + iconError = new QIcon(":/icons/error.png"); + iconWarn = new QIcon(":/icons/warn.png"); + } + + // Forward the clicked() signal + connect(ui->toolButton, SIGNAL(clicked()), + this, SIGNAL(clicked())); + + ui->toolButton->setVisible(false); +} + +WarningBtn::~WarningBtn() +{ + delete ui; +} + +void WarningBtn::SetWarn(QString msg) +{ + currMsg = msg; + ui->toolButton->setIcon(*iconWarn); + ui->toolButton->setVisible(true); +} + +void WarningBtn::SetError(QString msg) +{ + currMsg = msg; + ui->toolButton->setIcon(*iconError); + ui->toolButton->setVisible(true); +} + +void WarningBtn::Clear(void) +{ + currMsg = QString(); + ui->toolButton->setVisible(false); +} + +void WarningBtn::Set(Validity v, QString msg) +{ + switch (v) + { + case Valid: + Clear(); + break; + + case Warning: + SetWarn(msg); + break; + + case Invalid: + SetError(msg); + break; + + // Default: do nothing + } +} + +// Check for mouse-over events and show the current message +// in a tooltip when one arrises. +bool WarningBtn::event(QEvent *e) +{ + if(e->type() == QEvent::Enter) + { + if(!currMsg.isNull() && !currMsg.isEmpty()) + { + QToolTip::showText(mapToGlobal(mapFromParent(pos())), + currMsg, + ui->toolButton); + } + } + + return QWidget::event(e); +} diff --git a/os/win32/tools/config/warningbtn.h b/os/win32/tools/config/warningbtn.h new file mode 100644 index 0000000..3a3fb0f --- /dev/null +++ b/os/win32/tools/config/warningbtn.h @@ -0,0 +1,95 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef WARNINGBTN_H +#define WARNINGBTN_H + +#include +#include +#include + +#include "validity.h" +#include "ui_warningbtn.h" + +namespace Ui { +class WarningBtn; +} + +/// +/// \brief The WarningBtn is a UI element which shows an error or warning icon +/// to the user if a setting value is invalid or not recommended. +/// +class WarningBtn : public QWidget +{ + Q_OBJECT + +public: + explicit WarningBtn(QWidget *parent = 0); + ~WarningBtn(); + + /// + /// \brief Sets this ::WarningBtn to display a yellow warning icon + /// representing the given message. + /// + /// \param msg The message describing this warning. + /// + void SetWarn(QString msg); + + /// + /// \brief Sets this ::WarningBtn to display a red error icon representing + /// the given message. + /// + /// \param msg The message describing this error. + /// + void SetError(QString msg); + + /// + /// \brief Sets this ::WarningBtn to display no icon and show no message. + /// + void Clear(void); + + /// + /// \brief Sets the behavior of this ::WarningBtn + /// + /// \param v Specifies the state this ::WarningBtn is to report. + /// \param msg Specifies the message describing the validity reported. This + /// will not be used if \p v is equal to Validity::Valid. + /// + void Set(Validity v, QString msg); + +protected: + bool event(QEvent *e) override; + +private: + static QIcon *iconError; + static QIcon *iconWarn; + + QString currMsg; + Ui::WarningBtn *ui; + +signals: + void clicked(); +}; + +#endif // WARNINGBTN_H diff --git a/os/win32/tools/config/warningbtn.ui b/os/win32/tools/config/warningbtn.ui new file mode 100644 index 0000000..430905c --- /dev/null +++ b/os/win32/tools/config/warningbtn.ui @@ -0,0 +1,49 @@ + + + WarningBtn + + + + 0 + 0 + 21 + 19 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + .. + + + + :/icons/error.png:/icons/error.png + + + true + + + + + + + + + + diff --git a/os/win32/tools/imgbld/ibcommon.c b/os/win32/tools/imgbld/ibcommon.c new file mode 100644 index 0000000..cb98eab --- /dev/null +++ b/os/win32/tools/imgbld/ibcommon.c @@ -0,0 +1,231 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief implements image builder methods shared between POSIX and FSE +*/ + +/* Include errno first to make sure Windows errno values are defined, not the + Reliance Edge ones. This module does not deal directly with Reliance Edge + errno values, so this is safe to do. +*/ +#include + +#include + +#if REDCONF_IMAGE_BUILDER == 1 + +#include +#include +#include +#include + +#include "ibheader.h" + + +static int GetFileLen(FILE *fp, uint64_t *pLength); + + +/** @brief Copies from the file at the given path to the file of the given + index. + + @param volNum The FSE volume to which to copy the file. Unused in + POSIX configuration. + @param pFileEntry Mapping for the file to be copied. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int IbCopyFile( + int volNum, + const FILEMAPPING *pFileMapping) +{ + int ret = 0; + uint32_t ulCurrLen = 0U; + uint64_t ullCurrOffset = 0U; + uint64_t ullFSize; + FILE *pFile; + + /* Open the file which is being copied and query its length. + */ + pFile = fopen(pFileMapping->asInFilePath, "rb"); + if(pFile == NULL) + { + if(errno == ENOENT) + { + fprintf(stderr, "Input file not found: %s\n", pFileMapping->asInFilePath); + } + else + { + fprintf(stderr, "Error opening input file: %s\n", pFileMapping->asInFilePath); + } + + ret = -1; + } + else + { + ret = GetFileLen(pFile, &ullFSize); + if(ret != 0) + { + fprintf(stderr, "Error getting file length: %s\n", pFileMapping->asInFilePath); + } + } + + /* Force copy empty files on POSIX configuration. + */ + #if REDCONF_API_POSIX == 1 + if((ret == 0) && (ullFSize == 0)) + { + IbWriteFile(volNum, pFileMapping, 0, gpCopyBuffer, 0); + } + #endif + + /* Copy data from input to target file + */ + while((ret == 0) && (ullCurrOffset < ullFSize)) + { + size_t rresult; + + ulCurrLen = ((ullFSize - ullCurrOffset) < gulCopyBufferSize ? + (uint32_t) (ullFSize - ullCurrOffset) : gulCopyBufferSize); + rresult = fread(gpCopyBuffer, 1U, ulCurrLen, pFile); + + if(rresult != ulCurrLen) + { + if(feof(pFile)) + { + /* Shouldn't happen; we just checked file length. + */ + REDERROR(); + fprintf(stderr, "Warning: file size changed while reading file.\n"); + + ulCurrLen = (uint32_t) rresult; + ullFSize = ullCurrOffset + rresult; + } + else + { + REDASSERT(ferror(pFile)); + ret = -1; + fprintf(stderr, "Error reading input file %s\n", pFileMapping->asInFilePath); + + break; + } + } + + if(ret == 0) + { + ret = IbWriteFile(volNum, pFileMapping, ullCurrOffset, gpCopyBuffer, ulCurrLen); + + ullCurrOffset += (uint64_t) ulCurrLen; + } + } + + if(pFile != NULL) + { + (void) fclose(pFile); + } + + return ret; +} + +/* Private helper method to get the file length of the given file using the + Windows file API. +*/ +static int GetFileLen( + FILE *fp, + uint64_t *pLength) +{ + HANDLE fh = (HANDLE) _get_osfhandle(_fileno(fp)); + int ret = 0; + LARGE_INTEGER fsize; + BOOL success; + + success = GetFileSizeEx(fh, &fsize); + + if(success) + { + *pLength = (uint64_t) fsize.QuadPart; + } + else + { + ret = -1; + } + + return ret; +} + + +/** @brief Uses fopen(pszPath, "r") to determine if the given file path refers + to an existing file. + + @param pszPath File path to check. + @param pfExists Non-null pointer to bool. Assigned true if the file is + found, false if not found, indeterminate if an error occurs. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int CheckFileExists( + const char *pszPath, + bool *pfExists) +{ + int ret = 0; + FILE *pFile; + + if((pfExists == NULL) || (pszPath == NULL)) + { + ret = -1; + } + + if(ret == 0) + { + pFile = fopen(pszPath, "r"); + + if(pFile == NULL) + { + if(errno == ENOENT) + { + *pfExists = false; + } + else + { + ret = -1; + } + } + else + { + *pfExists = true; + (void) fclose(pFile); + } + } + + return ret; +} + +#endif + diff --git a/os/win32/tools/imgbld/ibfse.c b/os/win32/tools/imgbld/ibfse.c new file mode 100644 index 0000000..d34662b --- /dev/null +++ b/os/win32/tools/imgbld/ibfse.c @@ -0,0 +1,962 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements methods of the image builder tool specific to the FSE + configuration. +*/ +#include + +#if REDCONF_IMAGE_BUILDER == 1 && REDCONF_API_POSIX == 0 + +#include +#include +#include + +#include + +#include "../wintlcmn.h" +#include "ibheader.h" + + +typedef struct sSTRLISTENTRY STRLISTENTRY; +struct sSTRLISTENTRY +{ + char asStr[MACRO_NAME_MAX_LEN + 1]; + STRLISTENTRY *pNext; +}; + + +static int WriteDefineOut(FILE *pFileOut, const FILEMAPPING *pFileMapping, STRLISTENTRY **ppListNames); + +/* Private helper method to get the tail entry of a linked list +*/ +static STRLISTENTRY *GetLastEntry(STRLISTENTRY *pStrList) +{ + STRLISTENTRY *pCurrEntry = pStrList; + + while(pCurrEntry != NULL && pCurrEntry->pNext != NULL) + { + pCurrEntry = pCurrEntry->pNext; + } + + return pCurrEntry; +} + + +/* Private helper function to free a linked list of STRLISTENTRY's. *ppStrList + will be NULL after calling + + @param ppStrList Pointer to the base STRLISTENTRY of the linked list. + Returns without taking action if this is NULL. +*/ +static void FreeStrList( + STRLISTENTRY **ppStrList) +{ + while(*ppStrList != NULL) + { + STRLISTENTRY *pLastEntry = *ppStrList; + + *ppStrList = (*ppStrList)->pNext; + free(pLastEntry); + } +} + + +/** Helper function to free a linked list of FILELISTENTRY's. + *ppFileList will be NULL after calling. + + @param ppFileList Pointer to the base FILELISTENTRY of the linked list. + Returns without taking action if this is NULL. +*/ +void FreeFileList( + FILELISTENTRY **ppFileList) +{ + while(*ppFileList != NULL) + { + FILELISTENTRY *pLastEntry = *ppFileList; + + *ppFileList = (*ppFileList)->pNext; + free(pLastEntry); + } +} + + +int IbApiInit(void) +{ + REDSTATUS rstat = RedFseInit(); + + fprintf(stdout, "\n"); + + if(rstat != 0) + { + fprintf(stderr, "Error number %d initializing file system.\n", -rstat); + } + + return (rstat == 0) ? 0 : -1; +} + + +int IbApiUninit(void) +{ + REDSTATUS rstat = RedFseUninit(); + + if(rstat != 0) + { + fprintf(stderr, "Error number %d uninitializing file system.\n", -rstat); + } + + return (rstat == 0) ? 0 : -1; +} + + +/** @brief Reads a file map file off the disk and fills a linked structure with + the file indexes and names therein specified. Prints any error + messages to stderr. + + @param pszMapPath The path to the file map file. + @param pszIndirPath The path to the input directory. Should be set to + NULL if no input directory was specified. + @param ppFileListHead A pointer to a FILELISTENTRY to be filled. A linked + list is allocated onto this pointer if successful, + and thus should be freed after use by passing it to + FreeFileList. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int GetFileList( + const char *pszMapPath, + const char *pszIndirPath, + FILELISTENTRY **ppFileListHead) +{ + int ret = 0; + FILELISTENTRY *pCurrEntry = NULL; + FILE *pFile = NULL; + uint32_t lastIndex = 0; /* Used to ensure no duplicate indexes. */ + + *ppFileListHead = NULL; + if(pszMapPath == NULL) + { + REDASSERT(false); + ret = -1; + } + + if(ret == 0) + { + pFile = fopen(pszMapPath, "rt"); + if(pFile == NULL) + { + fprintf(stderr, "Error openning specified mapping file.\n"); + ret = -1; + } + } + + /* Parse each line of the map file and store the mapping information as a + new entry in ppFileListHead + */ + while (ret == 0) + { + uint32_t currIndex = 0; + char currPath[WIN_FILENAME_MAX]; + int currChar = fgetc(pFile); + + /* Skip over comment lines and whitespace between lines (allowing + indentation etc). + */ + while(isspace(currChar) || (currChar == '#')) + { + if(currChar == '#') + { + /* Skip over the entire comment line. + */ + while(currChar != '\n' && currChar != EOF) + { + currChar = fgetc(pFile); + } + } + else + { + currChar = fgetc(pFile); + } + } + + if(currChar == EOF) + { + if(ferror(pFile) != 0) + { + ret = -1; + } + + break; + } + + /* Put the last char, which was neither whitespace nor a comment, back + in the stream. + */ + currChar = ungetc(currChar, pFile); + + if(currChar == EOF) + { + ret = -1; + } + else + { + /* Read out the index number. + */ + if(fscanf(pFile, "%u\t", &currIndex) != 1) + { + ret = -1; + } + else if(currIndex <= 1) + { + fprintf(stderr, "Error in mapping file: file indexes 0 and 1 are reserved.\n"); + ret = -1; + } + else if(currIndex <= lastIndex) + { + fprintf(stderr, "Syntax error in mapping file: file indexes must unique and in ascending order.\n"); + ret = -1; + } + else + { + lastIndex = currIndex; + } + } + + /* Read the host path to the file for the index number. + */ + if(ret == 0) + { + currChar = fgetc(pFile); + + if(currChar == EOF) + { + ret = -1; + } + } + + if(ret == 0) + { + char asScanFormat[14]; + + /* The host path may be surrounded with quotes, in which case the + string between the quotes is the host path, or it may not be + surrounded with quotes, in which case the host path terminates + with the next whitespace character. + */ + if(currChar == '"') + { + if(sprintf(asScanFormat, "%%%u[^\"]\"", WIN_FILENAME_MAX - 1) < 0) + { + ret = -1; + } + else if(fscanf(pFile, asScanFormat, currPath) != 1) + { + ret = -1; + } + } + else + { + /* No quotes, so the character is part of the path and needs to + be put back into the stream. + */ + currChar = ungetc(currChar, pFile); + if(currChar == EOF) + { + ret = -1; + } + else if(sprintf(asScanFormat, "%%%us", WIN_FILENAME_MAX - 1) < 0) + { + ret = -1; + } + else if(fscanf(pFile, asScanFormat, currPath) != 1) + { + ret = -1; + } + } + } + + /* Ensure the rest of the line is whitespace + */ + while(ret == 0 && currChar != '\n' && currChar != EOF) + { + currChar = fgetc(pFile); + if(!isspace(currChar) && currChar != EOF) + { + fprintf(stderr, "Syntax error in mapping file: unexpected token %c at char #%d.\n", currChar, ftell(pFile)); + ret = -1; + } + } + + /* If a relative path was specified, set it to be relative to the input + directory. + */ + if(ret == 0 && !PathIsAbsolute(currPath)) + { + if(pszIndirPath == NULL) + { + fprintf(stderr, "Error: paths in mapping file must be absolute if no input directory is specified.\n"); + ret = -1; + } + else + { + char asTemp[WIN_FILENAME_MAX]; + int len; + char *pszToAppend; + size_t indirLen = strlen(pszIndirPath); + + REDASSERT(indirLen != 0); + + strcpy(asTemp, currPath); + + /* Ensure a path separator comes between the input directory + and the specified relative path. + */ + if((pszIndirPath[indirLen - 1] == '/') || (pszIndirPath[indirLen - 1] == '\\')) + { + pszToAppend = ""; + } + else + { + pszToAppend = "\\"; + } + + len = _snprintf(currPath, WIN_FILENAME_MAX, "%s%s%s", pszIndirPath, pszToAppend, asTemp); + + if((len < 0) || (len >= WIN_FILENAME_MAX)) + { + fprintf(stderr, "Error: file path too long: %s%s%s", pszIndirPath, pszToAppend, asTemp); + ret = -1; + } + } + } + + /* Store index and host file path as a new entry in ppFileListHead + */ + if(ret == 0) + { + FILELISTENTRY *pNewEntry = malloc(sizeof(*pNewEntry)); + + if(!pNewEntry) + { + fprintf(stderr, "Error allocating memory.\n"); + ret = -1; + } + + strncpy(pNewEntry->fileMapping.asInFilePath, currPath, WIN_FILENAME_MAX); + pNewEntry->fileMapping.ulOutFileIndex = currIndex; + pNewEntry->pNext = NULL; + + /* If pCurrEntry is NULL, then pNewEntry will be the root entry. + Otherwise add it to the end of the linked list. + */ + if(pCurrEntry == NULL) + { + *ppFileListHead = pNewEntry; + } + else + { + pCurrEntry->pNext = pNewEntry; + } + pCurrEntry = pNewEntry; + } + + if(currChar == EOF) + { + break; + } + } + + if(pFile != NULL) + { + (void) fclose(pFile); + } + + if(ret == 0 && pCurrEntry == NULL) + { + fprintf(stderr, "Warning: empty or invalid mapping file specified.\n"); + } + else if(ret != 0) + { + fprintf(stderr, "Error reading specified mapping file.\n"); + + FreeFileList(ppFileListHead); + } + + return ret; +} + + +/** @brief Checks whether a Windows file path appears to be relative or + absolute. + + @param pszPath The file path to check. + + @return True if the @p pszPath appears to be an absolute path; false + otherwise. +*/ +bool PathIsAbsolute( + const char *pszPath) +{ + bool fIsAbsolute = false; + + /* Check whether pszPath begins with a drive letter. + */ + if( ( ((pszPath[0U] >= 'A') && (pszPath[0U] <= 'Z')) + || ((pszPath[0U] >= 'a') && (pszPath[0U] <= 'z'))) + && (pszPath[1U] == ':') + && ((pszPath[2U] == '\\') || (pszPath[2U] == '/'))) + { + fIsAbsolute = true; + } + + return fIsAbsolute; +} + + +/** @brief Reads the contents of the input directory, assignes a file index + to each file name, and fills a linked list structure with the + names and indexes. Does not inspect subdirectories. Prints any + error messages to stderr. + + @param pszDirPath The path to the input directory. + @param ppFileListHead a pointer to a FILELISTENTRY pointer to be + filled. A linked list is allocated onto this pointer if + successful, and thus should be freed after use by passing + it to FreeFileList. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int CreateFileListWin( + const char *pszDirPath, + FILELISTENTRY **ppFileListHead) +{ + int ret = 0; + char asSPath[WIN_FILENAME_MAX]; + int currFileIndex = 2; /* Indexes 0 and 1 are reserved */ + FILELISTENTRY *pCurrEntry = NULL; + HANDLE searchHandle = INVALID_HANDLE_VALUE; + size_t pathLen = strlen(pszDirPath); + WIN32_FIND_DATA sFindData; + const char *pszToAppend; + + *ppFileListHead = NULL; + REDASSERT(pszDirPath != NULL); + + /* Assign host path separator to pszToAppend if pszDirPath does not already + end with one. + */ + if((pszDirPath[pathLen - 1] == '/') || (pszDirPath[pathLen - 1] == '\\')) + { + pszToAppend = ""; + } + else + { + pszToAppend = "\\"; + } + + if(pathLen + strlen(pszToAppend) >= WIN_FILENAME_MAX) + { + fprintf(stderr, "Input directory path exceeds maximum supported length.\n"); + ret = -1; + } + + if(ret == 0) + { + int stat; + + stat = sprintf(asSPath, "%s%s*", pszDirPath, pszToAppend); + + /* Strings are aready tested; sprintf shouldn't fail. + */ + REDASSERT(stat >= 0); + (void) stat; + } + + if(ret == 0) + { + searchHandle = FindFirstFile(asSPath, &sFindData); + + if(searchHandle == INVALID_HANDLE_VALUE) + { + if(GetLastError() == ERROR_FILE_NOT_FOUND) + { + fprintf(stderr, "Specified input directory empty or not found.\n"); + } + else + { + fprintf(stderr, "Could not read input directory contents or empty input directory.\n"); + } + + ret = -1; + } + } + + /* Find each file in the directory and populate ppFileListHead + */ + while(ret == 0) + { + /* Skip over directories. Create a new entry for each file and add it + to ppFileListHead + */ + if(!(sFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + int len; + FILELISTENTRY *pNewEntry = malloc(sizeof(*pNewEntry)); + + if(pNewEntry == NULL) + { + fprintf(stderr, "Error allocating memory.\n"); + ret = -1; + } + else + { + len = _snprintf(pNewEntry->fileMapping.asInFilePath, WIN_FILENAME_MAX, "%s%s%s", + pszDirPath, pszToAppend, sFindData.cFileName); + + if((len < 0) || (len >= WIN_FILENAME_MAX)) + { + fprintf(stderr, "Error: file path too long: %s%s%s", pszDirPath, pszToAppend, sFindData.cFileName); + ret = -1; + } + else + { + pNewEntry->fileMapping.ulOutFileIndex = currFileIndex; + pNewEntry->pNext = NULL; + + /* If pCurrEntry is NULL, then pNewEntry will be the root entry. + Otherwise add it to the end of the linked list. + */ + if(pCurrEntry == NULL) + { + *ppFileListHead = pNewEntry; + } + else + { + pCurrEntry->pNext = pNewEntry; + } + pCurrEntry = pNewEntry; + + currFileIndex++; + } + } + } + + if(ret == 0) + { + if(!FindNextFile(searchHandle, &sFindData)) + { + if(GetLastError() != ERROR_NO_MORE_FILES) + { + fprintf(stderr, "Error traversing input directory.\n"); + ret = -1; + } + else + { + break; + } + } + } + } + + if(searchHandle != INVALID_HANDLE_VALUE) + { + (void) FindClose(searchHandle); + } + + if(ret != 0) + { + FreeFileList(ppFileListHead); + } + + return ret; +} + + +/** @brief Mounts the volume and copies files to it. +*/ +int IbFseCopyFiles( + int volNum, + const FILELISTENTRY *pFileList) +{ + REDSTATUS err; + int ret = 0; + const FILELISTENTRY *currEntry = pFileList; + bool mountfail = false; + + REDASSERT(pFileList != NULL); + + err = RedFseMount(volNum); + if(err != 0) + { + fprintf(stderr, "Error number %d mounting volume.\n", -err); + mountfail = true; + ret = -1; + } + else + { + /* Iterate over pFileList and copy files + */ + while((ret == 0) && (currEntry != NULL)) + { + ret = IbCopyFile(volNum, &currEntry->fileMapping); + currEntry = currEntry->pNext; + } + + if(ret == 0) + { + err = RedFseTransact(volNum); + if(err != 0) + { + fprintf(stderr, "Unexpected error number %d in RedFseTransact.\n", -err); + ret = -1; + } + } + + if(!mountfail) + { + err = RedFseUnmount(volNum); + if(err != 0) + { + fprintf(stderr, "Error number %d unmounting volume.\n", -err); + ret = -1; + } + } + } + + return ret; +} + + +int IbWriteFile( + int volNum, + const FILEMAPPING *pFileMapping, + uint64_t ullOffset, + void *pData, + uint32_t ulDataLen) +{ + int ret = 0; + int32_t wResult; + + /* Only print out a mesage for the first write to a file. + */ + if(ullOffset == 0U) + { + fprintf(stdout, "Copying file %s to index %d\n", pFileMapping->asInFilePath, pFileMapping->ulOutFileIndex); + } + + wResult = RedFseWrite(volNum, pFileMapping->ulOutFileIndex, ullOffset, ulDataLen, pData); + + if(wResult < 0) + { + ret = -1; + + switch(wResult) + { + case -RED_EFBIG: + fprintf(stderr, "Error: input file too big: %s\n", pFileMapping->asInFilePath); + break; + case -RED_EBADF: + fprintf(stderr, "Error: invalid file index %d\n", pFileMapping->ulOutFileIndex); + break; + case -RED_ENOSPC: + fprintf(stderr, "Error: insufficient space on target volume.\n"); + break; + case -RED_EIO: + fprintf(stderr, "Error writing to target volume.\n"); + break; + default: + /* Other errors not expected. + */ + REDERROR(); + break; + } + } + else if((uint32_t) wResult != ulDataLen) + { + ret = -1; + fprintf(stderr, "Error: insufficient space on target volume.\n"); + } + else + { + /* Desired number of bytes were written, so the operation was + successful and there's nothing else to do. + */ + } + + return ret; +} + + +/** @brief Outputs a list of C/C++ macros identifying the files in the given + file map and outputs them based on the given given imgbld options. + If the imgbld options provide a defines output file but there are + errors accessing it, then the user is alerted and the output is + written to stdout. + + @param pFileList The map of input files paths processed and their file + indexes + @param sOptions The struct of command line options. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int OutputDefinesFile( + FILELISTENTRY *pFileList, + const IMGBLDOPTIONS *sOptions) +{ + int ret = 0; + FILELISTENTRY *pCurrEntry = pFileList; + STRLISTENTRY *pStrList = NULL; + FILE *pFileOut = NULL; + bool fUseFile = (sOptions->pszDefineFile != NULL); + + /* When using a defines file, check if file exists and confirm overwrite + unless nowarn was specified + */ + if(fUseFile && !sOptions->fNowarn) + { + bool fExists; + + ret = CheckFileExists(sOptions->pszDefineFile, &fExists); + + if((ret == 0) && fExists) + { + fprintf(stderr, "Specified defines file %s already exists.\n", sOptions->pszDefineFile); + + fUseFile = ConfirmOperation("Overwrite?"); + } + } + + if((ret == 0) && fUseFile) + { + pFileOut = fopen(sOptions->pszDefineFile, "w"); + if(pFileOut == NULL) + { + ret = -1; + } + } + + /* In the case of error accessing defines file, warn user and revert to + console output. + */ + if(ret == -1) + { + fprintf(stderr, "Error accessing specified defines output file.\n"); + fprintf(stdout, "Error accessing specified defines output file.\nWriting defines to stdout.\n"); + + fUseFile = false; + ret = 0; + } + + if(!fUseFile) + { + pFileOut = stdout; + } + + /* Iterate over pFileList and output #DEFINE information. + */ + while(ret == 0 && pCurrEntry != NULL) + { + ret = WriteDefineOut(pFileOut, &pCurrEntry->fileMapping, &pStrList); + pCurrEntry = pCurrEntry->pNext; + } + + FreeStrList(&pStrList); + + if(pFileOut != NULL) + { + fclose(pFileOut); + } + + return ret; +} + + +/** @brief Creates a macro name for the given file and outputs it on the given + stream. + + @param pfileOut The open output stream to write to. + @param fmapEntry The file for which to create a macro + @param ppListNames A linked list of macro names already used. The name + generated by this function will be appended. + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +static int WriteDefineOut( + FILE *pfileOut, + const FILEMAPPING *pFileMapping, + STRLISTENTRY **ppListNames) +{ + int ret = 0; + int fromIndex = 0; + int toIndex = 5; /* Index of next char after "FILE_" */ + STRLISTENTRY *pCurrEntry = malloc(sizeof(*pCurrEntry)); + + REDASSERT(ppListNames != NULL); + REDASSERT(pFileMapping->asInFilePath != NULL); + + if(pCurrEntry == NULL) + { + fprintf(stderr, "Error allocating memory.\n"); + ret = -1; + } + + if(ret == 0) + { + pCurrEntry->pNext = NULL; + + (void) strcpy(pCurrEntry->asStr, "FILE_"); + + /* Copy host file path to current entry, replacing non-compatible + characters for preprocessor symbols with underscores. + */ + while((toIndex < MACRO_NAME_MAX_LEN) && (pFileMapping->asInFilePath[fromIndex] != '\0')) + { + char c = pFileMapping->asInFilePath[fromIndex]; + + if((c == '\\') || (c == '/')) + { + toIndex = 5; /* Reset output: only use the file name, not path */ + fromIndex++; + } + else + { + if(!isalnum(c) && (c != '_')) + { + c = '_'; + } + + pCurrEntry->asStr[toIndex] = c; + + fromIndex++; + toIndex++; + } + } + + pCurrEntry->asStr[toIndex] = '\0'; + } + + /* Ensure current entry is not a duplicate, appending a number (or + increment a number already appended) if an identical string entry is + found. + */ + while(ret == 0) + { + STRLISTENTRY *cmpEntry = *ppListNames; + + while(cmpEntry != NULL) + { + if(strncmp(cmpEntry->asStr, pCurrEntry->asStr, MACRO_NAME_MAX_LEN) == 0) + { + /* Duplicate name found. Append a 0 or increment the number + found at the end. + */ + uint32_t ulEndStr = strlen(pCurrEntry->asStr); + uint32_t ulBeginNum = ulEndStr; + + + + /* Don't allow pBeginNum closer than 6 from the beginning for + "FILE_" plus one character + */ + while((ulBeginNum > 6U) && isdigit(pCurrEntry->asStr[ulBeginNum - 1])) + { + ulBeginNum--; + } + + if(ulBeginNum == ulEndStr) + { + if(ulEndStr == MACRO_NAME_MAX_LEN) + { + pCurrEntry->asStr[ulEndStr - 1] = '\0'; + } + + strcat(pCurrEntry->asStr, "0"); + } + else + { + uint32_t num; + int stat = sscanf(&pCurrEntry->asStr[ulBeginNum], "%lu", &num); + + /* We just checked and found decimal digits. Scanf should + find them too. + */ + REDASSERT(stat == 1); + + num++; + if(((num % 10) == 0) && (ulEndStr == MACRO_NAME_MAX_LEN)) + { + /* Overwrite with the new digit--no space is left. + */ + ulBeginNum--; + } + + sprintf(&pCurrEntry->asStr[ulBeginNum], "%d", num); + } + + /* Break to outer loop; check again and see if the new name is + a duplicate. + */ + break; + } + + cmpEntry = cmpEntry->pNext; + } + + if(cmpEntry == NULL) + { + /* Final entry reached without finding a duplicate. + */ + break; + } + } + + fprintf(pfileOut, "#define %s %d\n", pCurrEntry->asStr, pFileMapping->ulOutFileIndex); + + if(*ppListNames == NULL) + { + *ppListNames = pCurrEntry; + } + else + { + GetLastEntry(*ppListNames)->pNext = pCurrEntry; + } + + return ret; +} + +#endif /* REDCONF_IMAGE_BUILDER == 1 && REDCONF_API_POSIX == 0 */ + diff --git a/os/win32/tools/imgbld/ibheader.h b/os/win32/tools/imgbld/ibheader.h new file mode 100644 index 0000000..4b25881 --- /dev/null +++ b/os/win32/tools/imgbld/ibheader.h @@ -0,0 +1,100 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#ifndef IBHEADER_H +#define IBHEADER_H + +#if REDCONF_IMAGE_BUILDER == 1 + +#define WIN_FILENAME_MAX MAX_PATH +#define MACRO_NAME_MAX_LEN 32 + +typedef struct +{ + uint8_t bVolNumber; + const char *pszInputDir; + const char *pszOutputFile; + #if REDCONF_API_POSIX == 1 + const char *pszVolName; + #else + const char *pszMapFile; + const char *pszDefineFile; + #endif + bool fNowarn; + bool fHelp; +} IMGBLDOPTIONS; + +typedef struct +{ + #if REDCONF_API_POSIX == 1 + char asOutFilePath[WIN_FILENAME_MAX]; + #else + uint32_t ulOutFileIndex; + #endif + char asInFilePath[WIN_FILENAME_MAX]; +} FILEMAPPING; + + +extern void *gpCopyBuffer; +extern uint32_t gulCopyBufferSize; + + +#if REDCONF_API_POSIX == 1 + +REDSTATUS IbPosixCopyDir(const char *pszVolName, const char *pszInDir); + +#else + +typedef struct sFILELISTENTRY FILELISTENTRY; +struct sFILELISTENTRY +{ + FILEMAPPING fileMapping; + FILELISTENTRY *pNext; +}; + + +void FreeFileList(FILELISTENTRY **ppsFileList); + +int GetFileList(const char *pszPath, const char *pszIndirPath, FILELISTENTRY **ppFileListHead); +bool PathIsAbsolute(const char *pszPath); +int CreateFileListWin(const char *pszDirPath, FILELISTENTRY **ppFileListHead); +int OutputDefinesFile(FILELISTENTRY *pFileList, const IMGBLDOPTIONS *pOptions); +int IbFseCopyFiles(int volNum, const FILELISTENTRY *pFileList); + +#endif /* Not POSIX */ + +int IbCopyFile(int volNum, const FILEMAPPING *pFileMapping); +int CheckFileExists(const char *pszPath, bool *pfExists); + +/* Implemented separately in ibfse.c and ibposix.c +*/ +int IbApiInit(void); +int IbApiUninit(void); +int IbWriteFile(int volNum, const FILEMAPPING *pFileMapping, uint64_t ullOffset, void *pData, uint32_t ulDataLen); + +#endif /* IMAGE_BUILDER */ + + +#endif /* IMGBLD_H */ + diff --git a/os/win32/tools/imgbld/ibposix.c b/os/win32/tools/imgbld/ibposix.c new file mode 100644 index 0000000..2c28d97 --- /dev/null +++ b/os/win32/tools/imgbld/ibposix.c @@ -0,0 +1,479 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements methods of the image builder tool specific to the POSIX + configuration. +*/ +#include + +#if REDCONF_IMAGE_BUILDER == 1 && REDCONF_API_POSIX == 1 + +#include +#include +#include + +#include + +#include "ibheader.h" + + +static int RecursiveDirCopyWin(const char *pszVolName, const char *pszInDir); +static int CreatePosixDir(const char *pszVolName, const char *pszFullPath, const char *pszBasePath); +static int ConvertPath(const char *pszVolName, const char *pszFullPath, const char *pszBasePath, char *szOutPath); + + +int IbApiInit(void) +{ + int ret = 0; + + if(red_init() != 0) + { + fprintf(stdout, "\n"); + fprintf(stderr, "Error number %d initializing file system.\n", red_errno); + ret = -1; + } + else + { + fprintf(stdout, "\n"); + } + + return ret; +} + + +int IbApiUninit(void) +{ + int ret = 0; + + if(red_uninit() != 0) + { + ret = -1; + fprintf(stderr, "Error number %d uninitializing file system.\n", red_errno); + } + + return ret; +} + + +/** @brief Writes file data to a file. This method may be called multiple times + to write consecutive chunks of file data. + + @param volNum Unused parameter; maintained for compatability with + FSE IbWriteFile. + @param psFileMapping The file being copied. File data will be written to + ::asOutFilePath. + @param ullOffset The position in the file to which to write data. + @param pData Data to write to the file. + @param ulDataLen The number of bytes in @p pData to write + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +int IbWriteFile( + int volNum, + const FILEMAPPING *psFileMapping, + uint64_t ullOffset, + void *pData, + uint32_t ulDataLen) +{ + int ret = 0; + int32_t fd; + + (void) volNum; + + /* Only print out a mesage for the first write to a file. + */ + if(ullOffset == 0U) + { + fprintf(stdout, "Copying file %s to %s\n", psFileMapping->asInFilePath, psFileMapping->asOutFilePath); + } + + fd = red_open(psFileMapping->asOutFilePath, RED_O_WRONLY|RED_O_CREAT|RED_O_APPEND); + if(fd == -1) + { + ret = -1; + } + else + { + int32_t pret; + + REDASSERT(ullOffset <= INT64_MAX); + if(red_lseek(fd, (int64_t) ullOffset, RED_SEEK_SET) == -1) + { + ret = -1; + } + else + { + pret = red_write(fd, pData, ulDataLen); + if(pret < 0) + { + ret = -1; + } + else if((uint32_t)pret < ulDataLen) + { + ret = -1; + } + } + + pret = red_close(fd); + if(pret == -1) + { + ret = -1; + } + } + + if(ret == -1) + { + switch(red_errno) + { + case RED_ENOSPC: + fprintf(stderr, "Error: insufficient space to copy file %s.\n", psFileMapping->asInFilePath); + break; + case RED_EIO: + fprintf(stderr, "Disk IO error copying file %s.\n", psFileMapping->asInFilePath); + break; + case RED_ENFILE: + fprintf(stderr, "Error: maximum number of files exceeded.\n"); + break; + case RED_ENAMETOOLONG: + fprintf(stderr, "Error: maximum file name length exceeded. Max length: %d.\n", REDCONF_NAME_MAX); + break; + case RED_EFBIG: + fprintf(stderr, "Error: maximum file size exceeded."); + break; + default: + /* Other error types not expected. + */ + REDERROR(); + break; + } + } + + return ret; +} + + +int IbPosixCopyDir( + const char *pszVolName, + const char *pszInDir) +{ + int32_t ret = 0; + bool mountfail = false; + + if(red_mount(pszVolName) != 0) + { + if(red_errno == RED_ENOENT) + { + fprintf(stderr, "Error mounting volume: invalid path prefix specified.\n"); + } + else + { + fprintf(stderr, "Error number %d mounting volume.\n", red_errno); + } + + mountfail = true; + ret = -1; + } + + if(ret == 0) + { + char asInputDir[WIN_FILENAME_MAX]; + size_t inDirLen = strlen(pszInDir); + + (void) strncpy(asInputDir, pszInDir, WIN_FILENAME_MAX - 1); + + /* Get rid of ending path separator, if there is one. + */ + if(asInputDir[inDirLen - 2] == '/' + #ifdef _WIN32 + || asInputDir[inDirLen - 2] == '\\' + #endif + ) + { + asInputDir[inDirLen - 2] = '\0'; + } + + ret = RecursiveDirCopyWin(pszVolName, asInputDir); + } + + if(ret == 0) + { + ret = red_transact(pszVolName); + if(ret != 0) + { + fprintf(stderr, "Unexpected error number %d in red_transact.\n", -ret); + ret = -1; + } + } + + if(!mountfail) + { + if(red_umount(pszVolName) == -1) + { + fprintf(stderr, "Error number %d unmounting volume.\n", red_errno); + ret = -1; + } + } + + return ret; +} + + +static int RecursiveDirCopyWin( + const char *pszVolName, + const char *pszInDir) +{ + /* Used to record pszVolName the first time called in a recursion series. + */ + static bool isRecursing = false; + static const char *pszBaseDir; + bool rememberIsRecursing = isRecursing; + int ret = 0; + char asCurrPath[WIN_FILENAME_MAX]; + HANDLE h; + WIN32_FIND_DATA sFindData; + int len; + + if(!isRecursing) + { + pszBaseDir = pszInDir; + isRecursing = true; + } + + len = _snprintf(asCurrPath, WIN_FILENAME_MAX, "%s\\*", pszInDir); + if((len < 0) || (len >= WIN_FILENAME_MAX)) + { + ret = -1; + } + + if(ret == 0) + { + h = FindFirstFile(asCurrPath, &sFindData); + if(h == INVALID_HANDLE_VALUE) + { + fprintf(stderr, "Error reading from input directory.\n"); + ret = -1; + } + } + + while(ret == 0) + { + BOOL fFindSuccess; + + if((strcmp(sFindData.cFileName, ".") != 0) && (strcmp(sFindData.cFileName, "..") != 0)) + { + len = _snprintf(asCurrPath, WIN_FILENAME_MAX, "%s\\%s", pszInDir, sFindData.cFileName); + + if((len == WIN_FILENAME_MAX) || (len < 0)) + { + ret = -RED_ENAMETOOLONG; + } + else if(sFindData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + /* Create the direcctory, then recurse! + */ + ret = CreatePosixDir(pszVolName, asCurrPath, pszBaseDir); + if(ret == 0) + { + ret = RecursiveDirCopyWin(pszVolName, asCurrPath); + } + } + else + { + FILEMAPPING mapping; + + strcpy(mapping.asInFilePath, asCurrPath); + ret = ConvertPath(pszVolName, asCurrPath, pszBaseDir, mapping.asOutFilePath); + if(ret == 0) + { + ret = IbCopyFile(-1, &mapping); + } + } + } + + fFindSuccess = FindNextFile(h, &sFindData); + if(!fFindSuccess) + { + DWORD err = GetLastError(); + + if(err == ERROR_NO_MORE_FILES) + { + break; + } + else + { + fprintf(stderr, "Error traversing input directory %s. Error code: %d\n", pszInDir, err); + ret = -1; + } + } + } + + if(h != INVALID_HANDLE_VALUE) + { + (void) FindClose(h); + } + + if(ret == -RED_ENAMETOOLONG) + { + fprintf(stderr, "Error: file path too long in %s.\n", pszVolName); + } + + isRecursing = rememberIsRecursing; + + return ret; +} + + +/** @brief Creates a directory using the Reliance Edge POSIX API. + + @param pszVolName + @param pszFullPath + @param pszBasePath + + @return A negated ::REDSTATUS code indicating the operation result. +*/ +static int CreatePosixDir( + const char *pszVolName, + const char *pszFullPath, + const char *pszBasePath) +{ + int ret = 0; + char asOutPath[WIN_FILENAME_MAX]; + + ret = ConvertPath(pszVolName, pszFullPath, pszBasePath, asOutPath); + + if(ret == 0) + { + if(red_mkdir(asOutPath) != 0) + { + ret = -1; + + switch(red_errno) + { + case RED_EIO: + fprintf(stderr, "Disk I/O creating directory %s.\n", asOutPath); + break; + case RED_ENOSPC: + fprintf(stderr, "Insufficient space on target volume.\n"); + break; + case RED_ENFILE: + fprintf(stderr, "Error: maximum number of files for volume %s exceeded.\n", pszVolName); + break; + case RED_ENAMETOOLONG: + /* Message for RED_ENAMETOOLONG printed in RecursiveDirCopyWin. + */ + break; + default: + /* Other errors not expected. + */ + REDERROR(); + break; + } + } + } + + return ret; +} + + +/** @brief Takes a host system file path and converts it to a compatible path + for the Reliance Edge POSIX API + + @param pszVolName The Reliance Edge volume name + @param pszFullPath The full host file path + @param pszBasePath A base path which will be removed from the back of + @p pszFullPath + @param szOutPath A char array pointer allocated at least WIN_FILENAME_MAX + chars at which to store the converted path + + @return An integer indicating the operation result. + + @retval 0 Operation was successful. + @retval -1 An error occurred. +*/ +static int ConvertPath( + const char *pszVolName, + const char *pszFullPath, + const char *pszBasePath, + char *szOutPath) +{ + int ret = 0; + const char *pszInPath = pszFullPath; + size_t volNameLen = strlen(pszVolName); + size_t index = 0; + + while((pszInPath[0] == pszBasePath[index]) && (pszInPath[0] != '\0')) + { + pszInPath++; + index++; + } + + /* After skipping the base path, the next char should be a path separator. + Skip this too. + */ + if((pszInPath[0] == '/') || (pszInPath[0] == '\\')) + { + pszInPath++; + } + + if((strlen(pszInPath) + 1 + strlen(pszVolName)) >= (WIN_FILENAME_MAX - 1)) + { + fprintf(stderr, "Error: path name too long: %s\n", pszFullPath); + ret = -1; + } + else + { + int len; + + len = sprintf(szOutPath, "%s%c%s", pszVolName, REDCONF_PATH_SEPARATOR, pszInPath); + + REDASSERT(len >= (int) volNameLen); + + for(index = volNameLen + 1; szOutPath[index] != '\0'; index++) + { + if( (szOutPath[index] == '/') + #ifdef _WIN32 + || (szOutPath[index] == '\\') + #endif + ) + { + szOutPath[index] = REDCONF_PATH_SEPARATOR; + } + else if (szOutPath[index] == REDCONF_PATH_SEPARATOR) + { + fprintf(stderr, "Error: unexpected target path separator character in path %s\n", pszInPath); + ret = -1; + break; + } + } + } + + return ret; +} + +#endif + diff --git a/os/win32/tools/imgbld/imgbld.c b/os/win32/tools/imgbld/imgbld.c new file mode 100644 index 0000000..06cad04 --- /dev/null +++ b/os/win32/tools/imgbld/imgbld.c @@ -0,0 +1,512 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a Win32 command-line image builder tool +*/ +#include + +#if REDCONF_IMAGE_BUILDER == 1 + +#include + +#include +#include +#include + +#include "../wintlcmn.h" +#include "ibheader.h" + + +static int TryParsePrgmArgs(int argc, const char **argv, IMGBLDOPTIONS *pOptions); +static void Usage(bool fError); +static bool PathNamesVolume(const char *pszPath); + +static const char *pszPrgmName; + +#define COPY_BUFFER_SIZE_MIN (1024U) +#define COPY_BUFFER_SIZE_MAX (32UL * 1024 * 1024) + +void *gpCopyBuffer = NULL; +uint32_t gulCopyBufferSize; + + +/** @brief Entry point for the Reliance Edge image builder utility. + + @param argc The size of the @p argv array. + @param argv The arguments to the program. + + @return Zero on success, nonzero on failure. +*/ +int main( + int argc, + char *argv[]) +{ + IMGBLDOPTIONS options; + int ret = 0; + + pszPrgmName = argv[0]; + + /* Prints sign-on message + */ + ret = IbApiInit(); + + if(ret == 0) + { + ret = TryParsePrgmArgs(argc, argv, &options); + if(ret != 0) + { + Usage(!options.fHelp); + } + } + + if((ret == 0) && !options.fHelp) + { + #if REDCONF_API_POSIX == 0 + FILELISTENTRY *psFileListHead = NULL; + #endif + + /* Keep track of whether the target device has been formatted. If an + operation fails before the device is formatted, then the image file + does not need to be deleted. + */ + bool fFormatted = false; + + if(!options.fNowarn) + { + bool fWarn = true; + + if(PathNamesVolume(options.pszOutputFile)) + { + fprintf(stderr, "Are you sure you want to format the volume %s?", options.pszOutputFile); + } + else + { + ret = CheckFileExists(options.pszOutputFile, &fWarn); + + if(ret != 0) + { + fWarn = false; + fprintf(stderr, "Error accessing output device %s\n", options.pszOutputFile); + } + + if(fWarn) + { + fprintf(stderr, "Output image file %s exists.\nOverwrite?", options.pszOutputFile); + } + } + + if(fWarn && !ConfirmOperation("")) + { + fprintf(stderr, "Image build operation cancelled.\n"); + ret = -1; + } + } + + #if REDCONF_API_POSIX == 0 + if(ret == 0) + { + if(options.pszMapFile != NULL) + { + ret = GetFileList(options.pszMapFile, options.pszInputDir, &psFileListHead); + } + else + { + ret = CreateFileListWin(options.pszInputDir, &psFileListHead); + } + } + #endif + + if(ret == 0) + { + REDSTATUS err = RedOsBDevConfig(options.bVolNumber, options.pszOutputFile); + + if(err != 0) + { + ret = -1; + if(err == -RED_EINVAL) + { + fprintf(stderr, "Invalid volume number or empty output file name.\n"); + } + else + { + REDERROR(); + } + } + } + + if(ret == 0) + { + if(RedCoreVolSetCurrent(options.bVolNumber) != 0) + { + REDERROR(); + ret = -1; + } + } + + if(ret == 0) + { + REDSTATUS formaterr = RedCoreVolFormat(); + + fFormatted = true; + + if(formaterr != 0) + { + ret = -1; + fprintf(stderr, "Error number %d formatting volume.\n", -formaterr); + } + } + + if(ret == 0) + { + gulCopyBufferSize = COPY_BUFFER_SIZE_MAX; + + while((ret == 0) && (gpCopyBuffer == NULL)) + { + gpCopyBuffer = malloc(gulCopyBufferSize); + + if(gpCopyBuffer == NULL) + { + /* Reloop and try allocating a smaller portion unless we're + already down to the minimum allowed size. + */ + if(gulCopyBufferSize <= COPY_BUFFER_SIZE_MIN) + { + ret = -1; + fprintf(stderr, "Error: out of memory.\n"); + break; + } + + gulCopyBufferSize /= 2; + } + } + } + + #if REDCONF_API_POSIX == 1 + if(ret == 0) + { + ret = IbPosixCopyDir(options.pszVolName, options.pszInputDir); + } + #else + + if(ret == 0) + { + ret = IbFseCopyFiles(options.bVolNumber, psFileListHead); + } + + if((ret == 0) && (options.pszDefineFile != NULL)) + { + ret = OutputDefinesFile(psFileListHead, &options); + } + + FreeFileList(&psFileListHead); + #endif + + if(gpCopyBuffer != NULL) + { + free(gpCopyBuffer); + } + + if(IbApiUninit() != 0) + { + ret = -1; + } + + if(ret == 0) + { + fprintf(stdout, "Successfully created Reliance Edge image at %s.\n", options.pszOutputFile); + } + else + { + fprintf(stdout, "Error creating Reliance Edge image.\n"); + + if(fFormatted && !PathNamesVolume(options.pszOutputFile)) + { + fprintf(stderr, "Removing image file %s\n", options.pszOutputFile); + if(remove(options.pszOutputFile) != 0) + { + fprintf(stderr, "Error removing image file.\n"); + } + } + } + } + + return -ret; +} + + +/** @brief Helper function to parse command line arguments + + @param pOptions IMGBLDOPTIONS structure to fill + + @return Returns false if the command line arguments are malformatted or + otherwise insufficient; including in the case where the user + requests help. Returns true otherwise. +*/ +int TryParsePrgmArgs( + int argc, + const char **argv, + IMGBLDOPTIONS *pOptions) +{ + const static int ret_help = 1; + + int ret = 0; + int argIndex = 1; + + pOptions->pszInputDir = NULL; + pOptions->pszOutputFile = NULL; + pOptions->fHelp = false; + pOptions->fNowarn = false; + #if REDCONF_API_POSIX == 1 + pOptions->pszVolName = NULL; + #else + pOptions->pszDefineFile = NULL; + pOptions->pszMapFile = NULL; + #endif + + if(argc <= argIndex) + { + ret = -1; + } + + if(ret == 0) + { + pOptions->fHelp = IsHelpRequest(argv[argIndex]); + if(pOptions->fHelp) + { + /* Tested for at the end of this function + */ + ret = ret_help; + } + } + + if(ret == 0) + { + pOptions->bVolNumber = FindVolumeNumber(argv[argIndex]); + #if REDCONF_API_POSIX == 1 + pOptions->pszVolName = argv[argIndex]; + #endif + + if(pOptions->bVolNumber == REDCONF_VOLUME_COUNT) + { + #if REDCONF_API_POSIX == 1 + fprintf(stderr, "Error: \"%s\" is not a valid path prefix or volume number.\n", argv[argIndex]); + #else + fprintf(stderr, "Error: \"%s\" is not a valid volume number.\n", argv[argIndex]); + #endif + ret = -1; + } + } + + argIndex++; + + /* Test each param against valid param names and read values passed in. + */ + while((ret == 0) && (argIndex < argc)) + { + if(_stricmp(argv[argIndex], "/dir") == 0) + { + if(argIndex + 1 >= argc) + { + ret = -1; + break; + } + + pOptions->pszInputDir = argv[argIndex + 1]; + + argIndex += 2; + } + #if REDCONF_API_POSIX == 0 + else if(_stricmp(argv[argIndex], "/map") == 0) + { + if(argIndex + 1 >= argc) + { + ret = -1; + break; + } + + pOptions->pszMapFile = argv[argIndex + 1]; + + argIndex += 2; + } + else if(_stricmp(argv[argIndex], "/defines") == 0) + { + if(argIndex + 1 >= argc) + { + ret = -1; + break; + } + + pOptions->pszDefineFile = argv[argIndex + 1]; + + argIndex += 2; + } + #endif + else if(_stricmp(argv[argIndex], "/dev") == 0) + { + if(argIndex + 1 >= argc) + { + ret = -1; + break; + } + else if(pOptions->pszOutputFile != NULL) + { + fprintf(stderr, "Only one device may be specified.\n"); + ret = -1; + break; + } + + pOptions->pszOutputFile = MassageDriveName(argv[argIndex + 1]); + + argIndex += 2; + } + else if(_stricmp(argv[argIndex], "/nowarn") == 0) + { + pOptions->fNowarn = true; + + argIndex++; + } + else + { + fprintf(stderr, "Unrecognized argument.\n"); + ret = -1; + } + } + + #if REDCONF_API_POSIX == 1 + if((ret == 0) && (pOptions->pszInputDir == NULL)) + { + fprintf(stderr, "Input directory must be specified.\n"); + ret = -1; + } + + #else + + if((ret == 0) && (pOptions->pszInputDir == NULL) && (pOptions->pszMapFile == NULL)) + { + fprintf(stderr, "Either input directory or input file map must be specified.\n"); + ret = -1; + } + + #endif + + if((ret == 0) && (pOptions->pszOutputFile == NULL)) + { + fprintf(stderr, "Output device must be specified.\n"); + ret = -1; + } + + if(ret == ret_help) + { + ret = 0; + } + + return ret; +} + + +/** @brief Print usage information and exit. + + @param fError Whether this function is being invoked due to an error +*/ +void Usage( + bool fError) +{ + FILE *fout = (fError ? stderr : stdout); + + #if REDCONF_API_POSIX == 1 + fprintf(fout, +"usage: %s /dev /dir [/nowarn]\n" +"Build a Reliance Edge volume image which includes the given set of input files.\n" +"\n" +"Arguments:\n" +" A volume path prefix (e.g., VOL1: or /data) of the volume to\n" +" build.\n" +"/dev The block device underlying the volume to which to write the\n" +" image. This can be:\n" +" 1) The path and name of a file disk (e.g., red.bin);\n" +" 2) A drive letter (e.g., G:); or\n" +" 3) A Win32 device name (e.g., \\\\.\\PhysicalDrive7). This\n" +" might be better than using a drive letter, since the latter\n" +" may format a partition instead of the entire physical media.\n" +"/dir A path to a directory that contains all of the files to be\n" +" copied into the image.\n" +"/nowarn Prevents confirmation messages from blocking the interface\n" +" when overwriting files or formatting a drive.\n", pszPrgmName); + #else + fprintf(fout, + "usage: %s /dev [/dir ] [/map ] [/defines ] [/nowarn]\n" +"Build a Reliance Edge volume image which includes the given set of input files.\n" +"\n" +"Arguments:\n" +" A volume number (e.g., 2) of the volume to build.\n" +"/dev The block device underlying the volume to which to write the\n" +" image. This can be:\n" +" 1) The path and name of a file disk (e.g., red.bin);\n" +" 2) A drive letter (e.g., G:); or\n" +" 3) A Win32 device name (e.g., \\\\.\\PhysicalDrive7).\n" +" This might be better than using a drive letter, since\n" +" the latter may format a partition instead of the entire\n" +" physical media.\n" +"/dir A path to a directory that contains all of the files to be\n" +" copied into the image. If not specified, the file at\n" +" must contain full absolute file paths for all\n" +" input files.\n" +"/map Path to the file which maps file names (or paths) in\n" +" to file indices in the outputted image.\n" +"/defines Path to the file to which to store a set of #define\n" +" statements for accessing files by assigned index if\n" +" mappath is not specified.\n" +"/nowarn Prevents confirmation messages from blocking the interface\n" +" when overwriting files or formatting a drive.\n", pszPrgmName); + #endif +} + +/* Checks whether the given path appears to name a volume or not. Expects the + path to be in massaged "//./diskname" format if it names a volume. +*/ +static bool PathNamesVolume( + const char *pszPath) +{ + return ((pszPath[0] == '\\') + && (pszPath[1] == '\\') + && (pszPath[2] == '.') + && (pszPath[3] == '\\') + && (strchr(&pszPath[4], '\\') == NULL) + && (strchr(&pszPath[4], '/') == NULL)); +} + +#else + +/** @brief Stubbed entry point for the Reliance Edge image builder. + + @return Returns 1 +*/ +int main(void) +{ + fprintf(stderr, "Reliance Edge image builder tool disabled\n"); + return 1; +} + +#endif diff --git a/os/win32/tools/winfmt.c b/os/win32/tools/winfmt.c new file mode 100644 index 0000000..2dbf131 --- /dev/null +++ b/os/win32/tools/winfmt.c @@ -0,0 +1,178 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a Win32 command-line front-end for the Reliance Edge file + system formatter. +*/ +#include +#include + +#include + +#if (REDCONF_READ_ONLY == 0) && (((REDCONF_API_POSIX == 1) && (REDCONF_API_POSIX_FORMAT == 1)) || (REDCONF_IMAGE_BUILDER == 1)) + +#include +#include "wintlcmn.h" + + +static void Usage(bool fError); + + +static const char *gpszFormatterName; + + +/** @brief Entry point for the Reliance Edge file system formatter. + + @param argc The size of the @p argv array. + @param argv The arguments to the program. + + @return Zero on success, nonzero on failure. +*/ +int main( + int argc, + char *argv[]) +{ + gpszFormatterName = argv[0U]; + + printf("Reliance Edge File System Formatter\n"); + + if((argc > 1) && IsHelpRequest(argv[1U])) + { + Usage(false); + } + else if(argc != 4) + { + Usage(true); + } + else + { + const char *pszDrive; + uint8_t bVolNum; + REDSTATUS ret; + + /* Initialize early on since this also prints the signon message. + */ + ret = RedCoreInit(); + if(ret != 0) + { + fprintf(stderr, "Unexpected error %d from RedCoreInit()\n", (int)ret); + exit(ret); + } + + bVolNum = FindVolumeNumber(argv[1U]); + if(bVolNum == REDCONF_VOLUME_COUNT) + { + #if REDCONF_API_POSIX == 1 + fprintf(stderr, "Error: \"%s\" is not a valid volume number or path prefix.\n", argv[1U]); + #else + fprintf(stderr, "Error: \"%s\" is not a valid volume number.\n", argv[1U]); + #endif + Usage(true); + } + + if(_stricmp(argv[2U], "/dev") != 0) + { + fprintf(stderr, "Error: unexpected argument \"%s\"\n", argv[2U]); + Usage(true); + } + + pszDrive = MassageDriveName(argv[3U]); + ret = RedOsBDevConfig(bVolNum, pszDrive); + if(ret != 0) + { + fprintf(stderr, "Unexpected error %d from RedOsBDevConfig()\n", (int)ret); + exit(ret); + } + + #if REDCONF_VOLUME_COUNT > 1U + ret = RedCoreVolSetCurrent(bVolNum); + if(ret != 0) + { + fprintf(stderr, "Unexpected error %d from RedCoreVolSetCurrent()\n", (int)ret); + exit(ret); + } + #endif + + ret = RedCoreVolFormat(); + if(ret == 0) + { + printf("Format successful.\n"); + } + else + { + printf("Format failed with error %d!\n", (int)ret); + exit(ret); + } + } + + return 0; +} + + +/** @brief Print usage information and exit. + + @param fError Whether this function is being invoked due to an invocation + error. +*/ +static void Usage( + bool fError) +{ + static const char szUsage[] = +"usage: %s /dev \n" +"Format a Reliance Edge file system volume.\n" +"\n" +"Arguments:\n" +#if REDCONF_API_POSIX == 1 +" A volume number (e.g., 2) or a volume path prefix (e.g., VOL1:\n" +" or /data) of the volume to check.\n" +#else +" A volume number (e.g., 2) of the volume to check.\n" +#endif +"/dev The block device underlying the volume. This can be:\n" +" 1) The path and name of a file disk (e.g., red.bin);\n" +" 2) A drive letter (e.g., G:); or\n" +" 3) A Win32 device name (e.g., \\\\.\\PhysicalDrive7). This\n" +" might be better than using a drive letter, since the latter\n" +" may format a partition instead of the entire physical media.\n"; + + if(fError) + { + fprintf(stderr, szUsage, gpszFormatterName); + exit(1); + } + else + { + fprintf(stdout, szUsage, gpszFormatterName); + exit(0); + } +} + +#else + +#error "Misconfigured host redconf.h file: the formatter should be enabled!" + +#endif + + diff --git a/os/win32/tools/wintlcmn.c b/os/win32/tools/wintlcmn.c new file mode 100644 index 0000000..2f8c3d4 --- /dev/null +++ b/os/win32/tools/wintlcmn.c @@ -0,0 +1,209 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements certain shared methods for win32 command line tools. +*/ +#include +#include +#include + +#include +#include +#include + +#include "wintlcmn.h" + + +/** @brief Convert a string into a volume number. + + In a POSIX-like configuration, @p pszVolume can either be a volume number or + a volume path prefix. In case of ambiguity, the volume number of a matching + path prefix takes precedence. + + In an FSE configuration, @p pszVolume can be a volume number. + + @param pszVolume The volume string. + + @return On success, returns the volume number; on failure, returns + #REDCONF_VOLUME_COUNT. +*/ +uint8_t FindVolumeNumber( + const char *pszVolume) +{ + unsigned long ulNumber; + const char *pszEndPtr; + uint8_t bVolNum = REDCONF_VOLUME_COUNT; + #if REDCONF_API_POSIX == 1 + uint8_t bIndex; + #endif + + /* Determine if pszVolume can be interpreted as a volume number. + */ + errno = 0; + ulNumber = strtoul(pszVolume, (char **)&pszEndPtr, 10); + if((errno == 0) && (ulNumber != ULONG_MAX) && (pszEndPtr[0U] == '\0') && (ulNumber < REDCONF_VOLUME_COUNT)) + { + bVolNum = (uint8_t)ulNumber; + } + + #if REDCONF_API_POSIX == 1 + /* Determine if pszVolume is a valid path prefix. + */ + for(bIndex = 0U; bIndex < REDCONF_VOLUME_COUNT; bIndex++) + { + if(strcmp(gaRedVolConf[bIndex].pszPathPrefix, pszVolume) == 0) + { + break; + } + } + + if(bIndex < REDCONF_VOLUME_COUNT) + { + /* Edge case: It is technically possible for pszVolume to be both a + valid volume number and a valid volume prefix, for different + volumes. For example, if pszVolume is "2", that would be recognized + as volume number 2 above. But if "2" is the (poorly chosen) path + prefix for volume number 4, that would also be matched. Since the + POSIX-like API is primarily name based, and the ability to use + volume numbers with this tool is just a convenience, the volume + prefix takes precedence. + */ + bVolNum = bIndex; + + printf("Info: Volume prefix \"%s\" matched with volume number %u\n", pszVolume, (unsigned)bVolNum); + } + #endif + + return bVolNum; +} + + +/** @brief Massage a drive name into a standardized format. + + @return pszDrive The drive name to massage. + + @return Pointer to the massaged drive name. +*/ +const char *MassageDriveName( + const char *pszDrive) +{ + const char *pszRet; + + /* If it looks like a drive letter followed by nothing else... + */ + if( ( ((pszDrive[0U] >= 'A') && (pszDrive[0U] <= 'Z')) + || ((pszDrive[0U] >= 'a') && (pszDrive[0U] <= 'z'))) + && (pszDrive[1U] == ':') + && ( (pszDrive[2U] == '\0') + || ((pszDrive[2U] == '\\') && (pszDrive[3U] == '\0')))) + { + static char szBuffer[8U]; /* Big enough for "\\.\X:" */ + + /* Drives of the form "X:" or "X:\" are converted to "\\.\X:". + */ + (void)strcpy(szBuffer, "\\\\.\\?:"); + szBuffer[4U] = pszDrive[0U]; + + pszRet = szBuffer; + } + else + { + pszRet = pszDrive; + } + + return pszRet; +} + + +/** @brief Determine if the argument is a help request. + + @param pszArgument The argument to examine. + + @return Whether the argument is a help request. +*/ +bool IsHelpRequest( + const char *pszArgument) +{ + bool fIsHelpRequest; + + if( (strcmp(pszArgument, "?") == 0) + || (strcmp(pszArgument, "/?") == 0) + || (strcmp(pszArgument, "-?") == 0) + || (_stricmp(pszArgument, "/h") == 0) + || (_stricmp(pszArgument, "-h") == 0) + || (_stricmp(pszArgument, "--help") == 0)) + { + fIsHelpRequest = true; + } + else + { + fIsHelpRequest = false; + } + + return fIsHelpRequest; +} + + +/** @brief Prompt the user to confirm an operation by typing in y or n. + + @param pszMessage The message to show the user to prompt for input. The + string " [y/n] " is appended to the same line. + + @return Whether the user typed a y to confirm the operation. +*/ +bool ConfirmOperation( + const char *pszMessage) +{ + int iAnswer; + int iChar; + + fprintf(stderr, "%s [y/n] ", pszMessage); + fflush(stderr); + + while(true) + { + iAnswer = getchar(); + + /* Burn through the rest of the answer. If the user typed + "Affirmative", we don't want to complain twelve times. + */ + iChar = iAnswer; + while(iChar != '\n') + { + iChar = getchar(); + } + + if((iAnswer == 'y') || (iAnswer == 'Y') || (iAnswer == 'n') || (iAnswer == 'N')) + { + break; + } + + fprintf(stderr, "Answer 'y' or 'n': "); + fflush(stderr); + } + + return ((iAnswer == 'y') || (iAnswer == 'Y')); +} + diff --git a/os/win32/tools/wintlcmn.h b/os/win32/tools/wintlcmn.h new file mode 100644 index 0000000..2fe1438 --- /dev/null +++ b/os/win32/tools/wintlcmn.h @@ -0,0 +1,36 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef WINTLCMN_H +#define WINTLCMN_H + + +uint8_t FindVolumeNumber(const char *pszVolume); +bool IsHelpRequest(const char *pszArgument); +const char *MassageDriveName(const char *pszDrive); +bool ConfirmOperation(const char *pszMessage); + +#endif diff --git a/posix/path.c b/posix/path.c new file mode 100644 index 0000000..a8a64b3 --- /dev/null +++ b/posix/path.c @@ -0,0 +1,383 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements path utilities for the POSIX-like API layer. +*/ +#include + +#if REDCONF_API_POSIX == 1 + +#include +#include +#include +#include "redposixutil.h" + + +static bool IsRootDir(const char *pszPath); + + +/** @brief Split a path into its component parts: a volume and a volume-local + path. + + @param pszPath The path to split. + @param pbVolNum On successful return, if non-NULL, populated with + the volume number extracted from the path. + @param ppszLocalPath On successful return, populated with the + volume-local path: the path stripped of any volume + path prefixing. If this parameter is NULL, that + indicates there should be no local path, and any + characters beyond the prefix (other than path + separators) are treated as an error. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pszPath is `NULL`. + @retval -RED_ENOENT @p pszPath could not be matched to any volume. +*/ +REDSTATUS RedPathSplit( + const char *pszPath, + uint8_t *pbVolNum, + const char **ppszLocalPath) +{ + REDSTATUS ret = 0; + + if(pszPath == NULL) + { + ret = -RED_EINVAL; + } + else + { + const char *pszLocalPath = pszPath; + uint32_t ulPathLen = RedStrLen(pszPath); + uint8_t bMatchVol = UINT8_MAX; + uint32_t ulMatchLen = 0U; + uint8_t bDefaultVolNum = UINT8_MAX; + uint8_t bVolNum; + + for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) + { + const char *pszPrefix = gaRedVolConf[bVolNum].pszPathPrefix; + uint32_t ulPrefixLen = RedStrLen(pszPrefix); + + if(ulPrefixLen == 0U) + { + /* A volume with a path prefix of an empty string is the + default volume, used when the path does not match the + prefix of any other volume. + + The default volume should only be found once. During + initialization, RedCoreInit() ensures that all volume + prefixes are unique (including empty prefixes). + */ + REDASSERT(bDefaultVolNum == UINT8_MAX); + bDefaultVolNum = bVolNum; + } + /* For a path to match, it must either be the prefix exactly, or + be followed by a path separator character. Thus, with a volume + prefix of "/foo", both "/foo" and "/foo/bar" are matches, but + "/foobar" is not. + */ + else if( (ulPrefixLen <= ulPathLen) + && ((pszPath[ulPrefixLen] == '\0') || (pszPath[ulPrefixLen] == REDCONF_PATH_SEPARATOR)) + && (RedStrNCmp(pszPath, pszPrefix, ulPrefixLen) == 0)) + { + /* The length of this match should never exactly equal the + length of a previous match: that would require a duplicate + volume name, which should have been detected during init. + */ + REDASSERT(ulPrefixLen != ulMatchLen); + + /* If multiple prefixes match, the longest takes precedence. + Thus, if there are two prefixes "Flash" and "Flash/Backup", + the path "Flash/Backup/" will not be erroneously matched + with the "Flash" volume. + */ + if(ulPrefixLen > ulMatchLen) + { + bMatchVol = bVolNum; + ulMatchLen = ulPrefixLen; + } + } + else + { + /* No match, keep looking. + */ + } + } + + if(bMatchVol != UINT8_MAX) + { + /* The path matched a volume path prefix. + */ + bVolNum = bMatchVol; + pszLocalPath = &pszPath[ulMatchLen]; + } + else if(bDefaultVolNum != UINT8_MAX) + { + /* The path didn't match any of the prefixes, but one of the + volumes has a path prefix of "", so an unprefixed path is + assigned to that volume. + + + */ + bVolNum = bDefaultVolNum; + REDASSERT(pszLocalPath == pszPath); + } + else + { + /* The path cannot be assigned a volume. + */ + ret = -RED_ENOENT; + } + + if(ret == 0) + { + if(pbVolNum != NULL) + { + *pbVolNum = bVolNum; + } + + if(ppszLocalPath != NULL) + { + *ppszLocalPath = pszLocalPath; + } + else + { + /* If no local path is expected, then the string should either + terminate after the path prefix or the local path should name + the root directory. Allowing path separators here means that + red_mount("/data/") is OK with a path prefix of "/data". + */ + if((pszLocalPath[0U] != '\0') && !IsRootDir(pszLocalPath)) + { + ret = -RED_ENOENT; + } + } + } + } + + return ret; +} + + +/** @brief Lookup the inode named by the given path. + + @param pszPath The path to lookup; this is a local path, without any volume + prefix. + @param pulInode On successful return, populated with the number of the inode + named by pszPath. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulInode is + `NULL`. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT @p pszLocalPath is an empty string; or + @p pszLocalPath does not name an existing file + or directory. + @retval -RED_ENOTDIR A component of the path other than the last is + not a directory. + @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is + longer than #REDCONF_NAME_MAX. +*/ +REDSTATUS RedPathLookup( + const char *pszLocalPath, + uint32_t *pulInode) +{ + REDSTATUS ret; + + if((pszLocalPath == NULL) || (pulInode == NULL)) + { + ret = -RED_EINVAL; + } + else if(pszLocalPath[0U] == '\0') + { + ret = -RED_ENOENT; + } + else if(IsRootDir(pszLocalPath)) + { + ret = 0; + *pulInode = INODE_ROOTDIR; + } + else + { + uint32_t ulPInode; + const char *pszName; + + ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); + + if(ret == 0) + { + ret = RedCoreLookup(ulPInode, pszName, pulInode); + } + } + + return ret; +} + + +/** @brief Given a path, return the parent inode number and a pointer to the + last component in the path (the name). + + @param pszLocalPath The path to examine; this is a local path, without any + volume prefix. + @param pulPInode On successful return, populated with the inode number of + the parent directory of the last component in the path. + For example, with the path "a/b/c", populated with the + inode number of "b". + @param ppszName On successful return, populated with a pointer to the + last component in the path. For example, with the path + "a/b/c", populated with a pointer to "c". + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p pszLocalPath is `NULL`; or @p pulPInode is + `NULL`; or @p ppszName is `NULL`; or the path + names the root directory. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENOENT @p pszLocalPath is an empty string; or a + component of the path other than the last does + not exist. + @retval -RED_ENOTDIR A component of the path other than the last is + not a directory. + @retval -RED_ENAMETOOLONG The length of a component of @p pszLocalPath is + longer than #REDCONF_NAME_MAX. +*/ +REDSTATUS RedPathToName( + const char *pszLocalPath, + uint32_t *pulPInode, + const char **ppszName) +{ + REDSTATUS ret; + + if((pszLocalPath == NULL) || (pulPInode == NULL) || (ppszName == NULL) || IsRootDir(pszLocalPath)) + { + ret = -RED_EINVAL; + } + else if(pszLocalPath[0U] == '\0') + { + ret = -RED_ENOENT; + } + else + { + uint32_t ulInode = INODE_ROOTDIR; + uint32_t ulPInode = INODE_INVALID; + uint32_t ulPathIdx = 0U; + uint32_t ulLastNameIdx = 0U; + + ret = 0; + + do + { + uint32_t ulNameLen; + + /* Skip over path separators, to get pszLocalPath[ulPathIdx] + pointing at the next name. + */ + while(pszLocalPath[ulPathIdx] == REDCONF_PATH_SEPARATOR) + { + ulPathIdx++; + } + + if(pszLocalPath[ulPathIdx] == '\0') + { + break; + } + + /* Point ulLastNameIdx at the first character of the name; after + we exit the loop, it will point at the first character of the + last name in the path. + */ + ulLastNameIdx = ulPathIdx; + + /* Point ulPInode at the parent inode: either the root inode + (first pass) or the inode of the previous name. After we exit + the loop, this will point at the parent inode of the last name. + */ + ulPInode = ulInode; + + ulNameLen = RedNameLen(&pszLocalPath[ulPathIdx]); + + /* Lookup the inode of the name, unless we are at the last name in + the path: we don't care whether the last name exists or not. + */ + if(pszLocalPath[ulPathIdx + ulNameLen] == REDCONF_PATH_SEPARATOR) + { + ret = RedCoreLookup(ulPInode, &pszLocalPath[ulPathIdx], &ulInode); + } + + /* Move on to the next path element. + */ + if(ret == 0) + { + ulPathIdx += ulNameLen; + } + } + while(ret == 0); + + if(ret == 0) + { + *pulPInode = ulPInode; + *ppszName = &pszLocalPath[ulLastNameIdx]; + } + } + + return ret; +} + + +/** @brief Determine whether a path names the root directory. + + @param pszLocalPath The path to examine; this is a local path, without any + volume prefix. + + @return Returns whether @p pszLocalPath names the root directory. + + @retval true @p pszLocalPath names the root directory. + @retval false @p pszLocalPath does not name the root directory. +*/ +static bool IsRootDir( + const char *pszPath) +{ + uint32_t ulIdx = 0U; + + /* A string containing nothing but path separators (usually only one) + names the root directory. An empty string does *not* name the root + directory, since in POSIX empty strings typically elicit -RED_ENOENT + errors. + */ + while(pszPath[ulIdx] == REDCONF_PATH_SEPARATOR) + { + ulIdx++; + } + + return (ulIdx > 0U) && (pszPath[ulIdx] == '\0'); +} + +#endif /* REDCONF_API_POSIX */ + diff --git a/posix/posix.c b/posix/posix.c new file mode 100644 index 0000000..d367d72 --- /dev/null +++ b/posix/posix.c @@ -0,0 +1,3053 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implementation of the the Reliance Edge POSIX-like API. +*/ + +#include + +#if REDCONF_API_POSIX == 1 + +/** @defgroup red_group_posix The POSIX-like File System Interface + @{ +*/ + +#include +#include +#include +#include "redposixutil.h" + + +/*------------------------------------------------------------------- + File Descriptors +-------------------------------------------------------------------*/ + +#define FD_GEN_BITS 11U /* File descriptor bits for mount generation. */ +#define FD_VOL_BITS 8U /* File descriptor bits for volume number. */ +#define FD_IDX_BITS 12U /* File descriptor bits for handle index. */ + +/* 31 bits available: file descriptors are int32_t, but the sign bit must + always be zero. +*/ +#if (FD_GEN_BITS + FD_VOL_BITS + FD_IDX_BITS) > 31U + #error "Internal error: too many file descriptor bits!" +#endif + +/* Maximum values for file descriptor components. +*/ +#define FD_GEN_MAX ((1UL << FD_GEN_BITS) - 1U) +#define FD_VOL_MAX ((1UL << FD_VOL_BITS) - 1U) +#define FD_IDX_MAX ((1UL << FD_IDX_BITS) - 1U) + +#if REDCONF_VOLUME_COUNT >= FD_VOL_MAX + #error "Error: Too many file system volumes!" +#endif +#if REDCONF_HANDLE_COUNT >= FD_IDX_MAX + #error "Error: Too many file system handles!" +#endif + +/* File descriptors must never be negative; and must never be zero, one, or + two, to avoid confusion with STDIN, STDOUT, and STDERR. +*/ +#define FD_MIN (3) + +/*------------------------------------------------------------------- + Handles +-------------------------------------------------------------------*/ + +/* Mask of all RED_O_* values. +*/ +#define RED_O_MASK (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR|RED_O_APPEND|RED_O_CREAT|RED_O_EXCL|RED_O_TRUNC) + +#define HFLAG_DIRECTORY 0x01U /* Handle is for a directory. */ +#define HFLAG_READABLE 0x02U /* Handle is readable. */ +#define HFLAG_WRITEABLE 0x04U /* Handle is writeable. */ +#define HFLAG_APPENDING 0x08U /* Handle was opened in append mode. */ + +/* @brief Handle structure, used to implement file descriptors and directory + streams. +*/ +typedef struct sREDHANDLE +{ + uint32_t ulInode; /**< Inode number; 0 if handle is available. */ + uint8_t bVolNum; /**< Volume containing the inode. */ + uint8_t bFlags; /**< Handle flags (type and mode). */ + uint64_t ullOffset; /**< File or directory offset. */ + #if REDCONF_API_POSIX_READDIR == 1 + REDDIRENT dirent; /**< Dirent structure returned by red_readdir(). */ + #endif +} REDHANDLE; + +/*------------------------------------------------------------------- + Tasks +-------------------------------------------------------------------*/ + +#if REDCONF_TASK_COUNT > 1U +/* @brief Per-task information. +*/ +typedef struct +{ + uint32_t ulTaskId; /**< ID of the task which owns this slot; 0 if free. */ + REDSTATUS errno; /**< Last error value. */ +} TASKSLOT; +#endif + +/*------------------------------------------------------------------- + Local Prototypes +-------------------------------------------------------------------*/ + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) +static REDSTATUS UnlinkSub(const char *pszPath, FTYPE type); +#endif +static REDSTATUS FildesOpen(const char *pszPath, uint32_t ulOpenMode, FTYPE type, int32_t *piFildes); +static REDSTATUS FildesClose(int32_t iFildes); +static REDSTATUS FildesToHandle(int32_t iFildes, FTYPE expectedType, REDHANDLE **ppHandle); +static int32_t FildesPack(uint16_t uHandleIdx, uint8_t bVolNum); +static void FildesUnpack(int32_t iFildes, uint16_t *puHandleIdx, uint8_t *pbVolNum, uint16_t *puGeneration); +#if REDCONF_API_POSIX_READDIR == 1 +static bool DirStreamIsValid(const REDDIR *pDirStream); +#endif +static REDSTATUS PosixEnter(void); +static void PosixLeave(void); +static REDSTATUS ModeTypeCheck(uint16_t uMode, FTYPE expectedType); +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))) +static REDSTATUS InodeUnlinkCheck(uint32_t ulInode); +#endif +#if REDCONF_TASK_COUNT > 1U +static REDSTATUS TaskRegister(uint32_t *pulTaskIdx); +#endif +static int32_t PosixReturn(REDSTATUS iError); + +/*------------------------------------------------------------------- + Globals +-------------------------------------------------------------------*/ + +static bool gfPosixInited; /* Whether driver is initialized. */ +static REDHANDLE gaHandle[REDCONF_HANDLE_COUNT]; /* Array of all handles. */ +#if REDCONF_TASK_COUNT > 1U +static TASKSLOT gaTask[REDCONF_TASK_COUNT]; /* Array of task slots. */ +#endif + +/* Array of volume mount "generations". These are incremented for a volume + each time that volume is mounted. The generation number (along with the + volume number) is incorporated into the file descriptors; a stale file + descriptor from a previous mount can be detected since it will include a + stale generation number. +*/ +static uint16_t gauGeneration[REDCONF_VOLUME_COUNT]; + + +/*------------------------------------------------------------------- + Public API +-------------------------------------------------------------------*/ + +/** @brief Initialize the Reliance Edge file system driver. + + Prepares the Reliance Edge file system driver to be used. Must be the first + Reliance Edge function to be invoked: no volumes can be mounted or formatted + until the driver has been initialized. + + If this function is called when the Reliance Edge driver is already + initialized, it does nothing and returns success. + + This function is not thread safe: attempting to initialize from multiple + threads could leave things in a bad state. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: The volume path prefix configuration is invalid. +*/ +int32_t red_init(void) +{ + REDSTATUS ret; + + if(gfPosixInited) + { + ret = 0; + } + else + { + ret = RedCoreInit(); + if(ret == 0) + { + RedMemSet(gaHandle, 0U, sizeof(gaHandle)); + + #if REDCONF_TASK_COUNT > 1U + RedMemSet(gaTask, 0U, sizeof(gaTask)); + #endif + + gfPosixInited = true; + } + } + + return PosixReturn(ret); +} + + +/** @brief Uninitialize the Reliance Edge file system driver. + + Tears down the Reliance Edge file system driver. Cannot be used until all + Reliance Edge volumes are unmounted. A subsequent call to red_init() will + initialize the driver again. + + If this function is called when the Reliance Edge driver is already + uninitialized, it does nothing and returns success. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: At least one volume is still mounted. +*/ +int32_t red_uninit(void) +{ + REDSTATUS ret; + + if(gfPosixInited) + { + ret = PosixEnter(); + + if(ret == 0) + { + uint8_t bVolNum; + + for(bVolNum = 0U; bVolNum < REDCONF_VOLUME_COUNT; bVolNum++) + { + if(gaRedVolume[bVolNum].fMounted) + { + ret = -RED_EBUSY; + break; + } + } + + if(ret == 0) + { + /* All volumes are unmounted. Mark the driver as + uninitialized before releasing the FS mutex, to avoid any + race condition where a volume could be mounted and then the + driver uninitialized with a mounted volume. + */ + gfPosixInited = false; + } + + /* The FS mutex must be released before we uninitialize the core, + since the FS mutex needs to be in the released state when it + gets uninitialized. + + Don't use PosixLeave(), since it asserts gfPosixInited is true. + */ + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif + } + + if(ret == 0) + { + ret = RedCoreUninit(); + + /* Not good if the above fails, since things might be partly, but + not entirely, torn down, and there might not be a way back to + a valid driver state. + */ + REDASSERT(ret == 0); + } + } + else + { + ret = 0; + } + + return PosixReturn(ret); +} + + +/** @brief Mount a file system volume. + + Prepares the file system volume to be accessed. Mount will fail if the + volume has never been formatted, or if the on-disk format is inconsistent + with the compile-time configuration. + + An error is returned if the volume is already mounted. + + @param pszVolume A path prefix identifying the volume to mount. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: Volume is already mounted. + - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. + - #RED_EIO: Volume not formatted, improperly formatted, or corrupt. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_mount( + const char *pszVolume) +{ + REDSTATUS ret; + + ret = PosixEnter(); + + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + /* The core will return success if the volume is already mounted, so + check for that condition here to propagate the error. + */ + if((ret == 0) && gaRedVolume[bVolNum].fMounted) + { + ret = -RED_EBUSY; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolMount(); + } + + if(ret == 0) + { + /* Increment the mount generation, invalidating file descriptors + from previous mounts. Note that while the generation numbers + are stored in 16-bit values, we have less than 16-bits to store + generations in the file descriptors, so we must wrap-around + manually. + */ + gauGeneration[bVolNum]++; + if(gauGeneration[bVolNum] > FD_GEN_MAX) + { + /* Wrap-around to one, rather than zero. The generation is + stored in the top bits of the file descriptor, and doing + this means that low numbers are never valid file + descriptors. This implements the requirement that 0, 1, + and 2 are never valid file descriptors, thereby avoiding + confusion with STDIN, STDOUT, and STDERR. + */ + gauGeneration[bVolNum] = 1U; + } + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +/** @brief Unmount a file system volume. + + This function discards the in-memory state for the file system and marks it + as unmounted. Subsequent attempts to access the volume will fail until the + volume is mounted again. + + If unmount automatic transaction points are enabled, this function will + commit a transaction point prior to unmounting. If unmount automatic + transaction points are disabled, this function will unmount without + transacting, effectively discarding the working state. + + Before unmounting, this function will wait for any active file system + thread to complete by acquiring the FS mutex. The volume will be marked as + unmounted before the FS mutex is released, so subsequent FS threads will + possibly block and then see an error when attempting to access a volume + which is unmounting or unmounted. If the volume has open handles, the + unmount will fail. + + An error is returned if the volume is already unmounted. + + @param pszVolume A path prefix identifying the volume to unmount. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: There are still open handles for this file system volume. + - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized; or + the volume is already unmounted. + - #RED_EIO: I/O error during unmount automatic transaction point. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_umount( + const char *pszVolume) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + /* The core will return success if the volume is already unmounted, so + check for that condition here to propagate the error. + */ + if((ret == 0) && !gaRedVolume[bVolNum].fMounted) + { + ret = -RED_EINVAL; + } + + if(ret == 0) + { + uint16_t uHandleIdx; + + /* Do not unmount the volume if it still has open handles. + */ + for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) + { + const REDHANDLE *pHandle = &gaHandle[uHandleIdx]; + + if((pHandle->ulInode != INODE_INVALID) && (pHandle->bVolNum == bVolNum)) + { + ret = -RED_EBUSY; + break; + } + } + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolUnmount(); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FORMAT == 1) +/** @brief Format a file system volume. + + Uses the statically defined volume configuration. After calling this + function, the volume needs to be mounted -- see red_mount(). + + An error is returned if the volume is mounted. + + @param pszVolume A path prefix identifying the volume to format. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: Volume is mounted. + - #RED_EINVAL: @p pszVolume is `NULL`; or the driver is uninitialized. + - #RED_EIO: I/O error formatting the volume. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_format( + const char *pszVolume) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolFormat(); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if REDCONF_READ_ONLY == 0 +/** @brief Commit a transaction point. + + Reliance Edge is a transactional file system. All modifications, of both + metadata and filedata, are initially working state. A transaction point + is a process whereby the working state atomically becomes the committed + state, replacing the previous committed state. Whenever Reliance Edge is + mounted, including after power loss, the state of the file system after + mount is the most recent committed state. Nothing from the committed + state is ever missing, and nothing from the working state is ever included. + + @param pszVolume A path prefix identifying the volume to transact. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`. + - #RED_EIO: I/O error during the transaction point. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_transact( + const char *pszVolume) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolTransact(); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if REDCONF_READ_ONLY == 0 +/** @brief Update the transaction mask. + + The following events are available: + + - #RED_TRANSACT_UMOUNT + - #RED_TRANSACT_CREAT + - #RED_TRANSACT_UNLINK + - #RED_TRANSACT_MKDIR + - #RED_TRANSACT_RENAME + - #RED_TRANSACT_LINK + - #RED_TRANSACT_CLOSE + - #RED_TRANSACT_WRITE + - #RED_TRANSACT_FSYNC + - #RED_TRANSACT_TRUNCATE + - #RED_TRANSACT_VOLFULL + + The #RED_TRANSACT_MANUAL macro (by itself) may be used to disable all + automatic transaction events. The #RED_TRANSACT_MASK macro is a bitmask + of all transaction flags, excluding those representing excluded + functionality. + + Attempting to enable events for excluded functionality will result in an + error. + + @param pszVolume The path prefix of the volume whose transaction mask is + being changed. + @param ulEventMask A bitwise-OR'd mask of automatic transaction events to + be set as the current transaction mode. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + @p ulEventMask contains invalid bits. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_settransmask( + const char *pszVolume, + uint32_t ulEventMask) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreTransMaskSet(ulEventMask); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +/** @brief Read the transaction mask. + + If the volume is read-only, the returned event mask is always zero. + + @param pszVolume The path prefix of the volume whose transaction mask is + being retrieved. + @param pulEventMask Populated with a bitwise-OR'd mask of automatic + transaction events which represent the current + transaction mode for the volume. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + @p pulEventMask is `NULL`. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_gettransmask( + const char *pszVolume, + uint32_t *pulEventMask) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreTransMaskGet(pulEventMask); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +/** @brief Query file system status information. + + @p pszVolume should name a valid volume prefix or a valid root directory; + this differs from POSIX statvfs, where any existing file or directory is a + valid path. + + @param pszVolume The path prefix of the volume to query. + @param pStatvfs The buffer to populate with volume information. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: Volume is not mounted; or @p pszVolume is `NULL`; or + @p pStatvfs is `NULL`. + - #RED_ENOENT: @p pszVolume is not a valid volume path prefix. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_statvfs( + const char *pszVolume, + REDSTATFS *pStatvfs) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + uint8_t bVolNum; + + ret = RedPathSplit(pszVolume, &bVolNum, NULL); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreVolStat(pStatvfs); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +/** @brief Open a file or directory. + + Exactly one file access mode must be specified: + + - #RED_O_RDONLY: Open for reading only. + - #RED_O_WRONLY: Open for writing only. + - #RED_O_RDWR: Open for reading and writing. + + Directories can only be opened with `RED_O_RDONLY`. + + The following flags may also be used: + + - #RED_O_APPEND: Set the file offset to the end-of-file prior to each + write. + - #RED_O_CREAT: Create the named file if it does not exist. + - #RED_O_EXCL: In combination with `RED_O_CREAT`, return an error if the + path already exists. + - #RED_O_TRUNC: Truncate the opened file to size zero. Only supported when + #REDCONF_API_POSIX_FTRUNCATE is true. + + #RED_O_CREAT, #RED_O_EXCL, and #RED_O_TRUNC are invalid with #RED_O_RDONLY. + #RED_O_EXCL is invalid without #RED_O_CREAT. + + If the volume is read-only, #RED_O_RDONLY is the only valid open flag; use + of any other flag will result in an error. + + If #RED_O_TRUNC frees data which is in the committed state, it will not + return to free space until after a transaction point. + + The returned file descriptor must later be closed with red_close(). + + Unlike POSIX open, there is no optional third argument for the permissions + (which Reliance Edge does not use) and other open flags (like `O_SYNC`) are + not supported. + + @param pszPath The path to the file or directory. + @param ulOpenMode The open flags (mask of `RED_O_` values). + + @return On success, a nonnegative file descriptor is returned. On error, + -1 is returned and #red_errno is set appropriately. + + Errno values + - #RED_EEXIST: Using #RED_O_CREAT and #RED_O_EXCL, and the indicated path + already exists. + - #RED_EINVAL: @p ulOpenMode is invalid; or @p pszPath is `NULL`; or the + volume containing the path is not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_EISDIR: The path names a directory and @p ulOpenMode includes + #RED_O_WRONLY or #RED_O_RDWR. + - #RED_EMFILE: There are no available file descriptors. + - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + - #RED_ENFILE: Attempting to create a file but the file system has used all + available inode slots. + - #RED_ENOENT: #RED_O_CREAT is not set and the named file does not exist; or + #RED_O_CREAT is set and the parent directory does not exist; or the + volume does not exist; or the @p pszPath argument, after removing the + volume prefix, points to an empty string. + - #RED_ENOSPC: The file does not exist and #RED_O_CREAT was specified, but + there is insufficient free space to expand the directory or to create the + new file. + - #RED_ENOTDIR: A component of the prefix in @p pszPath does not name a + directory. + - #RED_EROFS: The path resides on a read-only file system and a write + operation was requested. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_open( + const char *pszPath, + uint32_t ulOpenMode) +{ + int32_t iFildes = -1; /* Init'd to quiet warnings. */ + REDSTATUS ret; + + #if REDCONF_READ_ONLY == 1 + if(ulOpenMode != RED_O_RDONLY) + { + ret = -RED_EROFS; + } + #else + if( (ulOpenMode != (ulOpenMode & RED_O_MASK)) + || ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY|RED_O_RDWR)) == 0U) + || (((ulOpenMode & RED_O_RDONLY) != 0U) && ((ulOpenMode & (RED_O_WRONLY|RED_O_RDWR)) != 0U)) + || (((ulOpenMode & RED_O_WRONLY) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_RDWR)) != 0U)) + || (((ulOpenMode & RED_O_RDWR) != 0U) && ((ulOpenMode & (RED_O_RDONLY|RED_O_WRONLY)) != 0U)) + || (((ulOpenMode & (RED_O_TRUNC|RED_O_CREAT|RED_O_EXCL)) != 0U) && ((ulOpenMode & RED_O_RDONLY) != 0U)) + || (((ulOpenMode & RED_O_EXCL) != 0U) && ((ulOpenMode & RED_O_CREAT) == 0U))) + { + ret = -RED_EINVAL; + } + #if REDCONF_API_POSIX_FTRUNCATE == 0 + else if((ulOpenMode & RED_O_TRUNC) != 0U) + { + ret = -RED_EINVAL; + } + #endif + #endif + else + { + ret = PosixEnter(); + } + + if(ret == 0) + { + ret = FildesOpen(pszPath, ulOpenMode, FTYPE_EITHER, &iFildes); + + PosixLeave(); + } + + if(ret != 0) + { + iFildes = PosixReturn(ret); + } + + return iFildes; +} + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_UNLINK == 1) +/** @brief Delete a file or directory. + + The given name is deleted and the link count of the corresponding inode is + decremented. If the link count falls to zero (no remaining hard links), + the inode will be deleted. + + Unlike POSIX unlink, deleting a file or directory with open handles (file + descriptors or directory streams) will fail with an #RED_EBUSY error. This + only applies when deleting an inode with a link count of one; if a file has + multiple names (hard links), all but the last name may be deleted even if + the file is open. + + If the path names a directory which is not empty, the unlink will fail. + + If the deletion frees data in the committed state, it will not return to + free space until after a transaction point. + + Unlike POSIX unlink, this function can fail when the disk is full. To fix + this, transact and try again: Reliance Edge guarantees that it is possible + to delete at least one file or directory after a transaction point. If disk + full automatic transactions are enabled, this will happen automatically. + + @param pszPath The path of the file or directory to delete. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: @p pszPath points to an inode with open handles and a link + count of one. + - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + - #RED_ENOENT: The path does not name an existing file; or the @p pszPath + argument, after removing the volume prefix, points to an empty string. + - #RED_ENOTDIR: A component of the path prefix is not a directory. + - #RED_ENOTEMPTY: The path names a directory which is not empty. + - #RED_ENOSPC: The file system does not have enough space to modify the + parent directory to perform the deletion. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_unlink( + const char *pszPath) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + ret = UnlinkSub(pszPath, FTYPE_EITHER); + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_MKDIR == 1) +/** @brief Create a new directory. + + Unlike POSIX mkdir, this function has no second argument for the + permissions (which Reliance Edge does not use). + + @param pszPath The name and location of the directory to create. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EEXIST: @p pszPath points to an existing file or directory. + - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + - #RED_ENOENT: A component of the path prefix does not name an existing + directory; or the @p pszPath argument, after removing the volume prefix, + points to an empty string. + - #RED_ENOSPC: The file system does not have enough space for the new + directory or to extend the parent directory of the new directory. + - #RED_ENOTDIR: A component of the path prefix is not a directory. + - #RED_EROFS: The parent directory resides on a read-only file system. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_mkdir( + const char *pszPath) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + const char *pszLocalPath; + uint8_t bVolNum; + + ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + const char *pszName; + uint32_t ulPInode; + + ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); + + if(ret == 0) + { + uint32_t ulInode; + + ret = RedCoreCreate(ulPInode, pszName, true, &ulInode); + } + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RMDIR == 1) +/** @brief Delete a directory. + + The given directory name is deleted and the corresponding directory inode + will be deleted. + + Unlike POSIX rmdir, deleting a directory with open handles (file + descriptors or directory streams) will fail with an #RED_EBUSY error. + + If the path names a directory which is not empty, the deletion will fail. + If the path names the root directory of a file system volume, the deletion + will fail. + + If the path names a regular file, the deletion will fail. This provides + type checking and may be useful in cases where an application knows the + path to be deleted should name a directory. + + If the deletion frees data in the committed state, it will not return to + free space until after a transaction point. + + Unlike POSIX rmdir, this function can fail when the disk is full. To fix + this, transact and try again: Reliance Edge guarantees that it is possible + to delete at least one file or directory after a transaction point. If disk + full automatic transactions are enabled, this will happen automatically. + + @param pszPath The path of the directory to delete. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: @p pszPath points to a directory with open handles. + - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENAMETOOLONG: The length of a component of @p pszPath is longer than + #REDCONF_NAME_MAX. + - #RED_ENOENT: The path does not name an existing directory; or the + @p pszPath argument, after removing the volume prefix, points to an empty + string. + - #RED_ENOTDIR: A component of the path is not a directory. + - #RED_ENOTEMPTY: The path names a directory which is not empty. + - #RED_ENOSPC: The file system does not have enough space to modify the + parent directory to perform the deletion. + - #RED_EROFS: The directory to be removed resides on a read-only file + system. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_rmdir( + const char *pszPath) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + ret = UnlinkSub(pszPath, FTYPE_DIR); + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_RENAME == 1) +/** @brief Rename a file or directory. + + Both paths must reside on the same file system volume. Attempting to use + this API to move a file to a different volume will result in an error. + + If @p pszNewPath names an existing file or directory, the behavior depends + on the configuration. If #REDCONF_RENAME_ATOMIC is false, and if the + destination name exists, this function always fails and sets #red_errno to + #RED_EEXIST. This behavior is contrary to POSIX. + + If #REDCONF_RENAME_ATOMIC is true, and if the new name exists, then in one + atomic operation, @p pszNewPath is unlinked and @p pszOldPath is renamed to + @p pszNewPath. Both @p pszNewPath and @p pszOldPath must be of the same + type (both files or both directories). As with red_unlink(), if + @p pszNewPath is a directory, it must be empty. The major exception to this + behavior is that if both @p pszOldPath and @p pszNewPath are links to the + same inode, then the rename does nothing and both names continue to exist. + Unlike POSIX rename, if @p pszNewPath points to an inode with a link count + of one and open handles (file descriptors or directory streams), the + rename will fail with #RED_EBUSY. + + If the rename deletes the old destination, it may free data in the + committed state, which will not return to free space until after a + transaction point. Similarly, if the deleted inode was part of the + committed state, the inode slot will not be available until after a + transaction point. + + @param pszOldPath The path of the file or directory to rename. + @param pszNewPath The new name and location after the rename. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBUSY: #REDCONF_RENAME_ATOMIC is true and @p pszNewPath points to an + inode with open handles and a link count of one. + - #RED_EEXIST: #REDCONF_RENAME_ATOMIC is false and @p pszNewPath exists. + - #RED_EINVAL: @p pszOldPath is `NULL`; or @p pszNewPath is `NULL`; or the + volume containing the path is not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_EISDIR: The @p pszNewPath argument names a directory and the + @p pszOldPath argument names a non-directory. + - #RED_ENAMETOOLONG: The length of a component of either @p pszOldPath or + @p pszNewPath is longer than #REDCONF_NAME_MAX. + - #RED_ENOENT: The link named by @p pszOldPath does not name an existing + entry; or either @p pszOldPath or @p pszNewPath, after removing the volume + prefix, point to an empty string. + - #RED_ENOTDIR: A component of either path prefix is not a directory; or + @p pszOldPath names a directory and @p pszNewPath names a file. + - #RED_ENOTEMPTY: The path named by @p pszNewPath is a directory which is + not empty. + - #RED_ENOSPC: The file system does not have enough space to extend the + directory that would contain @p pszNewPath. + - #RED_EROFS: The directory to be removed resides on a read-only file + system. + - #RED_EUSERS: Cannot become a file system user: too many users. + - #RED_EXDEV: @p pszOldPath and @p pszNewPath are on different file system + volumes. +*/ +int32_t red_rename( + const char *pszOldPath, + const char *pszNewPath) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + const char *pszOldLocalPath; + uint8_t bOldVolNum; + + ret = RedPathSplit(pszOldPath, &bOldVolNum, &pszOldLocalPath); + + if(ret == 0) + { + const char *pszNewLocalPath; + uint8_t bNewVolNum; + + ret = RedPathSplit(pszNewPath, &bNewVolNum, &pszNewLocalPath); + + if((ret == 0) && (bOldVolNum != bNewVolNum)) + { + ret = -RED_EXDEV; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bOldVolNum); + } + #endif + + if(ret == 0) + { + const char *pszOldName; + uint32_t ulOldPInode; + + ret = RedPathToName(pszOldLocalPath, &ulOldPInode, &pszOldName); + + if(ret == 0) + { + const char *pszNewName; + uint32_t ulNewPInode; + + ret = RedPathToName(pszNewLocalPath, &ulNewPInode, &pszNewName); + + #if REDCONF_RENAME_ATOMIC == 1 + if(ret == 0) + { + uint32_t ulDestInode; + + ret = RedCoreLookup(ulNewPInode, pszNewName, &ulDestInode); + if(ret == 0) + { + ret = InodeUnlinkCheck(ulDestInode); + } + else if(ret == -RED_ENOENT) + { + ret = 0; + } + else + { + /* Unexpected error, nothing to do. + */ + } + } + #endif + + if(ret == 0) + { + ret = RedCoreRename(ulOldPInode, pszOldName, ulNewPInode, pszNewName); + } + } + } + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_LINK == 1) +/** @brief Create a hard link. + + This creates an additional name (link) for the file named by @p pszPath. + The new name refers to the same file with the same contents. If a name is + deleted, but the underlying file has other names, the file continues to + exist. The link count (accessible via red_fstat()) indicates the number of + names that a file has. All of a file's names are on equal footing: there + is nothing special about the original name. + + If @p pszPath names a directory, the operation will fail. + + @param pszPath The path indicating the inode for the new link. + @param pszHardLink The name and location for the new link. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EEXIST: @p pszHardLink resolves to an existing file. + - #RED_EINVAL: @p pszPath or @p pszHardLink is `NULL`; or the volume + containing the paths is not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_EMLINK: Creating the link would exceed the maximum link count of the + inode named by @p pszPath. + - #RED_ENAMETOOLONG: The length of a component of either @p pszPath or + @p pszHardLink is longer than #REDCONF_NAME_MAX. + - #RED_ENOENT: A component of either path prefix does not exist; or the file + named by @p pszPath does not exist; or either @p pszPath or + @p pszHardLink, after removing the volume prefix, point to an empty + string. + - #RED_ENOSPC: There is insufficient free space to expand the directory that + would contain the link. + - #RED_ENOTDIR: A component of either path prefix is not a directory. + - #RED_EPERM: The @p pszPath argument names a directory. + - #RED_EROFS: The requested link requires writing in a directory on a + read-only file system. + - #RED_EUSERS: Cannot become a file system user: too many users. + - #RED_EXDEV: @p pszPath and @p pszHardLink are on different file system + volumes. +*/ +int32_t red_link( + const char *pszPath, + const char *pszHardLink) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + const char *pszLocalPath; + uint8_t bVolNum; + + ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); + + if(ret == 0) + { + const char *pszLinkLocalPath; + uint8_t bLinkVolNum; + + ret = RedPathSplit(pszHardLink, &bLinkVolNum, &pszLinkLocalPath); + + if((ret == 0) && (bVolNum != bLinkVolNum)) + { + ret = -RED_EXDEV; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + uint32_t ulInode; + + ret = RedPathLookup(pszLocalPath, &ulInode); + + if(ret == 0) + { + const char *pszLinkName; + uint32_t ulLinkPInode; + + ret = RedPathToName(pszLinkLocalPath, &ulLinkPInode, &pszLinkName); + + if(ret == 0) + { + ret = RedCoreLink(ulLinkPInode, pszLinkName, ulInode); + } + } + } + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +/** @brief Close a file descriptor. + + @param iFildes The file descriptor to close. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBADF: @p iFildes is not a valid file descriptor. + - #RED_EIO: A disk I/O error occurred. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_close( + int32_t iFildes) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + ret = FildesClose(iFildes); + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +/** @brief Read from an open file. + + The read takes place at the file offset associated with @p iFildes and + advances the file offset by the number of bytes actually read. + + Data which has not yet been written, but which is before the end-of-file + (sparse data), will read as zeroes. A short read -- where the number of + bytes read is less than requested -- indicates that the requested read was + partially or, if zero bytes were read, entirely beyond the end-of-file. + + @param iFildes The file descriptor from which to read. + @param pBuffer The buffer to populate with data read. Must be at least + @p ulLength bytes in size. + @param ulLength Number of bytes to attempt to read. + + @return On success, returns a nonnegative value indicating the number of + bytes actually read. On error, -1 is returned and #red_errno is + set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + for reading. + - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and + cannot be returned properly. + - #RED_EIO: A disk I/O error occurred. + - #RED_EISDIR: The @p iFildes is a file descriptor for a directory. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_read( + int32_t iFildes, + void *pBuffer, + uint32_t ulLength) +{ + uint32_t ulLenRead = 0U; + REDSTATUS ret; + int32_t iReturn; + + if(ulLength > (uint32_t)INT32_MAX) + { + ret = -RED_EINVAL; + } + else + { + ret = PosixEnter(); + } + + if(ret == 0) + { + REDHANDLE *pHandle; + + ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); + + if((ret == 0) && ((pHandle->bFlags & HFLAG_READABLE) == 0U)) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + if(ret == 0) + { + ulLenRead = ulLength; + ret = RedCoreFileRead(pHandle->ulInode, pHandle->ullOffset, &ulLenRead, pBuffer); + } + + if(ret == 0) + { + REDASSERT(ulLenRead <= ulLength); + + pHandle->ullOffset += ulLenRead; + } + + PosixLeave(); + } + + if(ret == 0) + { + iReturn = (int32_t)ulLenRead; + } + else + { + iReturn = PosixReturn(ret); + } + + return iReturn; +} + + +#if REDCONF_READ_ONLY == 0 +/** @brief Write to an open file. + + The write takes place at the file offset associated with @p iFildes and + advances the file offset by the number of bytes actually written. + Alternatively, if @p iFildes was opened with #RED_O_APPEND, the file offset + is set to the end-of-file before the write begins, and likewise advances by + the number of bytes actually written. + + A short write -- where the number of bytes written is less than requested + -- indicates either that the file system ran out of space but was still + able to write some of the request; or that the request would have caused + the file to exceed the maximum file size, but some of the data could be + written prior to the file size limit. + + If an error is returned (-1), either none of the data was written or a + critical error occurred (like an I/O error) and the file system volume will + be read-only. + + @param iFildes The file descriptor to write to. + @param pBuffer The buffer containing the data to be written. Must be at + least @p ulLength bytes in size. + @param ulLength Number of bytes to attempt to write. + + @return On success, returns a nonnegative value indicating the number of + bytes actually written. On error, -1 is returned and #red_errno is + set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + for writing. This includes the case where the file descriptor is for a + directory. + - #RED_EFBIG: No data can be written to the current file offset since the + resulting file size would exceed the maximum file size. + - #RED_EINVAL: @p pBuffer is `NULL`; or @p ulLength exceeds INT32_MAX and + cannot be returned properly. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENOSPC: No data can be written because there is insufficient free + space. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_write( + int32_t iFildes, + const void *pBuffer, + uint32_t ulLength) +{ + uint32_t ulLenWrote = 0U; + REDSTATUS ret; + int32_t iReturn; + + if(ulLength > (uint32_t)INT32_MAX) + { + ret = -RED_EINVAL; + } + else + { + ret = PosixEnter(); + } + + if(ret == 0) + { + REDHANDLE *pHandle; + + ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); + if(ret == -RED_EISDIR) + { + /* POSIX says that if a file descriptor is not writable, the + errno should be -RED_EBADF. Directory file descriptors are + never writable, and unlike for read(), the spec does not + list -RED_EISDIR as an allowed errno. Therefore -RED_EBAD + takes precedence. + */ + ret = -RED_EBADF; + } + + if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U)) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + if((ret == 0) && ((pHandle->bFlags & HFLAG_APPENDING) != 0U)) + { + REDSTAT s; + + ret = RedCoreStat(pHandle->ulInode, &s); + if(ret == 0) + { + pHandle->ullOffset = s.st_size; + } + } + + if(ret == 0) + { + ulLenWrote = ulLength; + ret = RedCoreFileWrite(pHandle->ulInode, pHandle->ullOffset, &ulLenWrote, pBuffer); + } + + if(ret == 0) + { + REDASSERT(ulLenWrote <= ulLength); + + pHandle->ullOffset += ulLenWrote; + } + + PosixLeave(); + } + + if(ret == 0) + { + iReturn = (int32_t)ulLenWrote; + } + else + { + iReturn = PosixReturn(ret); + } + + return iReturn; +} +#endif + + +#if REDCONF_READ_ONLY == 0 +/** @brief Synchronizes changes to a file. + + Commits all changes associated with a file or directory (including file + data, directory contents, and metadata) to permanent storage. This + function will not return until the operation is complete. + + In the current implementation, this function has global effect. All dirty + buffers are flushed and a transaction point is committed. Fsyncing one + file effectively fsyncs all files. + + If fsync automatic transactions have been disabled, this function does + nothing and returns success. In the current implementation, this is the + only real difference between this function and red_transact(): this + function can be configured to do nothing, whereas red_transact() is + unconditional. + + Applications written for portability should avoid assuming red_fsync() + effects all files, and use red_fsync() on each file that needs to be + synchronized. + + Passing read-only file descriptors to this function is permitted. + + @param iFildes The file descriptor to synchronize. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. + - #RED_EIO: A disk I/O error occurred. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_fsync( + int32_t iFildes) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + REDHANDLE *pHandle; + + ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + /* No core event for fsync, so this transaction flag needs to be + implemented here. + */ + if(ret == 0) + { + uint32_t ulTransMask; + + ret = RedCoreTransMaskGet(&ulTransMask); + + if((ret == 0) && ((ulTransMask & RED_TRANSACT_FSYNC) != 0U)) + { + ret = RedCoreVolTransact(); + } + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +/** @brief Move the read/write file offset. + + The file offset of the @p iFildes file descriptor is set to @p llOffset, + relative to some starting position. The available positions are: + + - ::RED_SEEK_SET Seek from the start of the file. In other words, + @p llOffset becomes the new file offset. + - ::RED_SEEK_CUR Seek from the current file offset. In other words, + @p llOffset is added to the current file offset. + - ::RED_SEEK_END Seek from the end-of-file. In other words, the new file + offset is the file size plus @p llOffset. + + Since @p llOffset is signed (can be negative), it is possible to seek + backward with ::RED_SEEK_CUR or ::RED_SEEK_END. + + It is permitted to seek beyond the end-of-file; this does not increase the + file size (a subsequent red_write() call would). + + Unlike POSIX lseek, this function cannot be used with directory file + descriptors. + + @param iFildes The file descriptor whose offset is to be updated. + @param llOffset The new file offset, relative to @p whence. + @param whence The location from which @p llOffset should be applied. + + @return On success, returns the new file position, measured in bytes from + the beginning of the file. On error, -1 is returned and #red_errno + is set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not an open file descriptor. + - #RED_EINVAL: @p whence is not a valid `RED_SEEK_` value; or the resulting + file offset would be negative. + - #RED_EIO: A disk I/O error occurred. + - #RED_EISDIR: The @p iFildes argument is a file descriptor for a directory. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int64_t red_lseek( + int32_t iFildes, + int64_t llOffset, + REDWHENCE whence) +{ + REDSTATUS ret; + int64_t llReturn = -1; /* Init'd to quiet warnings. */ + + ret = PosixEnter(); + if(ret == 0) + { + int64_t llFrom = 0; /* Init'd to quiet warnings. */ + REDHANDLE *pHandle; + + /* Unlike POSIX, we disallow lseek() on directory handles. + */ + ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + if(ret == 0) + { + switch(whence) + { + /* Seek from the beginning of the file. + */ + case RED_SEEK_SET: + llFrom = 0; + break; + + /* Seek from the current file offset. + */ + case RED_SEEK_CUR: + REDASSERT(pHandle->ullOffset <= INT64_MAX); + llFrom = (int64_t)pHandle->ullOffset; + break; + + /* Seek from the end of the file. + */ + case RED_SEEK_END: + { + REDSTAT s; + + ret = RedCoreStat(pHandle->ulInode, &s); + if(ret == 0) + { + REDASSERT(pHandle->ullOffset <= INT64_MAX); + llFrom = (int64_t)s.st_size; + } + + break; + } + + default: + ret = -RED_EINVAL; + break; + } + } + + if(ret == 0) + { + int64_t llNewOffset = llFrom + llOffset; + + if((llNewOffset < 0) || ((uint64_t)llNewOffset > gaRedVolume[pHandle->bVolNum].ullMaxInodeSize)) + { + /* Invalid file offset. + */ + ret = -RED_EINVAL; + } + else + { + pHandle->ullOffset = (uint64_t)llNewOffset; + llReturn = llNewOffset; + } + } + + PosixLeave(); + } + + if(ret != 0) + { + llReturn = PosixReturn(ret); + } + + return llReturn; +} + + +#if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) +/** @brief Truncate a file to a specified length. + + Allows the file size to be increased, decreased, or to remain the same. If + the file size is increased, the new area is sparse (will read as zeroes). + If the file size is decreased, the data beyond the new end-of-file will + return to free space once it is no longer part of the committed state + (either immediately or after the next transaction point). + + The value of the file offset is not modified by this function. + + Unlike POSIX ftruncate, this function can fail when the disk is full if + @p ullSize is non-zero. If decreasing the file size, this can be fixed by + transacting and trying again: Reliance Edge guarantees that it is possible + to perform a truncate of at least one file that decreases the file size + after a transaction point. If disk full transactions are enabled, this will + happen automatically. + + @param iFildes The file descriptor of the file to truncate. + @param ullSize The new size of the file. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not a valid file descriptor open + for writing. This includes the case where the file descriptor is for a + directory. + - #RED_EFBIG: @p ullSize exceeds the maximum file size. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENOSPC: Insufficient free space to perform the truncate. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_ftruncate( + int32_t iFildes, + uint64_t ullSize) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + REDHANDLE *pHandle; + + ret = FildesToHandle(iFildes, FTYPE_FILE, &pHandle); + if(ret == -RED_EISDIR) + { + /* Similar to red_write() (see comment there), the RED_EBADF error + for a non-writable file descriptor takes precedence. + */ + ret = -RED_EBADF; + } + + if((ret == 0) && ((pHandle->bFlags & HFLAG_WRITEABLE) == 0U)) + { + ret = -RED_EBADF; + } + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreFileTruncate(pHandle->ulInode, ullSize); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif + + +/** @brief Get the status of a file or directory. + + See the ::REDSTAT type for the details of the information returned. + + @param iFildes An open file descriptor for the file whose information is + to be retrieved. + @param pStat Pointer to a ::REDSTAT buffer to populate. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBADF: The @p iFildes argument is not a valid file descriptor. + - #RED_EINVAL: @p pStat is `NULL`. + - #RED_EIO: A disk I/O error occurred. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_fstat( + int32_t iFildes, + REDSTAT *pStat) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + REDHANDLE *pHandle; + + ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + if(ret == 0) + { + ret = RedCoreStat(pHandle->ulInode, pStat); + } + + PosixLeave(); + } + + return PosixReturn(ret); +} + + +#if REDCONF_API_POSIX_READDIR == 1 +/** @brief Open a directory stream for reading. + + @param pszPath The path of the directory to open. + + @return On success, returns a pointer to a ::REDDIR object that can be used + with red_readdir() and red_closedir(). On error, returns `NULL` + and #red_errno is set appropriately. + + Errno values + - #RED_EINVAL: @p pszPath is `NULL`; or the volume containing the path is + not mounted. + - #RED_EIO: A disk I/O error occurred. + - #RED_ENOENT: A component of @p pszPath does not exist; or the @p pszPath + argument, after removing the volume prefix, points to an empty string. + - #RED_ENOTDIR: A component of @p pszPath is a not a directory. + - #RED_EMFILE: There are no available file descriptors. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +REDDIR *red_opendir( + const char *pszPath) +{ + int32_t iFildes; + REDSTATUS ret; + REDDIR *pDir = NULL; + + ret = PosixEnter(); + if(ret == 0) + { + ret = FildesOpen(pszPath, RED_O_RDONLY, FTYPE_DIR, &iFildes); + if(ret == 0) + { + uint16_t uHandleIdx; + + FildesUnpack(iFildes, &uHandleIdx, NULL, NULL); + pDir = &gaHandle[uHandleIdx]; + } + + PosixLeave(); + } + + REDASSERT((pDir == NULL) == (ret != 0)); + + if(pDir == NULL) + { + red_errno = -ret; + } + + return pDir; +} + + +/** @brief Read from a directory stream. + + The ::REDDIRENT pointer returned by this function will be overwritten by + subsequent calls on the same @p pDir. Calls with other ::REDDIR objects + will *not* modify the returned ::REDDIRENT. + + If files are added to the directory after it is opened, the new files may + or may not be returned by this function. If files are deleted, the deleted + files will not be returned. + + This function (like its POSIX equivalent) returns `NULL` in two cases: on + error and when the end of the directory is reached. To distinguish between + these two cases, the application should set #red_errno to zero before + calling this function, and if `NULL` is returned, check if #red_errno is + still zero. If it is, the end of the directory was reached; otherwise, + there was an error. + + @param pDirStream The directory stream to read from. + + @return On success, returns a pointer to a ::REDDIRENT object which is + populated with directory entry information read from the directory. + On error, returns `NULL` and #red_errno is set appropriately. If at + the end of the directory, returns `NULL` but #red_errno is not + modified. + + Errno values + - #RED_EBADF: @p pDirStream is not an open directory stream. + - #RED_EIO: A disk I/O error occurred. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +REDDIRENT *red_readdir( + REDDIR *pDirStream) +{ + REDSTATUS ret; + REDDIRENT *pDirEnt = NULL; + + ret = PosixEnter(); + if(ret == 0) + { + if(DirStreamIsValid(pDirStream)) + { + #if REDCONF_VOLUME_COUNT > 1U + ret = RedCoreVolSetCurrent(pDirStream->bVolNum); + #else + ret = 0; + #endif + } + else + { + ret = -RED_EBADF; + } + + if(ret == 0) + { + uint32_t ulDirPosition; + + /* To save memory, the directory position is stored in the same + location as the file offset. This would be a bit cleaner using + a union, but MISRA-C:2012 Rule 19.2 disallows unions. + */ + REDASSERT(pDirStream->ullOffset <= UINT32_MAX); + ulDirPosition = (uint32_t)pDirStream->ullOffset; + + ret = RedCoreDirRead(pDirStream->ulInode, &ulDirPosition, pDirStream->dirent.d_name, &pDirStream->dirent.d_ino); + + pDirStream->ullOffset = ulDirPosition; + + if(ret == 0) + { + /* POSIX extension: return stat information with the dirent. + */ + ret = RedCoreStat(pDirStream->dirent.d_ino, &pDirStream->dirent.d_stat); + if(ret == 0) + { + pDirEnt = &pDirStream->dirent; + } + } + else if(ret == -RED_ENOENT) + { + /* Reached the end of the directory; return NULL but do not set + errno. + */ + ret = 0; + } + else + { + /* Miscellaneous error; return NULL and set errno (done below). + */ + } + } + + PosixLeave(); + } + + if(ret != 0) + { + REDASSERT(pDirEnt == NULL); + + red_errno = -ret; + } + + return pDirEnt; +} + + +/** @brief Rewind a directory stream to read it from the beginning. + + Similar to closing the directory object and opening it again, but without + the need for the path. + + Since this function (like its POSIX equivalent) cannot return an error, + it takes no action in error conditions, such as when @p pDirStream is + invalid. + + @param pDirStream The directory stream to rewind. +*/ +void red_rewinddir( + REDDIR *pDirStream) +{ + if(PosixEnter() == 0) + { + if(DirStreamIsValid(pDirStream)) + { + pDirStream->ullOffset = 0U; + } + + PosixLeave(); + } +} + + +/** @brief Close a directory stream. + + After calling this function, @p pDirStream should no longer be used. + + @param pDirStream The directory stream to close. + + @return On success, zero is returned. On error, -1 is returned and + #red_errno is set appropriately. + + Errno values + - #RED_EBADF: @p pDirStream is not an open directory stream. + - #RED_EUSERS: Cannot become a file system user: too many users. +*/ +int32_t red_closedir( + REDDIR *pDirStream) +{ + REDSTATUS ret; + + ret = PosixEnter(); + if(ret == 0) + { + if(DirStreamIsValid(pDirStream)) + { + /* Mark this handle as unused. + */ + pDirStream->ulInode = INODE_INVALID; + } + else + { + ret = -RED_EBADF; + } + + PosixLeave(); + } + + return PosixReturn(ret); +} +#endif /* REDCONF_API_POSIX_READDIR */ + + +/** @brief Pointer to where the last file system error (errno) is stored. + + This function is intended to be used via the #red_errno macro, or a similar + user-defined macro, that can be used both as an lvalue (writable) and an + rvalue (readable). + + Under normal circumstances, the errno for each task is stored in a + different location. Applications do not need to worry about one task + obliterating an error value that another task needed to read. This task + errno for is initially zero. When one of the POSIX-like APIs returns an + indication of error, the location for the calling task will be populated + with the error value. + + In some circumstances, this function will return a pointer to a global + errno location which is shared by multiple tasks. If the calling task is + not registered as a file system user and all of the task slots are full, + there can be no task-specific errno, so the global pointer is returned. + Likewise, if the file system driver is uninitialized, there are no + registered file system users and this function always returns the pointer + to the global errno. Under these circumstances, multiple tasks + manipulating errno could be problematic. + + This function never returns `NULL` under any circumstances. The #red_errno + macro unconditionally dereferences the return value from this function, so + returning `NULL` could result in a fault. + + @return Pointer to where the errno value is stored for this task. +*/ +REDSTATUS *red_errnoptr(void) +{ + /* The global errno value, used in single-task configurations and when the + caller is not (and cannot become) a file system user (which includes + when the driver is uninitialized). + */ + static REDSTATUS iGlobalErrno = 0; + + #if REDCONF_TASK_COUNT == 1U + + return &iGlobalErrno; + + #else + + REDSTATUS *piErrno; + + if(gfPosixInited) + { + uint32_t ulTaskId = RedOsTaskId(); + uint32_t ulIdx; + + REDASSERT(ulTaskId != 0U); + + /* If this task has used the file system before, it will already have + a task slot, which includes the task-specific errno. + */ + RedOsMutexAcquire(); + + for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++) + { + if(gaTask[ulIdx].ulTaskId == ulTaskId) + { + break; + } + } + + RedOsMutexRelease(); + + if(ulIdx == REDCONF_TASK_COUNT) + { + REDSTATUS ret; + + /* This task is not a file system user, so try to register it as + one. This FS mutex must be held in order to register. + */ + RedOsMutexAcquire(); + + ret = TaskRegister(&ulIdx); + + RedOsMutexRelease(); + + if(ret == 0) + { + REDASSERT(gaTask[ulIdx].ulTaskId == RedOsTaskId()); + REDASSERT(gaTask[ulIdx].errno == 0); + + piErrno = &gaTask[ulIdx].errno; + } + else + { + /* Unable to register; use the global errno. + */ + piErrno = &iGlobalErrno; + } + } + else + { + piErrno = &gaTask[ulIdx].errno; + } + } + else + { + /* There are no registered file system tasks when the driver is + uninitialized, so use the global errno. + */ + piErrno = &iGlobalErrno; + } + + /* This function is not allowed to return NULL. + */ + REDASSERT(piErrno != NULL); + return piErrno; + + #endif +} +/** @} */ + +/*------------------------------------------------------------------- + Helper Functions +-------------------------------------------------------------------*/ + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1)) + +/** @brief Remove a link to a file or directory. + + If the link count becomes zero, the file or directory is deleted. + + @param pszPath Path of the link to remove. + @param type The expected type of the path: file, directory, or either. + An error is returned if the expected type is file or + directory and does not match the path. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval -RED_EBUSY @p pszPath points to an inode with open handles + and a link count of one. + @retval -RED_EINVAL @p pszPath is `NULL`; or the volume containing + the path is not mounted. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_EISDIR @p type is ::FTYPE_FILE and the path names a + directory. + @retval -RED_ENAMETOOLONG @p pszName is too long. + @retval -RED_ENOENT The path does not name an existing file; or + @p pszPath, after removing the volume prefix, + points to an empty string. + @retval -RED_ENOTDIR @p type is ::FTYPE_DIR and the path does not + name a directory. + @retval -RED_ENOTEMPTY @p pszPath is a directory which is not empty. + @retval -RED_ENOSPC The file system does not have enough space to + modify the parent directory to perform the + deletion. +*/ +static REDSTATUS UnlinkSub( + const char *pszPath, + FTYPE type) +{ + uint8_t bVolNum; + const char *pszLocalPath; + REDSTATUS ret; + + ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); + + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(bVolNum); + } + #endif + + if(ret == 0) + { + const char *pszName; + uint32_t ulPInode; + + ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); + + if(ret == 0) + { + uint32_t ulInode; + + ret = RedCoreLookup(ulPInode, pszName, &ulInode); + + if(ret == 0) + { + REDSTAT InodeStat; + + ret = RedCoreStat(ulInode, &InodeStat); + if(ret == 0) + { + ret = ModeTypeCheck(InodeStat.st_mode, type); + } + } + + if(ret == 0) + { + ret = InodeUnlinkCheck(ulInode); + } + + if(ret == 0) + { + ret = RedCoreUnlink(ulPInode, pszName); + } + } + } + + return ret; +} +#endif /* (REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) */ + + +/** @brief Get a file descriptor for a path. + + @param pszPath Path to a file to open. + @param ulOpenMode The RED_O_* flags the descriptor is opened with. + @param type Indicates the expected descriptor type: file, directory, + or either. + @param piFildes On successful return, populated with the file + descriptor. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL @p piFildes is `NULL`; or @p pszPath is `NULL`; + or the volume is not mounted. + @retval -RED_EMFILE There are no available handles. + @retval -RED_EEXIST Using #RED_O_CREAT and #RED_O_EXCL, and the + indicated path already exists. + @retval -RED_EISDIR The path names a directory and @p ulOpenMode + includes #RED_O_WRONLY or #RED_O_RDWR. + @retval -RED_ENOENT #RED_O_CREAT is not set and the named file does + not exist; or #RED_O_CREAT is set and the parent + directory does not exist; or the volume does not + exist; or the @p pszPath argument, after + removing the volume prefix, points to an empty + string. + @retval -RED_EIO A disk I/O error occurred. + @retval -RED_ENAMETOOLONG The length of a component of @p pszPath is + longer than #REDCONF_NAME_MAX. + @retval -RED_ENFILE Attempting to create a file but the file system + has used all available inode slots. + @retval -RED_ENOSPC The file does not exist and #RED_O_CREAT was + specified, but there is insufficient free space + to expand the directory or to create the new + file. + @retval -RED_ENOTDIR A component of the prefix in @p pszPath does not + name a directory. + @retval -RED_EROFS The path resides on a read-only file system and + a write operation was requested. +*/ +static REDSTATUS FildesOpen( + const char *pszPath, + uint32_t ulOpenMode, + FTYPE type, + int32_t *piFildes) +{ + uint8_t bVolNum; + const char *pszLocalPath; + REDSTATUS ret; + + ret = RedPathSplit(pszPath, &bVolNum, &pszLocalPath); + + if(ret == 0) + { + if(piFildes == NULL) + { + ret = -RED_EINVAL; + } + #if REDCONF_READ_ONLY == 0 + else if(gaRedVolume[bVolNum].fReadOnly && (ulOpenMode != RED_O_RDONLY)) + { + ret = -RED_EROFS; + } + #endif + else + { + uint16_t uHandleIdx; + REDHANDLE *pHandle = NULL; + + /* Search for an unused handle. + */ + for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) + { + if(gaHandle[uHandleIdx].ulInode == INODE_INVALID) + { + pHandle = &gaHandle[uHandleIdx]; + break; + } + } + + /* Error if all the handles are in use. + */ + if(pHandle == NULL) + { + ret = -RED_EMFILE; + } + else + { + bool fCreated = false; + uint16_t uMode = 0U; + uint32_t ulInode = 0U; /* Init'd to quiet warnings. */ + + #if REDCONF_VOLUME_COUNT > 1U + ret = RedCoreVolSetCurrent(bVolNum); + if(ret == 0) + #endif + { + #if REDCONF_READ_ONLY == 0 + if((ulOpenMode & RED_O_CREAT) != 0U) + { + uint32_t ulPInode; + const char *pszName; + + ret = RedPathToName(pszLocalPath, &ulPInode, &pszName); + if(ret == 0) + { + ret = RedCoreCreate(ulPInode, pszName, false, &ulInode); + if(ret == 0) + { + fCreated = true; + } + else if((ret == -RED_EEXIST) && ((ulOpenMode & RED_O_EXCL) == 0U)) + { + /* If the path already exists and that's OK, + lookup its inode number. + */ + ret = RedCoreLookup(ulPInode, pszName, &ulInode); + } + else + { + /* No action, just propagate the error. + */ + } + } + } + else + #endif + { + ret = RedPathLookup(pszLocalPath, &ulInode); + } + } + + /* If we created the inode, none of the below stuff is + necessary. This is important from an error handling + perspective -- we do not need code to delete the created + inode on error. + */ + if(!fCreated) + { + if(ret == 0) + { + REDSTAT s; + + ret = RedCoreStat(ulInode, &s); + if(ret == 0) + { + uMode = s.st_mode; + } + } + + /* Error if the inode is not of the expected type. + */ + if(ret == 0) + { + ret = ModeTypeCheck(uMode, type); + } + + /* Directories must always be opened with O_RDONLY. + */ + if((ret == 0) && RED_S_ISDIR(uMode) && ((ulOpenMode & RED_O_RDONLY) == 0U)) + { + ret = -RED_EISDIR; + } + + #if (REDCONF_READ_ONLY == 0) && (REDCONF_API_POSIX_FTRUNCATE == 1) + if((ret == 0) && ((ulOpenMode & RED_O_TRUNC) != 0U)) + { + ret = RedCoreFileTruncate(ulInode, 0ULL); + } + #endif + } + + if(ret == 0) + { + RedMemSet(pHandle, 0U, sizeof(*pHandle)); + + /* Populate this handle, marking it as in use. + */ + pHandle->ulInode = ulInode; + pHandle->bVolNum = bVolNum; + + if(RED_S_ISDIR(uMode)) + { + pHandle->bFlags |= HFLAG_DIRECTORY; + } + + if(((ulOpenMode & RED_O_RDONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U)) + { + pHandle->bFlags |= HFLAG_READABLE; + } + + #if REDCONF_READ_ONLY == 0 + if(((ulOpenMode & RED_O_WRONLY) != 0U) || ((ulOpenMode & RED_O_RDWR) != 0U)) + { + pHandle->bFlags |= HFLAG_WRITEABLE; + } + + if((ulOpenMode & RED_O_APPEND) != 0U) + { + pHandle->bFlags |= HFLAG_APPENDING; + } + #endif + + *piFildes = FildesPack(uHandleIdx, bVolNum); + } + } + } + } + + return ret; +} + + +/** @brief Close a file descriptor. + + @param iFildes The file descriptor to close. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p iFildes is not a valid file descriptor. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS FildesClose( + int32_t iFildes) +{ + REDHANDLE *pHandle; + REDSTATUS ret; + + ret = FildesToHandle(iFildes, FTYPE_EITHER, &pHandle); + + #if REDCONF_READ_ONLY == 0 + #if REDCONF_VOLUME_COUNT > 1U + if(ret == 0) + { + ret = RedCoreVolSetCurrent(pHandle->bVolNum); + } + #endif + + /* No core event for close, so this transaction flag needs to be + implemented here. + */ + if(ret == 0) + { + uint32_t ulTransMask; + + ret = RedCoreTransMaskGet(&ulTransMask); + + if((ret == 0) && ((ulTransMask & RED_TRANSACT_CLOSE) != 0U)) + { + ret = RedCoreVolTransact(); + } + } + #endif + + if(ret == 0) + { + /* Mark this handle as unused. + */ + pHandle->ulInode = INODE_INVALID; + } + + return ret; +} + + +/** @brief Convert a file descriptor into a handle pointer. + + Also validates the file descriptor. + + @param iFildes The file descriptor for which to get a handle. + @param expectedType The expected type of the file descriptor: ::FTYPE_DIR, + ::FTYPE_FILE, or ::FTYPE_EITHER. + @param ppHandle On successful return, populated with a pointer to the + handle associated with @p iFildes. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p iFildes is not a valid file descriptor. + @retval -RED_EINVAL @p ppHandle is `NULL`. + @retval -RED_EISDIR Expected a file, but the file descriptor is for a + directory. + @retval -RED_ENOTDIR Expected a directory, but the file descriptor is for + a file. +*/ +static REDSTATUS FildesToHandle( + int32_t iFildes, + FTYPE expectedType, + REDHANDLE **ppHandle) +{ + REDSTATUS ret; + + if(ppHandle == NULL) + { + ret = -RED_EINVAL; + } + else if(iFildes < FD_MIN) + { + ret = -RED_EBADF; + } + else + { + uint16_t uHandleIdx; + uint8_t bVolNum; + uint16_t uGeneration; + + FildesUnpack(iFildes, &uHandleIdx, &bVolNum, &uGeneration); + + if( (uHandleIdx >= REDCONF_HANDLE_COUNT) + || (bVolNum >= REDCONF_VOLUME_COUNT) + || (gaHandle[uHandleIdx].ulInode == INODE_INVALID) + || (gaHandle[uHandleIdx].bVolNum != bVolNum) + || (gauGeneration[bVolNum] != uGeneration)) + { + ret = -RED_EBADF; + } + else if((expectedType == FTYPE_FILE) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) != 0U)) + { + ret = -RED_EISDIR; + } + else if((expectedType == FTYPE_DIR) && ((gaHandle[uHandleIdx].bFlags & HFLAG_DIRECTORY) == 0U)) + { + ret = -RED_ENOTDIR; + } + else + { + *ppHandle = &gaHandle[uHandleIdx]; + ret = 0; + } + } + + return ret; +} + + +/** @brief Pack a file descriptor. + + @param uHandleIdx The index of the file handle that will be associated + with this file descriptor. + @param bVolNum The volume which contains the file or directory this + file descriptor was opened against. + + @return The packed file descriptor. +*/ +static int32_t FildesPack( + uint16_t uHandleIdx, + uint8_t bVolNum) +{ + int32_t iFildes; + + REDASSERT(uHandleIdx <= FD_IDX_MAX); + + if(bVolNum >= REDCONF_VOLUME_COUNT) + { + REDERROR(); + iFildes = -1; + } + else + { + uint32_t ulFdBits; + + REDASSERT(gauGeneration[bVolNum] <= FD_GEN_MAX); + + ulFdBits = gauGeneration[bVolNum]; + ulFdBits <<= FD_VOL_BITS; + ulFdBits |= bVolNum; + ulFdBits <<= FD_IDX_BITS; + ulFdBits |= uHandleIdx; + + iFildes = (int32_t)ulFdBits; + + REDASSERT(iFildes >= FD_MIN); + } + + return iFildes; +} + + +/** @brief Unpack a file descriptor. + + @param iFildes The file descriptor to unpack. + @param puHandleIdx If non-NULL, populated with the handle index extracted + from the file descriptor. + @param pbVolNum If non-NULL, populated with the volume number extracted + from the file descriptor. + @param puGeneration If non-NULL, populated with the generation number + extracted from the file descriptor. +*/ +static void FildesUnpack( + int32_t iFildes, + uint16_t *puHandleIdx, + uint8_t *pbVolNum, + uint16_t *puGeneration) +{ + uint32_t ulFdBits = (uint32_t)iFildes; + + REDASSERT(iFildes >= FD_MIN); + + if(puHandleIdx != NULL) + { + *puHandleIdx = (uint16_t)(ulFdBits & FD_IDX_MAX); + } + + ulFdBits >>= FD_IDX_BITS; + + if(pbVolNum != NULL) + { + *pbVolNum = (uint8_t)(ulFdBits & FD_VOL_MAX); + } + + ulFdBits >>= FD_VOL_BITS; + + if(puGeneration != NULL) + { + *puGeneration = (uint16_t)(ulFdBits & FD_GEN_MAX); + } +} + + +#if REDCONF_API_POSIX_READDIR == 1 +/** @brief Validate a directory stream object. + + @param pDirStream The directory stream to validate. + + @return Whether the directory stream is valid. + + @retval true The directory stream object appears valid. + @retval false The directory stream object is invalid. +*/ +static bool DirStreamIsValid( + const REDDIR *pDirStream) +{ + bool fRet = true; + + if(pDirStream == NULL) + { + fRet = false; + } + else + { + uint16_t uHandleIdx; + + /* pDirStream should be a pointer to one of the handles. + + A good compiler will optimize this loop into a bounds check and an + alignment check. + */ + for(uHandleIdx = 0U; uHandleIdx < REDCONF_HANDLE_COUNT; uHandleIdx++) + { + if(pDirStream == &gaHandle[uHandleIdx]) + { + break; + } + } + + if(uHandleIdx < REDCONF_HANDLE_COUNT) + { + /* The handle must be in use, have a valid volume number, and be a + directory handle. + */ + if( (pDirStream->ulInode == INODE_INVALID) + || (pDirStream->bVolNum >= REDCONF_VOLUME_COUNT) + || ((pDirStream->bFlags & HFLAG_DIRECTORY) == 0U)) + { + fRet = false; + } + } + else + { + /* pDirStream is a non-null pointer, but it is not a pointer to one + of our handles. + */ + fRet = false; + } + } + + return fRet; +} +#endif + + +/** @brief Enter the file system driver. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EINVAL The file system driver is uninitialized. + @retval -RED_EUSERS Cannot become a file system user: too many users. +*/ +static REDSTATUS PosixEnter(void) +{ + REDSTATUS ret; + + if(gfPosixInited) + { + #if REDCONF_TASK_COUNT > 1U + RedOsMutexAcquire(); + + ret = TaskRegister(NULL); + if(ret != 0) + { + RedOsMutexRelease(); + } + #else + ret = 0; + #endif + } + else + { + ret = -RED_EINVAL; + } + + return ret; +} + + +/** @brief Leave the file system driver. +*/ +static void PosixLeave(void) +{ + /* If the driver was uninitialized, PosixEnter() should have failed and we + should not be calling PosixLeave(). + */ + REDASSERT(gfPosixInited); + + #if REDCONF_TASK_COUNT > 1U + RedOsMutexRelease(); + #endif +} + + +/** @brief Check that a mode is consistent with the given expected type. + + @param uMode An inode mode, indicating whether the inode is a file + or a directory. + @param expectedType The expected type: ::FTYPE_FILE, ::FTYPE_DIR, or + ::FTYPE_EITHER. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EISDIR Expected type is file, actual type is directory. + @retval -RED_ENOTDIR Expected type is directory, actual type is file. +*/ +static REDSTATUS ModeTypeCheck( + uint16_t uMode, + FTYPE expectedType) +{ + REDSTATUS ret; + + if((expectedType == FTYPE_FILE) && RED_S_ISDIR(uMode)) + { + /* Expected file, found directory. + */ + ret = -RED_EISDIR; + } + else if((expectedType == FTYPE_DIR) && RED_S_ISREG(uMode)) + { + /* Expected directory, found file. + */ + ret = -RED_ENOTDIR; + } + else + { + /* No expected type or found what we expected. + */ + ret = 0; + } + + return ret; +} + + +#if (REDCONF_READ_ONLY == 0) && ((REDCONF_API_POSIX_UNLINK == 1) || (REDCONF_API_POSIX_RMDIR == 1) || ((REDCONF_API_POSIX_RENAME == 1) && (REDCONF_RENAME_ATOMIC == 1))) +/** @brief Check whether an inode can be unlinked. + + If an inode has a link count of 1 (meaning unlinking another name would + result in the deletion of the inode) and open handles, it cannot be deleted + since this would break open handles. + + @param ulInode The inode whose name is to be unlinked. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EBADF @p ulInode is not a valid inode. + @retval -RED_EBUSY The inode has a link count of one and open handles. + @retval -RED_EIO A disk I/O error occurred. +*/ +static REDSTATUS InodeUnlinkCheck( + uint32_t ulInode) +{ + uint16_t uHandleIdx; + REDSTATUS ret; + + #if REDCONF_API_POSIX_LINK == 0 + ret = 0; + #else + REDSTAT InodeStat; + + ret = RedCoreStat(ulInode, &InodeStat); + + /* We only need to check for open handles if the inode is down to its last + link. If it has multiple links, the inode will continue to exist, so + deleting the name will not break the open handles. + */ + if((ret == 0) && (InodeStat.st_nlink == 1U)) + #endif + { + for(uHandleIdx = 0U; (uHandleIdx < REDCONF_HANDLE_COUNT); uHandleIdx++) + { + if(gaHandle[uHandleIdx].ulInode == ulInode) + { + ret = -RED_EBUSY; + break; + } + } + } + + return ret; +} +#endif + + +#if REDCONF_TASK_COUNT > 1U +/** @brief Register a task as a file system user, if it is not already + registered as one. + + The caller must hold the FS mutex. + + @param pulTaskIdx On successful return, if non-NULL, populated with the + index of the task slot assigned to the calling task. + This is populated whether or not the task had already + been registered. + + @return A negated ::REDSTATUS code indicating the operation result. + + @retval 0 Operation was successful. + @retval -RED_EUSERS Cannot become a file system user: too many users. +*/ +static REDSTATUS TaskRegister( + uint32_t *pulTaskIdx) +{ + uint32_t ulTaskId = RedOsTaskId(); + uint32_t ulFirstFreeIdx = REDCONF_TASK_COUNT; + uint32_t ulIdx; + REDSTATUS ret; + + REDASSERT(ulTaskId != 0U); + + /* Scan the task slots to determine if the task is registered as a file + system task. + */ + for(ulIdx = 0U; ulIdx < REDCONF_TASK_COUNT; ulIdx++) + { + if(gaTask[ulIdx].ulTaskId == ulTaskId) + { + break; + } + + if((ulFirstFreeIdx == REDCONF_TASK_COUNT) && (gaTask[ulIdx].ulTaskId == 0U)) + { + ulFirstFreeIdx = ulIdx; + } + } + + if(ulIdx == REDCONF_TASK_COUNT) + { + /* Task not already registered. + */ + if(ulFirstFreeIdx == REDCONF_TASK_COUNT) + { + /* Cannot register task, no more slots. + */ + ret = -RED_EUSERS; + } + else + { + /* Registering task. + */ + ulIdx = ulFirstFreeIdx; + gaTask[ulIdx].ulTaskId = ulTaskId; + ret = 0; + } + } + else + { + /* Task already registered. + */ + ret = 0; + } + + if((ret == 0) && (pulTaskIdx != NULL)) + { + *pulTaskIdx = ulIdx; + } + + return ret; +} +#endif /* REDCONF_TASK_COUNT > 1U */ + + +/** @brief Convert an error value into a simple 0 or -1 return. + + This function is simple, but what it does is needed in many places. It + returns zero if @p iError is zero (meaning success) or it returns -1 if + @p iError is nonzero (meaning error). Also, if @p iError is nonzero, it + is saved in red_errno. + + @param iError The error value. + + @return Returns 0 if @p iError is 0; otherwise, returns -1. +*/ +static int32_t PosixReturn( + REDSTATUS iError) +{ + int32_t iReturn; + + if(iError == 0) + { + iReturn = 0; + } + else + { + iReturn = -1; + + /* The errors should be negative, and errno positive. + */ + REDASSERT(iError < 0); + red_errno = -iError; + } + + return iReturn; +} + + +#endif /* REDCONF_API_POSIX == 1 */ + diff --git a/posix/redposixutil.h b/posix/redposixutil.h new file mode 100644 index 0000000..30058ae --- /dev/null +++ b/posix/redposixutil.h @@ -0,0 +1,37 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file +*/ +#ifndef REDPOSIXUTIL_H +#define REDPOSIXUTIL_H + + +REDSTATUS RedPathSplit(const char *pszPath, uint8_t *pbVolNum, const char **ppszLocalPath); +REDSTATUS RedPathLookup(const char *pszLocalPath, uint32_t *pulInode); +REDSTATUS RedPathToName(const char *pszLocalPath, uint32_t *pulPInode, const char **ppszName); + + +#endif + diff --git a/projects/freertos/atmel/sam4e-ek/README.txt b/projects/freertos/atmel/sam4e-ek/README.txt new file mode 100644 index 0000000..634c695 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/README.txt @@ -0,0 +1,70 @@ +README for the Reliance Edge Atmel SAM4E-EK FreeRTOS Project + +**Note** -- This project WILL NOT WORK until you setup the FreeRTOS directory. + Keep reading for details. + +Project +------- + +This is an Atmel Studio project for the Atmel SAM4E-EK (an evaluation board +available from Atmel). It is intended to demonstrate using Reliance Edge with +FreeRTOS on an Atmel target. + +Atmel Studio Framework +---------------------- + +This project includes a complete copy of the Atmel Studio Framework (ASF) +components that it needs. Minor modifications to the ASF components have been +made. One set of modifications was to the SD/MMC driver to add support for +multi-sector read and write requests, which greatly improves file system +performance. Other modifications quiet compiler warnings. + +FreeRTOS +-------- + +This project does not include a copy of the FreeRTOS source. This must be +supplied by you, the person building the project. + +The Atmel Studio project expects to find the FreeRTOS source in a "src/FreeRTOS" +subdirectory in this project. That is *only* the FreeRTOS source, not the +FreeRTOS-Plus source (thus there should be a "src/FreeRTOS/Source" directory, +and *NOT* "src/FreeRTOS/FreeRTOS/Source"). + +Creating this directory can be accomplished in two ways: + +1) Copy the FreeRTOS tree into src/FreeRTOS; + +2) Create a link src/FreeRTOS which points to a FreeRTOS tree located elsewhere. + +The latter avoids the burden of copying the FreeRTOS source (which, including +all the demos, is quite large) into the project. + +On Windows hosts (assuming Windows Vista or later), you can use "mklink /j + " to create a link in the src/ subdirectory. "rmdir" will delete +the link without deleting the directory it points at. + +If you open the Atmel Studio project without creating the FreeRTOS directory, +it will fail to build due to missing files. If the directory is created while +the Atmel Studio project is open, it may be necessary to restart Atmel Studio. + +Reliance Edge +----------- + +See the developer's guide for setting up Reliance Edge. + +The os/freertos/services/osbdev.c has code to use the modified ASF SD/MMC +driver, but it might not be enabled (see the macros in that file). + +Tested Versions +--------------- + +This project has been tested with FreeRTOS v8.2.0 and Atmel Studio 6.2. +Modifications may be required for other software versions. + +Resources +--------- + +Atmel Studio is available at: http://www.atmel.com/tools/atmelstudio.aspx + +FreeRTOS is available at: http://www.freertos.org/ + diff --git a/projects/freertos/atmel/sam4e-ek/RelianceEdge.atsln b/projects/freertos/atmel/sam4e-ek/RelianceEdge.atsln new file mode 100644 index 0000000..2a14ec7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/RelianceEdge.atsln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Atmel Studio Solution File, Format Version 11.00 +Project("{54F91283-7BC4-4236-8FF9-10F437C3AD48}") = "RelianceEdge", "RelianceEdge.cproj", "{F9687CC5-2ADA-4BDC-9CC9-50B289F40658}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|ARM = Debug|ARM + Release|ARM = Release|ARM + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F9687CC5-2ADA-4BDC-9CC9-50B289F40658}.Debug|ARM.ActiveCfg = Debug|ARM + {F9687CC5-2ADA-4BDC-9CC9-50B289F40658}.Debug|ARM.Build.0 = Debug|ARM + {F9687CC5-2ADA-4BDC-9CC9-50B289F40658}.Release|ARM.ActiveCfg = Release|ARM + {F9687CC5-2ADA-4BDC-9CC9-50B289F40658}.Release|ARM.Build.0 = Release|ARM + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/projects/freertos/atmel/sam4e-ek/RelianceEdge.cproj b/projects/freertos/atmel/sam4e-ek/RelianceEdge.cproj new file mode 100644 index 0000000..304e387 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/RelianceEdge.cproj @@ -0,0 +1,1188 @@ + + + + 2.0 + 6.2 + com.Atmel.ARMGCC.C + {f9687cc5-2ada-4bdc-9cc9-50b289f40658} + ATSAM4E16E + sam4e + Executable + C + $(MSBuildProjectName) + .elf + $(MSBuildProjectDirectory)\$(Configuration) + RelianceEdge + RelianceEdge + RelianceEdge + Native + true + false + true + true + 0x20000000 + + true + exception_table + 2 + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + com.atmel.avrdbg.tool.atmelice + + + + 7500000 + + JTAG + + com.atmel.avrdbg.tool.atmelice + J41800002033 + Atmel-ICE + + JTAG + + + + + True + True + True + True + True + + + BOARD=SAM4E_EK + scanf=iscanf + ARM_MATH_CM4=true + printf=iprintf + __SAM4E16E__ + SD_MMC_ENABLE + NDEBUG + + + False + + + ../common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/common/utils + ../src/ASF/sam/utils/fpu + ../src/ASF/common/services/serial/sam_uart + ../src/ASF/sam/drivers/pmc + ../src/ASF/sam/drivers/pdc + ../src/ASF/sam/boards + ../src/ASF/sam/utils/cmsis/sam4e/include + ../src/ASF/common/components/memory/sd_mmc + ../src/ASF/common/boards + ../src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/sam/utils/header_files + ../src/ASF/common/services/ioport + ../src/ASF/thirdparty/CMSIS/Include + ../src/ASF/sam/utils/cmsis/sam4e/source/templates + ../src/ASF/sam/drivers/hsmci + ../src/config + ../src/ASF/thirdparty/CMSIS/Lib/GCC + ../src/ASF/sam/drivers/pdc/pdc_uart_example + ../src + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/sam/utils + ../src/ASF/sam/utils/preprocessor + ../src/ASF/common/services/serial + ../src/ASF/sam/drivers/usart + ../src/ASF/sam/boards/sam4e_ek + ../src/ASF/sam/drivers/uart + ../../../../../include + ../../../../../core/include + ../../../../../os/freertos/include + ../../../../../posix + ../../../../../tests/posix + ../src/FreeRTOS/Source/portable/GCC/ARM_CM4F + ../src/ASF/common/services/storage/ctrl_access + ../../../../../tests/posix_api + ../../../../../tests/testfw + + + Optimize for size (-Os) + -fdata-sections + True + True + -pipe -fno-strict-aliasing -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -std=gnu99 -ffunction-sections -fdata-sections -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wbad-function-cast -Wwrite-strings -Wsign-compare -Wmissing-declarations -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Wunreachable-code --param max-inline-insns-single=500 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + + + libarm_cortexM4lf_math + libm + + + + + ../cmsis/linkerScripts + ../src/ASF/thirdparty/CMSIS/Lib/GCC + + + True + False + -Wl,--entry=Reset_Handler -Wl,--cref -mthumb -T../src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld + -DARM_MATH_CM4=true -DBOARD=SAM4E_EK -D__SAM4E16E__ -Dprintf=iprintf -Dscanf=iscanf -DSD_MMC_ENABLE + False + + + ../common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/common/utils + ../src/ASF/sam/utils/fpu + ../src/ASF/common/services/serial/sam_uart + ../src/ASF/sam/drivers/pmc + ../src/ASF/sam/drivers/pdc + ../src/ASF/sam/boards + ../src/ASF/sam/utils/cmsis/sam4e/include + ../src/ASF/common/components/memory/sd_mmc + ../src/ASF/common/boards + ../src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/sam/utils/header_files + ../src/ASF/common/services/ioport + ../src/ASF/thirdparty/CMSIS/Include + ../src/ASF/sam/utils/cmsis/sam4e/source/templates + ../src/ASF/sam/drivers/hsmci + ../src/config + ../src/ASF/thirdparty/CMSIS/Lib/GCC + ../src/ASF/sam/drivers/pdc/pdc_uart_example + ../src + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/sam/utils + ../src/ASF/sam/utils/preprocessor + ../src/ASF/common/services/serial + ../src/ASF/sam/drivers/usart + ../src/ASF/sam/boards/sam4e_ek + ../src/ASF/sam/drivers/uart + ../src/ASF/common/services/storage/ctrl_access + + + + + + + + + True + True + True + True + True + + + BOARD=SAM4E_EK + scanf=iscanf + ARM_MATH_CM4=true + printf=iprintf + __SAM4E16E__ + SD_MMC_ENABLE + DEBUG + + + False + + + ../common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/common/utils + ../src/ASF/sam/utils/fpu + ../src/ASF/common/services/serial/sam_uart + ../src/ASF/sam/drivers/pmc + ../src/ASF/sam/drivers/pdc + ../src/ASF/sam/boards + ../src/ASF/sam/utils/cmsis/sam4e/include + ../src/ASF/common/components/memory/sd_mmc + ../src/ASF/common/boards + ../src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/sam/utils/header_files + ../src/ASF/common/services/ioport + ../src/ASF/thirdparty/CMSIS/Include + ../src/ASF/sam/utils/cmsis/sam4e/source/templates + ../src/ASF/sam/drivers/hsmci + ../src/config + ../src/ASF/thirdparty/CMSIS/Lib/GCC + ../src/ASF/sam/drivers/pdc/pdc_uart_example + ../src + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/sam/utils + ../src/ASF/sam/utils/preprocessor + ../src/ASF/common/services/serial + ../src/ASF/sam/drivers/usart + ../src/ASF/sam/boards/sam4e_ek + ../src/ASF/sam/drivers/uart + ../../../../../include + ../../../../../core/include + ../../../../../os/freertos/include + ../../../../../posix + ../../../../../tests/posix + ../src/FreeRTOS/Source/portable/GCC/ARM_CM4F + ../src/ASF/common/services/storage/ctrl_access + ../../../../../tests/posix_api + ../../../../../tests/testfw + ../src/FreeRTOS/Source/include + + + -fdata-sections + True + Maximum (-g3) + True + -pipe -fno-strict-aliasing -Wall -Wstrict-prototypes -Wmissing-prototypes -Werror-implicit-function-declaration -Wpointer-arith -std=gnu99 -ffunction-sections -fdata-sections -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int -Wmain -Wparentheses -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef -Wshadow -Wbad-function-cast -Wwrite-strings -Wsign-compare -Wmissing-declarations -Wformat -Wno-deprecated-declarations -Wpacked -Wredundant-decls -Wnested-externs -Wunreachable-code --param max-inline-insns-single=500 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 + + + libarm_cortexM4lf_math + libm + + + + + ../cmsis/linkerScripts + ../src/ASF/thirdparty/CMSIS/Lib/GCC + + + True + False + -Wl,--entry=Reset_Handler -Wl,--cref -mthumb -T../src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld + Default (-g) + -DARM_MATH_CM4=true -DBOARD=SAM4E_EK -D__SAM4E16E__ -Dprintf=iprintf -Dscanf=iscanf -DSD_MMC_ENABLE + False + + + ../common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/common/utils + ../src/ASF/sam/utils/fpu + ../src/ASF/common/services/serial/sam_uart + ../src/ASF/sam/drivers/pmc + ../src/ASF/sam/drivers/pdc + ../src/ASF/sam/boards + ../src/ASF/sam/utils/cmsis/sam4e/include + ../src/ASF/common/components/memory/sd_mmc + ../src/ASF/common/boards + ../src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek + ../src/ASF/sam/utils/header_files + ../src/ASF/common/services/ioport + ../src/ASF/thirdparty/CMSIS/Include + ../src/ASF/sam/utils/cmsis/sam4e/source/templates + ../src/ASF/sam/drivers/hsmci + ../src/config + ../src/ASF/thirdparty/CMSIS/Lib/GCC + ../src/ASF/sam/drivers/pdc/pdc_uart_example + ../src + ../src/ASF/common/services/clock + ../src/ASF/common/services/delay + ../src/ASF/common/utils/stdio/stdio_serial + ../src/ASF/sam/utils + ../src/ASF/sam/utils/preprocessor + ../src/ASF/common/services/serial + ../src/ASF/sam/drivers/usart + ../src/ASF/sam/boards/sam4e_ek + ../src/ASF/sam/drivers/uart + ../src/ASF/common/services/storage/ctrl_access + + + Default (-Wa,-g) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + compile + src\RelianceEdge\printf.c + + + compile + src\RelianceEdge\rand.c + + + compile + src\RelianceEdge\sign.c + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + src\RelianceEdge\blockio.c + + + compile + src\RelianceEdge\buffer.c + + + compile + src\RelianceEdge\core.c + + + compile + src\RelianceEdge\dir.c + + + compile + src\RelianceEdge\format.c + + + compile + src\RelianceEdge\imap.c + + + compile + src\RelianceEdge\imapextern.c + + + compile + src\RelianceEdge\imapinline.c + + + compile + src\RelianceEdge\inode.c + + + compile + src\RelianceEdge\inodedata.c + + + compile + src\RelianceEdge\volume.c + + + compile + src\RelianceEdge\fse.c + + + compile + src\RelianceEdge\osassert.c + + + compile + src\RelianceEdge\osbdev.c + + + compile + src\RelianceEdge\osclock.c + + + compile + src\RelianceEdge\osmutex.c + + + compile + src\RelianceEdge\osoutput.c + + + compile + src\RelianceEdge\ostask.c + + + compile + src\RelianceEdge\ostimestamp.c + + + compile + src\RelianceEdge\path.c + + + compile + src\RelianceEdge\posix.c + + + compile + src\RelianceEdge\bitmap.c + + + compile + src\RelianceEdge\crc.c + + + compile + src\RelianceEdge\memory.c + + + compile + src\RelianceEdge\namelen.c + + + compile + src\RelianceEdge\string.c + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + compile + + + + \ No newline at end of file diff --git a/projects/freertos/atmel/sam4e-ek/host/Makefile b/projects/freertos/atmel/sam4e-ek/host/Makefile new file mode 100644 index 0000000..eb969f2 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/host/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for a Reliance Edge Win32 host tools project +# +P_BASEDIR ?= ../../../../.. +P_PROJDIR ?= $(P_BASEDIR)/projects/freertos/atmel/sam4e-ek/host +P_CONFDIR ?= $(P_PROJDIR)/../src/config +B_DEBUG ?= 0 + +include $(P_BASEDIR)/os/win32/build/host.mk + diff --git a/projects/freertos/atmel/sam4e-ek/host/redconf.c b/projects/freertos/atmel/sam4e-ek/host/redconf.c new file mode 100644 index 0000000..d797f4a --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/host/redconf.c @@ -0,0 +1,7 @@ +/** @file +*/ + +/* The host tools use the same volume configuration as the target. +*/ +#include "../src/config/redconf.c" + diff --git a/projects/freertos/atmel/sam4e-ek/host/redconf.h b/projects/freertos/atmel/sam4e-ek/host/redconf.h new file mode 100644 index 0000000..202c26d --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/host/redconf.h @@ -0,0 +1,95 @@ +/** @file +*/ + +/* Inherit most settings from the target configuration. +*/ +#include "../src/config/redconf.h" + + +#ifndef HOST_REDCONF_H +#define HOST_REDCONF_H + +#if REDCONF_ENDIAN_BIG == 1 +#define REDCONF_ENDIAN_SWAP +#endif + +#undef REDCONF_ENDIAN_BIG +#define REDCONF_ENDIAN_BIG 0 + +/* Ignore the target system memory alignment. For Windows, 4 bytes works well. +*/ +#undef REDCONF_ALIGNMENT_SIZE +#define REDCONF_ALIGNMENT_SIZE 4U + +/* Host tools always have output. +*/ +#undef REDCONF_OUTPUT +#define REDCONF_OUTPUT 1 + +/* Read-only must be disabled for the image builder. +*/ +#undef REDCONF_READ_ONLY +#define REDCONF_READ_ONLY 0 + +/* Enable the checker host tool. +*/ +#undef REDCONF_CHECKER +#define REDCONF_CHECKER 1 + +/* Enable the formatter code in POSIX-like API configurations for the image + builder and formatter host tools. +*/ +#undef REDCONF_API_POSIX_FORMAT +#define REDCONF_API_POSIX_FORMAT 1 + +/* Enable the image builder host tool. +*/ +#undef REDCONF_IMAGE_BUILDER +#define REDCONF_IMAGE_BUILDER 1 + +/* The image builder needs red_mkdir(). +*/ +#undef REDCONF_API_POSIX_MKDIR +#define REDCONF_API_POSIX_MKDIR 1 + +/* The image copier utility needs red_readdir(). +*/ +#undef REDCONF_API_POSIX_READDIR +#define REDCONF_API_POSIX_READDIR 1 + +/* The image copier utility needs a handle for every level of directory depth. + While Reliance Edge has no maximum directory depth or path depth, Windows + limits paths to 260 bytes, and each level of depth eats up at least two + characters, 130 handles will be sufficient for all images that can be + copied. +*/ +#undef REDCONF_HANDLE_COUNT +#define REDCONF_HANDLE_COUNT 130U + +/* The target redconf.h may have configured the memory and string functions to + use custom implementations that are only available on the target system. So + for the host, we just use the C library versions. +*/ +#include + +#undef RedMemCpy +#define RedMemCpy memcpy +#undef RedMemMove +#define RedMemMove memmove +#undef RedMemSet +#define RedMemSet memset +#undef RedMemCmp +#define RedMemCmp memcmp + +#undef RedStrLen +#define RedStrLen (uint32_t)strlen +#undef RedStrCmp +#define RedStrCmp strcmp +#undef RedStrNCmp +#define RedStrNCmp strncmp +#undef RedStrNCpy +#define RedStrNCpy strncpy + + +#endif + diff --git a/projects/freertos/atmel/sam4e-ek/host/redtypes.h b/projects/freertos/atmel/sam4e-ek/host/redtypes.h new file mode 100644 index 0000000..9ec53cc --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/host/redtypes.h @@ -0,0 +1,110 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +typedef int bool; /**< @brief Boolean type; either true or false. */ + +typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ +typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ + +typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ +typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ + +typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ +typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ + +typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ +typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ + +/** @brief Unsigned integer capable of storing a pointer. +*/ +#ifdef _WIN64 +typedef uint64_t uintptr_t; +#else +typedef uint32_t uintptr_t; +#endif + + +#endif + diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/boards/board.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/boards/board.h new file mode 100644 index 0000000..27f34eb --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/boards/board.h @@ -0,0 +1,392 @@ +/** + * \file + * + * \brief Standard board header file. + * + * This file includes the appropriate board header file according to the + * defined board (parameter BOARD). + * + * Copyright (c) 2009-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +/** + * \defgroup group_common_boards Generic board support + * + * The generic board support module includes board-specific definitions + * and function prototypes, such as the board initialization function. + * + * \{ + */ + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + + +/*! \name Base Boards + */ +//! @{ +#define EVK1100 1 //!< AT32UC3A EVK1100 board. +#define EVK1101 2 //!< AT32UC3B EVK1101 board. +#define UC3C_EK 3 //!< AT32UC3C UC3C-EK board. +#define EVK1104 4 //!< AT32UC3A3 EVK1104 board. +#define EVK1105 5 //!< AT32UC3A EVK1105 board. +#define STK600_RCUC3L0 6 //!< STK600 RCUC3L0 board. +#define UC3L_EK 7 //!< AT32UC3L-EK board. +#define XPLAIN 8 //!< ATxmega128A1 Xplain board. +#define STK600_RC064X 10 //!< ATxmega256A3 STK600 board. +#define STK600_RC100X 11 //!< ATxmega128A1 STK600 board. +#define UC3_A3_XPLAINED 13 //!< ATUC3A3 UC3-A3 Xplained board. +#define UC3_L0_XPLAINED 15 //!< ATUC3L0 UC3-L0 Xplained board. +#define STK600_RCUC3D 16 //!< STK600 RCUC3D board. +#define STK600_RCUC3C0 17 //!< STK600 RCUC3C board. +#define XMEGA_B1_XPLAINED 18 //!< ATxmega128B1 Xplained board. +#define XMEGA_A1_XPLAINED 19 //!< ATxmega128A1 Xplain-A1 board. +#define XMEGA_A1U_XPLAINED_PRO 20 //!< ATxmega128A1U XMEGA-A1U Xplained Pro board. +#define STK600_RCUC3L4 21 //!< ATUCL4 STK600 board +#define UC3_L0_XPLAINED_BC 22 //!< ATUC3L0 UC3-L0 Xplained board controller board +#define MEGA1284P_XPLAINED_BC 23 //!< ATmega1284P-Xplained board controller board +#define STK600_RC044X 24 //!< STK600 with RC044X routing card board. +#define STK600_RCUC3B0 25 //!< STK600 RCUC3B0 board. +#define UC3_L0_QT600 26 //!< QT600 UC3L0 MCU board. +#define XMEGA_A3BU_XPLAINED 27 //!< ATxmega256A3BU Xplained board. +#define STK600_RC064X_LCDX 28 //!< XMEGAB3 STK600 RC064X LCDX board. +#define STK600_RC100X_LCDX 29 //!< XMEGAB1 STK600 RC100X LCDX board. +#define UC3B_BOARD_CONTROLLER 30 //!< AT32UC3B1 board controller for Atmel boards +#define RZ600 31 //!< AT32UC3A RZ600 MCU board +#define SAM3S_EK 32 //!< SAM3S-EK board. +#define SAM3U_EK 33 //!< SAM3U-EK board. +#define SAM3X_EK 34 //!< SAM3X-EK board. +#define SAM3N_EK 35 //!< SAM3N-EK board. +#define SAM3S_EK2 36 //!< SAM3S-EK2 board. +#define SAM4S_EK 37 //!< SAM4S-EK board. +#define STK600_RCUC3A0 38 //!< STK600 RCUC3A0 board. +#define STK600_MEGA 39 //!< STK600 MEGA board. +#define MEGA_1284P_XPLAINED 40 //!< ATmega1284P Xplained board. +#define SAM4S_XPLAINED 41 //!< SAM4S Xplained board. +#define ATXMEGA128A1_QT600 42 //!< QT600 ATXMEGA128A1 MCU board. +#define ARDUINO_DUE_X 43 //!< Arduino Due/X board. +#define STK600_RCUC3L3 44 //!< ATUCL3 STK600 board +#define SAM4L_EK 45 //!< SAM4L-EK board. +#define STK600_MEGA_RF 46 //!< STK600 MEGA RF EVK board. +#define XMEGA_C3_XPLAINED 47 //!< ATxmega384C3 Xplained board. +#define STK600_RC032X 48 //!< STK600 with RC032X routing card board. +#define SAM4S_EK2 49 //!< SAM4S-EK2 board. +#define XMEGA_E5_XPLAINED 50 //!< ATxmega32E5 Xplained board. +#define SAM4E_EK 51 //!< SAM4E-EK board. +#define ATMEGA256RFR2_XPLAINED_PRO 52 //!< ATmega256RFR2 Xplained Pro board. +#define SAM4S_XPLAINED_PRO 53 //!< SAM4S Xplained Pro board. +#define SAM4L_XPLAINED_PRO 54 //!< SAM4L Xplained Pro board. +#define ATMEGA256RFR2_ZIGBIT 55 //!< ATmega256RFR2 zigbit +#define XMEGA_RF233_ZIGBIT 56 //!< ATxmega256A3U with AT86RF233 Zigbit +#define XMEGA_RF212B_ZIGBIT 57 //!< ATxmega256A3U with AT86RF212B Zigbit +#define SAM4S_WPIR_RD 58 //!< SAM4S-WPIR-RD board. +#define SAMD20_XPLAINED_PRO 59 //!< SAM D20 Xplained Pro board +#define SAM4L8_XPLAINED_PRO 60 //!< SAM4L8 Xplained Pro board. +#define SAM4N_XPLAINED_PRO 61 //!< SAM4N Xplained Pro board. +#define XMEGA_A3_REB_CBB 62 //!< XMEGA REB Controller Base board. +#define ATMEGARFX_RCB 63 //!< RFR2 & RFA1 RCB +#define SAM4C_EK 64 //!< SAM4C-EK board. +#define RCB256RFR2_XPRO 65 //!< RFR2 RCB Xplained Pro board. +#define SAMG53_XPLAINED_PRO 66 //!< SAMG53 Xplained Pro board. +#define SAM4CP16BMB 67 //!< SAM4CP16BMB board. +#define SAM4E_XPLAINED_PRO 68 //!< SAM4E Xplained Pro board. +#define SAMD21_XPLAINED_PRO 69 //!< SAM D21 Xplained Pro board. +#define SAMR21_XPLAINED_PRO 70 //!< SAM R21 Xplained Pro board. +#define SAM4CMP_DB 71 //!< SAM4CMP demo board. +#define SAM4CMS_DB 72 //!< SAM4CMS demo board. +#define ATPL230AMB 73 //!< ATPL230AMB board. +#define SAMD11_XPLAINED_PRO 74 //!< SAM D11 Xplained Pro board. +#define SAMG55_XPLAINED_PRO 75 //!< SAMG55 Xplained Pro board. +#define SAML21_XPLAINED_PRO 76 //!< SAM L21 Xplained Pro board. +#define SIMULATOR_XMEGA_A1 97 //!< Simulator for XMEGA A1 devices +#define AVR_SIMULATOR_UC3 98 //!< Simulator for the AVR UC3 device family. +#define USER_BOARD 99 //!< User-reserved board (if any). +#define DUMMY_BOARD 100 //!< Dummy board to support board-independent applications (e.g. bootloader) +//! @} + +/*! \name Extension Boards + */ +//! @{ +#define EXT1102 1 //!< AT32UC3B EXT1102 board +#define MC300 2 //!< AT32UC3 MC300 board +#define SENSORS_XPLAINED_INERTIAL_1 3 //!< Xplained inertial sensor board 1 +#define SENSORS_XPLAINED_INERTIAL_2 4 //!< Xplained inertial sensor board 2 +#define SENSORS_XPLAINED_PRESSURE_1 5 //!< Xplained pressure sensor board +#define SENSORS_XPLAINED_LIGHTPROX_1 6 //!< Xplained light & proximity sensor board +#define SENSORS_XPLAINED_INERTIAL_A1 7 //!< Xplained inertial sensor board "A" +#define RZ600_AT86RF231 8 //!< AT86RF231 RF board in RZ600 +#define RZ600_AT86RF230B 9 //!< AT86RF230B RF board in RZ600 +#define RZ600_AT86RF212 10 //!< AT86RF212 RF board in RZ600 +#define SENSORS_XPLAINED_BREADBOARD 11 //!< Xplained sensor development breadboard +#define SECURITY_XPLAINED 12 //!< Xplained ATSHA204 board +#define USER_EXT_BOARD 99 //!< User-reserved extension board (if any). +//! @} + +#if BOARD == EVK1100 +# include "evk1100/evk1100.h" +#elif BOARD == EVK1101 +# include "evk1101/evk1101.h" +#elif BOARD == UC3C_EK +# include "uc3c_ek/uc3c_ek.h" +#elif BOARD == EVK1104 +# include "evk1104/evk1104.h" +#elif BOARD == EVK1105 +# include "evk1105/evk1105.h" +#elif BOARD == STK600_RCUC3L0 +# include "stk600/rcuc3l0/stk600_rcuc3l0.h" +#elif BOARD == UC3L_EK +# include "uc3l_ek/uc3l_ek.h" +#elif BOARD == STK600_RCUC3L4 +# include "stk600/rcuc3l4/stk600_rcuc3l4.h" +#elif BOARD == XPLAIN +# include "xplain/xplain.h" +#elif BOARD == STK600_MEGA + /*No header-file to include*/ +#elif BOARD == STK600_MEGA_RF +# include "stk600.h" +#elif BOARD == ATMEGA256RFR2_XPLAINED_PRO +# include "atmega256rfr2_xplained_pro/atmega256rfr2_xplained_pro.h" +#elif BOARD == ATMEGA256RFR2_ZIGBIT +# include "atmega256rfr2_zigbit/atmega256rfr2_zigbit.h" +#elif BOARD == STK600_RC032X +# include "stk600/rc032x/stk600_rc032x.h" +#elif BOARD == STK600_RC044X +# include "stk600/rc044x/stk600_rc044x.h" +#elif BOARD == STK600_RC064X +# include "stk600/rc064x/stk600_rc064x.h" +#elif BOARD == STK600_RC100X +# include "stk600/rc100x/stk600_rc100x.h" +#elif BOARD == UC3_A3_XPLAINED +# include "uc3_a3_xplained/uc3_a3_xplained.h" +#elif BOARD == UC3_L0_XPLAINED +# include "uc3_l0_xplained/uc3_l0_xplained.h" +#elif BOARD == STK600_RCUC3B0 +# include "stk600/rcuc3b0/stk600_rcuc3b0.h" +#elif BOARD == STK600_RCUC3D +# include "stk600/rcuc3d/stk600_rcuc3d.h" +#elif BOARD == STK600_RCUC3C0 +# include "stk600/rcuc3c0/stk600_rcuc3c0.h" +#elif BOARD == SAMG53_XPLAINED_PRO +# include "samg53_xplained_pro/samg53_xplained_pro.h" +#elif BOARD == SAMG55_XPLAINED_PRO +# include "samg55_xplained_pro/samg55_xplained_pro.h" +#elif BOARD == XMEGA_B1_XPLAINED +# include "xmega_b1_xplained/xmega_b1_xplained.h" +#elif BOARD == STK600_RC064X_LCDX +# include "stk600/rc064x_lcdx/stk600_rc064x_lcdx.h" +#elif BOARD == STK600_RC100X_LCDX +# include "stk600/rc100x_lcdx/stk600_rc100x_lcdx.h" +#elif BOARD == XMEGA_A1_XPLAINED +# include "xmega_a1_xplained/xmega_a1_xplained.h" +#elif BOARD == XMEGA_A1U_XPLAINED_PRO +# include "xmega_a1u_xplained_pro/xmega_a1u_xplained_pro.h" +#elif BOARD == UC3_L0_XPLAINED_BC +# include "uc3_l0_xplained_bc/uc3_l0_xplained_bc.h" +#elif BOARD == SAM3S_EK +# include "sam3s_ek/sam3s_ek.h" +# include "system_sam3s.h" +#elif BOARD == SAM3S_EK2 +# include "sam3s_ek2/sam3s_ek2.h" +# include "system_sam3sd8.h" +#elif BOARD == SAM3U_EK +# include "sam3u_ek/sam3u_ek.h" +# include "system_sam3u.h" +#elif BOARD == SAM3X_EK +# include "sam3x_ek/sam3x_ek.h" +# include "system_sam3x.h" +#elif BOARD == SAM3N_EK +# include "sam3n_ek/sam3n_ek.h" +# include "system_sam3n.h" +#elif BOARD == SAM4S_EK +# include "sam4s_ek/sam4s_ek.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_WPIR_RD +# include "sam4s_wpir_rd/sam4s_wpir_rd.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_XPLAINED +# include "sam4s_xplained/sam4s_xplained.h" +# include "system_sam4s.h" +#elif BOARD == SAM4S_EK2 +# include "sam4s_ek2/sam4s_ek2.h" +# include "system_sam4s.h" +#elif BOARD == MEGA_1284P_XPLAINED + /*No header-file to include*/ +#elif BOARD == ARDUINO_DUE_X +# include "arduino_due_x/arduino_due_x.h" +# include "system_sam3x.h" +#elif BOARD == SAM4L_EK +# include "sam4l_ek/sam4l_ek.h" +#elif BOARD == SAM4E_EK +# include "sam4e_ek/sam4e_ek.h" +#elif BOARD == SAMD20_XPLAINED_PRO +# include "samd20_xplained_pro/samd20_xplained_pro.h" +#elif BOARD == SAMD21_XPLAINED_PRO +# include "samd21_xplained_pro/samd21_xplained_pro.h" +#elif BOARD == SAMR21_XPLAINED_PRO +# include "samr21_xplained_pro/samr21_xplained_pro.h" +#elif BOARD == SAMD11_XPLAINED_PRO +# include "samd11_xplained_pro/samd11_xplained_pro.h" +#elif BOARD == SAML21_XPLAINED_PRO +# include "saml21_xplained_pro/saml21_xplained_pro.h" +#elif BOARD == SAM4N_XPLAINED_PRO +# include "sam4n_xplained_pro/sam4n_xplained_pro.h" +#elif BOARD == MEGA1284P_XPLAINED_BC +# include "mega1284p_xplained_bc/mega1284p_xplained_bc.h" +#elif BOARD == UC3_L0_QT600 +# include "uc3_l0_qt600/uc3_l0_qt600.h" +#elif BOARD == XMEGA_A3BU_XPLAINED +# include "xmega_a3bu_xplained/xmega_a3bu_xplained.h" +#elif BOARD == XMEGA_E5_XPLAINED +# include "xmega_e5_xplained/xmega_e5_xplained.h" +#elif BOARD == UC3B_BOARD_CONTROLLER +# include "uc3b_board_controller/uc3b_board_controller.h" +#elif BOARD == RZ600 +# include "rz600/rz600.h" +#elif BOARD == STK600_RCUC3A0 +# include "stk600/rcuc3a0/stk600_rcuc3a0.h" +#elif BOARD == ATXMEGA128A1_QT600 +# include "atxmega128a1_qt600/atxmega128a1_qt600.h" +#elif BOARD == STK600_RCUC3L3 +# include "stk600/rcuc3l3/stk600_rcuc3l3.h" +#elif BOARD == SAM4S_XPLAINED_PRO +# include "sam4s_xplained_pro/sam4s_xplained_pro.h" +#elif BOARD == SAM4L_XPLAINED_PRO +# include "sam4l_xplained_pro/sam4l_xplained_pro.h" +#elif BOARD == SAM4L8_XPLAINED_PRO +# include "sam4l8_xplained_pro/sam4l8_xplained_pro.h" +#elif BOARD == SAM4C_EK +# include "sam4c_ek/sam4c_ek.h" +#elif BOARD == SAM4CMP_DB +# include "sam4cmp_db/sam4cmp_db.h" +#elif BOARD == SAM4CMS_DB +# include "sam4cms_db/sam4cms_db.h" +#elif BOARD == SAM4CP16BMB +# include "sam4cp16bmb/sam4cp16bmb.h" +#elif BOARD == ATPL230AMB +# include "atpl230amb/atpl230amb.h" +#elif BOARD == SIMULATOR_XMEGA_A1 +# include "simulator/xmega_a1/simulator_xmega_a1.h" +#elif BOARD == XMEGA_C3_XPLAINED +# include "xmega_c3_xplained/xmega_c3_xplained.h" +#elif BOARD == XMEGA_RF233_ZIGBIT +# include "xmega_rf233_zigbit/xmega_rf233_zigbit.h" +#elif BOARD == XMEGA_A3_REB_CBB +# include "xmega_a3_reb_cbb/xmega_a3_reb_cbb.h" +#elif BOARD == ATMEGARFX_RCB +# include "atmegarfx_rcb/atmegarfx_rcb.h" +#elif BOARD == RCB256RFR2_XPRO +# include "atmega256rfr2_rcb_xpro/atmega256rfr2_rcb_xpro.h" +#elif BOARD == XMEGA_RF212B_ZIGBIT +# include "xmega_rf212b_zigbit/xmega_rf212b_zigbit.h" +#elif BOARD == SAM4E_XPLAINED_PRO +# include "sam4e_xplained_pro/sam4e_xplained_pro.h" +#elif BOARD == AVR_SIMULATOR_UC3 +# include "avr_simulator_uc3/avr_simulator_uc3.h" +#elif BOARD == USER_BOARD + // User-reserved area: #include the header file of your board here (if any). +# include "user_board.h" +#elif BOARD == DUMMY_BOARD +# include "dummy/dummy_board.h" +#else +# error No known Atmel board defined +#endif + +#if (defined EXT_BOARD) +# if EXT_BOARD == MC300 +# include "mc300/mc300.h" +# elif (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_2) || \ + (EXT_BOARD == SENSORS_XPLAINED_INERTIAL_A1) || \ + (EXT_BOARD == SENSORS_XPLAINED_PRESSURE_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_LIGHTPROX_1) || \ + (EXT_BOARD == SENSORS_XPLAINED_BREADBOARD) +# include "sensors_xplained/sensors_xplained.h" +# elif EXT_BOARD == RZ600_AT86RF231 +# include "at86rf231/at86rf231.h" +# elif EXT_BOARD == RZ600_AT86RF230B +# include "at86rf230b/at86rf230b.h" +# elif EXT_BOARD == RZ600_AT86RF212 +# include "at86rf212/at86rf212.h" +# elif EXT_BOARD == SECURITY_XPLAINED +# include "security_xplained.h" +# elif EXT_BOARD == USER_EXT_BOARD + // User-reserved area: #include the header file of your extension board here + // (if any). +# endif +#endif + + +#if (defined(__GNUC__) && defined(__AVR32__)) || (defined(__ICCAVR32__) || defined(__AAVR32__)) +#ifdef __AVR32_ABI_COMPILER__ // Automatically defined when compiling for AVR32, not when assembling. + +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); + +#endif // #ifdef __AVR32_ABI_COMPILER__ +#else +/*! \brief This function initializes the board target resources + * + * This function should be called to ensure proper initialization of the target + * board hardware connected to the part. + */ +extern void board_init(void); +#endif + + +#ifdef __cplusplus +} +#endif + +/** + * \} + */ + +#endif // _BOARD_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek/conf_example.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek/conf_example.h new file mode 100644 index 0000000..0b257ab --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/example1/sam4e16e_sam4e_ek/conf_example.h @@ -0,0 +1,61 @@ +/*! \file + * + * \brief Example configuration. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_EXAMPLE_H_INCLUDED +#define CONF_EXAMPLE_H_INCLUDED + + +/** USART Interface : Console UART */ +#define CONF_TEST_USART CONSOLE_UART +/** Baudrate setting : 115200 */ +#define CONF_TEST_BAUDRATE 115200 +/** Char setting : 8-bit character length (don't care for UART) */ +#define CONF_TEST_CHARLENGTH 0 +/** Parity setting : No parity check */ +#define CONF_TEST_PARITY UART_MR_PAR_NO +/** Stopbit setting : No extra stopbit, i.e., use 1 (don't care for UART) */ +#define CONF_TEST_STOPBITS false + +#endif /* CONF_EXAMPLE_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.c new file mode 100644 index 0000000..a6adf74 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.c @@ -0,0 +1,2141 @@ +/** + * \file + * + * \brief Common SD/MMC stack + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include +#include "conf_board.h" +#include "board.h" +#include "conf_sd_mmc.h" +#include "sd_mmc_protocol.h" +#include "sd_mmc.h" +#include "delay.h" +#include "ioport.h" + +#ifdef FREERTOS_USED +#include "FreeRTOS.h" +#include "task.h" +#include "portmacro.h" +#include "projdefs.h" +#endif + +/** + * \ingroup sd_mmc_stack + * \defgroup sd_mmc_stack_internal Implementation of SD/MMC/SDIO Stack + * @{ + */ + +// Enable debug information for SD/MMC module +#ifdef SD_MMC_DEBUG +# include +# define sd_mmc_debug(...) printf(__VA_ARGS__) +#else +# define sd_mmc_debug(...) +#endif + +#ifndef SD_MMC_SPI_MEM_CNT +# define SD_MMC_SPI_MEM_CNT 0 +#endif +#ifndef SD_MMC_MCI_MEM_CNT +# define SD_MMC_MCI_MEM_CNT 0 +#endif +#ifndef SD_MMC_HSMCI_MEM_CNT +# define SD_MMC_HSMCI_MEM_CNT 0 +#endif + +// Macros to switch SD MMC stack to the correct driver (MCI or SPI) +#ifdef SD_MMC_SPI_MODE +# if (SD_MMC_SPI_MEM_CNT != 0) +# include "sd_mmc_spi.h" +# define driver sd_mmc_spi +# define SD_MMC_MEM_CNT SD_MMC_SPI_MEM_CNT +# define sd_mmc_is_spi() true +# else +# error No SPI interface is defined for SD MMC stack. \ + SD_MMC_SPI_MEM_CNT must be added in board.h file. +# endif +#else +# if (SD_MMC_HSMCI_MEM_CNT != 0) +# include "hsmci.h" +# define driver hsmci +# define SD_MMC_MEM_CNT SD_MMC_HSMCI_MEM_CNT +# define sd_mmc_is_spi() false +# elif (SD_MMC_MCI_MEM_CNT != 0) +# include "mci.h" +# define driver mci +# define SD_MMC_MEM_CNT SD_MMC_MCI_MEM_CNT +# define sd_mmc_is_spi() false +# else +# error No MCI or HSMCI interfaces are defined for SD MMC stack. \ + SD_MMC_MCI_MEM_CNT or SD_MMC_HSMCI_MEM_CNT must be added in board.h file. +# endif +#endif + + +#define driver_init ATPASTE2(driver, _init) +#define driver_select_device ATPASTE2(driver, _select_device) +#define driver_deselect_device ATPASTE2(driver, _deselect_device) +#define driver_get_bus_width ATPASTE2(driver, _get_bus_width) +#define driver_is_high_speed_capable ATPASTE2(driver, _is_high_speed_capable) +#define driver_send_clock ATPASTE2(driver, _send_clock) +#define driver_send_cmd ATPASTE2(driver, _send_cmd) +#define driver_get_response ATPASTE2(driver, _get_response) +#define driver_get_response_128 ATPASTE2(driver, _get_response_128) +#define driver_adtc_start ATPASTE2(driver, _adtc_start) +#define driver_adtc_stop ATPASTE2(driver, _send_cmd) +#define driver_read_word ATPASTE2(driver, _read_word) +#define driver_write_word ATPASTE2(driver, _write_word) +#define driver_start_read_blocks ATPASTE2(driver, _start_read_blocks) +#define driver_wait_end_of_read_blocks ATPASTE2(driver, _wait_end_of_read_blocks) +#define driver_start_write_blocks ATPASTE2(driver, _start_write_blocks) +#define driver_wait_end_of_write_blocks ATPASTE2(driver, _wait_end_of_write_blocks) + + +#if (!defined SD_MMC_0_CD_GPIO) || (!defined SD_MMC_0_CD_DETECT_VALUE) +# warning No pin for card detection has been defined in board.h. \ + The define SD_MMC_0_CD_GPIO, SD_MMC_0_CD_DETECT_VALUE must be added in board.h file. +#endif + +#ifdef SDIO_SUPPORT_ENABLE +# define IS_SDIO() (sd_mmc_card->type & CARD_TYPE_SDIO) +#else +# define IS_SDIO() false +#endif + +#define sd_mmc_is_mci() (!sd_mmc_is_spi()) + +//! This SD MMC stack supports only the high voltage +#define SD_MMC_VOLTAGE_SUPPORT \ + (OCR_VDD_27_28 | OCR_VDD_28_29 | \ + OCR_VDD_29_30 | OCR_VDD_30_31 | \ + OCR_VDD_31_32 | OCR_VDD_32_33) + +//! SD/MMC card states +enum card_state { + SD_MMC_CARD_STATE_READY = 0, //!< Ready to use + SD_MMC_CARD_STATE_DEBOUNCE = 1, //!< Debounce on going + SD_MMC_CARD_STATE_INIT = 2, //!< Initialization on going + SD_MMC_CARD_STATE_UNUSABLE = 3, //!< Unusable card + SD_MMC_CARD_STATE_NO_CARD = 4, //!< No SD/MMC card inserted +}; + +//! SD/MMC card information structure +struct sd_mmc_card { + uint32_t clock; //!< Card access clock + uint32_t capacity; //!< Card capacity in KBytes +#if (defined SD_MMC_0_CD_GPIO) + uint32_t cd_gpio; //!< Card detect GPIO +# if (defined SD_MMC_0_WP_GPIO) + uint32_t wp_gpio; //!< Card write protection GPIO +# endif +#endif + uint16_t rca; //!< Relative card address + enum card_state state; //!< Card state + card_type_t type; //!< Card type + card_version_t version; //!< Card version + uint8_t bus_width; //!< Number of DATA lin on bus (MCI only) + uint8_t csd[CSD_REG_BSIZE];//!< CSD register + uint8_t high_speed; //!< High speed card (1) +}; + +//! SD/MMC card list +//! Note: Initialize card detect pin fields if present +static struct sd_mmc_card sd_mmc_cards[SD_MMC_MEM_CNT] +#if (defined SD_MMC_0_CD_GPIO) && (defined SD_MMC_0_WP_GPIO) + = { +# define SD_MMC_CD_WP(slot, unused) \ + {.cd_gpio = SD_MMC_##slot##_CD_GPIO, \ + .wp_gpio = SD_MMC_##slot##_WP_GPIO}, + MREPEAT(SD_MMC_MEM_CNT, SD_MMC_CD_WP, ~) +# undef SD_MMC_CD_WP +} +#elif (defined SD_MMC_0_CD_GPIO) + = { +# define SD_MMC_CD(slot, unused) \ + {.cd_gpio = SD_MMC_##slot##_CD_GPIO}, + MREPEAT(SD_MMC_MEM_CNT, SD_MMC_CD, ~) +# undef SD_MMC_CD +} +#endif +; + +//! Index of current slot configurated +static uint8_t sd_mmc_slot_sel; +//! Pointer on current slot configurated +static struct sd_mmc_card *sd_mmc_card; +//! Number of block to read or write on the current transfer +static uint16_t sd_mmc_nb_block_to_tranfer = 0; +//! Number of block remaining to read or write on the current transfer +static uint16_t sd_mmc_nb_block_remaining = 0; + +//! SD/MMC transfer rate unit codes (10K) list +const uint32_t sd_mmc_trans_units[7] = { + 10, 100, 1000, 10000, 0, 0, 0 +}; +//! SD transfer multiplier factor codes (1/10) list +const uint32_t sd_trans_multipliers[16] = { + 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 +}; +//! MMC transfer multiplier factor codes (1/10) list +const uint32_t mmc_trans_multipliers[16] = { + 0, 10, 12, 13, 15, 20, 26, 30, 35, 40, 45, 52, 55, 60, 70, 80 +}; + +//! \name MMC, SD and SDIO commands process +//! @{ +static bool mmc_spi_op_cond(void); +static bool mmc_mci_op_cond(void); +static bool sd_spi_op_cond(uint8_t v2); +static bool sd_mci_op_cond(uint8_t v2); +static bool sdio_op_cond(void); +static bool sdio_get_max_speed(void); +static bool sdio_cmd52_set_bus_width(void); +static bool sdio_cmd52_set_high_speed(void); +static bool sd_cm6_set_high_speed(void); +static bool mmc_cmd6_set_bus_width(uint8_t bus_width); +static bool mmc_cmd6_set_high_speed(void); +static bool sd_cmd8(uint8_t * v2); +static bool mmc_cmd8(uint8_t *b_authorize_high_speed); +static bool sd_mmc_cmd9_spi(void); +static bool sd_mmc_cmd9_mci(void); +static void mmc_decode_csd(void); +static void sd_decode_csd(void); +static bool sd_mmc_cmd13(void); +#ifdef SDIO_SUPPORT_ENABLE +static bool sdio_cmd52(uint8_t rw_flag, uint8_t func_nb, + uint32_t reg_addr, uint8_t rd_after_wr, uint8_t *io_data); +static bool sdio_cmd53(uint8_t rw_flag, uint8_t func_nb, uint32_t reg_addr, + uint8_t inc_addr, uint32_t size, bool access_block); +#endif // SDIO_SUPPORT_ENABLE +static bool sd_acmd6(void); +static bool sd_acmd51(void); +//! @} + +//! \name Internal function to process the initialization and install +//! @{ +static sd_mmc_err_t sd_mmc_select_slot(uint8_t slot); +static void sd_mmc_configure_slot(void); +static void sd_mmc_deselect_slot(void); +static bool sd_mmc_spi_card_init(void); +static bool sd_mmc_mci_card_init(void); +static bool sd_mmc_spi_install_mmc(void); +static bool sd_mmc_mci_install_mmc(void); +//! @} + + +//! \name Internal functions to manage a large timeout after a card insertion +//! @{ +#define SD_MMC_DEBOUNCE_TIMEOUT 1000 // Unit ms + +#if XMEGA +# define SD_MMC_START_TIMEOUT() delay_ms(SD_MMC_DEBOUNCE_TIMEOUT) +# define SD_MMC_IS_TIMEOUT() true +# define SD_MMC_STOP_TIMEOUT() +#endif + +#if UC3 +static t_cpu_time timer; +# define SD_MMC_START_TIMEOUT() \ + cpu_set_timeout(cpu_ms_2_cy(SD_MMC_DEBOUNCE_TIMEOUT, sysclk_get_cpu_hz()), &timer) +# define SD_MMC_IS_TIMEOUT() \ + cpu_is_timeout(&timer) +# define SD_MMC_STOP_TIMEOUT() +#endif + +#if SAM +static bool sd_mmc_sam_systick_used; +# ifdef FREERTOS_USED + static xTimeOutType xTimeOut; +#endif + +static inline void SD_MMC_START_TIMEOUT(void) +{ + if (!SysTick->CTRL) { + sd_mmc_sam_systick_used = true; + SysTick->LOAD = (sysclk_get_cpu_hz() / (8 * 1000)) + * SD_MMC_DEBOUNCE_TIMEOUT; + SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; + } else { + sd_mmc_sam_systick_used = false; +#ifdef FREERTOS_USED + // Note: the define INCLUDE_vTaskDelay must be set to one + // in FreeRTOSConfig.h file. + vTaskSetTimeOutState(&xTimeOut); +#else + delay_ms(SD_MMC_DEBOUNCE_TIMEOUT); +#endif + } +} + +static inline bool SD_MMC_IS_TIMEOUT(void) +{ + if (!sd_mmc_sam_systick_used) { +#ifdef FREERTOS_USED + portTickType xTicksToWait = + SD_MMC_DEBOUNCE_TIMEOUT / portTICK_RATE_MS; + return (xTaskCheckForTimeOut( &xTimeOut, &xTicksToWait ) == pdTRUE); +#else + return true; +#endif + } + if (SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) { + SysTick->CTRL = 0; + return true; + } + return false; +} + +static inline void SD_MMC_STOP_TIMEOUT(void) +{ + if (sd_mmc_sam_systick_used) { + SysTick->CTRL = 0; + } +} +#endif +//! @} + +/** + * \brief Sends operation condition command and read OCR (SPI only) + * - CMD1 sends operation condition command + * - CMD58 reads OCR + * + * \return true if success, otherwise false + */ +static bool mmc_spi_op_cond(void) +{ + uint32_t retry, resp; + + /* + * Timeout 1s = 400KHz / ((6+1)*8) cylces = 7150 retry + * 6 = cmd byte size + * 1 = response byte size + */ + retry = 7150; + do { + if (!driver_send_cmd(MMC_SPI_CMD1_SEND_OP_COND, 0)) { + sd_mmc_debug("%s: CMD1 SPI Fail - Busy retry %d\n\r", + __func__, (int)(7150 - retry)); + return false; + } + // Check busy flag + resp = driver_get_response(); + if (!(resp & R1_SPI_IDLE)) { + break; + } + if (retry-- == 0) { + sd_mmc_debug("%s: CMD1 Timeout on busy\n\r", __func__); + return false; + } + } while (1); + + // Read OCR for SPI mode + if (!driver_send_cmd(SDMMC_SPI_CMD58_READ_OCR, 0)) { + sd_mmc_debug("%s: CMD58 Fail\n\r", __func__); + return false; + } + // Check OCR value + if ((driver_get_response() & OCR_ACCESS_MODE_MASK) + == OCR_ACCESS_MODE_SECTOR) { + sd_mmc_card->type |= CARD_TYPE_HC; + } + return true; +} + +/** + * \brief Sends operation condition command and read OCR (MCI only) + * - CMD1 sends operation condition command + * - CMD1 reads OCR + * + * \return true if success, otherwise false + */ +static bool mmc_mci_op_cond(void) +{ + uint32_t retry, resp; + + /* + * Timeout 1s = 400KHz / ((6+6)*8) cylces = 4200 retry + * 6 = cmd byte size + * 6 = response byte size + */ + retry = 4200; + do { + if (!driver_send_cmd(MMC_MCI_CMD1_SEND_OP_COND, + SD_MMC_VOLTAGE_SUPPORT | OCR_ACCESS_MODE_SECTOR)) { + sd_mmc_debug("%s: CMD1 MCI Fail - Busy retry %d\n\r", + __func__, (int)(4200 - retry)); + return false; + } + // Check busy flag + resp = driver_get_response(); + if (resp & OCR_POWER_UP_BUSY) { + // Check OCR value + if ((resp & OCR_ACCESS_MODE_MASK) + == OCR_ACCESS_MODE_SECTOR) { + sd_mmc_card->type |= CARD_TYPE_HC; + } + break; + } + if (retry-- == 0) { + sd_mmc_debug("%s: CMD1 Timeout on busy\n\r", __func__); + return false; + } + } while (1); + return true; +} + +/** + * \brief Ask to all cards to send their operations conditions (SPI only). + * - ACMD41 sends operation condition command. + * - CMD58 reads OCR + * + * \param v2 Shall be 1 if it is a SD card V2 + * + * \return true if success, otherwise false + */ +static bool sd_spi_op_cond(uint8_t v2) +{ + uint32_t arg, retry, resp; + + /* + * Timeout 1s = 400KHz / ((6+1)*8) cylces = 7150 retry + * 6 = cmd byte size + * 1 = response byte size + */ + retry = 7150; + do { + // CMD55 - Indicate to the card that the next command is an + // application specific command rather than a standard command. + if (!driver_send_cmd(SDMMC_CMD55_APP_CMD, 0)) { + sd_mmc_debug("%s: CMD55 Fail\n\r", __func__); + return false; + } + + // (ACMD41) Sends host OCR register + arg = 0; + if (v2) { + arg |= SD_ACMD41_HCS; + } + // Check response + if (!driver_send_cmd(SD_SPI_ACMD41_SD_SEND_OP_COND, arg)) { + sd_mmc_debug("%s: ACMD41 Fail\n\r", __func__); + return false; + } + resp = driver_get_response(); + if (!(resp & R1_SPI_IDLE)) { + // Card is ready + break; + } + if (retry-- == 0) { + sd_mmc_debug("%s: ACMD41 Timeout on busy, resp32 0x%08x \n\r", + __func__, resp); + return false; + } + } while (1); + + // Read OCR for SPI mode + if (!driver_send_cmd(SDMMC_SPI_CMD58_READ_OCR, 0)) { + sd_mmc_debug("%s: CMD58 Fail\n\r", __func__); + return false; + } + if ((driver_get_response() & OCR_CCS) != 0) { + sd_mmc_card->type |= CARD_TYPE_HC; + } + return true; +} + +/** + * \brief Ask to all cards to send their operations conditions (MCI only). + * - ACMD41 sends operation condition command. + * - ACMD41 reads OCR + * + * \param v2 Shall be 1 if it is a SD card V2 + * + * \return true if success, otherwise false + */ +static bool sd_mci_op_cond(uint8_t v2) +{ + uint32_t arg, retry, resp; + + /* + * Timeout 1s = 400KHz / ((6+6+6+6)*8) cylces = 2100 retry + * 6 = cmd byte size + * 6 = response byte size + * 6 = cmd byte size + * 6 = response byte size + */ + retry = 2100; + do { + // CMD55 - Indicate to the card that the next command is an + // application specific command rather than a standard command. + if (!driver_send_cmd(SDMMC_CMD55_APP_CMD, 0)) { + sd_mmc_debug("%s: CMD55 Fail\n\r", __func__); + return false; + } + + // (ACMD41) Sends host OCR register + arg = SD_MMC_VOLTAGE_SUPPORT; + if (v2) { + arg |= SD_ACMD41_HCS; + } + // Check response + if (!driver_send_cmd(SD_MCI_ACMD41_SD_SEND_OP_COND, arg)) { + sd_mmc_debug("%s: ACMD41 Fail\n\r", __func__); + return false; + } + resp = driver_get_response(); + if (resp & OCR_POWER_UP_BUSY) { + // Card is ready + if ((resp & OCR_CCS) != 0) { + sd_mmc_card->type |= CARD_TYPE_HC; + } + break; + } + if (retry-- == 0) { + sd_mmc_debug("%s: ACMD41 Timeout on busy, resp32 0x%08x \n\r", + __func__, resp); + return false; + } + } while (1); + return true; +} + +#ifdef SDIO_SUPPORT_ENABLE +/** + * \brief Try to get the SDIO card's operating condition + * - CMD5 to read OCR NF field + * - CMD5 to wait OCR power up busy + * - CMD5 to read OCR MP field + * sd_mmc_card->type is updated + * + * \return true if success, otherwise false + */ +static bool sdio_op_cond(void) +{ + uint32_t resp; + + // CMD5 - SDIO send operation condition (OCR) command. + if (!driver_send_cmd(SDIO_CMD5_SEND_OP_COND, 0)) { + sd_mmc_debug("%s: CMD5 Fail\n\r", __func__); + return true; // No error but card type not updated + } + resp = driver_get_response(); + if ((resp & OCR_SDIO_NF) == 0) { + return true; // No error but card type not updated + } + + /* + * Wait card ready + * Timeout 1s = 400KHz / ((6+4)*8) cylces = 5000 retry + * 6 = cmd byte size + * 4(SPI) 6(MCI) = response byte size + */ + uint32_t cmd5_retry = 5000; + while (1) { + // CMD5 - SDIO send operation condition (OCR) command. + if (!driver_send_cmd(SDIO_CMD5_SEND_OP_COND, + resp & SD_MMC_VOLTAGE_SUPPORT)) { + sd_mmc_debug("%s: CMD5 Fail\n\r", __func__); + return false; + } + resp = driver_get_response(); + if ((resp & OCR_POWER_UP_BUSY) == OCR_POWER_UP_BUSY) { + break; + } + if (cmd5_retry-- == 0) { + sd_mmc_debug("%s: CMD5 Timeout on busy\n\r", __func__); + return false; + } + } + // Update card type at the end of busy + if ((resp & OCR_SDIO_MP) > 0) { + sd_mmc_card->type = CARD_TYPE_SD_COMBO; + } else { + sd_mmc_card->type = CARD_TYPE_SDIO; + } + return true; // No error and card type updated with SDIO type +} + +/** + * \brief Get SDIO max transfer speed in Hz. + * - CMD53 reads CIS area address in CCCR area. + * - Nx CMD53 search Fun0 tuple in CIS area + * - CMD53 reads TPLFE_MAX_TRAN_SPEED in Fun0 tuple + * - Compute maximum speed of SDIO + * and update sd_mmc_card->clock + * + * \return true if success, otherwise false + */ +static bool sdio_get_max_speed(void) +{ + uint32_t addr, addr_cis; + uint8_t buf[6]; + uint32_t unit; + uint32_t mul; + uint8_t tplfe_max_tran_speed; + + // Read CIS area address in CCCR area + addr_cis = 0; // Init all bytes, because the next function fill 3 bytes only + if (!sdio_cmd53(SDIO_CMD53_READ_FLAG, SDIO_CIA, SDIO_CCCR_CIS_PTR, + 1, 3, true)) { + sd_mmc_debug("%s: CMD53 Read CIS Fail\n\r", __func__); + return false; + } + if (!driver_start_read_blocks((uint8_t *)&addr_cis, 1)) { + return false; + } + if (!driver_wait_end_of_read_blocks()) { + return false; + } + addr_cis = le32_to_cpu(addr_cis); + + // Search Fun0 tuple in the CIA area + addr = addr_cis; + while (1) { + // Read a sample of CIA area + if (!sdio_cmd53(SDIO_CMD53_READ_FLAG, SDIO_CIA, addr, 1, 3, true)) { + sd_mmc_debug("%s: CMD53 Read CIA Fail\n\r", __func__); + return false; + } + if (!driver_start_read_blocks(buf, 1)) { + return false; + } + if (!driver_wait_end_of_read_blocks()) { + return false; + } + if (buf[0] == SDIO_CISTPL_END) { + sd_mmc_debug("%s: CMD53 Tuple error\n\r", __func__); + return false; // Tuple error + } + if (buf[0] == SDIO_CISTPL_FUNCE && buf[2] == 0x00) { + break; // Fun0 tuple found + } + if (buf[1] == 0) { + sd_mmc_debug("%s: CMD53 Tuple error\n\r", __func__); + return false; // Tuple error + } + + // Next address + addr += (buf[1] + 2); + if (addr > (addr_cis + 256)) { + sd_mmc_debug("%s: CMD53 Outoff CIS area\n\r", __func__); + return false; // Outoff CIS area + } + } + + // Read all Fun0 tuple fields: fn0_blk_siz & max_tran_speed + if (!sdio_cmd53(SDIO_CMD53_READ_FLAG, SDIO_CIA, addr, 1, 6, true)) { + sd_mmc_debug("%s: CMD53 Read all Fun0 Fail\n\r", __func__); + return false; + } + if (!driver_start_read_blocks(buf, 1)) { + return false; + } + if (!driver_wait_end_of_read_blocks()) { + return false; + } + tplfe_max_tran_speed = buf[5]; + if (tplfe_max_tran_speed > 0x32) { + /* Error on SDIO register, the high speed is not activated + * and the clock can not be more than 25MHz. + * This error is present on specific SDIO card + * (H&D wireless card - HDG104 WiFi SIP). + */ + tplfe_max_tran_speed = 0x32; // 25Mhz + } + + // Decode transfer speed in Hz. + unit = sd_mmc_trans_units[tplfe_max_tran_speed & 0x7]; + mul = sd_trans_multipliers[(tplfe_max_tran_speed >> 3) & 0xF]; + sd_mmc_card->clock = unit * mul * 1000; + /** + * Note: A combo card shall be a Full-Speed SDIO card + * which supports upto 25MHz. + * A SDIO card alone can be: + * - a Low-Speed SDIO card which supports 400Khz minimum + * - a Full-Speed SDIO card which supports upto 25MHz + */ + return true; +} + +/** + * \brief CMD52 for SDIO - Switches the bus width mode to 4 + * + * \note sd_mmc_card->bus_width is updated. + * + * \return true if success, otherwise false + */ +static bool sdio_cmd52_set_bus_width(void) +{ + /** + * A SD memory card always supports bus 4bit + * A SD COMBO card always supports bus 4bit + * A SDIO Full-Speed alone always supports 4bit + * A SDIO Low-Speed alone can supports 4bit (Optional) + */ + uint8_t u8_value; + + // Check 4bit support in 4BLS of "Card Capability" register + if (!sdio_cmd52(SDIO_CMD52_READ_FLAG, SDIO_CIA, SDIO_CCCR_CAP, + 0, &u8_value)) { + return false; + } + if ((u8_value & SDIO_CAP_4BLS) != SDIO_CAP_4BLS) { + // No supported, it is not a protocol error + return true; + } + // HS mode possible, then enable + u8_value = SDIO_BUSWIDTH_4B; + if (!sdio_cmd52(SDIO_CMD52_WRITE_FLAG, SDIO_CIA, SDIO_CCCR_BUS_CTRL, + 1, &u8_value)) { + return false; + } + sd_mmc_card->bus_width = 4; + sd_mmc_debug("%d-bit bus width enabled.\n\r", (int)sd_mmc_card->bus_width); + return true; +} + +/** + * \brief CMD52 for SDIO - Enable the high speed mode + * + * \note sd_mmc_card->high_speed is updated. + * \note sd_mmc_card->clock is updated. + * + * \return true if success, otherwise false + */ +static bool sdio_cmd52_set_high_speed(void) +{ + uint8_t u8_value; + + // Check CIA.HS + if (!sdio_cmd52(SDIO_CMD52_READ_FLAG, SDIO_CIA, SDIO_CCCR_HS, 0, &u8_value)) { + return false; + } + if ((u8_value & SDIO_SHS) != SDIO_SHS) { + // No supported, it is not a protocol error + return true; + } + // HS mode possible, then enable + u8_value = SDIO_EHS; + if (!sdio_cmd52(SDIO_CMD52_WRITE_FLAG, SDIO_CIA, SDIO_CCCR_HS, + 1, &u8_value)) { + return false; + } + sd_mmc_card->high_speed = 1; + sd_mmc_card->clock *= 2; + return true; +} + +#else +static bool sdio_op_cond(void) +{ + return true; // No error but card type not updated +} +static bool sdio_get_max_speed(void) +{ + return false; +} +static bool sdio_cmd52_set_bus_width(void) +{ + return false; +} +static bool sdio_cmd52_set_high_speed(void) +{ + return false; +} +#endif // SDIO_SUPPORT_ENABLE + +/** + * \brief CMD6 for SD - Switch card in high speed mode + * + * \note CMD6 for SD is valid under the "trans" state. + * \note sd_mmc_card->high_speed is updated. + * \note sd_mmc_card->clock is updated. + * + * \return true if success, otherwise false + */ +static bool sd_cm6_set_high_speed(void) +{ + uint8_t switch_status[SD_SW_STATUS_BSIZE]; + + if (!driver_adtc_start(SD_CMD6_SWITCH_FUNC, + SD_CMD6_MODE_SWITCH + | SD_CMD6_GRP6_NO_INFLUENCE + | SD_CMD6_GRP5_NO_INFLUENCE + | SD_CMD6_GRP4_NO_INFLUENCE + | SD_CMD6_GRP3_NO_INFLUENCE + | SD_CMD6_GRP2_DEFAULT + | SD_CMD6_GRP1_HIGH_SPEED, + SD_SW_STATUS_BSIZE, 1, true)) { + return false; + } + if (!driver_start_read_blocks(switch_status, 1)) { + return false; + } + if (!driver_wait_end_of_read_blocks()) { + return false; + } + + if (driver_get_response() & CARD_STATUS_SWITCH_ERROR) { + sd_mmc_debug("%s: CMD6 CARD_STATUS_SWITCH_ERROR\n\r", __func__); + return false; + } + if (SD_SW_STATUS_FUN_GRP1_RC(switch_status) + == SD_SW_STATUS_FUN_GRP_RC_ERROR) { + // No supported, it is not a protocol error + return true; + } + if (SD_SW_STATUS_FUN_GRP1_BUSY(switch_status)) { + sd_mmc_debug("%s: CMD6 SD_SW_STATUS_FUN_GRP1_BUSY\n\r", __func__); + return false; + } + // CMD6 function switching period is within 8 clocks + // after the end bit of status data. + driver_send_clock(); + sd_mmc_card->high_speed = 1; + sd_mmc_card->clock *= 2; + return true; +} + +/** + * \brief CMD6 for MMC - Switches the bus width mode + * + * \note CMD6 is valid under the "trans" state. + * \note sd_mmc_card->bus_width is updated. + * + * \param bus_width Bus width to set + * + * \return true if success, otherwise false + */ +static bool mmc_cmd6_set_bus_width(uint8_t bus_width) +{ + uint32_t arg; + + switch (bus_width) { + case 8: + arg = MMC_CMD6_ACCESS_SET_BITS + | MMC_CMD6_INDEX_BUS_WIDTH + | MMC_CMD6_VALUE_BUS_WIDTH_8BIT; + break; + case 4: + arg = MMC_CMD6_ACCESS_SET_BITS + | MMC_CMD6_INDEX_BUS_WIDTH + | MMC_CMD6_VALUE_BUS_WIDTH_4BIT; + break; + default: + arg = MMC_CMD6_ACCESS_SET_BITS + | MMC_CMD6_INDEX_BUS_WIDTH + | MMC_CMD6_VALUE_BUS_WIDTH_1BIT; + break; + } + if (!driver_send_cmd(MMC_CMD6_SWITCH, arg)) { + return false; + } + if (driver_get_response() & CARD_STATUS_SWITCH_ERROR) { + // No supported, it is not a protocol error + sd_mmc_debug("%s: CMD6 CARD_STATUS_SWITCH_ERROR\n\r", __func__); + return false; + } + sd_mmc_card->bus_width = bus_width; + sd_mmc_debug("%d-bit bus width enabled.\n\r", (int)sd_mmc_card->bus_width); + return true; +} + +/** + * \brief CMD6 for MMC - Switches in high speed mode + * + * \note CMD6 is valid under the "trans" state. + * \note sd_mmc_card->high_speed is updated. + * \note sd_mmc_card->clock is updated. + * + * \return true if success, otherwise false + */ +static bool mmc_cmd6_set_high_speed(void) +{ + if (!driver_send_cmd(MMC_CMD6_SWITCH, + MMC_CMD6_ACCESS_WRITE_BYTE + | MMC_CMD6_INDEX_HS_TIMING + | MMC_CMD6_VALUE_HS_TIMING_ENABLE)) { + return false; + } + if (driver_get_response() & CARD_STATUS_SWITCH_ERROR) { + // No supported, it is not a protocol error + sd_mmc_debug("%s: CMD6 CARD_STATUS_SWITCH_ERROR\n\r", __func__); + return false; + } + sd_mmc_card->high_speed = 1; + sd_mmc_card->clock = 52000000lu; + return true; +} + +/** + * \brief CMD8 for SD card - Send Interface Condition Command. + * + * \note + * Send SD Memory Card interface condition, which includes host supply + * voltage information and asks the card whether card supports voltage. + * Should be performed at initialization time to detect the card type. + * + * \param v2 Pointer to v2 flag to update + * + * \return true if success, otherwise false + * with a update of \ref sd_mmc_err. + */ +static bool sd_cmd8(uint8_t * v2) +{ + uint32_t resp; + + *v2 = 0; + // Test for SD version 2 + if (!driver_send_cmd(SD_CMD8_SEND_IF_COND, + SD_CMD8_PATTERN | SD_CMD8_HIGH_VOLTAGE)) { + return true; // It is not a V2 + } + // Check R7 response + resp = driver_get_response(); + if (resp == 0xFFFFFFFF) { + // No compliance R7 value + return true; // It is not a V2 + } + if ((resp & (SD_CMD8_MASK_PATTERN | SD_CMD8_MASK_VOLTAGE)) + != (SD_CMD8_PATTERN | SD_CMD8_HIGH_VOLTAGE)) { + sd_mmc_debug("%s: CMD8 resp32 0x%08x UNUSABLE CARD\n\r", + __func__, resp); + return false; + } + sd_mmc_debug("SD card V2\n\r"); + *v2 = 1; + return true; +} + +/** + * \brief CMD8 - The card sends its EXT_CSD register as a block of data. + * + * \param b_authorize_high_speed Pointer to update with the high speed + * support information + * + * \return true if success, otherwise false + */ +static bool mmc_cmd8(uint8_t *b_authorize_high_speed) +{ + uint16_t i; + uint32_t ext_csd; + uint32_t sec_count; + + if (!driver_adtc_start(MMC_CMD8_SEND_EXT_CSD, 0, + EXT_CSD_BSIZE, 1, false)) { + return false; + } + //** Read and decode Extended Extended CSD + // Note: The read access is done in byte to avoid a buffer + // of EXT_CSD_BSIZE Byte in stack. + + // Read card type + for (i = 0; i < (EXT_CSD_CARD_TYPE_INDEX + 4) / 4; i++) { + if (!driver_read_word(&ext_csd)) { + return false; + } + } + *b_authorize_high_speed = (ext_csd >> ((EXT_CSD_CARD_TYPE_INDEX % 4) * 8)) + & MMC_CTYPE_52MHZ; + + if (MMC_CSD_C_SIZE(sd_mmc_card->csd) == 0xFFF) { + // For high capacity SD/MMC card, + // memory capacity = SEC_COUNT * 512 byte + for (; i <(EXT_CSD_SEC_COUNT_INDEX + 4) / 4; i++) { + if (!driver_read_word(&sec_count)) { + return false; + } + } + sd_mmc_card->capacity = sec_count / 2; + } + for (; i < EXT_CSD_BSIZE / 4; i++) { + if (!driver_read_word(&sec_count)) { + return false; + } + } + return true; +} + +/** + * \brief CMD9: Addressed card sends its card-specific + * data (CSD) on the CMD line spi. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_cmd9_spi(void) +{ + if (!driver_adtc_start(SDMMC_SPI_CMD9_SEND_CSD, (uint32_t)sd_mmc_card->rca << 16, + CSD_REG_BSIZE, 1, true)) { + return false; + } + if (!driver_start_read_blocks(sd_mmc_card->csd, 1)) { + return false; + } + return driver_wait_end_of_read_blocks(); +} + +/** + * \brief CMD9: Addressed card sends its card-specific + * data (CSD) on the CMD line mci. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_cmd9_mci(void) +{ + if (!driver_send_cmd(SDMMC_MCI_CMD9_SEND_CSD, (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + driver_get_response_128(sd_mmc_card->csd); + return true; +} + +/** + * \brief Decodes MMC CSD register + */ +static void mmc_decode_csd(void) +{ + uint32_t unit; + uint32_t mul; + uint32_t tran_speed; + + // Get MMC System Specification version supported by the card + switch (MMC_CSD_SPEC_VERS(sd_mmc_card->csd)) { + default: + case 0: + sd_mmc_card->version = CARD_VER_MMC_1_2; + break; + + case 1: + sd_mmc_card->version = CARD_VER_MMC_1_4; + break; + + case 2: + sd_mmc_card->version = CARD_VER_MMC_2_2; + break; + + case 3: + sd_mmc_card->version = CARD_VER_MMC_3; + break; + + case 4: + sd_mmc_card->version = CARD_VER_MMC_4; + break; + } + + // Get MMC memory max transfer speed in Hz. + tran_speed = CSD_TRAN_SPEED(sd_mmc_card->csd); + unit = sd_mmc_trans_units[tran_speed & 0x7]; + mul = mmc_trans_multipliers[(tran_speed >> 3) & 0xF]; + sd_mmc_card->clock = unit * mul * 1000; + + /* + * Get card capacity. + * ---------------------------------------------------- + * For normal SD/MMC card: + * memory capacity = BLOCKNR * BLOCK_LEN + * Where + * BLOCKNR = (C_SIZE+1) * MULT + * MULT = 2 ^ (C_SIZE_MULT+2) (C_SIZE_MULT < 8) + * BLOCK_LEN = 2 ^ READ_BL_LEN (READ_BL_LEN < 12) + * ---------------------------------------------------- + * For high capacity SD/MMC card: + * memory capacity = SEC_COUNT * 512 byte + */ + if (MMC_CSD_C_SIZE(sd_mmc_card->csd) != 0xFFF) { + uint32_t blocknr = ((MMC_CSD_C_SIZE(sd_mmc_card->csd) + 1) * + (1 << (MMC_CSD_C_SIZE_MULT(sd_mmc_card->csd) + 2))); + sd_mmc_card->capacity = blocknr * + (1 << MMC_CSD_READ_BL_LEN(sd_mmc_card->csd)) / 1024; + } +} + +/** + * \brief Decodes SD CSD register + */ +static void sd_decode_csd(void) +{ + uint32_t unit; + uint32_t mul; + uint32_t tran_speed; + + // Get SD memory maximum transfer speed in Hz. + tran_speed = CSD_TRAN_SPEED(sd_mmc_card->csd); + unit = sd_mmc_trans_units[tran_speed & 0x7]; + mul = sd_trans_multipliers[(tran_speed >> 3) & 0xF]; + sd_mmc_card->clock = unit * mul * 1000; + + /* + * Get card capacity. + * ---------------------------------------------------- + * For normal SD/MMC card: + * memory capacity = BLOCKNR * BLOCK_LEN + * Where + * BLOCKNR = (C_SIZE+1) * MULT + * MULT = 2 ^ (C_SIZE_MULT+2) (C_SIZE_MULT < 8) + * BLOCK_LEN = 2 ^ READ_BL_LEN (READ_BL_LEN < 12) + * ---------------------------------------------------- + * For high capacity SD card: + * memory capacity = (C_SIZE+1) * 512K byte + */ + if (CSD_STRUCTURE_VERSION(sd_mmc_card->csd) >= SD_CSD_VER_2_0) { + sd_mmc_card->capacity = + (SD_CSD_2_0_C_SIZE(sd_mmc_card->csd) + 1) + * 512; + } else { + uint32_t blocknr = ((SD_CSD_1_0_C_SIZE(sd_mmc_card->csd) + 1) * + (1 << (SD_CSD_1_0_C_SIZE_MULT(sd_mmc_card->csd) + 2))); + sd_mmc_card->capacity = blocknr * + (1 << SD_CSD_1_0_READ_BL_LEN(sd_mmc_card->csd)) + / 1024; + } +} + +/** + * \brief CMD13 - Addressed card sends its status register. + * This function waits the clear of the busy flag + * + * \return true if success, otherwise false + */ +static bool sd_mmc_cmd13(void) +{ + uint32_t nec_timeout; + + /* Wait for data ready status. + * Nec timing: 0 to unlimited + * However a timeout is used. + * 200 000 * 8 cycles + */ + nec_timeout = 200000; + do { + if (sd_mmc_is_spi()) { + if (!driver_send_cmd(SDMMC_SPI_CMD13_SEND_STATUS, 0)) { + return false; + } + // Check busy flag + if (!(driver_get_response() & 0xFF)) { + break; + } + } else { + if (!driver_send_cmd(SDMMC_MCI_CMD13_SEND_STATUS, + (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + // Check busy flag + if (driver_get_response() & CARD_STATUS_READY_FOR_DATA) { + break; + } + } + if (nec_timeout-- == 0) { + sd_mmc_debug("%s: CMD13 Busy timeout\n\r", __func__); + return false; + } + } while (1); + + return true; +} + +#ifdef SDIO_SUPPORT_ENABLE +/** + * \brief CMD52 - SDIO IO_RW_DIRECT command + * + * \param rw_flag Direction, 1:write, 0:read. + * \param func_nb Number of the function. + * \param rd_after_wr Read after Write flag. + * \param reg_addr register address. + * \param io_data Pointer to input argument and response buffer. + * + * \return true if success, otherwise false + */ +static bool sdio_cmd52(uint8_t rw_flag, uint8_t func_nb, + uint32_t reg_addr, uint8_t rd_after_wr, uint8_t *io_data) +{ + Assert(io_data != NULL); + if (!driver_send_cmd(SDIO_CMD52_IO_RW_DIRECT, + ((uint32_t)*io_data << SDIO_CMD52_WR_DATA) + | ((uint32_t)rw_flag << SDIO_CMD52_RW_FLAG) + | ((uint32_t)func_nb << SDIO_CMD52_FUNCTION_NUM) + | ((uint32_t)rd_after_wr << SDIO_CMD52_RAW_FLAG) + | ((uint32_t)reg_addr << SDIO_CMD52_REG_ADRR))) { + return false; + } + *io_data = driver_get_response() & 0xFF; + return true; +} + +/** + * \brief CMD53 - SDIO IO_RW_EXTENDED command + * This implementation support only the SDIO multi-byte transfer mode which is + * similar to the single block transfer on memory. + * Note: The SDIO block transfer mode is optional for SDIO card. + * + * \param rw_flag Direction, 1:write, 0:read. + * \param func_nb Number of the function. + * \param reg_addr Register address. + * \param inc_addr 1:Incrementing address, 0: fixed. + * \param size Transfer data size. + * \param access_block true, if the block access (DMA) is used + * + * \return true if success, otherwise false + */ +static bool sdio_cmd53(uint8_t rw_flag, uint8_t func_nb, uint32_t reg_addr, + uint8_t inc_addr, uint32_t size, bool access_block) +{ + Assert(size != 0); + Assert(size <= 512); + + return driver_adtc_start((rw_flag == SDIO_CMD53_READ_FLAG)? + SDIO_CMD53_IO_R_BYTE_EXTENDED : + SDIO_CMD53_IO_W_BYTE_EXTENDED, + ((size % 512) << SDIO_CMD53_COUNT) + | ((uint32_t)reg_addr << SDIO_CMD53_REG_ADDR) + | ((uint32_t)inc_addr << SDIO_CMD53_OP_CODE) + | ((uint32_t)0 << SDIO_CMD53_BLOCK_MODE) + | ((uint32_t)func_nb << SDIO_CMD53_FUNCTION_NUM) + | ((uint32_t)rw_flag << SDIO_CMD53_RW_FLAG), + size, 1, access_block); +} +#endif // SDIO_SUPPORT_ENABLE + +/** + * \brief ACMD6 - Define the data bus width to 4 bits bus + * + * \return true if success, otherwise false + */ +static bool sd_acmd6(void) +{ + // CMD55 - Indicate to the card that the next command is an + // application specific command rather than a standard command. + if (!driver_send_cmd(SDMMC_CMD55_APP_CMD, (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + // 10b = 4 bits bus + if (!driver_send_cmd(SD_ACMD6_SET_BUS_WIDTH, 0x2)) { + return false; + } + sd_mmc_card->bus_width = 4; + sd_mmc_debug("%d-bit bus width enabled.\n\r", (int)sd_mmc_card->bus_width); + return true; +} + +/** + * \brief ACMD51 - Read the SD Configuration Register. + * + * \note + * SD Card Configuration Register (SCR) provides information on the SD Memory + * Card's special features that were configured into the given card. The size + * of SCR register is 64 bits. + * + * + * \return true if success, otherwise false + */ +static bool sd_acmd51(void) +{ + uint8_t scr[SD_SCR_REG_BSIZE]; + + // CMD55 - Indicate to the card that the next command is an + // application specific command rather than a standard command. + if (!driver_send_cmd(SDMMC_CMD55_APP_CMD, (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + if (!driver_adtc_start(SD_ACMD51_SEND_SCR, 0, + SD_SCR_REG_BSIZE, 1, true)) { + return false; + } + if (!driver_start_read_blocks(scr, 1)) { + return false; + } + if (!driver_wait_end_of_read_blocks()) { + return false; + } + + // Get SD Memory Card - Spec. Version + switch (SD_SCR_SD_SPEC(scr)) { + case SD_SCR_SD_SPEC_1_0_01: + sd_mmc_card->version = CARD_VER_SD_1_0; + break; + + case SD_SCR_SD_SPEC_1_10: + sd_mmc_card->version = CARD_VER_SD_1_10; + break; + + case SD_SCR_SD_SPEC_2_00: + if (SD_SCR_SD_SPEC3(scr) == SD_SCR_SD_SPEC_3_00) { + sd_mmc_card->version = CARD_VER_SD_3_0; + } else { + sd_mmc_card->version = CARD_VER_SD_2_0; + } + break; + + default: + sd_mmc_card->version = CARD_VER_SD_1_0; + break; + } + return true; +} + +/** + * \brief Select a card slot and initialize the associated driver + * + * \param slot Card slot number + * + * \retval SD_MMC_ERR_SLOT Wrong slot number + * \retval SD_MMC_ERR_NO_CARD No card present on slot + * \retval SD_MMC_ERR_UNUSABLE Unusable card + * \retval SD_MMC_INIT_ONGOING Card initialization requested + * \retval SD_MMC_OK Card present + */ +static sd_mmc_err_t sd_mmc_select_slot(uint8_t slot) +{ + if (slot >= SD_MMC_MEM_CNT) { + return SD_MMC_ERR_SLOT; + } + Assert(sd_mmc_nb_block_remaining == 0); + +#if (defined SD_MMC_0_CD_GPIO) + //! Card Detect pins + if (ioport_get_pin_level(sd_mmc_cards[slot].cd_gpio) + != SD_MMC_0_CD_DETECT_VALUE) { + if (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_DEBOUNCE) { + SD_MMC_STOP_TIMEOUT(); + } + sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_NO_CARD; + return SD_MMC_ERR_NO_CARD; + } + if (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_NO_CARD) { + // A card plug on going, but this is not initialized + sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_DEBOUNCE; + // Debounce + Power On Setup + SD_MMC_START_TIMEOUT(); + return SD_MMC_ERR_NO_CARD; + } + if (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_DEBOUNCE) { + if (!SD_MMC_IS_TIMEOUT()) { + // Debounce on going + return SD_MMC_ERR_NO_CARD; + } + // Card is not initialized + sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_INIT; + // Set 1-bit bus width and low clock for initialization + sd_mmc_cards[slot].clock = SDMMC_CLOCK_INIT; + sd_mmc_cards[slot].bus_width = 1; + sd_mmc_cards[slot].high_speed = 0; + } + if (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_UNUSABLE) { + return SD_MMC_ERR_UNUSABLE; + } +#else + // No pin card detection, then always try to install it + if ((sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_NO_CARD) + || (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_UNUSABLE)) { + // Card is not initialized + sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_INIT; + // Set 1-bit bus width and low clock for initialization + sd_mmc_cards[slot].clock = SDMMC_CLOCK_INIT; + sd_mmc_cards[slot].bus_width = 1; + sd_mmc_cards[slot].high_speed = 0; + } +#endif + + // Initialize interface + sd_mmc_slot_sel = slot; + sd_mmc_card = &sd_mmc_cards[slot]; + sd_mmc_configure_slot(); + return (sd_mmc_cards[slot].state == SD_MMC_CARD_STATE_INIT) ? + SD_MMC_INIT_ONGOING : SD_MMC_OK; +} + +/** + * \brief Configures the driver with the selected card configuration + */ +static void sd_mmc_configure_slot(void) +{ + driver_select_device(sd_mmc_slot_sel, sd_mmc_card->clock, + sd_mmc_card->bus_width, sd_mmc_card->high_speed); +} + +/** + * \brief Deselect the current card slot + */ +static void sd_mmc_deselect_slot(void) +{ + if (sd_mmc_slot_sel < SD_MMC_MEM_CNT) { + driver_deselect_device(sd_mmc_slot_sel); + } +} + +/** + * \brief Initialize the SD card in SPI mode. + * + * \note + * This function runs the initialization procedure and the identification + * process, then it sets the SD/MMC card in transfer state. + * At last, it will automaticly enable maximum bus width and transfer speed. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_spi_card_init(void) +{ + uint8_t v2 = 0; + + // In first, try to install SD/SDIO card + sd_mmc_card->type = CARD_TYPE_SD; + sd_mmc_card->version = CARD_VER_UNKNOWN; + sd_mmc_card->rca = 0; + sd_mmc_debug("Start SD card install\n\r"); + + // Card need of 74 cycles clock minimum to start + driver_send_clock(); + + // CMD0 - Reset all cards to idle state. + if (!driver_send_cmd(SDMMC_SPI_CMD0_GO_IDLE_STATE, 0)) { + return false; + } + if (!sd_cmd8(&v2)) { + return false; + } + // Try to get the SDIO card's operating condition + if (!sdio_op_cond()) { + return false; + } + + if (sd_mmc_card->type & CARD_TYPE_SD) { + // Try to get the SD card's operating condition + if (!sd_spi_op_cond(v2)) { + // It is not a SD card + sd_mmc_debug("Start MMC Install\n\r"); + sd_mmc_card->type = CARD_TYPE_MMC; + return sd_mmc_spi_install_mmc(); + } + + /* The CRC on card is disabled by default. + * However, to be sure, the CRC OFF command is send. + * Unfortunately, specific SDIO card does not support it + * (H&D wireless card - HDG104 WiFi SIP) + * and the command is send only on SD card. + */ + if (!driver_send_cmd(SDMMC_SPI_CMD59_CRC_ON_OFF, 0)) { + return false; + } + } + // SD MEMORY + if (sd_mmc_card->type & CARD_TYPE_SD) { + // Get the Card-Specific Data + if (!sd_mmc_cmd9_spi()) { + return false; + } + sd_decode_csd(); + // Read the SCR to get card version + if (!sd_acmd51()) { + return false; + } + } + if (IS_SDIO()) { + if (!sdio_get_max_speed()) { + return false; + } + } + // SD MEMORY not HC, Set default block size + if ((sd_mmc_card->type & CARD_TYPE_SD) && + (0 == (sd_mmc_card->type & CARD_TYPE_HC))) { + if (!driver_send_cmd(SDMMC_CMD16_SET_BLOCKLEN, SD_MMC_BLOCK_SIZE)) { + return false; + } + } + // Check communication + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (!sd_mmc_cmd13()) { + return false; + } + } + // Reinitialize the slot with the new speed + sd_mmc_configure_slot(); + return true; +} + +/** + * \brief Initialize the SD card in MCI mode. + * + * \note + * This function runs the initialization procedure and the identification + * process, then it sets the SD/MMC card in transfer state. + * At last, it will automaticly enable maximum bus width and transfer speed. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_mci_card_init(void) +{ + uint8_t v2 = 0; + + // In first, try to install SD/SDIO card + sd_mmc_card->type = CARD_TYPE_SD; + sd_mmc_card->version = CARD_VER_UNKNOWN; + sd_mmc_card->rca = 0; + sd_mmc_debug("Start SD card install\n\r"); + + // Card need of 74 cycles clock minimum to start + driver_send_clock(); + + // CMD0 - Reset all cards to idle state. + if (!driver_send_cmd(SDMMC_MCI_CMD0_GO_IDLE_STATE, 0)) { + return false; + } + if (!sd_cmd8(&v2)) { + return false; + } + // Try to get the SDIO card's operating condition + if (!sdio_op_cond()) { + return false; + } + + if (sd_mmc_card->type & CARD_TYPE_SD) { + // Try to get the SD card's operating condition + if (!sd_mci_op_cond(v2)) { + // It is not a SD card + sd_mmc_debug("Start MMC Install\n\r"); + sd_mmc_card->type = CARD_TYPE_MMC; + return sd_mmc_mci_install_mmc(); + } + } + + if (sd_mmc_card->type & CARD_TYPE_SD) { + // SD MEMORY, Put the Card in Identify Mode + // Note: The CID is not used in this stack + if (!driver_send_cmd(SDMMC_CMD2_ALL_SEND_CID, 0)) { + return false; + } + } + // Ask the card to publish a new relative address (RCA). + if (!driver_send_cmd(SD_CMD3_SEND_RELATIVE_ADDR, 0)) { + return false; + } + sd_mmc_card->rca = (driver_get_response() >> 16) & 0xFFFF; + + // SD MEMORY, Get the Card-Specific Data + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (!sd_mmc_cmd9_mci()) { + return false; + } + sd_decode_csd(); + } + // Select the and put it into Transfer Mode + if (!driver_send_cmd(SDMMC_CMD7_SELECT_CARD_CMD, + (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + // SD MEMORY, Read the SCR to get card version + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (!sd_acmd51()) { + return false; + } + } + if (IS_SDIO()) { + if (!sdio_get_max_speed()) { + return false; + } + } + if ((4 <= driver_get_bus_width(sd_mmc_slot_sel))) { + // TRY to enable 4-bit mode + if (IS_SDIO()) { + if (!sdio_cmd52_set_bus_width()) { + return false; + } + } + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (!sd_acmd6()) { + return false; + } + } + // Switch to selected bus mode + sd_mmc_configure_slot(); + } + if (driver_is_high_speed_capable()) { + // TRY to enable High-Speed Mode + if (IS_SDIO()) { + if (!sdio_cmd52_set_high_speed()) { + return false; + } + } + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (sd_mmc_card->version > CARD_VER_SD_1_0) { + if (!sd_cm6_set_high_speed()) { + return false; + } + } + } + // Valid new configuration + sd_mmc_configure_slot(); + } + // SD MEMORY, Set default block size + if (sd_mmc_card->type & CARD_TYPE_SD) { + if (!driver_send_cmd(SDMMC_CMD16_SET_BLOCKLEN, SD_MMC_BLOCK_SIZE)) { + return false; + } + } + return true; +} + +/** + * \brief Initialize the MMC card in SPI mode. + * + * \note + * This function runs the initialization procedure and the identification + * process, then it sets the SD/MMC card in transfer state. + * At last, it will automaticly enable maximum bus width and transfer speed. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_spi_install_mmc(void) +{ + uint8_t b_authorize_high_speed; + + // CMD0 - Reset all cards to idle state. + if (!driver_send_cmd(SDMMC_SPI_CMD0_GO_IDLE_STATE, 0)) { + return false; + } + + if (!mmc_spi_op_cond()) { + return false; + } + + // Disable CRC check for SPI mode + if (!driver_send_cmd(SDMMC_SPI_CMD59_CRC_ON_OFF, 0)) { + return false; + } + // Get the Card-Specific Data + if (!sd_mmc_cmd9_spi()) { + return false; + } + mmc_decode_csd(); + // For MMC 4.0 Higher version + if (sd_mmc_card->version >= CARD_VER_MMC_4) { + // Get EXT_CSD + if (!mmc_cmd8(&b_authorize_high_speed)) { + return false; + } + } + // Set default block size + if (!driver_send_cmd(SDMMC_CMD16_SET_BLOCKLEN, SD_MMC_BLOCK_SIZE)) { + return false; + } + // Check communication + if (!sd_mmc_cmd13()) { + return false; + } + // Reinitialize the slot with the new speed + sd_mmc_configure_slot(); + return true; +} + + +/** + * \brief Initialize the MMC card in MCI mode. + * + * \note + * This function runs the initialization procedure and the identification + * process, then it sets the SD/MMC card in transfer state. + * At last, it will automaticly enable maximum bus width and transfer speed. + * + * \return true if success, otherwise false + */ +static bool sd_mmc_mci_install_mmc(void) +{ + uint8_t b_authorize_high_speed; + + // CMD0 - Reset all cards to idle state. + if (!driver_send_cmd(SDMMC_MCI_CMD0_GO_IDLE_STATE, 0)) { + return false; + } + + if (!mmc_mci_op_cond()) { + return false; + } + + // Put the Card in Identify Mode + // Note: The CID is not used in this stack + if (!driver_send_cmd(SDMMC_CMD2_ALL_SEND_CID, 0)) { + return false; + } + // Assign relative address to the card. + sd_mmc_card->rca = 1; + if (!driver_send_cmd(MMC_CMD3_SET_RELATIVE_ADDR, + (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + // Get the Card-Specific Data + if (!sd_mmc_cmd9_mci()) { + return false; + } + mmc_decode_csd(); + // Select the and put it into Transfer Mode + if (!driver_send_cmd(SDMMC_CMD7_SELECT_CARD_CMD, + (uint32_t)sd_mmc_card->rca << 16)) { + return false; + } + if (sd_mmc_card->version >= CARD_VER_MMC_4) { + // For MMC 4.0 Higher version + // Get EXT_CSD + if (!mmc_cmd8(&b_authorize_high_speed)) { + return false; + } + if (4 <= driver_get_bus_width(sd_mmc_slot_sel)) { + // Enable more bus width + if (!mmc_cmd6_set_bus_width(driver_get_bus_width(sd_mmc_slot_sel))) { + return false; + } + // Reinitialize the slot with the bus width + sd_mmc_configure_slot(); + } + if (driver_is_high_speed_capable() && b_authorize_high_speed) { + // Enable HS + if (!mmc_cmd6_set_high_speed()) { + return false; + } + // Reinitialize the slot with the new speed + sd_mmc_configure_slot(); + } + } else { + // Reinitialize the slot with the new speed + sd_mmc_configure_slot(); + } + + uint8_t retry = 10; + while (retry--) { + // Retry is a WORKAROUND for no compliance card (Atmel Internal ref. MMC19): + // These cards seem not ready immediatly + // after the end of busy of mmc_cmd6_set_high_speed() + + // Set default block size + if (driver_send_cmd(SDMMC_CMD16_SET_BLOCKLEN, SD_MMC_BLOCK_SIZE)) { + return true; + } + } + return false; +} + +//------------------------------------------------------------------- +//--------------------- PUBLIC FUNCTIONS ---------------------------- + +void sd_mmc_init(void) +{ + //! Enable the PMC clock for the card detect pins +#if (defined SD_MMC_0_CD_GPIO) && (!defined SAM4L) +# include "pmc.h" +# define SD_MMC_ENABLE_CD_PIN(slot, unused) \ + pmc_enable_periph_clk(SD_MMC_##slot##_CD_PIO_ID); + MREPEAT(SD_MMC_MEM_CNT, SD_MMC_ENABLE_CD_PIN, ~) +# undef SD_MMC_ENABLE_CD_PIN +#endif + //! Enable the PMC clock for the card write protection pins +#if (defined SD_MMC_0_WP_GPIO) && (!defined SAM4L) +# include "pmc.h" +# define SD_MMC_ENABLE_WP_PIN(slot, unused) \ + pmc_enable_periph_clk(SD_MMC_##slot##_WP_PIO_ID); + MREPEAT(SD_MMC_MEM_CNT, SD_MMC_ENABLE_WP_PIN, ~) +# undef SD_MMC_ENABLE_WP_PIN +#endif + for (uint8_t slot = 0; slot < SD_MMC_MEM_CNT; slot++) { + sd_mmc_cards[slot].state = SD_MMC_CARD_STATE_NO_CARD; + } + sd_mmc_slot_sel = 0xFF; // No slot configurated + driver_init(); +} + +uint8_t sd_mmc_nb_slot(void) +{ + return SD_MMC_MEM_CNT; +} + +sd_mmc_err_t sd_mmc_check(uint8_t slot) +{ + sd_mmc_err_t sd_mmc_err; + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_INIT_ONGOING) { + sd_mmc_deselect_slot(); + return sd_mmc_err; + } + + // Initialization of the card requested + if (sd_mmc_is_spi()? sd_mmc_spi_card_init() + : sd_mmc_mci_card_init()) { + sd_mmc_debug("SD/MMC card ready\n\r"); + sd_mmc_card->state = SD_MMC_CARD_STATE_READY; + sd_mmc_deselect_slot(); + // To notify that the card has been just initialized + // It is necessary for USB Device MSC + return SD_MMC_INIT_ONGOING; + } + sd_mmc_debug("SD/MMC card initialization failed\n\r"); + sd_mmc_card->state = SD_MMC_CARD_STATE_UNUSABLE; + sd_mmc_deselect_slot(); + return SD_MMC_ERR_UNUSABLE; +} + +card_type_t sd_mmc_get_type(uint8_t slot) +{ + if (SD_MMC_OK != sd_mmc_select_slot(slot)) { + return CARD_TYPE_UNKNOWN; + } + sd_mmc_deselect_slot(); + return sd_mmc_card->type; +} + +card_version_t sd_mmc_get_version(uint8_t slot) +{ + if (SD_MMC_OK != sd_mmc_select_slot(slot)) { + return CARD_VER_UNKNOWN; + } + sd_mmc_deselect_slot(); + return sd_mmc_card->version; +} + +uint32_t sd_mmc_get_capacity(uint8_t slot) +{ + if (SD_MMC_OK != sd_mmc_select_slot(slot)) { + return 0; + } + sd_mmc_deselect_slot(); + return sd_mmc_card->capacity; +} + +bool sd_mmc_is_write_protected(uint8_t slot) +{ + UNUSED(slot); +#if (defined SD_MMC_0_WP_GPIO) + //! Card Detect pins + if (ioport_get_pin_level(sd_mmc_cards[slot].wp_gpio) + == SD_MMC_0_WP_DETECT_VALUE) { + return true; + } +#endif + return false; +} + +sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, + uint16_t nb_block) +{ + sd_mmc_err_t sd_mmc_err; + uint32_t cmd, arg, resp; + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + + // Wait for data ready status + if (!sd_mmc_cmd13()) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + + if (nb_block > 1) { + cmd = SDMMC_CMD18_READ_MULTIPLE_BLOCK; + } else { + cmd = SDMMC_CMD17_READ_SINGLE_BLOCK; + } + /* + * SDSC Card (CCS=0) uses byte unit address, + * SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit). + */ + if (sd_mmc_card->type & CARD_TYPE_HC) { + arg = start; + } else { + arg = (start * SD_MMC_BLOCK_SIZE); + } + + if (!driver_adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block, true)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + // Check response + if (sd_mmc_is_mci()) { + resp = driver_get_response(); + if (resp & CARD_STATUS_ERR_RD_WR) { + sd_mmc_debug("%s: Read blocks %02d resp32 0x%08x CARD_STATUS_ERR_RD_WR\n\r", + __func__, (int)SDMMC_CMD_GET_INDEX(cmd), resp); + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + } + sd_mmc_nb_block_remaining = nb_block; + sd_mmc_nb_block_to_tranfer = nb_block; + return SD_MMC_OK; +} + +sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block) +{ + Assert(sd_mmc_nb_block_remaining >= nb_block); + + if (!driver_start_read_blocks(dest, nb_block)) { + sd_mmc_nb_block_remaining = 0; + return SD_MMC_ERR_COMM; + } + sd_mmc_nb_block_remaining -= nb_block; + return SD_MMC_OK; +} + +sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort) +{ + if (!driver_wait_end_of_read_blocks()) { + return SD_MMC_ERR_COMM; + } + if (abort) { + sd_mmc_nb_block_remaining = 0; + } else if (sd_mmc_nb_block_remaining) { + return SD_MMC_OK; + } + + // All blocks are transfered then stop read operation + if (sd_mmc_nb_block_to_tranfer == 1) { + // Single block transfer, then nothing to do + sd_mmc_deselect_slot(); + return SD_MMC_OK; + } + // WORKAROUND for no compliance card (Atmel Internal ref. !MMC7 !SD19): + // The errors on this command must be ignored + // and one retry can be necessary in SPI mode for no compliance card. + if (!driver_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0)) { + driver_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0); + } + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} + +sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, + uint16_t nb_block) +{ + sd_mmc_err_t sd_mmc_err; + uint32_t cmd, arg, resp; + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + if (sd_mmc_is_write_protected(slot)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_WP; + } + + if (nb_block > 1) { + cmd = SDMMC_CMD25_WRITE_MULTIPLE_BLOCK; + } else { + cmd = SDMMC_CMD24_WRITE_BLOCK; + } + /* + * SDSC Card (CCS=0) uses byte unit address, + * SDHC and SDXC Cards (CCS=1) use block unit address (512 Bytes unit). + */ + if (sd_mmc_card->type & CARD_TYPE_HC) { + arg = start; + } else { + arg = (start * SD_MMC_BLOCK_SIZE); + } + if (!driver_adtc_start(cmd, arg, SD_MMC_BLOCK_SIZE, nb_block, true)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + // Check response + if (sd_mmc_is_mci()) { + resp = driver_get_response(); + if (resp & CARD_STATUS_ERR_RD_WR) { + sd_mmc_debug("%s: Write blocks %02d r1 0x%08x CARD_STATUS_ERR_RD_WR\n\r", + __func__, (int)SDMMC_CMD_GET_INDEX(cmd), resp); + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + } + sd_mmc_nb_block_remaining = nb_block; + sd_mmc_nb_block_to_tranfer = nb_block; + return SD_MMC_OK; +} + +sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block) +{ + Assert(sd_mmc_nb_block_remaining >= nb_block); + if (!driver_start_write_blocks(src, nb_block)) { + sd_mmc_nb_block_remaining = 0; + return SD_MMC_ERR_COMM; + } + sd_mmc_nb_block_remaining -= nb_block; + return SD_MMC_OK; +} + +sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort) +{ + if (!driver_wait_end_of_write_blocks()) { + return SD_MMC_ERR_COMM; + } + if (abort) { + sd_mmc_nb_block_remaining = 0; + } else if (sd_mmc_nb_block_remaining) { + return SD_MMC_OK; + } + + // All blocks are transfered then stop write operation + if (sd_mmc_nb_block_to_tranfer == 1) { + // Single block transfer, then nothing to do + sd_mmc_deselect_slot(); + return SD_MMC_OK; + } + + if (sd_mmc_is_mci()) { + // Note: SPI multiblock writes terminate using a special + // token, not a STOP_TRANSMISSION request. + if (!driver_adtc_stop(SDMMC_CMD12_STOP_TRANSMISSION, 0)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + } + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} + +#ifdef SDIO_SUPPORT_ENABLE +sd_mmc_err_t sdio_read_direct(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t *dest) +{ + sd_mmc_err_t sd_mmc_err; + + if (dest == NULL) { + return SD_MMC_ERR_PARAM; + } + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + + if (!sdio_cmd52(SDIO_CMD52_READ_FLAG, func_num, addr, 0, dest)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} + +sd_mmc_err_t sdio_write_direct(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t data) +{ + sd_mmc_err_t sd_mmc_err; + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + + if (!sdio_cmd52(SDIO_CMD52_WRITE_FLAG, func_num, addr, 0, &data)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} + +sd_mmc_err_t sdio_read_extended(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t inc_addr, uint8_t *dest, uint16_t size) +{ + sd_mmc_err_t sd_mmc_err; + + if ((size == 0) || (size > 512)) { + return SD_MMC_ERR_PARAM; + } + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + + if (!sdio_cmd53(SDIO_CMD53_READ_FLAG, func_num, addr, inc_addr, + size, true)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + if (!driver_start_read_blocks(dest, 1)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + if (!driver_wait_end_of_read_blocks()) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} + +sd_mmc_err_t sdio_write_extended(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t inc_addr, uint8_t *src, uint16_t size) +{ + sd_mmc_err_t sd_mmc_err; + + if ((size == 0) || (size > 512)) { + return SD_MMC_ERR_PARAM; + } + + sd_mmc_err = sd_mmc_select_slot(slot); + if (sd_mmc_err != SD_MMC_OK) { + return sd_mmc_err; + } + + if (!sdio_cmd53(SDIO_CMD53_WRITE_FLAG, func_num, addr, inc_addr, + size, true)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + if (!driver_start_write_blocks(src, 1)) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + if (!driver_wait_end_of_write_blocks()) { + sd_mmc_deselect_slot(); + return SD_MMC_ERR_COMM; + } + + sd_mmc_deselect_slot(); + return SD_MMC_OK; +} +#endif // SDIO_SUPPORT_ENABLE + +//! @} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.h new file mode 100644 index 0000000..71df8da --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc.h @@ -0,0 +1,313 @@ +/** + * \file + * + * \brief Common SD/MMC stack header file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef SD_MMC_H_INCLUDED +#define SD_MMC_H_INCLUDED + +#include "compiler.h" +#include "conf_sd_mmc.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \ingroup common_memory + * \defgroup sd_mmc_stack_group SD/MMC/SDIO common stack + * + * SD/MMC/SDIO basic APIs used by SD/MMC/SDIO memory + * APIs (\ref sd_mmc_stack_mem_group). + * Also, it can be used by application which use the SDIO card + * or specific application which does not need of File System. + * + * For usual application which use the SD/MMC card in + * memory mode with a file system, please refer to + * \ref sd_mmc_stack_mem_group. + * @{ + */ + +typedef uint8_t sd_mmc_err_t; //!< Type of return error code + +//! \name Return error codes +//! @{ +#define SD_MMC_OK 0 //! No error +#define SD_MMC_INIT_ONGOING 1 //! Card not initialized +#define SD_MMC_ERR_NO_CARD 2 //! No SD/MMC card inserted +#define SD_MMC_ERR_UNUSABLE 3 //! Unusable card +#define SD_MMC_ERR_SLOT 4 //! Slot unknow +#define SD_MMC_ERR_COMM 5 //! General communication error +#define SD_MMC_ERR_PARAM 6 //! Illeage input parameter +#define SD_MMC_ERR_WP 7 //! Card write protected +//! @} + +typedef uint8_t card_type_t; //!< Type of card type + +//! \name Card Types +//! @{ +#define CARD_TYPE_UNKNOWN (0) //!< Unknown type card +#define CARD_TYPE_SD (1 << 0) //!< SD card +#define CARD_TYPE_MMC (1 << 1) //!< MMC card +#define CARD_TYPE_SDIO (1 << 2) //!< SDIO card +#define CARD_TYPE_HC (1 << 3) //!< High capacity card +//! SD combo card (io + memory) +#define CARD_TYPE_SD_COMBO (CARD_TYPE_SD | CARD_TYPE_SDIO) +//! @} + +typedef uint8_t card_version_t; //!< Type of card version + +//! \name Card Versions +//! @{ +#define CARD_VER_UNKNOWN (0) //! Unknown card version +#define CARD_VER_SD_1_0 (0x10) //! SD version 1.0 and 1.01 +#define CARD_VER_SD_1_10 (0x1A) //! SD version 1.10 +#define CARD_VER_SD_2_0 (0X20) //! SD version 2.00 +#define CARD_VER_SD_3_0 (0X30) //! SD version 3.0X +#define CARD_VER_MMC_1_2 (0x12) //! MMC version 1.2 +#define CARD_VER_MMC_1_4 (0x14) //! MMC version 1.4 +#define CARD_VER_MMC_2_2 (0x22) //! MMC version 2.2 +#define CARD_VER_MMC_3 (0x30) //! MMC version 3 +#define CARD_VER_MMC_4 (0x40) //! MMC version 4 +//! @} + +//! This SD MMC stack uses the maximum block size autorized (512 bytes) +#define SD_MMC_BLOCK_SIZE 512 + +/** + * \brief Initialize the SD/MMC stack and low level driver required + */ +void sd_mmc_init(void); + +/** \brief Return the number of slot available + * + * \return Number of card slot available + */ +uint8_t sd_mmc_nb_slot(void); + +/** \brief Performs a card checks + * + * \param slot Card slot to use + * + * \retval SD_MMC_OK Card ready + * \retval SD_MMC_INIT_ONGOING Initialization on going + * \retval SD_MMC_ERR_NO_CARD Card not present in slot + * \retval Other value for error cases, see \ref sd_mmc_err_t + */ +sd_mmc_err_t sd_mmc_check(uint8_t slot); + +/** \brief Get the card type + * + * \param slot Card slot + * + * \return Card type (\ref card_type_t) + */ +card_type_t sd_mmc_get_type(uint8_t slot); + +/** \brief Get the card version + * + * \param slot Card slot + * + * \return Card version (\ref card_version_t) + */ +card_version_t sd_mmc_get_version(uint8_t slot); + +/** \brief Get the memory capacity + * + * \param slot Card slot + * + * \return Capacity (unit KB) + */ +uint32_t sd_mmc_get_capacity(uint8_t slot); + +/** \brief Get the card write protection status + * + * \param slot Card slot + * + * \return true, if write portected + */ +bool sd_mmc_is_write_protected(uint8_t slot); + +/** + * \brief Initialize the read blocks of data from the card. + * + * \param slot Card slot to use + * \param start Start block number to to read. + * \param nb_block Total number of blocks to be read. + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_init_read_blocks(uint8_t slot, uint32_t start, + uint16_t nb_block); + +/** + * \brief Start the read blocks of data from the card. + * + * \param dest Pointer to read buffer. + * \param nb_block Number of blocks to be read. + * + * \return return SD_MMC_OK if started, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_start_read_blocks(void *dest, uint16_t nb_block); + +/** + * \brief Wait the end of read blocks of data from the card. + * + * \param abort Abort reading process initialized by + * \ref sd_mmc_init_read_blocks() after the reading issued by + * \ref sd_mmc_start_read_blocks() is done + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_wait_end_of_read_blocks(bool abort); + +/** + * \brief Initialize the write blocks of data + * + * \param slot Card slot to use + * \param start Start block number to be written. + * \param nb_block Total number of blocks to be written. + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_init_write_blocks(uint8_t slot, uint32_t start, + uint16_t nb_block); + +/** + * \brief Start the write blocks of data + * + * \param src Pointer to write buffer. + * \param nb_block Number of blocks to be written. + * + * \return return SD_MMC_OK if started, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_start_write_blocks(const void *src, uint16_t nb_block); + +/** + * \brief Wait the end of write blocks of data + * + * \param abort Abort writing process initialized by + * \ref sd_mmc_init_write_blocks() after the writing issued by + * \ref sd_mmc_start_write_blocks() is done + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sd_mmc_wait_end_of_write_blocks(bool abort); + +#ifdef SDIO_SUPPORT_ENABLE +/** + * \brief Read one byte from SDIO using RW_DIRECT command. + * + * \param slot Card slot to use + * \param func_num Function number. + * \param addr Register address to read from. + * \param dest Pointer to read buffer. + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sdio_read_direct(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t *dest); +/** + * \brief Write one byte to SDIO using RW_DIRECT command. + * + * \param slot Card slot to use + * \param func_num Function number. + * \param addr Register address to read from. + * \param data Data to be written. + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sdio_write_direct(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t data); + +/** + * \brief Read bytes from SDIO using RW_EXTENDED command. + * + * \param slot Card slot to use + * \param func_num Function number. + * \param addr First register address to read from. + * \param inc_addr 0 - The data address is fixed. + * 1 - The data address increase automatically. + * \param dest Pointer to read buffer. + * \param size Number of bytes to read (1 ~ 512). + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sdio_read_extended(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t inc_addr, uint8_t *dest, uint16_t size); + +/** + * \brief Write bytes to SDIO using RW_EXTENDED command. + * + * \param slot Card slot to use + * \param func_num Function number. + * \param addr First register address to write to. + * \param inc_addr 0 - The data address is fixed. + * 1 - The data address increase automatically. + * \param src Pointer to write buffer. + * \param size Number of bytes to read (1 ~ 512). + * + * \return return SD_MMC_OK if success, + * otherwise return an error code (\ref sd_mmc_err_t). + */ +sd_mmc_err_t sdio_write_extended(uint8_t slot, uint8_t func_num, uint32_t addr, + uint8_t inc_addr, uint8_t *src, uint16_t size); +#endif // SDIO_SUPPORT_ENABLE + +/** @} */ + +#ifdef __cplusplus +} +#endif + +#endif /* SD_MMC_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.c new file mode 100644 index 0000000..5e682b6 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.c @@ -0,0 +1,379 @@ +/** + * \file + * + * \brief CTRL_ACCESS interface for common SD/MMC stack + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "conf_access.h" + +#if (SD_MMC_0_MEM == ENABLE) || (SD_MMC_1_MEM == ENABLE) + +#include "conf_sd_mmc.h" +#include "sd_mmc.h" +#include "sd_mmc_mem.h" + +/** + * \ingroup sd_mmc_stack_mem + * \defgroup sd_mmc_stack_mem_internal Implementation of SD/MMC Memory + * @{ + */ + +/** + * \name Control Interface + * @{ + */ + +static bool sd_mmc_ejected[2] = {false, false}; + +Ctrl_status sd_mmc_test_unit_ready(uint8_t slot) +{ + switch (sd_mmc_check(slot)) + { + case SD_MMC_OK: + if (sd_mmc_ejected[slot]) { + return CTRL_NO_PRESENT; + } + if (sd_mmc_get_type(slot) & (CARD_TYPE_SD | CARD_TYPE_MMC)) { + return CTRL_GOOD; + } + // It is not a memory card + return CTRL_NO_PRESENT; + + case SD_MMC_INIT_ONGOING: + return CTRL_BUSY; + + case SD_MMC_ERR_NO_CARD: + sd_mmc_ejected[slot] = false; + return CTRL_NO_PRESENT; + + default: + return CTRL_FAIL; + } +} + +Ctrl_status sd_mmc_test_unit_ready_0(void) +{ + return sd_mmc_test_unit_ready(0); +} + + +Ctrl_status sd_mmc_test_unit_ready_1(void) +{ + return sd_mmc_test_unit_ready(1); +} + +Ctrl_status sd_mmc_read_capacity(uint8_t slot, uint32_t *nb_sector) +{ + // Return last sector address (-1) + *nb_sector = (sd_mmc_get_capacity(slot) * 2) - 1; + return sd_mmc_test_unit_ready(slot); +} + +Ctrl_status sd_mmc_read_capacity_0(uint32_t *nb_sector) +{ + return sd_mmc_read_capacity(0, nb_sector); +} + +Ctrl_status sd_mmc_read_capacity_1(uint32_t *nb_sector) +{ + return sd_mmc_read_capacity(1, nb_sector); +} + +bool sd_mmc_unload(uint8_t slot, bool unload) +{ + sd_mmc_ejected[slot] = unload; + return true; +} + +bool sd_mmc_unload_0(bool unload) +{ + return sd_mmc_unload(0, unload); +} + +bool sd_mmc_unload_1(bool unload) +{ + return sd_mmc_unload(1, unload); +} + +bool sd_mmc_wr_protect(uint8_t slot) +{ + return sd_mmc_is_write_protected(slot); +} + +bool sd_mmc_wr_protect_0(void) +{ + return sd_mmc_wr_protect(0); +} + +bool sd_mmc_wr_protect_1(void) +{ + return sd_mmc_wr_protect(1); +} + +bool sd_mmc_removal(uint8_t slot) +{ + UNUSED(slot); + return true; +} + +bool sd_mmc_removal_0(void) +{ + return sd_mmc_removal(0); +} + +bool sd_mmc_removal_1(void) +{ + return sd_mmc_removal(1); +} +//! @} + +#if ACCESS_USB == true +/** + * \name MEM <-> USB Interface + * @{ + */ + +#include "udi_msc.h" + +COMPILER_WORD_ALIGNED +uint8_t sector_buf_0[SD_MMC_BLOCK_SIZE]; + +COMPILER_WORD_ALIGNED +uint8_t sector_buf_1[SD_MMC_BLOCK_SIZE]; + +Ctrl_status sd_mmc_usb_read_10(uint8_t slot, uint32_t addr, uint16_t nb_sector) +{ + bool b_first_step = true; + uint16_t nb_step; + + switch (sd_mmc_init_read_blocks(slot, addr, nb_sector)) { + case SD_MMC_OK: + break; + case SD_MMC_ERR_NO_CARD: + return CTRL_NO_PRESENT; + default: + return CTRL_FAIL; + } + // Pipeline the 2 transfer in order to speed-up the performances + nb_step = nb_sector + 1; + while (nb_step--) { + if (nb_step) { // Skip last step + // MCI -> RAM + if (SD_MMC_OK != sd_mmc_start_read_blocks(((nb_step % 2) == 0) ? + sector_buf_0 : sector_buf_1, 1)) { + return CTRL_FAIL; + } + } + if (!b_first_step) { // Skip first step + // RAM -> USB + if (!udi_msc_trans_block(true, + ((nb_step % 2) == 0) ? + sector_buf_1 : sector_buf_0, + SD_MMC_BLOCK_SIZE, + NULL)) { + if (!b_first_step) { + sd_mmc_wait_end_of_read_blocks(true); + } + return CTRL_FAIL; + } + } else { + b_first_step = false; + } + if (nb_step) { // Skip last step + if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) { + return CTRL_FAIL; + } + } + b_first_step = false; + } + return CTRL_GOOD; +} + +Ctrl_status sd_mmc_usb_read_10_0(uint32_t addr, uint16_t nb_sector) +{ + return sd_mmc_usb_read_10(0, addr, nb_sector); +} + +Ctrl_status sd_mmc_usb_read_10_1(uint32_t addr, uint16_t nb_sector) +{ + return sd_mmc_usb_read_10(1, addr, nb_sector); +} + +Ctrl_status sd_mmc_usb_write_10(uint8_t slot, uint32_t addr, uint16_t nb_sector) +{ + bool b_first_step = true; + uint16_t nb_step; + + switch (sd_mmc_init_write_blocks(slot, addr, nb_sector)) { + case SD_MMC_OK: + break; + case SD_MMC_ERR_NO_CARD: + return CTRL_NO_PRESENT; + default: + return CTRL_FAIL; + } + // Pipeline the 2 transfer in order to speed-up the performances + nb_step = nb_sector + 1; + while (nb_step--) { + if (!b_first_step) { // Skip first step + // RAM -> MCI + if (SD_MMC_OK != sd_mmc_start_write_blocks(((nb_step % 2) == 0) ? + sector_buf_0 : sector_buf_1, 1)) { + return CTRL_FAIL; + } + } + if (nb_step) { // Skip last step + // USB -> RAM + if (!udi_msc_trans_block(false, + ((nb_step % 2) == 0) ? + sector_buf_1 : sector_buf_0, + SD_MMC_BLOCK_SIZE, + NULL)) { + if (!b_first_step) { + sd_mmc_wait_end_of_write_blocks(true); + } + return CTRL_FAIL; + } + } + if (!b_first_step) { // Skip first step + if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) { + return CTRL_FAIL; + } + } else { + b_first_step = false; + } + } + return CTRL_GOOD; +} + +Ctrl_status sd_mmc_usb_write_10_0(uint32_t addr, uint16_t nb_sector) +{ + return sd_mmc_usb_write_10(0, addr, nb_sector); +} + +Ctrl_status sd_mmc_usb_write_10_1(uint32_t addr, uint16_t nb_sector) +{ + return sd_mmc_usb_write_10(1, addr, nb_sector); +} +//! @} +#endif // ACCESS_USB == true + + +#if ACCESS_MEM_TO_RAM == true +/** + * \name MEM <-> RAM Interface + * @{ + */ +Ctrl_status sd_mmc_mem_2_ram(uint8_t slot, uint32_t addr, void *ram) +{ + return sd_mmc_mem_2_ram_multi(slot, addr, 1, ram); +} + +Ctrl_status sd_mmc_mem_2_ram_multi(uint8_t slot, uint32_t addr, uint16_t nb_block, void *ram) +{ + switch (sd_mmc_init_read_blocks(slot, addr, nb_block)) { + case SD_MMC_OK: + break; + case SD_MMC_ERR_NO_CARD: + return CTRL_NO_PRESENT; + default: + return CTRL_FAIL; + } + if (SD_MMC_OK != sd_mmc_start_read_blocks(ram, nb_block)) { + return CTRL_FAIL; + } + if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) { + return CTRL_FAIL; + } + return CTRL_GOOD; +} + +Ctrl_status sd_mmc_mem_2_ram_0(uint32_t addr, void *ram) +{ + return sd_mmc_mem_2_ram(0, addr, ram); +} + +Ctrl_status sd_mmc_mem_2_ram_1(uint32_t addr, void *ram) +{ + return sd_mmc_mem_2_ram(1, addr, ram); +} + +Ctrl_status sd_mmc_ram_2_mem(uint8_t slot, uint32_t addr, const void *ram) +{ + return sd_mmc_ram_2_mem_multi(slot, addr, 1, ram); +} + +Ctrl_status sd_mmc_ram_2_mem_multi(uint8_t slot, uint32_t addr, uint16_t nb_block, const void *ram) +{ + switch (sd_mmc_init_write_blocks(slot, addr, nb_block)) { + case SD_MMC_OK: + break; + case SD_MMC_ERR_NO_CARD: + return CTRL_NO_PRESENT; + default: + return CTRL_FAIL; + } + if (SD_MMC_OK != sd_mmc_start_write_blocks(ram, nb_block)) { + return CTRL_FAIL; + } + if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) { + return CTRL_FAIL; + } + return CTRL_GOOD; +} + +Ctrl_status sd_mmc_ram_2_mem_0(uint32_t addr, const void *ram) +{ + return sd_mmc_ram_2_mem(0, addr, ram); +} + +Ctrl_status sd_mmc_ram_2_mem_1(uint32_t addr, const void *ram) +{ + return sd_mmc_ram_2_mem(1, addr, ram); +} +//! @} + +//! @} +#endif // ACCESS_MEM_TO_RAM == true + +#endif // SD_MMC_0_MEM == ENABLE || SD_MMC_1_MEM == ENABLE diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.h new file mode 100644 index 0000000..7285cb1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_mem.h @@ -0,0 +1,248 @@ +/** + * \file + * + * \brief CTRL_ACCESS interface for common SD/MMC stack + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SD_MMC_MEM_H_ +#define _SD_MMC_MEM_H_ + +/** + * \ingroup sd_mmc_stack_group + * \defgroup sd_mmc_stack_mem SD/MMC Memory + * + * SD/MMC memory APIs required by CTRL_ACCESS module + * (\ref group_common_services_storage_ctrl_access). + * + * For usual application which use the SD/MMC card in + * memory mode through a file system or a USB device MSC, + * only a call of \ref sd_mmc_init() function is required in the startup. + * + * @{ + */ + +#include "conf_access.h" +#include "ctrl_access.h" + +#if (SD_MMC_0_MEM == ENABLE) || (SD_MMC_1_MEM == ENABLE) + +/*! \name Control Interface + */ +//! @{ + +/*! \brief Tests the memory state and initializes the memory if required. + * + * The TEST UNIT READY SCSI primary command allows an application client to poll + * a LUN until it is ready without having to allocate memory for returned data. + * + * This command may be used to check the media status of LUNs with removable + * media. + * + * \param slot SD/MMC Slot Card Selected. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_test_unit_ready(uint8_t slot); +//! Instance Declaration for sd_mmc_test_unit_ready Slot O +extern Ctrl_status sd_mmc_test_unit_ready_0(void); +//! Instance Declaration for sd_mmc_test_unit_ready Slot 1 +extern Ctrl_status sd_mmc_test_unit_ready_1(void); + +/*! \brief Returns the address of the last valid sector in the memory. + * + * \param slot SD/MMC Slot Card Selected. + * \param u32_nb_sector Pointer to the address of the last valid sector. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_read_capacity(uint8_t slot,uint32_t *u32_nb_sector); +//! Instance Declaration for sd_mmc_read_capacity Slot O +extern Ctrl_status sd_mmc_read_capacity_0(uint32_t *u32_nb_sector); +//! Instance Declaration for sd_mmc_read_capacity Slot 1 +extern Ctrl_status sd_mmc_read_capacity_1(uint32_t *u32_nb_sector); + +/*! \brief Unload/Load the SD/MMC card selected + * + * The START STOP UNIT SCSI optional command allows an application client to + * eject the removable medium on a LUN. + * + * \param slot SD/MMC Slot Card Selected. + * \param unload \c true to unload the medium, \c false to load the medium. + * + * \return \c true if unload/load done success. + */ +extern bool sd_mmc_unload(uint8_t slot, bool unload); +//! Instance Declaration for sd_mmc_unload Slot O +extern bool sd_mmc_unload_0(bool unload); +//! Instance Declaration for sd_mmc_unload Slot 1 +extern bool sd_mmc_unload_1(bool unload); + +/*! \brief Returns the write-protection state of the memory. + * +* \param slot SD/MMC Slot Card Selected. + * \return \c true if the memory is write-protected, else \c false. + * + * \note Only used by removable memories with hardware-specific write + * protection. + */ +extern bool sd_mmc_wr_protect(uint8_t slot); +//! Instance Declaration for sd_mmc_wr_protect Slot O +extern bool sd_mmc_wr_protect_0(void); +//! Instance Declaration for sd_mmc_wr_protect Slot 1 +extern bool sd_mmc_wr_protect_1(void); + +/*! \brief Tells whether the memory is removable. + * + * \param slot SD/MMC Slot Card Selected. + * \return \c true if the memory is removable, else \c false. + */ +extern bool sd_mmc_removal(uint8_t slot); +//! Instance Declaration for sd_mmc_removal Slot O +extern bool sd_mmc_removal_0(void); +//! Instance Declaration for sd_mmc_removal Slot 1 +extern bool sd_mmc_removal_1(void); + +//! @} + + +#if ACCESS_USB == true + +/*! \name MEM <-> USB Interface + */ +//! @{ + +/*! \brief Transfers data from the memory to USB. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to read. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_usb_read_10(uint8_t slot,uint32_t addr, uint16_t nb_sector); +//! Instance Declaration for sd_mmc_usb_read_10 Slot O +extern Ctrl_status sd_mmc_usb_read_10_0(uint32_t addr, uint16_t nb_sector); +//! Instance Declaration for sd_mmc_usb_read_10 Slot 1 +extern Ctrl_status sd_mmc_usb_read_10_1(uint32_t addr, uint16_t nb_sector); + +/*! \brief Transfers data from USB to the memory. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to write. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_usb_write_10(uint8_t slot,uint32_t addr, uint16_t nb_sector); +//! Instance Declaration for sd_mmc_usb_write_10 Slot O +extern Ctrl_status sd_mmc_usb_write_10_0(uint32_t addr, uint16_t nb_sector); +//! Instance Declaration for sd_mmc_usb_write_10 Slot 1 +extern Ctrl_status sd_mmc_usb_write_10_1(uint32_t addr, uint16_t nb_sector); + +//! @} + +#endif + + +#if ACCESS_MEM_TO_RAM == true + +/*! \name MEM <-> RAM Interface + */ +//! @{ + +/*! \brief Copies 1 data sector from the memory to RAM. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to read. + * \param ram Pointer to RAM buffer to write. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_mem_2_ram(uint8_t slot, uint32_t addr, void *ram); +/*! \brief Copies multiple data sectors from the memory to RAM. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to read. + * \param nb_block The number of sectors to copy. + * \param ram Pointer to RAM buffer to write. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_mem_2_ram_multi(uint8_t slot, uint32_t addr, uint16_t nb_block, void *ram); +//! Instance Declaration for sd_mmc_mem_2_ram Slot O +extern Ctrl_status sd_mmc_mem_2_ram_0(uint32_t addr, void *ram); +//! Instance Declaration for sd_mmc_mem_2_ram Slot 1 +extern Ctrl_status sd_mmc_mem_2_ram_1(uint32_t addr, void *ram); + +/*! \brief Copies 1 data sector from RAM to the memory. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to write. + * \param ram Pointer to RAM buffer to read. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_ram_2_mem(uint8_t slot, uint32_t addr, const void *ram); +/*! \brief Copies multiple data sectors from RAM to the memory. + * + * \param slot SD/MMC Slot Card Selected. + * \param addr Address of first memory sector to write. + * \param nb_block The number of sectors to copy. + * \param ram Pointer to RAM buffer to read. + * + * \return Status. + */ +extern Ctrl_status sd_mmc_ram_2_mem_multi(uint8_t slot, uint32_t addr, uint16_t nb_block, const void *ram); +//! Instance Declaration for sd_mmc_mem_2_ram Slot O +extern Ctrl_status sd_mmc_ram_2_mem_0(uint32_t addr, const void *ram); +//! Instance Declaration for sd_mmc_mem_2_ram Slot 1 +extern Ctrl_status sd_mmc_ram_2_mem_1(uint32_t addr, const void *ram); + +//! @} + +#endif +#endif + +//! @} + +#endif // _SD_MMC_MEM_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_protocol.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_protocol.h new file mode 100644 index 0000000..f85429f --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/components/memory/sd_mmc/sd_mmc_protocol.h @@ -0,0 +1,1007 @@ +/** + * \file + * + * \brief SD/MMC protocol definitions. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef SD_MMC_PROTOCOL_H_INCLUDED +#define SD_MMC_PROTOCOL_H_INCLUDED + +#include "compiler.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \addtogroup sd_mmc_protocol SD/MMC Protocol Definition + * \ingroup sd_mmc_stack_group + * @{ + */ + +// SD/MMC/SDIO default clock frequency for initialization (400KHz) +#define SDMMC_CLOCK_INIT 400000 + + +/** + * \name Macros for command definition + * + * Commands types: + * - broadcast commands (bc), no response + * - broadcast commands with response (bcr) (Note: No open drain on SD card) + * - addressed (point-to-point) commands (ac), no data transfer on DAT lines + * - addressed (point-to-point) data transfer commands (adtc), data transfer + * on DAT lines + * + * Specific MMC norms: + * CMD1, CMD2 & CMD3 are processed in the open-drain mode. + * The CMD line is driven with push-pull drivers. + * + * Specific SD norms: + * There is no open drain mode in SD memory card. + * + *************************************** + * Responses types: + * + * R1, R3, R4 & R5 use a 48 bits response protected by a 7bit CRC checksum + * - R1 receiv data not specified + * - R3 receiv OCR + * - R4, R5 RCA management (MMC only) + * - R6, R7 RCA management (SD only) + * + * R1b assert the BUSY signal and respond with R1. + * If the busy signal is asserted, it is done two clock cycles (Nsr time) + * after the end bit of the command. The DAT0 line is driven low. + * DAT1-DAT7 lines are driven by the card though their values are not relevant. + * + * R2 use a 136 bits response protected by a 7bit CRC checksum + * The content is CID or CSD + * + * Specific MMC norms: + * - R4 (Fast I/O) return RCA + * - R5 (interrupt request) return RCA null + * + * Specific SD norms: + * - R6 (Published RCA) return RCA + * - R7 (Card interface condition) return RCA null + * + * @{ + */ + +//! Value to define a SD/MMC/SDIO command +typedef uint32_t sdmmc_cmd_def_t; + +//! \name Flags used to define a SD/MMC/SDIO command +//! @{ +#define SDMMC_CMD_GET_INDEX(cmd) (cmd & 0x3F) +//! Have response (MCI only) +#define SDMMC_RESP_PRESENT (1lu << 8) +//! 8 bit response (SPI only) +#define SDMMC_RESP_8 (1lu << 9) +//! 32 bit response (SPI only) +#define SDMMC_RESP_32 (1lu << 10) +//! 136 bit response (MCI only) +#define SDMMC_RESP_136 (1lu << 11) +//! Expect valid crc (MCI only) +#define SDMMC_RESP_CRC (1lu << 12) +//! Card may send busy +#define SDMMC_RESP_BUSY (1lu << 13) +// Open drain for a braodcast command (bc) +// or to enter in inactive state (MCI only) +#define SDMMC_CMD_OPENDRAIN (1lu << 14) +//! To signal a data write operation +#define SDMMC_CMD_WRITE (1lu << 15) +//! To signal a SDIO tranfer in multi byte mode +#define SDMMC_CMD_SDIO_BYTE (1lu << 16) +//! To signal a SDIO tranfer in block mode +#define SDMMC_CMD_SDIO_BLOCK (1lu << 17) +//! To signal a data transfer in stream mode +#define SDMMC_CMD_STREAM (1lu << 18) +//! To signal a data transfer in single block mode +#define SDMMC_CMD_SINGLE_BLOCK (1lu << 19) +//! To signal a data transfer in multi block mode +#define SDMMC_CMD_MULTI_BLOCK (1lu << 20) +//! @} + +//! \name Set of flags to define a reponse type +//! @{ +#define SDMMC_CMD_NO_RESP (0) +#define SDMMC_CMD_R1 (SDMMC_RESP_PRESENT | SDMMC_RESP_CRC) +#define SDMMC_CMD_R1B (SDMMC_RESP_PRESENT | SDMMC_RESP_CRC | SDMMC_RESP_BUSY) +#define SDMMC_CMD_R2 (SDMMC_RESP_PRESENT | SDMMC_RESP_8 | SDMMC_RESP_136 | SDMMC_RESP_CRC) +#define SDMMC_CMD_R3 (SDMMC_RESP_PRESENT | SDMMC_RESP_32) +#define SDMMC_CMD_R4 (SDMMC_RESP_PRESENT | SDMMC_RESP_32) +#define SDMMC_CMD_R5 (SDMMC_RESP_PRESENT | SDMMC_RESP_8 | SDMMC_RESP_CRC) +#define SDMMC_CMD_R6 (SDMMC_RESP_PRESENT | SDMMC_RESP_CRC) +#define SDMMC_CMD_R7 (SDMMC_RESP_PRESENT | SDMMC_RESP_32 | SDMMC_RESP_CRC) +//! @} + +//! \name SD/MMC/SDIO command definitions +//! SDMMC_CMDx are include in SD and MMC norms +//! MMC_CMDx are include in MMC norms only +//! SD_CMDx are include in SD norms only +//! SDIO_CMDx are include in SDIO norms only +//! @{ + +/* + * --- Basic commands and read-stream command (class 0 and class 1) --- + */ + +/** Cmd0(bc): Reset all cards to idle state */ +#define SDMMC_SPI_CMD0_GO_IDLE_STATE (0 | SDMMC_CMD_R1) +#define SDMMC_MCI_CMD0_GO_IDLE_STATE (0 | SDMMC_CMD_NO_RESP | SDMMC_CMD_OPENDRAIN) +/** MMC Cmd1(bcr, R3): Ask the card to send its Operating Conditions */ +#define MMC_SPI_CMD1_SEND_OP_COND (1 | SDMMC_CMD_R1) +#define MMC_MCI_CMD1_SEND_OP_COND (1 | SDMMC_CMD_R3 | SDMMC_CMD_OPENDRAIN) +/** Cmd2(bcr, R2): Ask the card to send its CID number (stuff but arg 0 used) */ +#define SDMMC_CMD2_ALL_SEND_CID (2 | SDMMC_CMD_R2 | SDMMC_CMD_OPENDRAIN) +/** SD Cmd3(bcr, R6): Ask the card to publish a new relative address (RCA) */ +#define SD_CMD3_SEND_RELATIVE_ADDR (3 | SDMMC_CMD_R6 | SDMMC_CMD_OPENDRAIN) +/** MMC Cmd3(ac, R1): Assigns relative address to the card */ +#define MMC_CMD3_SET_RELATIVE_ADDR (3 | SDMMC_CMD_R1) +/** Cmd4(bc): Program the DSR of all cards (MCI only) */ +#define SDMMC_CMD4_SET_DSR (4 | SDMMC_CMD_NO_RESP) +/** MMC Cmd5(ac, R1b): Toggle the card between Sleep state and Standby state. */ +#define MMC_CMD5_SLEEP_AWAKE (5 | SDMMC_CMD_R1B) +/** Cmd7(ac, R1/R1b): Select/Deselect card + * For SD: R1b only from the selected card. + * For MMC: R1 while selecting from Stand-By State to Transfer State; + * R1b while selecting from Disconnected State to Programming State. + */ +#define SDMMC_CMD7_SELECT_CARD_CMD (7 | SDMMC_CMD_R1B) +#define SDMMC_CMD7_DESELECT_CARD_CMD (7 | SDMMC_CMD_R1) +/** MMC Cmd8(adtc, R1): Send EXT_CSD register as a block of data */ +#define MMC_CMD8_SEND_EXT_CSD (8 | SDMMC_CMD_R1 | SDMMC_CMD_SINGLE_BLOCK) +/** SD Cmd8(bcr, R7) : Send SD Memory Card interface condition */ +#define SD_CMD8_SEND_IF_COND (8 | SDMMC_CMD_R7 | SDMMC_CMD_OPENDRAIN) +/** Cmd9 SPI (R1): Addressed card sends its card-specific data (CSD) */ +#define SDMMC_SPI_CMD9_SEND_CSD (9 | SDMMC_CMD_R1 | SDMMC_CMD_SINGLE_BLOCK) +/** Cmd9 MCI (ac, R2): Addressed card sends its card-specific data (CSD) */ +#define SDMMC_MCI_CMD9_SEND_CSD (9 | SDMMC_CMD_R2) +/** Cmd10(ac, R2): Addressed card sends its card identification (CID) */ +#define SDMMC_CMD10_SEND_CID (10 | SDMMC_CMD_R2) +/** + * MMC Cmd11(adtc, R1): Read data stream from the card, starting at the given + * address, until a STOP_TRANSMISSION follows. + */ +#define MMC_CMD11_READ_DAT_UNTIL_STOP (11 | SDMMC_CMD_R1) +/* SD Cmd11 MCI (ac, R1): Voltage switching */ +#define SD_CMD11_READ_DAT_UNTIL_STOP (11 | SDMMC_CMD_R1) +/** Cmd12(ac, R1b): Force the card to stop transmission */ +#define SDMMC_CMD12_STOP_TRANSMISSION (12 | SDMMC_CMD_R1B) +/** Cmd13(R2): Addressed card sends its status register. */ +#define SDMMC_SPI_CMD13_SEND_STATUS (13 | SDMMC_CMD_R2) +/** Cmd13(ac, R1): Addressed card sends its status register. */ +#define SDMMC_MCI_CMD13_SEND_STATUS (13 | SDMMC_CMD_R1) +/** MMC Cmd14(adtc, R1): Read the reversed bus testing data pattern from a card. */ +#define MMC_CMD14_BUSTEST_R (14 | SDMMC_CMD_R1) +/** Cmd15(ac): Send an addressed card into the Inactive State. */ +// Note: It is a ac cmd, but it must be send like bc cmd to open drain +#define SDMMC_CMD15_GO_INACTIVE_STATE (15 | SDMMC_CMD_NO_RESP | SDMMC_CMD_OPENDRAIN) +/** MMC Cmd19(adtc, R1): Send the bus test data pattern */ +#define MMC_CMD19_BUSTEST_W (19 | SDMMC_CMD_R1) +/** Cmd58(R3): Reads the OCR register of a card */ +#define SDMMC_SPI_CMD58_READ_OCR (58 | SDMMC_CMD_R3) +/** Cmd59(R1): Turns the CRC option on or off */ +#define SDMMC_SPI_CMD59_CRC_ON_OFF (59 | SDMMC_CMD_R1) + +/* + * --- Block-oriented read commands (class 2) --- + */ +/** Cmd16(ac, R1): Set the block length (in bytes) */ +#define SDMMC_CMD16_SET_BLOCKLEN (16 | SDMMC_CMD_R1) +/** Cmd17(adtc, R1): Read single block */ +#define SDMMC_CMD17_READ_SINGLE_BLOCK (17 | SDMMC_CMD_R1 | SDMMC_CMD_SINGLE_BLOCK) +/** Cmd18(adtc, R1): Read multiple block */ +#define SDMMC_CMD18_READ_MULTIPLE_BLOCK (18 | SDMMC_CMD_R1 | SDMMC_CMD_MULTI_BLOCK) + +/* + * --- Sequential write commands (class 3) --- + */ + +/** + * MMC Cmd20(adtc, R1): Write a data stream from the host, starting at the + * given address, until a STOP_TRANSMISSION follows. + */ +#define MMC_CMD20_WRITE_DAT_UNTIL_STOP (20 | SDMMC_CMD_R1) + +/* + * --- Block-oriented write commands (class 4) --- + */ +/** MMC Cmd23(ac, R1): Set block count */ +#define MMC_CMD23_SET_BLOCK_COUNT (23 | SDMMC_CMD_R1) +/** Cmd24(adtc, R1): Write block */ +#define SDMMC_CMD24_WRITE_BLOCK (24 | SDMMC_CMD_R1 | SDMMC_CMD_WRITE | SDMMC_CMD_SINGLE_BLOCK) +/** Cmd25(adtc, R1): Write multiple block */ +#define SDMMC_CMD25_WRITE_MULTIPLE_BLOCK (25 | SDMMC_CMD_R1 | SDMMC_CMD_WRITE | SDMMC_CMD_MULTI_BLOCK) +/** MMC Cmd26(adtc, R1): Programming of the card identification register. */ +#define MMC_CMD26_PROGRAM_CID (26 | SDMMC_CMD_R1) +/** Cmd27(adtc, R1): Programming of the programmable bits of the CSD. */ +#define SDMMC_CMD27_PROGRAM_CSD (27 | SDMMC_CMD_R1) + +/* + * --- Erase commands (class 5) --- + */ +/** SD Cmd32(ac, R1): */ +#define SD_CMD32_ERASE_WR_BLK_START (32 | SDMMC_CMD_R1) +/** SD Cmd33(ac, R1): */ +#define SD_CMD33_ERASE_WR_BLK_END (33 | SDMMC_CMD_R1) +/** MMC Cmd35(ac, R1): */ +#define MMC_CMD35_ERASE_GROUP_START (35 | SDMMC_CMD_R1) +/** MMC Cmd36(ac, R1): */ +#define MMC_CMD36_ERASE_GROUP_END (36 | SDMMC_CMD_R1) +/** Cmd38(ac, R1B): */ +#define SDMMC_CMD38_ERASE (38 | SDMMC_CMD_R1B) + +/* + * --- Block Oriented Write Protection Commands (class 6) --- + */ +/** Cmd28(ac, R1b): Set write protection */ +#define SDMMC_CMD28_SET_WRITE_PROT (28 | SDMMC_CMD_R1B) +/** Cmd29(ac, R1b): Clr write protection */ +#define SDMMC_CMD29_CLR_WRITE_PROT (29 | SDMMC_CMD_R1B) +/** Cmd30(adtc, R1b): Send write protection */ +#define SDMMC_CMD30_SEND_WRITE_PROT (30 | SDMMC_CMD_R1) + +/* + * --- Lock Card (class 7) --- + */ +/** Cmd42(adtc, R1): Used to set/reset the password or lock/unlock the card. */ +#define SDMMC_CMD42_LOCK_UNLOCK (42 | SDMMC_CMD_R1) + +/* + * --- Application-specific commands (class 8) --- + */ +/** + * Cmd55(ac, R1): Indicate to the card that the next command is an application + * specific command rather than a standard command. + */ +#define SDMMC_CMD55_APP_CMD (55 | SDMMC_CMD_R1) +/** + * Cmd 56(adtc, R1): Used either to transfer a data block to the card or to get + * a data block from the card for general purpose/application specific commands. + */ +#define SDMMC_CMD56_GEN_CMD (56 | SDMMC_CMD_R1) + +/** + * MMC Cmd6(ac, R1b) : Switche the mode of operation of the selected card + * or modifies the EXT_CSD registers. + */ +#define MMC_CMD6_SWITCH (6 | SDMMC_CMD_R1B) +/** + * SD Cmd6(adtc, R1) : Check switchable function (mode 0) + * and switch card function (mode 1). + */ +#define SD_CMD6_SWITCH_FUNC (6 | SDMMC_CMD_R1 | SDMMC_CMD_SINGLE_BLOCK) +/** ACMD6(ac, R1): Define the data bus width */ +#define SD_ACMD6_SET_BUS_WIDTH (6 | SDMMC_CMD_R1) +/** ACMD13(adtc, R1): Send the SD Status. */ +#define SD_ACMD13_SD_STATUS (13 | SDMMC_CMD_R1) +/** + * ACMD22(adtc, R1): Send the number of the written (with-out errors) write + * blocks. + */ +#define SD_ACMD22_SEND_NUM_WR_BLOCKS (22 | SDMMC_CMD_R1) +/** + * ACMD23(ac, R1): Set the number of write blocks to be pre-erased before + * writing + */ +#define SD_ACMD23_SET_WR_BLK_ERASE_COUNT (23 | SDMMC_CMD_R1) +/** + * ACMD41(bcr, R3): Send host capacity support information (HCS) and asks the + * accessed card to send its operating condition register (OCR) content + * in the response + */ +#define SD_MCI_ACMD41_SD_SEND_OP_COND (41 | SDMMC_CMD_R3 | SDMMC_CMD_OPENDRAIN) +/** + * ACMD41(R1): Send host capacity support information (HCS) and activates the + * card's initilization process + */ +#define SD_SPI_ACMD41_SD_SEND_OP_COND (41 | SDMMC_CMD_R1) +/** + * ACMD42(ac, R1): Connect[1]/Disconnect[0] the 50 KOhm pull-up resistor on + * CD/DAT3 (pin 1) of the card. + */ +#define SD_ACMD42_SET_CLR_CARD_DETECT (42 | SDMMC_CMD_R1) +/** ACMD51(adtc, R1): Read the SD Configuration Register (SCR). */ +#define SD_ACMD51_SEND_SCR (51 | SDMMC_CMD_R1 | SDMMC_CMD_SINGLE_BLOCK) + +/* + * --- I/O mode commands (class 9) --- + */ +/** MMC Cmd39(ac, R4): Used to write and read 8 bit (register) data fields. */ +#define MMC_CMD39_FAST_IO (39 | SDMMC_CMD_R4) +/** MMC Cmd40(bcr, R5): Set the system into interrupt mode */ +#define MMC_CMD40_GO_IRQ_STATE (40 | SDMMC_CMD_R5 | SDMMC_CMD_OPENDRAIN) +/** SDIO Cmd5(R4): Send operation condition */ +#define SDIO_CMD5_SEND_OP_COND (5 | SDMMC_CMD_R4 | SDMMC_CMD_OPENDRAIN) +/** SDIO CMD52(R5): Direct IO read/write */ +#define SDIO_CMD52_IO_RW_DIRECT (52 | SDMMC_CMD_R5) +/** SDIO CMD53(R5): Extended IO read/write */ +#define SDIO_CMD53_IO_R_BYTE_EXTENDED (53 | SDMMC_CMD_R5 | SDMMC_CMD_SDIO_BYTE) +#define SDIO_CMD53_IO_W_BYTE_EXTENDED (53 | SDMMC_CMD_R5 | SDMMC_CMD_SDIO_BYTE | SDMMC_CMD_WRITE) +#define SDIO_CMD53_IO_R_BLOCK_EXTENDED (53 | SDMMC_CMD_R5 | SDMMC_CMD_SDIO_BLOCK) +#define SDIO_CMD53_IO_W_BLOCK_EXTENDED (53 | SDMMC_CMD_R5 | SDMMC_CMD_SDIO_BLOCK | SDMMC_CMD_WRITE) +//! @} +//! @} + + +//! \name Macros for command argument definition +//! @{ + + //! \name MMC CMD6 argument structure + //! @{ +//! [31:26] Set to 0 +//! [25:24] Access +#define MMC_CMD6_ACCESS_COMMAND_SET (0lu << 24) +#define MMC_CMD6_ACCESS_SET_BITS (1lu << 24) +#define MMC_CMD6_ACCESS_CLEAR_BITS (2lu << 24) +#define MMC_CMD6_ACCESS_WRITE_BYTE (3lu << 24) +//! [23:16] Index for Mode Segment +#define MMC_CMD6_INDEX_CMD_SET (EXT_CSD_CMD_SET_INDEX << 16) +#define MMC_CMD6_INDEX_CMD_SET_REV (EXT_CSD_CMD_SET_REV_INDEX << 16) +#define MMC_CMD6_INDEX_POWER_CLASS (EXT_CSD_POWER_CLASS_INDEX << 16) +#define MMC_CMD6_INDEX_HS_TIMING (EXT_CSD_HS_TIMING_INDEX << 16) +#define MMC_CMD6_INDEX_BUS_WIDTH (EXT_CSD_BUS_WIDTH_INDEX << 16) +#define MMC_CMD6_INDEX_ERASED_MEM_CONT (EXT_CSD_ERASED_MEM_CONT_INDEX << 16) +#define MMC_CMD6_INDEX_BOOT_CONFIG (EXT_CSD_BOOT_CONFIG_INDEX << 16) +#define MMC_CMD6_INDEX_BOOT_BUS_WIDTH (EXT_CSD_BOOT_BUS_WIDTH_INDEX << 16) +#define MMC_CMD6_INDEX_ERASE_GROUP_DEF (EXT_CSD_ERASE_GROUP_DEF_INDEX << 16) +//! [15:8] Value +#define MMC_CMD6_VALUE_BUS_WIDTH_1BIT (0x0lu << 8) +#define MMC_CMD6_VALUE_BUS_WIDTH_4BIT (0x1lu << 8) +#define MMC_CMD6_VALUE_BUS_WIDTH_8BIT (0x2lu << 8) +#define MMC_CMD6_VALUE_HS_TIMING_ENABLE (0x1lu << 8) +#define MMC_CMD6_VALUE_HS_TIMING_DISABLE (0x0lu << 8) +//! [7:3] Set to 0 +//! [2:0] Cmd Set + //! @} + + //! \name SD CMD6 argument structure + //! @{ +//! CMD6 arg[ 3: 0] function group 1, access mode +#define SD_CMD6_GRP1_HIGH_SPEED (0x1lu << 0) +#define SD_CMD6_GRP1_DEFAULT (0x0lu << 0) +//! CMD6 arg[ 7: 4] function group 2, command system +#define SD_CMD6_GRP2_NO_INFLUENCE (0xFlu << 4) +#define SD_CMD6_GRP2_DEFAULT (0x0lu << 4) +//! CMD6 arg[11: 8] function group 3, 0xF or 0x0 +#define SD_CMD6_GRP3_NO_INFLUENCE (0xFlu << 8) +#define SD_CMD6_GRP3_DEFAULT (0x0lu << 8) +//! CMD6 arg[15:12] function group 4, 0xF or 0x0 +#define SD_CMD6_GRP4_NO_INFLUENCE (0xFlu << 12) +#define SD_CMD6_GRP4_DEFAULT (0x0lu << 12) +//! CMD6 arg[19:16] function group 5, 0xF or 0x0 +#define SD_CMD6_GRP5_NO_INFLUENCE (0xFlu << 16) +#define SD_CMD6_GRP5_DEFAULT (0x0lu << 16) +//! CMD6 arg[23:20] function group 6, 0xF or 0x0 +#define SD_CMD6_GRP6_NO_INFLUENCE (0xFlu << 20) +#define SD_CMD6_GRP6_DEFAULT (0x0lu << 20) +//! CMD6 arg[30:24] reserved 0 +//! CMD6 arg[31 ] Mode, 0: Check, 1: Switch +#define SD_CMD6_MODE_CHECK (0lu << 31) +#define SD_CMD6_MODE_SWITCH (1lu << 31) + //! @} + + //! \name SD CMD8 argument structure + //! @{ +#define SD_CMD8_PATTERN 0xAA +#define SD_CMD8_MASK_PATTERN 0xFF +#define SD_CMD8_HIGH_VOLTAGE 0x100 +#define SD_CMD8_MASK_VOLTAGE 0xF00 + //! @} + + //! \name SD ACMD41 arguments + //! @{ +#define SD_ACMD41_HCS (1lu << 30) //!< (SD) Host Capacity Support + //! @} +//! @} + + +//! \name SDIO definitions +//! @{ + + //! \name SDIO state (in R5) + //! @{ +#define SDIO_R5_COM_CRC_ERROR (1lu << 15) /**< CRC check error */ +#define SDIO_R5_ILLEGAL_COMMAND (1lu << 14) /**< Illegal command */ +#define SDIO_R5_STATE (3lu << 12) /**< SDIO R5 state mask */ +#define SDIO_R5_STATE_DIS (0lu << 12) /**< Disabled */ +#define SDIO_R5_STATE_CMD (1lu << 12) /**< DAT lines free */ +#define SDIO_R5_STATE_TRN (2lu << 12) /**< Transfer */ +#define SDIO_R5_STATE_RFU (3lu << 12) /**< Reserved */ +#define SDIO_R5_ERROR (1lu << 11) /**< General error */ +#define SDIO_R5_FUNC_NUM (1lu << 9) /**< Invalid function number */ +#define SDIO_R5_OUT_OF_RANGE (1lu << 8) /**< Argument out of range */ +#define SDIO_R5_STATUS_ERR (SDIO_R5_ERROR | SDIO_R5_FUNC_NUM \ + | SDIO_R5_OUT_OF_RANGE) //!< Errro status bits mask + //! @} + + //! \name SDIO state (in R6) + //! @{ +/** The CRC check of the previous command failed. */ +#define SDIO_R6_COM_CRC_ERROR (1lu << 15) +/** Command not legal for the card state. */ +#define SDIO_R6_ILLEGAL_COMMAND (1lu << 14) +/** A general or an unknown error occurred during the operation. */ +#define SDIO_R6_ERROR (1lu << 13) +/** Status bits mask for SDIO R6 */ +#define SDIO_STATUS_R6 (SDIO_R6_COM_CRC_ERROR \ + | SDIO_R6_ILLEGAL_COMMAND | SDIO_R6_ERROR) + //! @} + + //! \name SDIO CMD52 argument bit offset + //! @{ +//! CMD52 arg[ 7: 0] Write data or stuff bits +#define SDIO_CMD52_WR_DATA 0 +//! CMD52 arg[ 8] Reserved +#define SDIO_CMD52_STUFF0 8 +//! CMD52 arg[25: 9] Register address +#define SDIO_CMD52_REG_ADRR 9 +//! CMD52 arg[ 26] Reserved +#define SDIO_CMD52_STUFF1 26 +//! CMD52 arg[ 27] Read after Write flag +#define SDIO_CMD52_RAW_FLAG 27 +//! CMD52 arg[30:28] Number of the function +#define SDIO_CMD52_FUNCTION_NUM 28 +//! CMD52 arg[ 31] Direction, 1:write, 0:read. +#define SDIO_CMD52_RW_FLAG 31 +# define SDIO_CMD52_READ_FLAG 0 +# define SDIO_CMD52_WRITE_FLAG 1 + //! @} + + //! \name SDIO CMD53 argument structure + //! @{ +/** + * [ 8: 0] Byte mode: number of bytes to transfer, + * 0 cause 512 bytes transfer. + * Block mode: number of blocks to transfer, + * 0 set count to infinite. + */ +#define SDIO_CMD53_COUNT 0 +//! CMD53 arg[25: 9] Start Address I/O register +#define SDIO_CMD53_REG_ADDR 9 +//! CMD53 arg[ 26] 1:Incrementing address, 0: fixed +#define SDIO_CMD53_OP_CODE 26 +//! CMD53 arg[ 27] (Optional) 1:block mode +#define SDIO_CMD53_BLOCK_MODE 27 +//! CMD53 arg[30:28] Number of the function +#define SDIO_CMD53_FUNCTION_NUM 28 +//! CMD53 arg[ 31] Direction, 1:WR, 0:RD +#define SDIO_CMD53_RW_FLAG 31 +# define SDIO_CMD53_READ_FLAG 0 +# define SDIO_CMD53_WRITE_FLAG 1 + //! @} + + //! \name SDIO Functions + //! @{ +#define SDIO_CIA 0 /**< SDIO Function 0 (CIA) */ +#define SDIO_FN0 0 /**< SDIO Function 0 */ +#define SDIO_FN1 1 /**< SDIO Function 1 */ +#define SDIO_FN2 2 /**< SDIO Function 2 */ +#define SDIO_FN3 3 /**< SDIO Function 3 */ +#define SDIO_FN4 4 /**< SDIO Function 4 */ +#define SDIO_FN5 5 /**< SDIO Function 5 */ +#define SDIO_FN6 6 /**< SDIO Function 6 */ +#define SDIO_FN7 7 /**< SDIO Function 7 */ + //! @} + + //! \name SDIO Card Common Control Registers (CCCR) + //! @{ +#define SDIO_CCCR_SDIO_REV 0x00 /**< CCCR/SDIO revision (RO) */ +#define SDIO_CCCR_REV_1_00 (0x0lu << 0) /**< CCCR/FBR Version 1.00 */ +#define SDIO_CCCR_REV_1_10 (0x1lu << 0) /**< CCCR/FBR Version 1.10 */ +#define SDIO_CCCR_REV_2_00 (0x2lu << 0) /**< CCCR/FBR Version 2.00 */ +#define SDIO_CCCR_REV_3_00 (0x3lu << 0) /**< CCCR/FBR Version 3.00 */ +#define SDIO_SDIO_REV_1_00 (0x0lu << 4) /**< SDIO Spec 1.00 */ +#define SDIO_SDIO_REV_1_10 (0x1lu << 4) /**< SDIO Spec 1.10 */ +#define SDIO_SDIO_REV_1_20 (0x2lu << 4) /**< SDIO Spec 1.20(unreleased) */ +#define SDIO_SDIO_REV_2_00 (0x3lu << 4) /**< SDIO Spec Version 2.00 */ +#define SDIO_SDIO_REV_3_00 (0x4lu << 4) /**< SDIO Spec Version 3.00 */ +#define SDIO_CCCR_SD_REV 0x01 /**< SD Spec Revision (RO) */ +#define SDIO_SD_REV_1_01 (0x0lu << 0) /**< SD 1.01 (Mar 2000) */ +#define SDIO_SD_REV_1_10 (0x1lu << 0) /**< SD 1.10 (Oct 2004) */ +#define SDIO_SD_REV_2_00 (0x2lu << 0) /**< SD 2.00 (May 2006) */ +#define SDIO_SD_REV_3_00 (0x3lu << 0) /**< SD 3.00 */ +#define SDIO_CCCR_IOE 0x02 /**< I/O Enable (R/W) */ +#define SDIO_IOE_FN1 (0x1lu << 1) /**< Function 1 Enable/Disable */ +#define SDIO_IOE_FN2 (0x1lu << 2) /**< Function 2 Enable/Disable */ +#define SDIO_IOE_FN3 (0x1lu << 3) /**< Function 3 Enable/Disable */ +#define SDIO_IOE_FN4 (0x1lu << 4) /**< Function 4 Enable/Disable */ +#define SDIO_IOE_FN5 (0x1lu << 5) /**< Function 5 Enable/Disable */ +#define SDIO_IOE_FN6 (0x1lu << 6) /**< Function 6 Enable/Disable */ +#define SDIO_IOE_FN7 (0x1lu << 7) /**< Function 7 Enable/Disable */ +#define SDIO_CCCR_IOR 0x03 /**< I/O Ready (RO) */ +#define SDIO_IOR_FN1 (0x1lu << 1) /**< Function 1 ready */ +#define SDIO_IOR_FN2 (0x1lu << 2) /**< Function 2 ready */ +#define SDIO_IOR_FN3 (0x1lu << 3) /**< Function 3 ready */ +#define SDIO_IOR_FN4 (0x1lu << 4) /**< Function 4 ready */ +#define SDIO_IOR_FN5 (0x1lu << 5) /**< Function 5 ready */ +#define SDIO_IOR_FN6 (0x1lu << 6) /**< Function 6 ready */ +#define SDIO_IOR_FN7 (0x1lu << 7) /**< Function 7 ready */ +#define SDIO_CCCR_IEN 0x04 /**< Int Enable */ +#define SDIO_IENM (0x1lu << 0) /**< Int Enable Master (R/W) */ +#define SDIO_IEN_FN1 (0x1lu << 1) /**< Function 1 Int Enable */ +#define SDIO_IEN_FN2 (0x1lu << 2) /**< Function 2 Int Enable */ +#define SDIO_IEN_FN3 (0x1lu << 3) /**< Function 3 Int Enable */ +#define SDIO_IEN_FN4 (0x1lu << 4) /**< Function 4 Int Enable */ +#define SDIO_IEN_FN5 (0x1lu << 5) /**< Function 5 Int Enable */ +#define SDIO_IEN_FN6 (0x1lu << 6) /**< Function 6 Int Enable */ +#define SDIO_IEN_FN7 (0x1lu << 7) /**< Function 7 Int Enable */ +#define SDIO_CCCR_INT 0x05 /**< Int Pending */ +#define SDIO_INT_FN1 (0x1lu << 1) /**< Function 1 Int pending */ +#define SDIO_INT_FN2 (0x1lu << 2) /**< Function 2 Int pending */ +#define SDIO_INT_FN3 (0x1lu << 3) /**< Function 3 Int pending */ +#define SDIO_INT_FN4 (0x1lu << 4) /**< Function 4 Int pending */ +#define SDIO_INT_FN5 (0x1lu << 5) /**< Function 5 Int pending */ +#define SDIO_INT_FN6 (0x1lu << 6) /**< Function 6 Int pending */ +#define SDIO_INT_FN7 (0x1lu << 7) /**< Function 7 Int pending */ +#define SDIO_CCCR_IOA 0x06 /**< I/O Abort */ +#define SDIO_AS_FN1 (0x1lu << 0) /**< Abort function 1 IO */ +#define SDIO_AS_FN2 (0x2lu << 0) /**< Abort function 2 IO */ +#define SDIO_AS_FN3 (0x3lu << 0) /**< Abort function 3 IO */ +#define SDIO_AS_FN4 (0x4lu << 0) /**< Abort function 4 IO */ +#define SDIO_AS_FN5 (0x5lu << 0) /**< Abort function 5 IO */ +#define SDIO_AS_FN6 (0x6lu << 0) /**< Abort function 6 IO */ +#define SDIO_AS_FN7 (0x7lu << 0) /**< Abort function 7 IO */ +#define SDIO_RES (0x1lu << 3) /**< IO CARD RESET (WO) */ +#define SDIO_CCCR_BUS_CTRL 0x07 /**< Bus Interface Control */ +#define SDIO_BUSWIDTH_1B (0x0lu << 0) /**< 1-bit data bus */ +#define SDIO_BUSWIDTH_4B (0x2lu << 0) /**< 4-bit data bus */ +/** Enable Continuous SPI interrupt (R/W) */ +#define SDIO_BUS_ECSI (0x1lu << 5) +/** Support Continuous SPI interrupt (RO) */ +#define SDIO_BUS_SCSI (0x1lu << 6) +/** Connect(0)/Disconnect(1) pull-up on CD/DAT[3] (R/W) */ +#define SDIO_BUS_CD_DISABLE (0x1lu << 7) +#define SDIO_CCCR_CAP 0x08 /**< Card Capability */ +/** Support Direct Commands during data transfer (RO) */ +#define SDIO_CAP_SDC (0x1lu << 0) +/** Support Multi-Block (RO) */ +#define SDIO_CAP_SMB (0x1lu << 1) +/** Support Read Wait (RO) */ +#define SDIO_CAP_SRW (0x1lu << 2) +/** Support Suspend/Resume (RO) */ +#define SDIO_CAP_SBS (0x1lu << 3) +/** Support interrupt between blocks of data in 4-bit SD mode (RO) */ +#define SDIO_CAP_S4MI (0x1lu << 4) +/** Enable interrupt between blocks of data in 4-bit SD mode (R/W) */ +#define SDIO_CAP_E4MI (0x1lu << 5) +/** Low-Speed Card (RO) */ +#define SDIO_CAP_LSC (0x1lu << 6) +/** 4-bit support for Low-Speed Card (RO) */ +#define SDIO_CAP_4BLS (0x1lu << 7) +/** Pointer to CIS (3B, LSB first) */ +#define SDIO_CCCR_CIS_PTR 0x09 +/** Bus Suspend */ +#define SDIO_CCCR_BUS_SUSPEND 0x0C +/** Bus Status (transfer on DAT[x] lines) (RO) */ +#define SDIO_BS (0x1lu << 0) +/** Bus Release Request/Status (R/W) */ +#define SDIO_BR (0x1lu << 1) +#define SDIO_CCCR_FUN_SEL 0x0D /**< Function select */ +#define SDIO_DF (0x1lu << 7) /**< Resume Data Flag (RO) */ +#define SDIO_FS_CIA (0x0lu << 0) /**< Select CIA (function 0) */ +#define SDIO_FS_FN1 (0x1lu << 0) /**< Select Function 1 */ +#define SDIO_FS_FN2 (0x2lu << 0) /**< Select Function 2 */ +#define SDIO_FS_FN3 (0x3lu << 0) /**< Select Function 3 */ +#define SDIO_FS_FN4 (0x4lu << 0) /**< Select Function 4 */ +#define SDIO_FS_FN5 (0x5lu << 0) /**< Select Function 5 */ +#define SDIO_FS_FN6 (0x6lu << 0) /**< Select Function 6 */ +#define SDIO_FS_FN7 (0x7lu << 0) /**< Select Function 7 */ +#define SDIO_FS_MEM (0x8lu << 0) /**< Select memory in combo card */ +#define SDIO_CCCR_EXEC 0x0E /**< Exec Flags (RO) */ +#define SDIO_EXM (0x1lu << 0) /**< Executing status of memory */ +#define SDIO_EX_FN1 (0x1lu << 1) /**< Executing status of func 1 */ +#define SDIO_EX_FN2 (0x1lu << 2) /**< Executing status of func 2 */ +#define SDIO_EX_FN3 (0x1lu << 3) /**< Executing status of func 3 */ +#define SDIO_EX_FN4 (0x1lu << 4) /**< Executing status of func 4 */ +#define SDIO_EX_FN5 (0x1lu << 5) /**< Executing status of func 5 */ +#define SDIO_EX_FN6 (0x1lu << 6) /**< Executing status of func 6 */ +#define SDIO_EX_FN7 (0x1lu << 7) /**< Executing status of func 7 */ +#define SDIO_CCCR_READY 0x0F /**< Ready Flags (RO) */ +#define SDIO_RFM (0x1lu << 0) /**< Ready Flag for memory */ +#define SDIO_RF_FN1 (0x1lu << 1) /**< Ready Flag for function 1 */ +#define SDIO_RF_FN2 (0x1lu << 2) /**< Ready Flag for function 2 */ +#define SDIO_RF_FN3 (0x1lu << 3) /**< Ready Flag for function 3 */ +#define SDIO_RF_FN4 (0x1lu << 4) /**< Ready Flag for function 4 */ +#define SDIO_RF_FN5 (0x1lu << 5) /**< Ready Flag for function 5 */ +#define SDIO_RF_FN6 (0x1lu << 6) /**< Ready Flag for function 6 */ +#define SDIO_RF_FN7 (0x1lu << 7) /**< Ready Flag for function 7 */ +#define SDIO_CCCR_FN0_BLKSIZ 0x10 /**< FN0 Block Size (2B, LSB first) (R/W) */ +#define SDIO_CCCR_POWER 0x12 /**< Power Control */ +#define SDIO_POWER_SMPC (0x1lu << 0) /**< Support Master Power Control*/ +#define SDIO_POWER_EMPC (0x1lu << 1) /**< Enable Master Power Control */ +#define SDIO_CCCR_HS 0x13 /**< High-Speed */ +#define SDIO_SHS (0x1lu << 0) /**< Support High-Speed (RO) */ +#define SDIO_EHS (0x1lu << 1) /**< Enable High-Speed (R/W) */ + //! @} + + //! \name SDIO Card Metaformat + //! @{ +/** Null tuple (PCMCIA 3.1.9) */ +#define SDIO_CISTPL_NULL 0x00 +/** Device tuple (PCMCIA 3.2.2) */ +#define SDIO_CISTPL_DEVICE 0x01 +/** Checksum control (PCMCIA 3.1.1) */ +#define SDIO_CISTPL_CHECKSUM 0x10 +/** Level 1 version (PCMCIA 3.2.10) */ +#define SDIO_CISTPL_VERS_1 0x15 +/** Alternate Language String (PCMCIA 3.2.1) */ +#define SDIO_CISTPL_ALTSTR 0x16 +/** Manufacturer Identification String (PCMCIA 3.2.9) */ +#define SDIO_CISTPL_MANFID 0x20 +/** Function Identification (PCMCIA 3.2.7) */ +#define SDIO_CISTPL_FUNCID 0x21 +/** Function Extensions (PCMCIA 3.2.6) */ +#define SDIO_CISTPL_FUNCE 0x22 +/** Additional information for SDIO (PCMCIA 6.1.2) */ +#define SDIO_CISTPL_SDIO_STD 0x91 +/** Reserved for future SDIO (PCMCIA 6.1.3) */ +#define SDIO_CISTPL_SDIO_EXT 0x92 +/** The End-of-chain Tuple (PCMCIA 3.1.2) */ +#define SDIO_CISTPL_END 0xFF + //! @} + +//! @} + +//! \name CSD, OCR, SCR, Switch status, extend CSD definitions +//! @{ + +/** + * \brief Macro function to extract a bits field from a large SD MMC register + * Used by : CSD, SCR, Switch status + */ +static inline uint32_t SDMMC_UNSTUFF_BITS(uint8_t *reg, uint16_t reg_size, + uint16_t pos, uint8_t size) +{ + uint32_t value; + value = reg[((reg_size - pos + 7) / 8) - 1] >> (pos % 8); + if (((pos % 8) + size) > 8) { + value |= (uint32_t)reg[((reg_size - pos + 7) / 8) - 2] << (8 - (pos % 8)); + } + if (((pos % 8) + size) > 16) { + value |= (uint32_t)reg[((reg_size - pos + 7) / 8) - 3] << (16 - (pos % 8)); + } + if (((pos % 8) + size) > 16) { + value |= (uint32_t)reg[((reg_size - pos + 7) / 8) - 3] << (16 - (pos % 8)); + } + value &= ((uint32_t)1 << size) - 1; + return value; +} + + //! \name CSD Fields + //! @{ +#define CSD_REG_BIT_SIZE 128 //!< 128 bits +#define CSD_REG_BSIZE (CSD_REG_BIT_SIZE / 8) //!< 16 bytes +#define CSD_STRUCTURE(csd, pos, size) \ + SDMMC_UNSTUFF_BITS(csd, CSD_REG_BIT_SIZE, pos, size) +#define CSD_STRUCTURE_VERSION(csd) CSD_STRUCTURE(csd, 126, 2) +#define SD_CSD_VER_1_0 0 +#define SD_CSD_VER_2_0 1 +#define MMC_CSD_VER_1_0 0 +#define MMC_CSD_VER_1_1 1 +#define MMC_CSD_VER_1_2 2 +#define CSD_TRAN_SPEED(csd) CSD_STRUCTURE(csd, 96, 8) +#define SD_CSD_1_0_C_SIZE(csd) CSD_STRUCTURE(csd, 62, 12) +#define SD_CSD_1_0_C_SIZE_MULT(csd) CSD_STRUCTURE(csd, 47, 3) +#define SD_CSD_1_0_READ_BL_LEN(csd) CSD_STRUCTURE(csd, 80, 4) +#define SD_CSD_2_0_C_SIZE(csd) CSD_STRUCTURE(csd, 48, 22) +#define MMC_CSD_C_SIZE(csd) CSD_STRUCTURE(csd, 62, 12) +#define MMC_CSD_C_SIZE_MULT(csd) CSD_STRUCTURE(csd, 47, 3) +#define MMC_CSD_READ_BL_LEN(csd) CSD_STRUCTURE(csd, 80, 4) +#define MMC_CSD_SPEC_VERS(csd) CSD_STRUCTURE(csd, 122, 4) + //! @} + + //! \name OCR Register Fields + //! @{ +#define OCR_REG_BSIZE (32 / 8) /**< 32 bits, 4 bytes */ +#define OCR_VDD_170_195 (1lu << 7) +#define OCR_VDD_20_21 (1lu << 8) +#define OCR_VDD_21_22 (1lu << 9) +#define OCR_VDD_22_23 (1lu << 10) +#define OCR_VDD_23_24 (1lu << 11) +#define OCR_VDD_24_25 (1lu << 12) +#define OCR_VDD_25_26 (1lu << 13) +#define OCR_VDD_26_27 (1lu << 14) +#define OCR_VDD_27_28 (1lu << 15) +#define OCR_VDD_28_29 (1lu << 16) +#define OCR_VDD_29_30 (1lu << 17) +#define OCR_VDD_30_31 (1lu << 18) +#define OCR_VDD_31_32 (1lu << 19) +#define OCR_VDD_32_33 (1lu << 20) +#define OCR_VDD_33_34 (1lu << 21) +#define OCR_VDD_34_35 (1lu << 22) +#define OCR_VDD_35_36 (1lu << 23) +#define OCR_SDIO_S18R (1lu << 24) /**< Switching to 1.8V Accepted */ +#define OCR_SDIO_MP (1lu << 27) /**< Memory Present */ +#define OCR_SDIO_NF (7lu << 28) /**< Number of I/O Functions */ +#define OCR_ACCESS_MODE_MASK (3lu << 29) /**< (MMC) Access mode mask */ +#define OCR_ACCESS_MODE_BYTE (0lu << 29) /**< (MMC) Byte access mode */ +#define OCR_ACCESS_MODE_SECTOR (2lu << 29) /**< (MMC) Sector access mode */ +#define OCR_CCS (1lu << 30) /**< (SD) Card Capacity Status */ +#define OCR_POWER_UP_BUSY (1lu << 31) /**< Card power up status bit */ + //! @} + + //! \name SD SCR Register Fields + //! @{ +#define SD_SCR_REG_BIT_SIZE 64 //!< 64 bits +#define SD_SCR_REG_BSIZE (SD_SCR_REG_BIT_SIZE / 8) //!< 8 bytes +#define SD_SCR_STRUCTURE(scr, pos, size) \ + SDMMC_UNSTUFF_BITS(scr, SD_SCR_REG_BIT_SIZE, pos, size) +#define SD_SCR_SCR_STRUCTURE(scr) SD_SCR_STRUCTURE(scr, 60, 4) +#define SD_SCR_SCR_STRUCTURE_1_0 0 +#define SD_SCR_SD_SPEC(scr) SD_SCR_STRUCTURE(scr, 56, 4) +#define SD_SCR_SD_SPEC_1_0_01 0 +#define SD_SCR_SD_SPEC_1_10 1 +#define SD_SCR_SD_SPEC_2_00 2 +#define SD_SCR_DATA_STATUS_AFTER_ERASE(scr) SD_SCR_STRUCTURE(scr, 55, 1) +#define SD_SCR_SD_SECURITY(scr) SD_SCR_STRUCTURE(scr, 52, 3) +#define SD_SCR_SD_SECURITY_NO 0 +#define SD_SCR_SD_SECURITY_NOTUSED 1 +#define SD_SCR_SD_SECURITY_1_01 2 +#define SD_SCR_SD_SECURITY_2_00 3 +#define SD_SCR_SD_SECURITY_3_00 4 +#define SD_SCR_SD_BUS_WIDTHS(scr) SD_SCR_STRUCTURE(scr, 48, 4) +#define SD_SCR_SD_BUS_WIDTH_1BITS (1lu << 0) +#define SD_SCR_SD_BUS_WIDTH_4BITS (1lu << 2) +#define SD_SCR_SD_SPEC3(scr) SD_SCR_STRUCTURE(scr, 47, 1) +#define SD_SCR_SD_SPEC_3_00 1 +#define SD_SCR_SD_EX_SECURITY(scr) SD_SCR_STRUCTURE(scr, 43, 4) +#define SD_SCR_SD_CMD_SUPPORT(scr) SD_SCR_STRUCTURE(scr, 32, 2) + //! @} + + //! \name SD Switch Status Fields + //! @{ +#define SD_SW_STATUS_BIT_SIZE 512 //!< 512 bits +#define SD_SW_STATUS_BSIZE (SD_SW_STATUS_BIT_SIZE / 8) //!< 64 bytes +#define SD_SW_STATUS_STRUCTURE(sd_sw_status, pos, size) \ + SDMMC_UNSTUFF_BITS(sd_sw_status, SD_SW_STATUS_BIT_SIZE, pos, size) +#define SD_SW_STATUS_MAX_CURRENT_CONSUMPTION(status) \ + SD_SW_STATUS_STRUCTURE(status, 496, 16) +#define SD_SW_STATUS_FUN_GRP6_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 480, 16) +#define SD_SW_STATUS_FUN_GRP5_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 464, 16) +#define SD_SW_STATUS_FUN_GRP4_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 448, 16) +#define SD_SW_STATUS_FUN_GRP3_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 432, 16) +#define SD_SW_STATUS_FUN_GRP2_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 416, 16) +#define SD_SW_STATUS_FUN_GRP1_INFO(status) \ + SD_SW_STATUS_STRUCTURE(status, 400, 16) +#define SD_SW_STATUS_FUN_GRP6_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 396, 4) +#define SD_SW_STATUS_FUN_GRP5_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 392, 4) +#define SD_SW_STATUS_FUN_GRP4_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 388, 4) +#define SD_SW_STATUS_FUN_GRP3_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 384, 4) +#define SD_SW_STATUS_FUN_GRP2_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 380, 4) +#define SD_SW_STATUS_FUN_GRP1_RC(status) \ + SD_SW_STATUS_STRUCTURE(status, 376, 4) +#define SD_SW_STATUS_FUN_GRP_RC_ERROR 0xFU +#define SD_SW_STATUS_DATA_STRUCT_VER(status) \ + SD_SW_STATUS_STRUCTURE(status, 368, 8) +#define SD_SW_STATUS_FUN_GRP6_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 352, 16) +#define SD_SW_STATUS_FUN_GRP5_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 336, 16) +#define SD_SW_STATUS_FUN_GRP4_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 320, 16) +#define SD_SW_STATUS_FUN_GRP3_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 304, 16) +#define SD_SW_STATUS_FUN_GRP2_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 288, 16) +#define SD_SW_STATUS_FUN_GRP1_BUSY(status) \ + SD_SW_STATUS_STRUCTURE(status, 272, 16) + //! @} + + //! \name Card Status Fields + //! @{ +#define CARD_STATUS_APP_CMD (1lu << 5) +#define CARD_STATUS_SWITCH_ERROR (1lu << 7) +#define CARD_STATUS_READY_FOR_DATA (1lu << 8) +#define CARD_STATUS_STATE_IDLE (0lu << 9) +#define CARD_STATUS_STATE_READY (1lu << 9) +#define CARD_STATUS_STATE_IDENT (2lu << 9) +#define CARD_STATUS_STATE_STBY (3lu << 9) +#define CARD_STATUS_STATE_TRAN (4lu << 9) +#define CARD_STATUS_STATE_DATA (5lu << 9) +#define CARD_STATUS_STATE_RCV (6lu << 9) +#define CARD_STATUS_STATE_PRG (7lu << 9) +#define CARD_STATUS_STATE_DIS (8lu << 9) +#define CARD_STATUS_STATE (0xFlu << 9) +#define CARD_STATUS_ERASE_RESET (1lu << 13) +#define CARD_STATUS_WP_ERASE_SKIP (1lu << 15) +#define CARD_STATUS_CIDCSD_OVERWRITE (1lu << 16) +#define CARD_STATUS_OVERRUN (1lu << 17) +#define CARD_STATUS_UNERRUN (1lu << 18) +#define CARD_STATUS_ERROR (1lu << 19) +#define CARD_STATUS_CC_ERROR (1lu << 20) +#define CARD_STATUS_CARD_ECC_FAILED (1lu << 21) +#define CARD_STATUS_ILLEGAL_COMMAND (1lu << 22) +#define CARD_STATUS_COM_CRC_ERROR (1lu << 23) +#define CARD_STATUS_UNLOCK_FAILED (1lu << 24) +#define CARD_STATUS_CARD_IS_LOCKED (1lu << 25) +#define CARD_STATUS_WP_VIOLATION (1lu << 26) +#define CARD_STATUS_ERASE_PARAM (1lu << 27) +#define CARD_STATUS_ERASE_SEQ_ERROR (1lu << 28) +#define CARD_STATUS_BLOCK_LEN_ERROR (1lu << 29) +#define CARD_STATUS_ADDRESS_MISALIGN (1lu << 30) +#define CARD_STATUS_ADDR_OUT_OF_RANGE (1lu << 31) + +#define CARD_STATUS_ERR_RD_WR (CARD_STATUS_ADDR_OUT_OF_RANGE \ + | CARD_STATUS_ADDRESS_MISALIGN \ + | CARD_STATUS_BLOCK_LEN_ERROR \ + | CARD_STATUS_WP_VIOLATION \ + | CARD_STATUS_ILLEGAL_COMMAND \ + | CARD_STATUS_CC_ERROR \ + | CARD_STATUS_ERROR) + //! @} + + //! \name SD Status Field + //! @{ +#define SD_STATUS_BSIZE (512 / 8) /**< 512 bits, 64bytes */ + //! @} + + //! \name MMC Extended CSD Register Field + //! @{ +#define EXT_CSD_BSIZE 512 /**< 512 bytes. */ +/* Below belongs to Properties Segment */ +#define EXT_CSD_S_CMD_SET_INDEX 504lu +#define EXT_CSD_BOOT_INFO_INDEX 228lu +#define EXT_CSD_BOOT_SIZE_MULTI_INDEX 226lu +#define EXT_CSD_ACC_SIZE_INDEX 225lu +#define EXT_CSD_HC_ERASE_GRP_SIZE_INDEX 224lu +#define EXT_CSD_ERASE_TIMEOUT_MULT_INDEX 223lu +#define EXT_CSD_REL_WR_SEC_C_INDEX 222lu +#define EXT_CSD_HC_WP_GRP_SIZE_INDEX 221lu +#define EXT_CSD_S_C_VCC_INDEX 220lu +#define EXT_CSD_S_C_VCCQ_INDEX 219lu +#define EXT_CSD_S_A_TIMEOUT_INDEX 217lu +#define EXT_CSD_SEC_COUNT_INDEX 212lu +#define EXT_CSD_MIN_PERF_W_8_52_INDEX 210lu +#define EXT_CSD_MIN_PERF_R_8_52_INDEX 209lu +#define EXT_CSD_MIN_PERF_W_8_26_4_52_INDEX 208lu +#define EXT_CSD_MIN_PERF_R_8_26_4_52_INDEX 207lu +#define EXT_CSD_MIN_PERF_W_4_26_INDEX 206lu +#define EXT_CSD_MIN_PERF_R_4_26_INDEX 205lu +#define EXT_CSD_PWR_CL_26_360_INDEX 203lu +#define EXT_CSD_PWR_CL_52_360_INDEX 202lu +#define EXT_CSD_PWR_CL_26_195_INDEX 201lu +#define EXT_CSD_PWR_CL_52_195_INDEX 200lu +#define EXT_CSD_CARD_TYPE_INDEX 196lu +/* MMC card type */ +# define MMC_CTYPE_26MHZ 0x1 +# define MMC_CTYPE_52MHZ 0x2 +#define EXT_CSD_CSD_STRUCTURE_INDEX 194lu +#define EXT_CSD_EXT_CSD_REV_INDEX 192lu + +/* Below belongs to Mode Segment */ +#define EXT_CSD_CMD_SET_INDEX 191lu +#define EXT_CSD_CMD_SET_REV_INDEX 189lu +#define EXT_CSD_POWER_CLASS_INDEX 187lu +#define EXT_CSD_HS_TIMING_INDEX 185lu +#define EXT_CSD_BUS_WIDTH_INDEX 183lu +#define EXT_CSD_ERASED_MEM_CONT_INDEX 181lu +#define EXT_CSD_BOOT_CONFIG_INDEX 179lu +#define EXT_CSD_BOOT_BUS_WIDTH_INDEX 177lu +#define EXT_CSD_ERASE_GROUP_DEF_INDEX 175lu + //! @} +//! @} + + +//! \name Definition for SPI mode only +//! @{ + +//! SPI commands start with a start bit "0" and a transmit bit "1" +#define SPI_CMD_ENCODE(x) (0x40 | (x & 0x3F)) + +//! \name Register R1 definition for SPI mode +//! The R1 register is always send after a command. +//! @{ +#define R1_SPI_IDLE (1lu << 0) +#define R1_SPI_ERASE_RESET (1lu << 1) +#define R1_SPI_ILLEGAL_COMMAND (1lu << 2) +#define R1_SPI_COM_CRC (1lu << 3) +#define R1_SPI_ERASE_SEQ (1lu << 4) +#define R1_SPI_ADDRESS (1lu << 5) +#define R1_SPI_PARAMETER (1lu << 6) +// R1 bit 7 is always zero, reuse this bit for error +#define R1_SPI_ERROR (1lu << 7) +//! @} + +//! \name Register R2 definition for SPI mode +//! The R2 register can be send after R1 register. +//! @{ +#define R2_SPI_CARD_LOCKED (1lu << 0) +#define R2_SPI_WP_ERASE_SKIP (1lu << 1) +#define R2_SPI_LOCK_UNLOCK_FAIL R2_SPI_WP_ERASE_SKIP +#define R2_SPI_ERROR (1lu << 2) +#define R2_SPI_CC_ERROR (1lu << 3) +#define R2_SPI_CARD_ECC_ERROR (1lu << 4) +#define R2_SPI_WP_VIOLATION (1lu << 5) +#define R2_SPI_ERASE_PARAM (1lu << 6) +#define R2_SPI_OUT_OF_RANGE (1lu << 7) +#define R2_SPI_CSD_OVERWRITE R2_SPI_OUT_OF_RANGE +//! @} + +//! \name Control Tokens in SPI Mode +//! @{ + //! \name Tokens used for a read operation + //! @{ +#define SPI_TOKEN_SINGLE_MULTI_READ 0xFE +#define SPI_TOKEN_DATA_ERROR_VALID(token) (((token) & 0xF0) == 0) +#define SPI_TOKEN_DATA_ERROR_ERRORS (0x0F) +#define SPI_TOKEN_DATA_ERROR_ERROR (1lu << 0) +#define SPI_TOKEN_DATA_ERROR_CC_ERROR (1lu << 1) +#define SPI_TOKEN_DATA_ERROR_ECC_ERROR (1lu << 2) +#define SPI_TOKEN_DATA_ERROR_OUT_RANGE (1lu << 3) + //! @} + //! \name Tokens used for a write operation + //! @{ +#define SPI_TOKEN_SINGLE_WRITE 0xFE +#define SPI_TOKEN_MULTI_WRITE 0xFC +#define SPI_TOKEN_STOP_TRAN 0xFD +#define SPI_TOKEN_DATA_RESP_VALID(token) \ + ((((token) & (1 << 4)) == 0) && (((token) & (1 << 0)) == 1)) +#define SPI_TOKEN_DATA_RESP_CODE(token) ((token) & 0x1E) +#define SPI_TOKEN_DATA_RESP_ACCEPTED (2lu << 1) +#define SPI_TOKEN_DATA_RESP_CRC_ERR (5lu << 1) +#define SPI_TOKEN_DATA_RESP_WRITE_ERR (6lu << 1) + //! @} +//! @} +//! @} + + +//! @} end of sd_mmc_protocol + +#ifdef __cplusplus +} +#endif + +#endif /* SD_MMC_PROTOCOL_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/genclk.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/genclk.h new file mode 100644 index 0000000..99cb409 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/genclk.h @@ -0,0 +1,191 @@ +/** + * \file + * + * \brief Generic clock management + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef CLK_GENCLK_H_INCLUDED +#define CLK_GENCLK_H_INCLUDED + +#include "parts.h" + +#if SAM3S +# include "sam3s/genclk.h" +#elif SAM3U +# include "sam3u/genclk.h" +#elif SAM3N +# include "sam3n/genclk.h" +#elif SAM3XA +# include "sam3x/genclk.h" +#elif SAM4S +# include "sam4s/genclk.h" +#elif SAM4L +# include "sam4l/genclk.h" +#elif SAM4E +# include "sam4e/genclk.h" +#elif SAM4N +# include "sam4n/genclk.h" +#elif SAM4C +# include "sam4c/genclk.h" +#elif SAM4CM +# include "sam4cm/genclk.h" +#elif SAM4CP +# include "sam4cp/genclk.h" +#elif SAMG +# include "samg/genclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/genclk.h" +#elif UC3A3 +# include "uc3a3_a4/genclk.h" +#elif UC3B +# include "uc3b0_b1/genclk.h" +#elif UC3C +# include "uc3c/genclk.h" +#elif UC3D +# include "uc3d/genclk.h" +#elif UC3L +# include "uc3l/genclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup genclk_group Generic Clock Management + * + * Generic clocks are configurable clocks which run outside the system + * clock domain. They are often connected to peripherals which have an + * asynchronous component running independently of the bus clock, e.g. + * USB controllers, low-power timers and RTCs, etc. + * + * Note that not all platforms have support for generic clocks; on such + * platforms, this API will not be available. + * + * @{ + */ + +/** + * \def GENCLK_DIV_MAX + * \brief Maximum divider supported by the generic clock implementation + */ +/** + * \enum genclk_source + * \brief Generic clock source ID + * + * Each generic clock may be generated from a different clock source. + * These are the available alternatives provided by the chip. + */ + +//! \name Generic clock configuration +//@{ +/** + * \struct genclk_config + * \brief Hardware representation of a set of generic clock parameters + */ +/** + * \fn void genclk_config_defaults(struct genclk_config *cfg, + * unsigned int id) + * \brief Initialize \a cfg to the default configuration for the clock + * identified by \a id. + */ +/** + * \fn void genclk_config_read(struct genclk_config *cfg, unsigned int id) + * \brief Read the currently active configuration of the clock + * identified by \a id into \a cfg. + */ +/** + * \fn void genclk_config_write(const struct genclk_config *cfg, + * unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id. + */ +/** + * \fn void genclk_config_set_source(struct genclk_config *cfg, + * enum genclk_source src) + * \brief Select a new source clock \a src in configuration \a cfg. + */ +/** + * \fn void genclk_config_set_divider(struct genclk_config *cfg, + * unsigned int divider) + * \brief Set a new \a divider in configuration \a cfg. + */ +/** + * \fn void genclk_enable_source(enum genclk_source src) + * \brief Enable the source clock \a src used by a generic clock. + */ + //@} + +//! \name Enabling and disabling Generic Clocks +//@{ +/** + * \fn void genclk_enable(const struct genclk_config *cfg, unsigned int id) + * \brief Activate the configuration \a cfg on the clock identified by + * \a id and enable it. + */ +/** + * \fn void genclk_disable(unsigned int id) + * \brief Disable the generic clock identified by \a id. + */ +//@} + +/** + * \brief Enable the configuration defined by \a src and \a divider + * for the generic clock identified by \a id. + * + * \param id The ID of the generic clock. + * \param src The source clock of the generic clock. + * \param divider The divider used to generate the generic clock. + */ +static inline void genclk_enable_config(unsigned int id, enum genclk_source src, unsigned int divider) +{ + struct genclk_config gcfg; + + genclk_config_defaults(&gcfg, id); + genclk_enable_source(src); + genclk_config_set_source(&gcfg, src); + genclk_config_set_divider(&gcfg, divider); + genclk_enable(&gcfg, id); +} + +//! @} + +#endif /* CLK_GENCLK_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/osc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/osc.h new file mode 100644 index 0000000..2ff1a48 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/osc.h @@ -0,0 +1,177 @@ +/** + * \file + * + * \brief Oscillator management + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef OSC_H_INCLUDED +#define OSC_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/osc.h" +#elif SAM3XA +# include "sam3x/osc.h" +#elif SAM3U +# include "sam3u/osc.h" +#elif SAM3N +# include "sam3n/osc.h" +#elif SAM4S +# include "sam4s/osc.h" +#elif SAM4E +# include "sam4e/osc.h" +#elif SAM4C +# include "sam4c/osc.h" +#elif SAM4CM +# include "sam4cm/osc.h" +#elif SAM4CP +# include "sam4cp/osc.h" +#elif SAM4L +# include "sam4l/osc.h" +#elif SAM4N +# include "sam4n/osc.h" +#elif SAMG +# include "samg/osc.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/osc.h" +#elif UC3A3 +# include "uc3a3_a4/osc.h" +#elif UC3B +# include "uc3b0_b1/osc.h" +#elif UC3C +# include "uc3c/osc.h" +#elif UC3D +# include "uc3d/osc.h" +#elif UC3L +# include "uc3l/osc.h" +#elif XMEGA +# include "xmega/osc.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup osc_group Oscillator Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip oscillators. Internal RC-oscillators, + * external crystal oscillators and external clock generators are + * supported by this module. What all of these have in common is that + * they swing at a fixed, nominal frequency which is normally not + * adjustable. + * + * \par Example: Enabling an oscillator + * + * The following example demonstrates how to enable the external + * oscillator on XMEGA A and wait for it to be ready to use. The + * oscillator identifiers are platform-specific, so while the same + * procedure is used on all platforms, the parameter to osc_enable() + * will be different from device to device. + * \code + osc_enable(OSC_ID_XOSC); + osc_wait_ready(OSC_ID_XOSC); \endcode + * + * \section osc_group_board Board-specific Definitions + * If external oscillators are used, the board code must provide the + * following definitions for each of those: + * - \b BOARD__HZ: The nominal frequency of the oscillator. + * - \b BOARD__STARTUP_US: The startup time of the + * oscillator in microseconds. + * - \b BOARD__TYPE: The type of oscillator connected, i.e. + * whether it's a crystal or external clock, and sometimes what kind + * of crystal it is. The meaning of this value is platform-specific. + * + * @{ + */ + +//! \name Oscillator Management +//@{ +/** + * \fn void osc_enable(uint8_t id) + * \brief Enable oscillator \a id + * + * The startup time and mode value is automatically determined based on + * definitions in the board code. + */ +/** + * \fn void osc_disable(uint8_t id) + * \brief Disable oscillator \a id + */ +/** + * \fn osc_is_ready(uint8_t id) + * \brief Determine whether oscillator \a id is ready. + * \retval true Oscillator \a id is running and ready to use as a clock + * source. + * \retval false Oscillator \a id is not running. + */ +/** + * \fn uint32_t osc_get_rate(uint8_t id) + * \brief Return the frequency of oscillator \a id in Hz + */ + +#ifndef __ASSEMBLY__ + +/** + * \brief Wait until the oscillator identified by \a id is ready + * + * This function will busy-wait for the oscillator identified by \a id + * to become stable and ready to use as a clock source. + * + * \param id A number identifying the oscillator to wait for. + */ +static inline void osc_wait_ready(uint8_t id) +{ + while (!osc_is_ready(id)) { + /* Do nothing */ + } +} + +#endif /* __ASSEMBLY__ */ + +//@} + +//! @} + +#endif /* OSC_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/pll.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/pll.h new file mode 100644 index 0000000..709d8c1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/pll.h @@ -0,0 +1,333 @@ +/** + * \file + * + * \brief PLL management + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef CLK_PLL_H_INCLUDED +#define CLK_PLL_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/pll.h" +#elif SAM3XA +# include "sam3x/pll.h" +#elif SAM3U +# include "sam3u/pll.h" +#elif SAM3N +# include "sam3n/pll.h" +#elif SAM4S +# include "sam4s/pll.h" +#elif SAM4E +# include "sam4e/pll.h" +#elif SAM4C +# include "sam4c/pll.h" +#elif SAM4CM +# include "sam4cm/pll.h" +#elif SAM4CP +# include "sam4cp/pll.h" +#elif SAM4L +# include "sam4l/pll.h" +#elif SAM4N +# include "sam4n/pll.h" +#elif SAMG +# include "samg/pll.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/pll.h" +#elif UC3A3 +# include "uc3a3_a4/pll.h" +#elif UC3B +# include "uc3b0_b1/pll.h" +#elif UC3C +# include "uc3c/pll.h" +#elif UC3D +# include "uc3d/pll.h" +#elif (UC3L0128 || UC3L0256 || UC3L3_L4) +# include "uc3l/pll.h" +#elif XMEGA +# include "xmega/pll.h" +#else +# error Unsupported chip type +#endif + +/** + * \ingroup clk_group + * \defgroup pll_group PLL Management + * + * This group contains functions and definitions related to configuring + * and enabling/disabling on-chip PLLs. A PLL will take an input signal + * (the \em source), optionally divide the frequency by a configurable + * \em divider, and then multiply the frequency by a configurable \em + * multiplier. + * + * Some devices don't support input dividers; specifying any other + * divisor than 1 on these devices will result in an assertion failure. + * Other devices may have various restrictions to the frequency range of + * the input and output signals. + * + * \par Example: Setting up PLL0 with default parameters + * + * The following example shows how to configure and enable PLL0 using + * the default parameters specified using the configuration symbols + * listed above. + * \code + pll_enable_config_defaults(0); \endcode + * + * To configure, enable PLL0 using the default parameters and to disable + * a specific feature like Wide Bandwidth Mode (a UC3A3-specific + * PLL option.), you can use this initialization process. + * \code + struct pll_config pllcfg; + if (pll_is_locked(pll_id)) { + return; // Pll already running + } + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_config_set_option(&pllcfg, PLL_OPT_WBM_DISABLE); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); \endcode + * + * When the last function call returns, PLL0 is ready to be used as the + * main system clock source. + * + * \section pll_group_config Configuration Symbols + * + * Each PLL has a set of default parameters determined by the following + * configuration symbols in the application's configuration file: + * - \b CONFIG_PLLn_SOURCE: The default clock source connected to the + * input of PLL \a n. Must be one of the values defined by the + * #pll_source enum. + * - \b CONFIG_PLLn_MUL: The default multiplier (loop divider) of PLL + * \a n. + * - \b CONFIG_PLLn_DIV: The default input divider of PLL \a n. + * + * These configuration symbols determine the result of calling + * pll_config_defaults() and pll_get_default_rate(). + * + * @{ + */ + +//! \name Chip-specific PLL characteristics +//@{ +/** + * \def PLL_MAX_STARTUP_CYCLES + * \brief Maximum PLL startup time in number of slow clock cycles + */ +/** + * \def NR_PLLS + * \brief Number of on-chip PLLs + */ + +/** + * \def PLL_MIN_HZ + * \brief Minimum frequency that the PLL can generate + */ +/** + * \def PLL_MAX_HZ + * \brief Maximum frequency that the PLL can generate + */ +/** + * \def PLL_NR_OPTIONS + * \brief Number of PLL option bits + */ +//@} + +/** + * \enum pll_source + * \brief PLL clock source + */ + +//! \name PLL configuration +//@{ + +/** + * \struct pll_config + * \brief Hardware-specific representation of PLL configuration. + * + * This structure contains one or more device-specific values + * representing the current PLL configuration. The contents of this + * structure is typically different from platform to platform, and the + * user should not access any fields except through the PLL + * configuration API. + */ + +/** + * \fn void pll_config_init(struct pll_config *cfg, + * enum pll_source src, unsigned int div, unsigned int mul) + * \brief Initialize PLL configuration from standard parameters. + * + * \note This function may be defined inline because it is assumed to be + * called very few times, and usually with constant parameters. Inlining + * it will in such cases reduce the code size significantly. + * + * \param cfg The PLL configuration to be initialized. + * \param src The oscillator to be used as input to the PLL. + * \param div PLL input divider. + * \param mul PLL loop divider (i.e. multiplier). + * + * \return A configuration which will make the PLL run at + * (\a mul / \a div) times the frequency of \a src + */ +/** + * \def pll_config_defaults(cfg, pll_id) + * \brief Initialize PLL configuration using default parameters. + * + * After this function returns, \a cfg will contain a configuration + * which will make the PLL run at (CONFIG_PLLx_MUL / CONFIG_PLLx_DIV) + * times the frequency of CONFIG_PLLx_SOURCE. + * + * \param cfg The PLL configuration to be initialized. + * \param pll_id Use defaults for this PLL. + */ +/** + * \def pll_get_default_rate(pll_id) + * \brief Get the default rate in Hz of \a pll_id + */ +/** + * \fn void pll_config_set_option(struct pll_config *cfg, + * unsigned int option) + * \brief Set the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be set. + */ +/** + * \fn void pll_config_clear_option(struct pll_config *cfg, + * unsigned int option) + * \brief Clear the PLL option bit \a option in the configuration \a cfg. + * + * \param cfg The PLL configuration to be changed. + * \param option The PLL option bit to be cleared. + */ +/** + * \fn void pll_config_read(struct pll_config *cfg, unsigned int pll_id) + * \brief Read the currently active configuration of \a pll_id. + * + * \param cfg The configuration object into which to store the currently + * active configuration. + * \param pll_id The ID of the PLL to be accessed. + */ +/** + * \fn void pll_config_write(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg on \a pll_id + * + * \param cfg The configuration object representing the PLL + * configuration to be activated. + * \param pll_id The ID of the PLL to be updated. + */ + +//@} + +//! \name Interaction with the PLL hardware +//@{ +/** + * \fn void pll_enable(const struct pll_config *cfg, + * unsigned int pll_id) + * \brief Activate the configuration \a cfg and enable PLL \a pll_id. + * + * \param cfg The PLL configuration to be activated. + * \param pll_id The ID of the PLL to be enabled. + */ +/** + * \fn void pll_disable(unsigned int pll_id) + * \brief Disable the PLL identified by \a pll_id. + * + * After this function is called, the PLL identified by \a pll_id will + * be disabled. The PLL configuration stored in hardware may be affected + * by this, so if the caller needs to restore the same configuration + * later, it should either do a pll_config_read() before disabling the + * PLL, or remember the last configuration written to the PLL. + * + * \param pll_id The ID of the PLL to be disabled. + */ +/** + * \fn bool pll_is_locked(unsigned int pll_id) + * \brief Determine whether the PLL is locked or not. + * + * \param pll_id The ID of the PLL to check. + * + * \retval true The PLL is locked and ready to use as a clock source + * \retval false The PLL is not yet locked, or has not been enabled. + */ +/** + * \fn void pll_enable_source(enum pll_source src) + * \brief Enable the source of the pll. + * The source is enabled, if the source is not already running. + * + * \param src The ID of the PLL source to enable. + */ +/** + * \fn void pll_enable_config_defaults(unsigned int pll_id) + * \brief Enable the pll with the default configuration. + * PLL is enabled, if the PLL is not already locked. + * + * \param pll_id The ID of the PLL to enable. + */ + +/** + * \brief Wait for PLL \a pll_id to become locked + * + * \todo Use a timeout to avoid waiting forever and hanging the system + * + * \param pll_id The ID of the PLL to wait for. + * + * \retval STATUS_OK The PLL is now locked. + * \retval ERR_TIMEOUT Timed out waiting for PLL to become locked. + */ +static inline int pll_wait_for_lock(unsigned int pll_id) +{ + Assert(pll_id < NR_PLLS); + + while (!pll_is_locked(pll_id)) { + /* Do nothing */ + } + + return 0; +} + +//@} +//! @} + +#endif /* CLK_PLL_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/genclk.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/genclk.h new file mode 100644 index 0000000..6d7835b --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/genclk.h @@ -0,0 +1,269 @@ +/** + * \file + * + * \brief Chip-specific generic clock management. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CHIP_GENCLK_H_INCLUDED +#define CHIP_GENCLK_H_INCLUDED + +#include +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup genclk_group + * @{ + */ + +//! \name Programmable Clock Identifiers (PCK) +//@{ +#define GENCLK_PCK_0 0 //!< PCK0 ID +#define GENCLK_PCK_1 1 //!< PCK1 ID +#define GENCLK_PCK_2 2 //!< PCK2 ID +//@} + +//! \name Programmable Clock Sources (PCK) +//@{ + +enum genclk_source { + GENCLK_PCK_SRC_SLCK_RC = 0,//!< Internal 32kHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_XTAL = 1,//!< External 32kHz crystal oscillator as PCK source clock + GENCLK_PCK_SRC_SLCK_BYPASS = 2,//!< External 32kHz bypass oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_4M_RC = 3,//!< Internal 4MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_8M_RC = 4,//!< Internal 8MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_12M_RC = 5,//!< Internal 12MHz RC oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_XTAL = 6,//!< External crystal oscillator as PCK source clock + GENCLK_PCK_SRC_MAINCK_BYPASS = 7,//!< External bypass oscillator as PCK source clock + GENCLK_PCK_SRC_PLLACK = 8,//!< Use PLLACK as PCK source clock + GENCLK_PCK_SRC_MCK = 9,//!< Use Master Clk as PCK source clock +}; + +//@} + +//! \name Programmable Clock Prescalers (PCK) +//@{ + +enum genclk_divider { + GENCLK_PCK_PRES_1 = PMC_PCK_PRES_CLK_1, //!< Set PCK clock prescaler to 1 + GENCLK_PCK_PRES_2 = PMC_PCK_PRES_CLK_2, //!< Set PCK clock prescaler to 2 + GENCLK_PCK_PRES_4 = PMC_PCK_PRES_CLK_4, //!< Set PCK clock prescaler to 4 + GENCLK_PCK_PRES_8 = PMC_PCK_PRES_CLK_8, //!< Set PCK clock prescaler to 8 + GENCLK_PCK_PRES_16 = PMC_PCK_PRES_CLK_16, //!< Set PCK clock prescaler to 16 + GENCLK_PCK_PRES_32 = PMC_PCK_PRES_CLK_32, //!< Set PCK clock prescaler to 32 + GENCLK_PCK_PRES_64 = PMC_PCK_PRES_CLK_64, //!< Set PCK clock prescaler to 64 +}; + +//@} + +struct genclk_config { + uint32_t ctrl; +}; + +static inline void genclk_config_defaults(struct genclk_config *p_cfg, + uint32_t ul_id) +{ + ul_id = ul_id; + p_cfg->ctrl = 0; +} + +static inline void genclk_config_read(struct genclk_config *p_cfg, + uint32_t ul_id) +{ + p_cfg->ctrl = PMC->PMC_PCK[ul_id]; +} + +static inline void genclk_config_write(const struct genclk_config *p_cfg, + uint32_t ul_id) +{ + PMC->PMC_PCK[ul_id] = p_cfg->ctrl; +} + +//! \name Programmable Clock Source and Prescaler configuration +//@{ + +static inline void genclk_config_set_source(struct genclk_config *p_cfg, + enum genclk_source e_src) +{ + p_cfg->ctrl &= (~PMC_PCK_CSS_Msk); + + switch (e_src) { + case GENCLK_PCK_SRC_SLCK_RC: + case GENCLK_PCK_SRC_SLCK_XTAL: + case GENCLK_PCK_SRC_SLCK_BYPASS: + p_cfg->ctrl |= (PMC_PCK_CSS_SLOW_CLK); + break; + + case GENCLK_PCK_SRC_MAINCK_4M_RC: + case GENCLK_PCK_SRC_MAINCK_8M_RC: + case GENCLK_PCK_SRC_MAINCK_12M_RC: + case GENCLK_PCK_SRC_MAINCK_XTAL: + case GENCLK_PCK_SRC_MAINCK_BYPASS: + p_cfg->ctrl |= (PMC_PCK_CSS_MAIN_CLK); + break; + + case GENCLK_PCK_SRC_PLLACK: + p_cfg->ctrl |= (PMC_PCK_CSS_PLLA_CLK); + break; + + case GENCLK_PCK_SRC_MCK: + p_cfg->ctrl |= (PMC_PCK_CSS_MCK); + break; + + default: + break; + } +} + +static inline void genclk_config_set_divider(struct genclk_config *p_cfg, + uint32_t e_divider) +{ + p_cfg->ctrl &= ~PMC_PCK_PRES_Msk; + p_cfg->ctrl |= e_divider; +} + +//@} + +static inline void genclk_enable(const struct genclk_config *p_cfg, uint32_t ul_id) +{ + PMC->PMC_PCK[ul_id] = p_cfg->ctrl; + pmc_enable_pck(ul_id); +} + +static inline void genclk_disable(uint32_t ul_id) +{ + pmc_disable_pck(ul_id); +} + +static inline void genclk_enable_source(enum genclk_source e_src) +{ + switch (e_src) { + case GENCLK_PCK_SRC_SLCK_RC: + if (!osc_is_ready(OSC_SLCK_32K_RC)) { + osc_enable(OSC_SLCK_32K_RC); + osc_wait_ready(OSC_SLCK_32K_RC); + } + break; + + case GENCLK_PCK_SRC_SLCK_XTAL: + if (!osc_is_ready(OSC_SLCK_32K_XTAL)) { + osc_enable(OSC_SLCK_32K_XTAL); + osc_wait_ready(OSC_SLCK_32K_XTAL); + } + break; + + case GENCLK_PCK_SRC_SLCK_BYPASS: + if (!osc_is_ready(OSC_SLCK_32K_BYPASS)) { + osc_enable(OSC_SLCK_32K_BYPASS); + osc_wait_ready(OSC_SLCK_32K_BYPASS); + } + break; + + case GENCLK_PCK_SRC_MAINCK_4M_RC: + if (!osc_is_ready(OSC_MAINCK_4M_RC)) { + osc_enable(OSC_MAINCK_4M_RC); + osc_wait_ready(OSC_MAINCK_4M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_8M_RC: + if (!osc_is_ready(OSC_MAINCK_8M_RC)) { + osc_enable(OSC_MAINCK_8M_RC); + osc_wait_ready(OSC_MAINCK_8M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_12M_RC: + if (!osc_is_ready(OSC_MAINCK_12M_RC)) { + osc_enable(OSC_MAINCK_12M_RC); + osc_wait_ready(OSC_MAINCK_12M_RC); + } + break; + + case GENCLK_PCK_SRC_MAINCK_XTAL: + if (!osc_is_ready(OSC_MAINCK_XTAL)) { + osc_enable(OSC_MAINCK_XTAL); + osc_wait_ready(OSC_MAINCK_XTAL); + } + break; + + case GENCLK_PCK_SRC_MAINCK_BYPASS: + if (!osc_is_ready(OSC_MAINCK_BYPASS)) { + osc_enable(OSC_MAINCK_BYPASS); + osc_wait_ready(OSC_MAINCK_BYPASS); + } + break; + +#ifdef CONFIG_PLL0_SOURCE + case GENCLK_PCK_SRC_PLLACK: + pll_enable_config_defaults(0); + break; +#endif + + case GENCLK_PCK_SRC_MCK: + break; + + default: + Assert(false); + break; + } +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_GENCLK_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/osc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/osc.h new file mode 100644 index 0000000..ec570b1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/osc.h @@ -0,0 +1,247 @@ +/** + * \file + * + * \brief Chip-specific oscillator management functions. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CHIP_OSC_H_INCLUDED +#define CHIP_OSC_H_INCLUDED + +#include "board.h" +#include "pmc.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/* + * Below BOARD_XXX macros are related to the specific board, and + * should be defined by the board code, otherwise default value are used. + */ +#if !defined(BOARD_FREQ_SLCK_XTAL) +# warning The board slow clock xtal frequency has not been defined. +# define BOARD_FREQ_SLCK_XTAL (32768UL) +#endif + +#if !defined(BOARD_FREQ_SLCK_BYPASS) +# warning The board slow clock bypass frequency has not been defined. +# define BOARD_FREQ_SLCK_BYPASS (32768UL) +#endif + +#if !defined(BOARD_FREQ_MAINCK_XTAL) +# warning The board main clock xtal frequency has not been defined. +# define BOARD_FREQ_MAINCK_XTAL (12000000UL) +#endif + +#if !defined(BOARD_FREQ_MAINCK_BYPASS) +# warning The board main clock bypass frequency has not been defined. +# define BOARD_FREQ_MAINCK_BYPASS (12000000UL) +#endif + +#if !defined(BOARD_OSC_STARTUP_US) +# warning The board main clock xtal startup time has not been defined. +# define BOARD_OSC_STARTUP_US (15625UL) +#endif + +/** + * \weakgroup osc_group + * @{ + */ + +//! \name Oscillator identifiers +//@{ +#define OSC_SLCK_32K_RC 0 //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL 1 //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS 2 //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL 6 //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS 7 //!< External bypass oscillator. +//@} + +//! \name Oscillator clock speed in hertz +//@{ +#define OSC_SLCK_32K_RC_HZ CHIP_FREQ_SLCK_RC //!< Internal 32kHz RC oscillator. +#define OSC_SLCK_32K_XTAL_HZ BOARD_FREQ_SLCK_XTAL //!< External 32kHz crystal oscillator. +#define OSC_SLCK_32K_BYPASS_HZ BOARD_FREQ_SLCK_BYPASS //!< External 32kHz bypass oscillator. +#define OSC_MAINCK_4M_RC_HZ CHIP_FREQ_MAINCK_RC_4MHZ //!< Internal 4MHz RC oscillator. +#define OSC_MAINCK_8M_RC_HZ CHIP_FREQ_MAINCK_RC_8MHZ //!< Internal 8MHz RC oscillator. +#define OSC_MAINCK_12M_RC_HZ CHIP_FREQ_MAINCK_RC_12MHZ //!< Internal 12MHz RC oscillator. +#define OSC_MAINCK_XTAL_HZ BOARD_FREQ_MAINCK_XTAL //!< External crystal oscillator. +#define OSC_MAINCK_BYPASS_HZ BOARD_FREQ_MAINCK_BYPASS //!< External bypass oscillator. +//@} + +static inline void osc_enable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + break; + + case OSC_SLCK_32K_XTAL: + pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + break; + + case OSC_SLCK_32K_BYPASS: + pmc_switch_sclk_to_32kxtal(PMC_OSC_BYPASS); + break; + + + case OSC_MAINCK_4M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + break; + + case OSC_MAINCK_8M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + break; + + case OSC_MAINCK_12M_RC: + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + break; + + + case OSC_MAINCK_XTAL: + pmc_switch_mainck_to_xtal(PMC_OSC_XTAL, + pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, + OSC_SLCK_32K_RC_HZ)); + break; + + case OSC_MAINCK_BYPASS: + pmc_switch_mainck_to_xtal(PMC_OSC_BYPASS, + pmc_us_to_moscxtst(BOARD_OSC_STARTUP_US, + OSC_SLCK_32K_RC_HZ)); + break; + } +} + +static inline void osc_disable(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + break; + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + pmc_osc_disable_fastrc(); + break; + + case OSC_MAINCK_XTAL: + pmc_osc_disable_xtal(PMC_OSC_XTAL); + break; + + case OSC_MAINCK_BYPASS: + pmc_osc_disable_xtal(PMC_OSC_BYPASS); + break; + } +} + +static inline bool osc_is_ready(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return 1; + + case OSC_SLCK_32K_XTAL: + case OSC_SLCK_32K_BYPASS: + return pmc_osc_is_ready_32kxtal(); + + case OSC_MAINCK_4M_RC: + case OSC_MAINCK_8M_RC: + case OSC_MAINCK_12M_RC: + case OSC_MAINCK_XTAL: + case OSC_MAINCK_BYPASS: + return pmc_osc_is_ready_mainck(); + } + + return 0; +} + +static inline uint32_t osc_get_rate(uint32_t ul_id) +{ + switch (ul_id) { + case OSC_SLCK_32K_RC: + return OSC_SLCK_32K_RC_HZ; + + case OSC_SLCK_32K_XTAL: + return BOARD_FREQ_SLCK_XTAL; + + case OSC_SLCK_32K_BYPASS: + return BOARD_FREQ_SLCK_BYPASS; + + case OSC_MAINCK_4M_RC: + return OSC_MAINCK_4M_RC_HZ; + + case OSC_MAINCK_8M_RC: + return OSC_MAINCK_8M_RC_HZ; + + case OSC_MAINCK_12M_RC: + return OSC_MAINCK_12M_RC_HZ; + + case OSC_MAINCK_XTAL: + return BOARD_FREQ_MAINCK_XTAL; + + case OSC_MAINCK_BYPASS: + return BOARD_FREQ_MAINCK_BYPASS; + } + + return 0; +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_OSC_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/pll.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/pll.h new file mode 100644 index 0000000..fdadc17 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/pll.h @@ -0,0 +1,228 @@ +/** + * \file + * + * \brief Chip-specific PLL definitions. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CHIP_PLL_H_INCLUDED +#define CHIP_PLL_H_INCLUDED + +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup pll_group + * @{ + */ + +#define PLL_OUTPUT_MIN_HZ 80000000 +#define PLL_OUTPUT_MAX_HZ 240000000 + +#define PLL_INPUT_MIN_HZ 3000000 +#define PLL_INPUT_MAX_HZ 32000000 + +#define NR_PLLS 1 +#define PLLA_ID 0 + +#define PLL_COUNT 0x3fU + +enum pll_source { + PLL_SRC_MAINCK_4M_RC = OSC_MAINCK_4M_RC, //!< Internal 4MHz RC oscillator. + PLL_SRC_MAINCK_8M_RC = OSC_MAINCK_8M_RC, //!< Internal 8MHz RC oscillator. + PLL_SRC_MAINCK_12M_RC = OSC_MAINCK_12M_RC, //!< Internal 12MHz RC oscillator. + PLL_SRC_MAINCK_XTAL = OSC_MAINCK_XTAL, //!< External crystal oscillator. + PLL_SRC_MAINCK_BYPASS = OSC_MAINCK_BYPASS, //!< External bypass oscillator. + PLL_NR_SOURCES, //!< Number of PLL sources. +}; + +struct pll_config { + uint32_t ctrl; +}; + +#define pll_get_default_rate(pll_id) \ + ((osc_get_rate(CONFIG_PLL##pll_id##_SOURCE) \ + * CONFIG_PLL##pll_id##_MUL) \ + / CONFIG_PLL##pll_id##_DIV) + +/** + * \note The SAM4E PLL hardware interprets mul as mul+1. For readability the + * hardware mul+1 is hidden in this implementation. Use mul as mul effective + * value. + */ +static inline void pll_config_init(struct pll_config *p_cfg, + enum pll_source e_src, uint32_t ul_div, uint32_t ul_mul) +{ + uint32_t vco_hz; + + Assert(e_src < PLL_NR_SOURCES); + + /* Calculate internal VCO frequency */ + vco_hz = osc_get_rate(e_src) / ul_div; + Assert(vco_hz >= PLL_INPUT_MIN_HZ); + Assert(vco_hz <= PLL_INPUT_MAX_HZ); + + vco_hz *= ul_mul; + Assert(vco_hz >= PLL_OUTPUT_MIN_HZ); + Assert(vco_hz <= PLL_OUTPUT_MAX_HZ); + + /* PMC hardware will automatically make it mul+1 */ + p_cfg->ctrl = CKGR_PLLAR_MULA(ul_mul - 1) | CKGR_PLLAR_DIVA(ul_div) | \ + CKGR_PLLAR_PLLACOUNT(PLL_COUNT); +} + +#define pll_config_defaults(cfg, pll_id) \ + pll_config_init(cfg, \ + CONFIG_PLL##pll_id##_SOURCE, \ + CONFIG_PLL##pll_id##_DIV, \ + CONFIG_PLL##pll_id##_MUL) + +static inline void pll_config_read(struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + p_cfg->ctrl = PMC->CKGR_PLLAR; + } +} + +static inline void pll_config_write(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } +} + +static inline void pll_enable(const struct pll_config *p_cfg, uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); // Always stop PLL first! + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | p_cfg->ctrl; + } +} + +/** + * \note This will only disable the selected PLL, not the underlying oscillator (mainck). + */ +static inline void pll_disable(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + if (ul_pll_id == PLLA_ID) { + pmc_disable_pllack(); + } +} + +static inline uint32_t pll_is_locked(uint32_t ul_pll_id) +{ + Assert(ul_pll_id < NR_PLLS); + + UNUSED(ul_pll_id); + return pmc_is_locked_pllack(); +} + +static inline void pll_enable_source(enum pll_source e_src) +{ + switch (e_src) { + case PLL_SRC_MAINCK_4M_RC: + case PLL_SRC_MAINCK_8M_RC: + case PLL_SRC_MAINCK_12M_RC: + case PLL_SRC_MAINCK_XTAL: + case PLL_SRC_MAINCK_BYPASS: + osc_enable(e_src); + osc_wait_ready(e_src); + break; + + default: + Assert(false); + break; + } +} + +static inline void pll_enable_config_defaults(unsigned int ul_pll_id) +{ + struct pll_config pllcfg; + + if (pll_is_locked(ul_pll_id)) { + return; // Pll already running + } + switch (ul_pll_id) { +#ifdef CONFIG_PLL0_SOURCE + case 0: + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_init(&pllcfg, + CONFIG_PLL0_SOURCE, + CONFIG_PLL0_DIV, + CONFIG_PLL0_MUL); + break; +#endif + default: + Assert(false); + break; + } + pll_enable(&pllcfg, ul_pll_id); + while (!pll_is_locked(ul_pll_id)); +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_PLL_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.c new file mode 100644 index 0000000..30a8d36 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.c @@ -0,0 +1,240 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +#if defined(CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +/** + * \brief boolean signalling that the sysclk_init is done. + */ +uint32_t sysclk_initialized = 0; +#endif + +/** + * \brief Set system clock prescaler configuration + * + * This function will change the system clock prescaler configuration to + * match the parameters. + * + * \note The parameters to this function are device-specific. + * + * \param ul_pres The CPU clock will be divided by \f$2^{mck\_pres}\f$ + */ +void sysclk_set_prescalers(uint32_t ul_pres) +{ + pmc_mck_set_prescaler(ul_pres); + SystemCoreClockUpdate(); +} + +/** + * \brief Change the source of the main system clock. + * + * \param ul_src The new system clock source. Must be one of the constants + * from the System Clock Sources section. + */ +void sysclk_set_source(uint32_t ul_src) +{ + switch (ul_src) { + case SYSCLK_SRC_SLCK_RC: + case SYSCLK_SRC_SLCK_XTAL: + case SYSCLK_SRC_SLCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_SLOW_CLK); + break; + + case SYSCLK_SRC_MAINCK_4M_RC: + case SYSCLK_SRC_MAINCK_8M_RC: + case SYSCLK_SRC_MAINCK_12M_RC: + case SYSCLK_SRC_MAINCK_XTAL: + case SYSCLK_SRC_MAINCK_BYPASS: + pmc_mck_set_source(PMC_MCKR_CSS_MAIN_CLK); + break; + + case SYSCLK_SRC_PLLACK: + pmc_mck_set_source(PMC_MCKR_CSS_PLLA_CLK); + break; + } + + SystemCoreClockUpdate(); +} + +#if defined(CONFIG_USBCLK_SOURCE) || defined(__DOXYGEN__) +/** + * \brief Enable USB clock. + * + * \note The SAM3S UDP hardware interprets div as div+1. For readability the hardware div+1 + * is hidden in this implementation. Use div as div effective value. + * + * \param pll_id Source of the USB clock. + * \param div Actual clock divisor. Must be superior to 0. + */ +void sysclk_enable_usb(void) +{ + Assert(CONFIG_USBCLK_DIV > 0); + +#ifdef CONFIG_PLL0_SOURCE + if (CONFIG_USBCLK_SOURCE == USBCLK_SRC_PLL0) { + struct pll_config pllcfg; + + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_udpck_to_pllack(CONFIG_USBCLK_DIV - 1); + pmc_enable_udpck(); + return; + } +#endif +} + +/** + * \brief Disable the USB clock. + * + * \note This implementation does not switch off the PLL, it just turns off the USB clock. + */ +void sysclk_disable_usb(void) +{ + pmc_disable_udpck(); +} +#endif // CONFIG_USBCLK_SOURCE + +void sysclk_init(void) +{ + /* Set flash wait state to max in case the below clock switching. */ + system_init_flash(CHIP_FREQ_CPU_MAX); + + /* Config system clock setting */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { + osc_enable(OSC_SLCK_32K_RC); + osc_wait_ready(OSC_SLCK_32K_RC); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { + osc_enable(OSC_SLCK_32K_XTAL); + osc_wait_ready(OSC_SLCK_32K_XTAL); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { + osc_enable(OSC_SLCK_32K_BYPASS); + osc_wait_ready(OSC_SLCK_32K_BYPASS); + pmc_switch_mck_to_sclk(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { + /* Already running from SYSCLK_SRC_MAINCK_4M_RC */ + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { + osc_enable(OSC_MAINCK_8M_RC); + osc_wait_ready(OSC_MAINCK_8M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { + osc_enable(OSC_MAINCK_12M_RC); + osc_wait_ready(OSC_MAINCK_12M_RC); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { + osc_enable(OSC_MAINCK_XTAL); + osc_wait_ready(OSC_MAINCK_XTAL); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + } + + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { + osc_enable(OSC_MAINCK_BYPASS); + osc_wait_ready(OSC_MAINCK_BYPASS); + pmc_switch_mck_to_mainck(CONFIG_SYSCLK_PRES); + } + +#ifdef CONFIG_PLL0_SOURCE + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { + struct pll_config pllcfg; + + pll_enable_source(CONFIG_PLL0_SOURCE); + pll_config_defaults(&pllcfg, 0); + pll_enable(&pllcfg, 0); + pll_wait_for_lock(0); + pmc_switch_mck_to_pllack(CONFIG_SYSCLK_PRES); + } +#endif + + /* Update the SystemFrequency variable */ + SystemCoreClockUpdate(); + + /* Set a flash wait state depending on the new cpu frequency */ + system_init_flash(sysclk_get_cpu_hz()); + +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + /* Signal that the internal frequencies are setup */ + sysclk_initialized = 1; +#endif +} + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.h new file mode 100644 index 0000000..50f19ed --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sam4e/sysclk.h @@ -0,0 +1,459 @@ +/** + * \file + * + * \brief Chip-specific system clock management functions. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CHIP_SYSCLK_H_INCLUDED +#define CHIP_SYSCLK_H_INCLUDED + +#include +#include + +/** + * \page sysclk_quickstart Quick Start Guide for the System Clock Management + * service (SAM4E) + * + * This is the quick start guide for the \ref sysclk_group "System Clock + * Management" service, with step-by-step instructions on how to configure and + * use the service for specific use cases. + * + * \section sysclk_quickstart_usecases System Clock Management use cases + * - \ref sysclk_quickstart_basic + * - \ref sysclk_quickstart_use_case_2 + * + * \section sysclk_quickstart_basic Basic usage of the System Clock Management + * service + * This section will present a basic use case for the System Clock Management + * service. This use case will configure the main system clock to 120MHz, + * using an internal PLL module to multiply the frequency of a crystal attached + * to the microcontroller. + * + * \subsection sysclk_quickstart_use_case_1_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_1_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_1_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_1_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL + #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / BUS_div + #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +\endcode + * + * \subsection sysclk_quickstart_use_case_1_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL module as + * its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode + * -# Configure the PLL module to use the fast external fast crystal + * oscillator as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL module to multiply the external fast crystal + * oscillator frequency up to 120MHz: + * \code + #define CONFIG_PLL0_MUL (120000000UL / BOARD_FREQ_MAINCK_XTAL) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the + * board \c conf_board.h configuration + * file as the frequency of the fast crystal attached to the microcontroller. + * -# Configure the main clock to run at the full 120MHz, disable scaling of + * the main system clock speed: + * \code + #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +\endcode + * \note Some dividers are powers of two, while others are integer division + * factors. Refer to the formulas in the conf_clock.h template commented + * above each division define. + */ + +/** + * \page sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus Clock + * Management (SAM4E) + * + * \section sysclk_quickstart_use_case_2 Advanced use case - Peripheral Bus + * Clock Management + * This section will present a more advanced use case for the System Clock + * Management service. This use case will configure the main system clock to + * 96MHz, using an internal PLL module to multiply the frequency of a crystal + * attached to the microcontroller. The USB clock will be configured via the + * same PLL module. + * + * \subsection sysclk_quickstart_use_case_2_prereq Prerequisites + * - None + * + * \subsection sysclk_quickstart_use_case_2_setup_steps Initialization code + * Add to the application initialization code: + * \code + sysclk_init(); +\endcode + * + * \subsection sysclk_quickstart_use_case_2_setup_steps_workflow Workflow + * -# Configure the system clocks according to the settings in conf_clock.h: + * \code sysclk_init(); \endcode + * + * \subsection sysclk_quickstart_use_case_2_example_code Example code + * Add or uncomment the following in your conf_clock.h header file, + * commenting out all other definitions of the same symbol(s): + * \code + #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + + // Fpll0 = (Fclk * PLL_mul) / PLL_div + #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL + #define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL) + #define CONFIG_PLL0_DIV 1 + + // Fbus = Fsys / BUS_div + #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 + + // Fusb = Fsys / USB_div + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 + #define CONFIG_USBCLK_DIV 2 +\endcode + * + * \subsection sysclk_quickstart_use_case_2_example_workflow Workflow + * -# Configure the main system clock to use the output of the PLL0 module as + * its source: + * \code #define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK \endcode + * -# Configure the PLL0 module to use the fast external fast crystal + * oscillator as its source: + * \code #define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL \endcode + * -# Configure the PLL0 module to multiply the external fast crystal + * oscillator frequency up to 96MHz: + * \code + #define CONFIG_PLL0_MUL (96000000UL / BOARD_FREQ_MAINCK_XTAL) + #define CONFIG_PLL0_DIV 1 +\endcode + * \note For user boards, \c BOARD_FREQ_MAINCK_XTAL should be defined in the + * board \c conf_board.h configuration file as the frequency of the fast + * crystal attached to the microcontroller. + * -# Configure the main clock to run at the full 96MHz, disable scaling of + * the main system clock speed: + * \code + #define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +\endcode + * \note Some dividers are powers of two, while others are integer division + * factors. Refer to the formulas in the conf_clock.h template commented + * above each division define. + * -# Configure the USB module clock to use the output of the PLL0 module as + * its source with division 2: + * \code + #define CONFIG_USBCLK_SOURCE USBCLK_SRC_PLL0 + #define CONFIG_USBCLK_DIV 2 +\endcode + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \weakgroup sysclk_group + * @{ + */ + +//! \name Configuration Symbols +//@{ +/** + * \def CONFIG_SYSCLK_SOURCE + * \brief Initial/static main system clock source + * + * The main system clock will be configured to use this clock during + * initialization. + */ +#ifndef CONFIG_SYSCLK_SOURCE +# define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +#endif +/** + * \def CONFIG_SYSCLK_PRES + * \brief Initial CPU clock divider (mck) + * + * The MCK will run at + * \f[ + * f_{MCK} = \frac{f_{sys}}{\mathrm{CONFIG\_SYSCLK\_PRES}}\,\mbox{Hz} + * \f] + * after initialization. + */ +#ifndef CONFIG_SYSCLK_PRES +# define CONFIG_SYSCLK_PRES 0 +#endif + +//@} + +//! \name Master Clock Sources (MCK) +//@{ +#define SYSCLK_SRC_SLCK_RC 0 //!< Internal 32kHz RC oscillator as master source clock +#define SYSCLK_SRC_SLCK_XTAL 1 //!< External 32kHz crystal oscillator as master source clock +#define SYSCLK_SRC_SLCK_BYPASS 2 //!< External 32kHz bypass oscillator as master source clock +#define SYSCLK_SRC_MAINCK_4M_RC 3 //!< Internal 4MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_8M_RC 4 //!< Internal 8MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_12M_RC 5 //!< Internal 12MHz RC oscillator as master source clock +#define SYSCLK_SRC_MAINCK_XTAL 6 //!< External crystal oscillator as master source clock +#define SYSCLK_SRC_MAINCK_BYPASS 7 //!< External bypass oscillator as master source clock +#define SYSCLK_SRC_PLLACK 8 //!< Use PLLACK as master source clock +//@} + +//! \name Master Clock Prescalers (MCK) +//@{ +#define SYSCLK_PRES_1 PMC_MCKR_PRES_CLK_1 //!< Set master clock prescaler to 1 +#define SYSCLK_PRES_2 PMC_MCKR_PRES_CLK_2 //!< Set master clock prescaler to 2 +#define SYSCLK_PRES_4 PMC_MCKR_PRES_CLK_4 //!< Set master clock prescaler to 4 +#define SYSCLK_PRES_8 PMC_MCKR_PRES_CLK_8 //!< Set master clock prescaler to 8 +#define SYSCLK_PRES_16 PMC_MCKR_PRES_CLK_16 //!< Set master clock prescaler to 16 +#define SYSCLK_PRES_32 PMC_MCKR_PRES_CLK_32 //!< Set master clock prescaler to 32 +#define SYSCLK_PRES_64 PMC_MCKR_PRES_CLK_64 //!< Set master clock prescaler to 64 +#define SYSCLK_PRES_3 PMC_MCKR_PRES_CLK_3 //!< Set master clock prescaler to 3 +//@} + +//! \name USB Clock Sources +//@{ +#define USBCLK_SRC_PLL0 0 //!< Use PLLA +//@} + +/** + * \def CONFIG_USBCLK_SOURCE + * \brief Configuration symbol for the USB generic clock source + * + * Sets the clock source to use for the USB. The source must also be properly + * configured. + * + * Define this to one of the \c USBCLK_SRC_xxx settings. Leave it undefined if + * USB is not required. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_SOURCE +#endif + +/** + * \def CONFIG_USBCLK_DIV + * \brief Configuration symbol for the USB generic clock divider setting + * + * Sets the clock division for the USB generic clock. If a USB clock source is + * selected with CONFIG_USBCLK_SOURCE, this configuration symbol must also be + * defined. + */ +#ifdef __DOXYGEN__ +# define CONFIG_USBCLK_DIV +#endif + +/** + * \name Querying the system clock + * + * The following functions may be used to query the current frequency of + * the system clock and the CPU and bus clocks derived from it. + * sysclk_get_main_hz() and sysclk_get_cpu_hz() can be assumed to be + * available on all platforms, although some platforms may define + * additional accessors for various chip-internal bus clocks. These are + * usually not intended to be queried directly by generic code. + */ +//@{ + +/** + * \brief Return the current rate in Hz of the main system clock + * + * \todo This function assumes that the main clock source never changes + * once it's been set up, and that PLL0 always runs at the compile-time + * configured default rate. While this is probably the most common + * configuration, which we want to support as a special case for + * performance reasons, we will at some point need to support more + * dynamic setups as well. + */ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) +extern uint32_t sysclk_initialized; +#endif +static inline uint32_t sysclk_get_main_hz(void) +{ +#if (defined CONFIG_SYSCLK_DEFAULT_RETURNS_SLOW_OSC) + if (!sysclk_initialized ) { + return OSC_MAINCK_4M_RC_HZ; + } +#endif + + /* Config system clock setting */ + if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_RC) { + return OSC_SLCK_32K_RC_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_XTAL) { + return OSC_SLCK_32K_XTAL_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_SLCK_BYPASS) { + return OSC_SLCK_32K_BYPASS_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_4M_RC) { + return OSC_MAINCK_4M_RC_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_8M_RC) { + return OSC_MAINCK_8M_RC_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_12M_RC) { + return OSC_MAINCK_12M_RC_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_XTAL) { + return OSC_MAINCK_XTAL_HZ; + } else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_MAINCK_BYPASS) { + return OSC_MAINCK_BYPASS_HZ; + } +#ifdef CONFIG_PLL0_SOURCE + else if (CONFIG_SYSCLK_SOURCE == SYSCLK_SRC_PLLACK) { + return pll_get_default_rate(0); + } +#endif + + else { + /* unhandled_case(CONFIG_SYSCLK_SOURCE); */ + return 0; + } +} + +/** + * \brief Return the current rate in Hz of the CPU clock + * + * \todo This function assumes that the CPU always runs at the system + * clock frequency. We want to support at least two more scenarios: + * Fixed CPU/bus clock dividers (config symbols) and dynamic CPU/bus + * clock dividers (which may change at run time). Ditto for all the bus + * clocks. + * + * \return Frequency of the CPU clock, in Hz. + */ +static inline uint32_t sysclk_get_cpu_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediate value. */ + return sysclk_get_main_hz() / + ((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : + (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))); +} + +/** + * \brief Retrieves the current rate in Hz of the peripheral clocks. + * + * \return Frequency of the peripheral clocks, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_hz(void) +{ + /* CONFIG_SYSCLK_PRES is the register value for setting the expected */ + /* prescaler, not an immediate value. */ + return sysclk_get_main_hz() / + ((CONFIG_SYSCLK_PRES == SYSCLK_PRES_3) ? 3 : + (1 << (CONFIG_SYSCLK_PRES >> PMC_MCKR_PRES_Pos))); +} + +/** + * \brief Retrieves the current rate in Hz of the Peripheral Bus clock attached + * to the specified peripheral. + * + * \param module Pointer to the module's base address. + * + * \return Frequency of the bus attached to the specified peripheral, in Hz. + */ +static inline uint32_t sysclk_get_peripheral_bus_hz(const volatile void *module) +{ + UNUSED(module); + return sysclk_get_peripheral_hz(); +} +//@} + +//! \name Enabling and disabling synchronous clocks +//@{ + +/** + * \brief Enable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_enable_peripheral_clock(uint32_t ul_id) +{ + pmc_enable_periph_clk(ul_id); +} + +/** + * \brief Disable a peripheral's clock. + * + * \param ul_id Id (number) of the peripheral clock. + */ +static inline void sysclk_disable_peripheral_clock(uint32_t ul_id) +{ + pmc_disable_periph_clk(ul_id); +} + +//@} + +//! \name System Clock Source and Prescaler configuration +//@{ + +extern void sysclk_set_prescalers(uint32_t ul_pres); +extern void sysclk_set_source(uint32_t ul_src); + +//@} + +extern void sysclk_enable_usb(void); +extern void sysclk_disable_usb(void); + +extern void sysclk_init(void); + +//! @} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* CHIP_SYSCLK_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sysclk.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sysclk.h new file mode 100644 index 0000000..d5b22d4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/clock/sysclk.h @@ -0,0 +1,186 @@ +/** + * \file + * + * \brief System clock management + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef SYSCLK_H_INCLUDED +#define SYSCLK_H_INCLUDED + +#include "parts.h" +#include "conf_clock.h" + +#if SAM3S +# include "sam3s/sysclk.h" +#elif SAM3U +# include "sam3u/sysclk.h" +#elif SAM3N +# include "sam3n/sysclk.h" +#elif SAM3XA +# include "sam3x/sysclk.h" +#elif SAM4S +# include "sam4s/sysclk.h" +#elif SAM4E +# include "sam4e/sysclk.h" +#elif SAM4C +# include "sam4c/sysclk.h" +#elif SAM4CM +# include "sam4cm/sysclk.h" +#elif SAM4CP +# include "sam4cp/sysclk.h" +#elif SAM4L +# include "sam4l/sysclk.h" +#elif SAM4N +# include "sam4n/sysclk.h" +#elif SAMG +# include "samg/sysclk.h" +#elif (UC3A0 || UC3A1) +# include "uc3a0_a1/sysclk.h" +#elif UC3A3 +# include "uc3a3_a4/sysclk.h" +#elif UC3B +# include "uc3b0_b1/sysclk.h" +#elif UC3C +# include "uc3c/sysclk.h" +#elif UC3D +# include "uc3d/sysclk.h" +#elif UC3L +# include "uc3l/sysclk.h" +#elif XMEGA +# include "xmega/sysclk.h" +#elif MEGA +# include "mega/sysclk.h" +#else +# error Unsupported chip type +#endif + +/** + * \defgroup clk_group Clock Management + */ + +/** + * \ingroup clk_group + * \defgroup sysclk_group System Clock Management + * + * See \ref sysclk_quickstart. + * + * The sysclk API covers the system clock and all + * clocks derived from it. The system clock is a chip-internal clock on + * which all synchronous clocks, i.e. CPU and bus/peripheral + * clocks, are based. The system clock is typically generated from one + * of a variety of sources, which may include crystal and RC oscillators + * as well as PLLs. The clocks derived from the system clock are + * sometimes also known as synchronous clocks, since they + * always run synchronously with respect to each other, as opposed to + * generic clocks which may run from different oscillators or + * PLLs. + * + * Most applications should simply call sysclk_init() to initialize + * everything related to the system clock and its source (oscillator, + * PLL or DFLL), and leave it at that. More advanced applications, and + * platform-specific drivers, may require additional services from the + * clock system, some of which may be platform-specific. + * + * \section sysclk_group_platform Platform Dependencies + * + * The sysclk API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms with the same + * parameters and functionality. These functions may be called freely by + * portable applications, drivers and services: + * - sysclk_init() + * - sysclk_set_source() + * - sysclk_get_main_hz() + * - sysclk_get_cpu_hz() + * - sysclk_get_peripheral_bus_hz() + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behavior. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - sysclk_enable_peripheral_clock() + * - sysclk_disable_peripheral_clock() + * - sysclk_enable_module() + * - sysclk_disable_module() + * - sysclk_module_is_enabled() + * - sysclk_set_prescalers() + * + * All other functions should be considered platform-specific. + * Enabling/disabling clocks to specific peripherals as well as + * determining the speed of these clocks should be done by calling + * functions provided by the driver for that peripheral. + * + * @{ + */ + +//! \name System Clock Initialization +//@{ +/** + * \fn void sysclk_init(void) + * \brief Initialize the synchronous clock system. + * + * This function will initialize the system clock and its source. This + * includes: + * - Mask all synchronous clocks except for any clocks which are + * essential for normal operation (for example internal memory + * clocks). + * - Set up the system clock prescalers as specified by the + * application's configuration file. + * - Enable the clock source specified by the application's + * configuration file (oscillator or PLL) and wait for it to become + * stable. + * - Set the main system clock source to the clock specified by the + * application's configuration file. + * + * Since all non-essential peripheral clocks are initially disabled, it + * is the responsibility of the peripheral driver to re-enable any + * clocks that are needed for normal operation. + */ +//@} + +//! @} + +#endif /* SYSCLK_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/delay.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/delay.h new file mode 100644 index 0000000..4d20450 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/delay.h @@ -0,0 +1,139 @@ +/** + * \file + * + * \brief Common Delay Service + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef _DELAY_H_ +#define _DELAY_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#if UC3 +# include +#elif XMEGA +# include "xmega/cycle_counter.h" +#elif MEGA +# include "mega/cycle_counter.h" +#elif SAM +# include "sam/cycle_counter.h" +#endif + +/** + * @defgroup group_common_services_delay Busy-Wait Delay Routines + * + * This module provides simple loop-based delay routines for those + * applications requiring a brief wait during execution. Common API + * for UC3, XMEGA, and AVR MEGA. + * + * @{ + */ + +/** + * @def F_CPU + * @brief MCU Clock Frequency (Hertz) + * + * @deprecated + * The \ref F_CPU configuration constant is used for compatibility with the + * \ref group_common_services_delay routines. The common loop-based delay + * routines are designed to use the \ref clk_group modules while anticipating + * support for legacy applications assuming a statically defined clock + * frequency. Applications using a statically configured MCU clock frequency + * can define \ref F_CPU (Hertz), in which case the common delay routines will + * use this value rather than calling sysclk_get_cpu_hz() to get the current + * MCU clock frequency. + */ +#ifndef F_CPU +# define F_CPU sysclk_get_cpu_hz() +#endif + +/** + * @def delay_init + * + * @brief Initialize the delay driver. + * @param fcpu_hz CPU frequency in Hz + * + * @deprecated + * This function is provided for compatibility with ASF applications that + * may not have been updated to configure the system clock via the common + * clock service; e.g. sysclk_init() and a configuration header file are + * used to configure clocks. + * + * The functions in this module call \ref sysclk_get_cpu_hz() function to + * obtain the system clock frequency. + */ +#define delay_init(fcpu_hz) + +/** + * @def delay_s + * @brief Delay in seconds. + * @param delay Delay in seconds + */ +#define delay_s(delay) cpu_delay_ms(1000 * delay, F_CPU) + +/** + * @def delay_ms + * @brief Delay in milliseconds. + * @param delay Delay in milliseconds + */ +#define delay_ms(delay) cpu_delay_ms(delay, F_CPU) + +/** + * @def delay_us + * @brief Delay in microseconds. + * @param delay Delay in microseconds + */ +#define delay_us(delay) cpu_delay_us(delay, F_CPU) + +#ifdef __cplusplus +} +#endif + +/** + * @} + */ + +#endif /* _DELAY_H_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.c new file mode 100644 index 0000000..2454aee --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.c @@ -0,0 +1,61 @@ +/** + * \file + * + * \brief ARM functions for busy-wait delay loops + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "cycle_counter.h" + +// Delay loop is put to SRAM so that FWS will not affect delay time +OPTIMIZE_HIGH +RAMFUNC +void portable_delay_cycles(unsigned long n) +{ + UNUSED(n); + + __asm ( + "loop: DMB \n" + "SUBS R0, R0, #1 \n" + "BNE.N loop " + ); +} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.h new file mode 100644 index 0000000..82f4f15 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/delay/sam/cycle_counter.h @@ -0,0 +1,114 @@ +/** + * \file + * + * \brief ARM functions for busy-wait delay loops + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef _cycle_counter_h_ +#define _cycle_counter_h_ + +#ifdef __cplusplus +extern "C" { +#endif + + +#include + +/** + * @name Convenience functions for busy-wait delay loops + * + * @def delay_cycles + * @brief Delay program execution for a specified number of CPU cycles. + * @param n number of CPU cycles to wait + * + * @def cpu_delay_ms + * @brief Delay program execution for a specified number of milliseconds. + * @param delay number of milliseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_delay_us + * @brief Delay program execution for a specified number of microseconds. + * @param delay number of microseconds to wait + * @param f_cpu CPU frequency in Hertz + * + * @def cpu_ms_2_cy + * @brief Convert milli-seconds into CPU cycles. + * @param ms number of milliseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @def cpu_us_2_cy + * @brief Convert micro-seconds into CPU cycles. + * @param ms number of microseconds + * @param f_cpu CPU frequency in Hertz + * @return the converted number of CPU cycles + * + * @{ + */ + +/** + * \brief Delay loop to delay n number of cycles + * + * \note The function runs in internal RAM so that flash wait states + * will not affect the delay time. + * + * \param n Number of cycles + */ +void portable_delay_cycles(unsigned long n); + +#define cpu_ms_2_cy(ms, f_cpu) \ + (((uint64_t)(ms) * (f_cpu) + (uint64_t)(14e3-1ul)) / (uint64_t)14e3) +#define cpu_us_2_cy(us, f_cpu) \ + (((uint64_t)(us) * (f_cpu) + (uint64_t)(14e6-1ul)) / (uint64_t)14e6) + +#define delay_cycles portable_delay_cycles + +#define cpu_delay_ms(delay, f_cpu) delay_cycles(cpu_ms_2_cy(delay, f_cpu)) +#define cpu_delay_us(delay, f_cpu) delay_cycles(cpu_us_2_cy(delay, f_cpu)) +//! @} + + +#ifdef __cplusplus +} +#endif + +#endif /* _cycle_counter_h_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/ioport.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/ioport.h new file mode 100644 index 0000000..2c04ade --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/ioport.h @@ -0,0 +1,541 @@ +/** + * \file + * + * \brief Common IOPORT service main header file for AVR, UC3 and ARM + * architectures. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef IOPORT_H +#define IOPORT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +/** + * \defgroup ioport_group Common IOPORT API + * + * See \ref ioport_quickstart. + * + * This is common IOPORT service for GPIO pin configuration and control in a + * standardized manner across the MEGA, MEGA_RF, XMEGA, UC3 and ARM devices. + * + * Port pin control code is optimized for each platform, and should produce + * both compact and fast execution times when used with constant values. + * + * \section dependencies Dependencies + * This driver depends on the following modules: + * - \ref sysclk_group for clock speed and functions. + * @{ + */ + +/** + * \def IOPORT_CREATE_PIN(port, pin) + * \brief Create IOPORT pin number + * + * Create a IOPORT pin number for use with the IOPORT functions. + * + * \param port IOPORT port (e.g. PORTA, PA or PIOA depending on chosen + * architecture) + * \param pin IOPORT zero-based index of the I/O pin + */ + +/** \brief IOPORT pin directions */ +enum ioport_direction { + IOPORT_DIR_INPUT, /*!< IOPORT input direction */ + IOPORT_DIR_OUTPUT, /*!< IOPORT output direction */ +}; + +/** \brief IOPORT levels */ +enum ioport_value { + IOPORT_PIN_LEVEL_LOW, /*!< IOPORT pin value low */ + IOPORT_PIN_LEVEL_HIGH, /*!< IOPORT pin value high */ +}; + +#if MEGA_RF +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_LEVEL, /*!< IOPORT sense low level */ + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ +}; +#elif SAM && !SAM4L +/** \brief IOPORT edge sense modes */ +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_LEVEL_LOW, /*!< IOPORT sense low level */ + IOPORT_SENSE_LEVEL_HIGH,/*!< IOPORT sense High level */ +}; +#else +enum ioport_sense { + IOPORT_SENSE_BOTHEDGES, /*!< IOPORT sense both rising and falling edges */ + IOPORT_SENSE_RISING, /*!< IOPORT sense rising edges */ + IOPORT_SENSE_FALLING, /*!< IOPORT sense falling edges */ +}; +#endif + + +#if XMEGA +# include "xmega/ioport.h" +# if defined(IOPORT_XMEGA_COMPAT) +# include "xmega/ioport_compat.h" +# endif +#elif MEGA +# include "mega/ioport.h" +#elif UC3 +# include "uc3/ioport.h" +#elif SAM +# if SAM4L +# include "sam/ioport_gpio.h" +# elif (SAMD20 | SAMD21) +# include "sam0/ioport.h" +# else +# include "sam/ioport_pio.h" +# endif +#endif + +/** + * \brief Initializes the IOPORT service, ready for use. + * + * This function must be called before using any other functions in the IOPORT + * service. + */ +static inline void ioport_init(void) +{ + arch_ioport_init(); +} + +/** + * \brief Enable an IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to enable + */ +static inline void ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_pin(pin); +} + +/** + * \brief Enable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to enable + * \param mask Mask of pins within the port to enable + */ +static inline void ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_enable_port(port, mask); +} + +/** + * \brief Disable IOPORT pin, based on a pin created with \ref + * IOPORT_CREATE_PIN(). + * + * \param pin IOPORT pin to disable + */ +static inline void ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_pin(pin); +} + +/** + * \brief Disable multiple pins in a single IOPORT port. + * + * \param port IOPORT port to disable + * \param mask Pin mask of pins to disable + */ +static inline void ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_disable_port(port, mask); +} + +/** + * \brief Set multiple pin modes in a single IOPORT port, such as pull-up, + * pull-down, etc. configuration. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param mode Mode masks to configure for the specified pins (\ref + * ioport_modes) + */ +static inline void ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + arch_ioport_set_port_mode(port, mask, mode); +} + +/** + * \brief Set pin mode for one single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +static inline void ioport_set_pin_mode(ioport_pin_t pin, ioport_mode_t mode) +{ + arch_ioport_set_pin_mode(pin, mode); +} + +/** + * \brief Reset multiple pin modes in a specified IOPORT port to defaults. + * + * \param port IOPORT port to configure + * \param mask Mask of pins whose mode configuration is to be reset + */ +static inline void ioport_reset_port_mode(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_set_port_mode(port, mask, 0); +} + +/** + * \brief Reset pin mode configuration for a single IOPORT pin + * + * \param pin IOPORT pin to configure + */ +static inline void ioport_reset_pin_mode(ioport_pin_t pin) +{ + arch_ioport_set_pin_mode(pin, 0); +} + +/** + * \brief Set I/O direction for a group of pins in a single IOPORT. + * + * \param port IOPORT port to configure + * \param mask Pin mask of pins to configure + * \param dir Direction to set for the specified pins (\ref ioport_direction) + */ +static inline void ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction dir) +{ + arch_ioport_set_port_dir(port, mask, dir); +} + +/** + * \brief Set direction for a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param dir Direction to set for the specified pin (\ref ioport_direction) + */ +static inline void ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + arch_ioport_set_pin_dir(pin, dir); +} + +/** + * \brief Set an IOPORT pin to a specified logical value. + * + * \param pin IOPORT pin to configure + * \param level Logical value of the pin + */ +static inline void ioport_set_pin_level(ioport_pin_t pin, bool level) +{ + arch_ioport_set_pin_level(pin, level); +} + +/** + * \brief Set a group of IOPORT pins in a single port to a specified logical + * value. + * + * \param port IOPORT port to write to + * \param mask Pin mask of pins to modify + * \param level Level of the pins to be modified + */ +static inline void ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + arch_ioport_set_port_level(port, mask, level); +} + +/** + * \brief Get current value of an IOPORT pin, which has been configured as an + * input. + * + * \param pin IOPORT pin to read + * \return Current logical value of the specified pin + */ +static inline bool ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_get_pin_level(pin); +} + +/** + * \brief Get current value of several IOPORT pins in a single port, which have + * been configured as an inputs. + * + * \param port IOPORT port to read + * \param mask Pin mask of pins to read + * \return Logical levels of the specified pins from the read port, returned as + * a mask. + */ +static inline ioport_port_mask_t ioport_get_port_level(ioport_pin_t port, + ioport_port_mask_t mask) +{ + return arch_ioport_get_port_level(port, mask); +} + +/** + * \brief Toggle the value of an IOPORT pin, which has previously configured as + * an output. + * + * \param pin IOPORT pin to toggle + */ +static inline void ioport_toggle_pin_level(ioport_pin_t pin) +{ + arch_ioport_toggle_pin_level(pin); +} + +/** + * \brief Toggle the values of several IOPORT pins located in a single port. + * + * \param port IOPORT port to modify + * \param mask Pin mask of pins to toggle + */ +static inline void ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_toggle_port_level(port, mask); +} + +/** + * \brief Set the pin sense mode of a single IOPORT pin. + * + * \param pin IOPORT pin to configure + * \param pin_sense Edge to sense for the pin (\ref ioport_sense) + */ +static inline void ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_pin_sense_mode(pin, pin_sense); +} + +/** + * \brief Set the pin sense mode of a multiple IOPORT pins on a single port. + * + * \param port IOPORT port to configure + * \param mask Bitmask if pins whose edge sense is to be configured + * \param pin_sense Edge to sense for the pins (\ref ioport_sense) + */ +static inline void ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(port, mask, pin_sense); +} + +/** + * \brief Convert a pin ID into a its port ID. + * + * \param pin IOPORT pin ID to convert + * \retval Port ID for the given pin ID + */ +static inline ioport_port_t ioport_pin_to_port_id(ioport_pin_t pin) +{ + return arch_ioport_pin_to_port_id(pin); +} + +/** + * \brief Convert a pin ID into a bitmask mask for the given pin on its port. + * + * \param pin IOPORT pin ID to convert + * \retval Bitmask with a bit set that corresponds to the given pin ID in its port + */ +static inline ioport_port_mask_t ioport_pin_to_mask(ioport_pin_t pin) +{ + return arch_ioport_pin_to_mask(pin); +} + +/** @} */ + +/** + * \page ioport_quickstart Quick start guide for the common IOPORT service + * + * This is the quick start guide for the \ref ioport_group, with + * step-by-step instructions on how to configure and use the service in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section ioport_quickstart_basic Basic use case + * In this use case we will configure one IO pin for button input and one for + * LED control. Then it will read the button state and output it on the LED. + * + * \section ioport_quickstart_basic_setup Setup steps + * + * \subsection ioport_quickstart_basic_setup_code Example code + * \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) + + ioport_init(); + + ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); + ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the GPIOs symbolic names and this can be done with + * the \ref IOPORT_CREATE_PIN macro. We define one for a LED and one for a + * button. + * - \code + #define MY_LED IOPORT_CREATE_PIN(PORTA, 5) + #define MY_BUTTON IOPORT_CREATE_PIN(PORTA, 6) +\endcode + * - \note The usefulness of the \ref IOPORT_CREATE_PIN macro and port names + * differ between architectures: + * - MEGA, MEGA_RF and XMEGA: Use \ref IOPORT_CREATE_PIN macro with port definitions + * PORTA, PORTB ... + * - UC3: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: AVR32_PIN_PB06 + * - SAM: Most convenient to pick up the device header file pin definition + * and us it directly. E.g.: PIO_PA5_IDX
+ * \ref IOPORT_CREATE_PIN can also be used with port definitions + * PIOA, PIOB ... + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set the LED GPIO as output: + * - \code ioport_set_pin_dir(MY_LED, IOPORT_DIR_OUTPUT); \endcode + * -# Set the button GPIO as input: + * - \code ioport_set_pin_dir(MY_BUTTON, IOPORT_DIR_INPUT); \endcode + * -# Enable pull-up for the button GPIO: + * - \code ioport_set_pin_mode(MY_BUTTON, IOPORT_MODE_PULLUP); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + bool value; + + value = ioport_get_pin_level(MY_BUTTON); + ioport_set_pin_level(MY_LED, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a boolean variable for state storage: + * - \code bool value; \endcode + * -# Read out the button level into variable value: + * - \code value = ioport_get_pin_level(MY_BUTTON); \endcode + * -# Set the LED to read out value from the button: + * - \code ioport_set_pin_level(MY_LED, value); \endcode + * + * \section ioport_quickstart_advanced Advanced use cases + * - \subpage ioport_quickstart_use_case_1 : Port access + */ + +/** + * \page ioport_quickstart_use_case_1 Advanced use case doing port access + * + * In this case we will read out the pins from one whole port and write the + * read value to another port. + * + * \section ioport_quickstart_use_case_1_setup Setup steps + * + * \subsection ioport_quickstart_use_case_1_setup_code Example code + * \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB + #define MASK 0x00000060 + + ioport_init(); + + ioport_set_port_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); + ioport_set_port_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); +\endcode + * + * \subsection ioport_quickstart_basic_setup_flow Workflow + * -# It's useful to give the ports symbolic names: + * - \code + #define IN_PORT IOPORT_PORTA + #define OUT_PORT IOPORT_PORTB +\endcode + * - \note The port names differ between architectures: + * - MEGA_RF, MEGA and XMEGA: There are predefined names for ports: IOPORT_PORTA, + * IOPORT_PORTB ... + * - UC3: Use the index value of the different IO blocks: 0, 1 ... + * - SAM: There are predefined names for ports: IOPORT_PIOA, IOPORT_PIOB + * ... + * -# Also useful to define a mask for the bits to work with: + * - \code #define MASK 0x00000060 \endcode + * -# Initialize the ioport service. This typically enables the IO module if + * needed. + * - \code ioport_init(); \endcode + * -# Set one of the ports as input: + * - \code ioport_set_pin_dir(IN_PORT, MASK, IOPORT_DIR_INPUT); \endcode + * -# Set the other port as output: + * - \code ioport_set_pin_dir(OUT_PORT, MASK, IOPORT_DIR_OUTPUT); \endcode + * + * \section ioport_quickstart_basic_usage Usage steps + * + * \subsection ioport_quickstart_basic_usage_code Example code + * \code + ioport_port_mask_t value; + + value = ioport_get_port_level(IN_PORT, MASK); + ioport_set_port_level(OUT_PORT, MASK, value); +\endcode + * + * \subsection ioport_quickstart_basic_usage_flow Workflow + * -# Define a variable for port date storage: + * - \code ioport_port_mask_t value; \endcode + * -# Read out from one port: + * - \code value = ioport_get_port_level(IN_PORT, MASK); \endcode + * -# Put the read data out on the other port: + * - \code ioport_set_port_level(OUT_PORT, MASK, value); \endcode + */ + +#ifdef __cplusplus +} +#endif + +#endif /* IOPORT_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/sam/ioport_pio.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/sam/ioport_pio.h new file mode 100644 index 0000000..9401d20 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/ioport/sam/ioport_pio.h @@ -0,0 +1,380 @@ +/** + * \file + * + * \brief SAM architecture specific IOPORT service implementation header file. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef IOPORT_SAM_H +#define IOPORT_SAM_H + +#include + +#define IOPORT_CREATE_PIN(port, pin) ((IOPORT_ ## port) * 32 + (pin)) +#define IOPORT_BASE_ADDRESS (uintptr_t)PIOA +#define IOPORT_PIO_OFFSET ((uintptr_t)PIOB - (uintptr_t)PIOA) + +#define IOPORT_PIOA 0 +#define IOPORT_PIOB 1 +#define IOPORT_PIOC 2 +#define IOPORT_PIOD 3 +#define IOPORT_PIOE 4 +#define IOPORT_PIOF 5 + +/** + * \weakgroup ioport_group + * \section ioport_modes IOPORT Modes + * + * For details on these please see the SAM Manual. + * + * @{ + */ + +/** \name IOPORT Mode bit definitions */ +/** @{ */ +#define IOPORT_MODE_MUX_MASK (0x7 << 0) /*!< MUX bits mask */ +#define IOPORT_MODE_MUX_BIT0 ( 1 << 0) /*!< MUX BIT0 mask */ + +#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP +#define IOPORT_MODE_MUX_BIT1 ( 1 << 1) /*!< MUX BIT1 mask */ +#endif + +#define IOPORT_MODE_MUX_A ( 0 << 0) /*!< MUX function A */ +#define IOPORT_MODE_MUX_B ( 1 << 0) /*!< MUX function B */ + +#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP +#define IOPORT_MODE_MUX_C ( 2 << 0) /*!< MUX function C */ +#define IOPORT_MODE_MUX_D ( 3 << 0) /*!< MUX function D */ +#endif + +#define IOPORT_MODE_PULLUP ( 1 << 3) /*!< Pull-up */ + +#if SAM3N || SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP +#define IOPORT_MODE_PULLDOWN ( 1 << 4) /*!< Pull-down */ +#endif + +#define IOPORT_MODE_OPEN_DRAIN ( 1 << 5) /*!< Open drain */ + +#define IOPORT_MODE_GLITCH_FILTER ( 1 << 6) /*!< Glitch filter */ +#define IOPORT_MODE_DEBOUNCE ( 1 << 7) /*!< Input debounce */ +/** @} */ + +/** @} */ + +typedef uint32_t ioport_mode_t; +typedef uint32_t ioport_pin_t; +typedef uint32_t ioport_port_t; +typedef uint32_t ioport_port_mask_t; + +__always_inline static ioport_port_t arch_ioport_pin_to_port_id(ioport_pin_t pin) +{ + return pin >> 5; +} + +__always_inline static Pio *arch_ioport_port_to_base(ioport_port_t port) +{ +#if (SAM4C || SAM4CM || SAM4CP) + if (port == IOPORT_PIOC) { + return (Pio *)(uintptr_t)PIOC; +# ifdef ID_PIOD + } else if (port == IOPORT_PIOD) { + return (Pio *)(uintptr_t)PIOD; +# endif + } else { + return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS + + (IOPORT_PIO_OFFSET * port)); + } +#else + return (Pio *)((uintptr_t)IOPORT_BASE_ADDRESS + + (IOPORT_PIO_OFFSET * port)); +#endif +} + +__always_inline static Pio *arch_ioport_pin_to_base(ioport_pin_t pin) +{ + return arch_ioport_port_to_base(arch_ioport_pin_to_port_id(pin)); +} + +__always_inline static ioport_port_mask_t arch_ioport_pin_to_mask(ioport_pin_t pin) +{ + return 1U << (pin & 0x1F); +} + +__always_inline static void arch_ioport_init(void) +{ +#ifdef ID_PIOA + sysclk_enable_peripheral_clock(ID_PIOA); +#endif +#ifdef ID_PIOB + sysclk_enable_peripheral_clock(ID_PIOB); +#endif +#ifdef ID_PIOC + sysclk_enable_peripheral_clock(ID_PIOC); +#endif +#ifdef ID_PIOD + sysclk_enable_peripheral_clock(ID_PIOD); +#endif +#ifdef ID_PIOE + sysclk_enable_peripheral_clock(ID_PIOE); +#endif +#ifdef ID_PIOF + sysclk_enable_peripheral_clock(ID_PIOF); +#endif +} + +__always_inline static void arch_ioport_enable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_port_to_base(port)->PIO_PER = mask; +} + +__always_inline static void arch_ioport_disable_port(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_port_to_base(port)->PIO_PDR = mask; +} + +__always_inline static void arch_ioport_enable_pin(ioport_pin_t pin) +{ + arch_ioport_enable_port(arch_ioport_pin_to_port_id(pin), + arch_ioport_pin_to_mask(pin)); +} + +__always_inline static void arch_ioport_disable_pin(ioport_pin_t pin) +{ + arch_ioport_disable_port(arch_ioport_pin_to_port_id(pin), + arch_ioport_pin_to_mask(pin)); +} + +__always_inline static void arch_ioport_set_port_mode(ioport_port_t port, + ioport_port_mask_t mask, ioport_mode_t mode) +{ + Pio *base = arch_ioport_port_to_base(port); + + if (mode & IOPORT_MODE_PULLUP) { + base->PIO_PUER = mask; + } else { + base->PIO_PUDR = mask; + } + +#if defined(IOPORT_MODE_PULLDOWN) + if (mode & IOPORT_MODE_PULLDOWN) { + base->PIO_PPDER = mask; + } else { + base->PIO_PPDDR = mask; + } +#endif + + if (mode & IOPORT_MODE_OPEN_DRAIN) { + base->PIO_MDER = mask; + } else { + base->PIO_MDDR = mask; + } + + if (mode & (IOPORT_MODE_GLITCH_FILTER | IOPORT_MODE_DEBOUNCE)) { + base->PIO_IFER = mask; + } else { + base->PIO_IFDR = mask; + } + + if (mode & IOPORT_MODE_DEBOUNCE) { +#if SAM3U || SAM3XA + base->PIO_DIFSR = mask; +#else + base->PIO_IFSCER = mask; +#endif + } else { +#if SAM3U || SAM3XA + base->PIO_SCIFSR = mask; +#else + base->PIO_IFSCDR = mask; +#endif + } + +#if !defined(IOPORT_MODE_MUX_BIT1) + if (mode & IOPORT_MODE_MUX_BIT0) { + base->PIO_ABSR |= mask; + } else { + base->PIO_ABSR &= ~mask; + } +#else + if (mode & IOPORT_MODE_MUX_BIT0) { + base->PIO_ABCDSR[0] |= mask; + } else { + base->PIO_ABCDSR[0] &= ~mask; + } + + if (mode & IOPORT_MODE_MUX_BIT1) { + base->PIO_ABCDSR[1] |= mask; + } else { + base->PIO_ABCDSR[1] &= ~mask; + } +#endif +} + +__always_inline static void arch_ioport_set_pin_mode(ioport_pin_t pin, + ioport_mode_t mode) +{ + arch_ioport_set_port_mode(arch_ioport_pin_to_port_id(pin), + arch_ioport_pin_to_mask(pin), mode); +} + +__always_inline static void arch_ioport_set_port_dir(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_direction group_direction) +{ + Pio *base = arch_ioport_port_to_base(port); + + if (group_direction == IOPORT_DIR_OUTPUT) { + base->PIO_OER = mask; + } else if (group_direction == IOPORT_DIR_INPUT) { + base->PIO_ODR = mask; + } + + base->PIO_OWER = mask; +} + +__always_inline static void arch_ioport_set_pin_dir(ioport_pin_t pin, + enum ioport_direction dir) +{ + Pio *base = arch_ioport_pin_to_base(pin); + + if (dir == IOPORT_DIR_OUTPUT) { + base->PIO_OER = arch_ioport_pin_to_mask(pin); + } else if (dir == IOPORT_DIR_INPUT) { + base->PIO_ODR = arch_ioport_pin_to_mask(pin); + } + + base->PIO_OWER = arch_ioport_pin_to_mask(pin); +} + +__always_inline static void arch_ioport_set_pin_level(ioport_pin_t pin, + bool level) +{ + Pio *base = arch_ioport_pin_to_base(pin); + + if (level) { + base->PIO_SODR = arch_ioport_pin_to_mask(pin); + } else { + base->PIO_CODR = arch_ioport_pin_to_mask(pin); + } +} + +__always_inline static void arch_ioport_set_port_level(ioport_port_t port, + ioport_port_mask_t mask, ioport_port_mask_t level) +{ + Pio *base = arch_ioport_port_to_base(port); + + base->PIO_SODR = mask & level; + base->PIO_CODR = mask & ~level; +} + +__always_inline static bool arch_ioport_get_pin_level(ioport_pin_t pin) +{ + return arch_ioport_pin_to_base(pin)->PIO_PDSR & arch_ioport_pin_to_mask(pin); +} + +__always_inline static ioport_port_mask_t arch_ioport_get_port_level( + ioport_port_t port, ioport_port_mask_t mask) +{ + return arch_ioport_port_to_base(port)->PIO_PDSR & mask; +} + +__always_inline static void arch_ioport_toggle_pin_level(ioport_pin_t pin) +{ + Pio *port = arch_ioport_pin_to_base(pin); + ioport_port_mask_t mask = arch_ioport_pin_to_mask(pin); + + if (port->PIO_PDSR & arch_ioport_pin_to_mask(pin)) { + port->PIO_CODR = mask; + } else { + port->PIO_SODR = mask; + } +} + +__always_inline static void arch_ioport_toggle_port_level(ioport_port_t port, + ioport_port_mask_t mask) +{ + arch_ioport_port_to_base(port)->PIO_ODSR ^= mask; +} + +__always_inline static void arch_ioport_set_port_sense_mode(ioport_port_t port, + ioport_port_mask_t mask, enum ioport_sense pin_sense) +{ + Pio *base = arch_ioport_port_to_base(port); + /* AIMMR ELSR FRLHSR + * 0 X X IOPORT_SENSE_BOTHEDGES (Default) + * 1 0 0 IOPORT_SENSE_FALLING + * 1 0 1 IOPORT_SENSE_RISING + * 1 1 0 IOPORT_SENSE_LEVEL_LOW + * 1 1 1 IOPORT_SENSE_LEVEL_HIGH + */ + switch(pin_sense) { + case IOPORT_SENSE_LEVEL_LOW: + base->PIO_LSR = mask; + base->PIO_FELLSR = mask; + break; + case IOPORT_SENSE_LEVEL_HIGH: + base->PIO_LSR = mask; + base->PIO_REHLSR = mask; + break; + case IOPORT_SENSE_FALLING: + base->PIO_ESR = mask; + base->PIO_FELLSR = mask; + break; + case IOPORT_SENSE_RISING: + base->PIO_ESR = mask; + base->PIO_REHLSR = mask; + break; + default: + base->PIO_AIMDR = mask; + return; + } + base->PIO_AIMER = mask; +} + +__always_inline static void arch_ioport_set_pin_sense_mode(ioport_pin_t pin, + enum ioport_sense pin_sense) +{ + arch_ioport_set_port_sense_mode(arch_ioport_pin_to_port_id(pin), + arch_ioport_pin_to_mask(pin), pin_sense); +} + +#endif /* IOPORT_SAM_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/sam_uart/uart_serial.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/sam_uart/uart_serial.h new file mode 100644 index 0000000..54cbfcc --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/sam_uart/uart_serial.h @@ -0,0 +1,686 @@ +/** + * \file + * + * \brief Uart Serial for SAM. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef _UART_SERIAL_H_ +#define _UART_SERIAL_H_ + +#include "compiler.h" +#include "sysclk.h" +#if (SAMG55) +#include "flexcom.h" +#endif +#if ((!SAM4L) && (!SAMG55)) +#include "uart.h" +#endif +#include "usart.h" + +/** + * \name Serial Management Configuration + */ +//! @{ +#include "conf_uart_serial.h" + +//! @} + +/** Input parameters when initializing RS232 and similar modes. */ +typedef struct uart_rs232_options { + /** Set baud rate of the USART (unused in slave modes). */ + uint32_t baudrate; + + /** Number of bits to transmit as a character (5 to 9). */ + uint32_t charlength; + + /** + * Parity type: USART_PMODE_DISABLED_gc, USART_PMODE_EVEN_gc, + * USART_PMODE_ODD_gc. + */ + uint32_t paritytype; + + /** + * Number of stop bits between two characters: + * true: 2 stop bits + * false: 1 stop bit + */ + bool stopbits; + +} usart_rs232_options_t; + +typedef usart_rs232_options_t usart_serial_options_t; + +typedef Usart *usart_if; + +/** + * \brief Initializes the Usart in master mode. + * + * \param p_usart Base address of the USART instance. + * \param opt Options needed to set up RS232 communication (see + * \ref usart_options_t). + */ +static inline void usart_serial_init(usart_if p_usart, + usart_serial_options_t *opt) +{ +#if ((!SAM4L) && (!SAMG55)) + sam_uart_opt_t uart_settings; + uart_settings.ul_mck = sysclk_get_peripheral_hz(); + uart_settings.ul_baudrate = opt->baudrate; + uart_settings.ul_mode = opt->paritytype; +#endif + + sam_usart_opt_t usart_settings; + usart_settings.baudrate = opt->baudrate; + usart_settings.char_length = opt->charlength; + usart_settings.parity_type = opt->paritytype; + usart_settings.stop_bits= opt->stopbits; + usart_settings.channel_mode= US_MR_CHMODE_NORMAL; + +#ifdef UART + if (UART == (Uart*)p_usart) { + sysclk_enable_peripheral_clock(ID_UART); + /* Configure UART */ + uart_init((Uart*)p_usart, &uart_settings); + } +#else +# ifdef UART0 + if (UART0 == (Uart*)p_usart) { + sysclk_enable_peripheral_clock(ID_UART0); + /* Configure UART */ + uart_init((Uart*)p_usart, &uart_settings); + } +# endif +# ifdef UART1 + if (UART1 == (Uart*)p_usart) { + sysclk_enable_peripheral_clock(ID_UART1); + /* Configure UART */ + uart_init((Uart*)p_usart, &uart_settings); + } +# endif +# ifdef UART2 + if (UART2 == (Uart*)p_usart) { + sysclk_enable_peripheral_clock(ID_UART2); + /* Configure UART */ + uart_init((Uart*)p_usart, &uart_settings); + } +# endif +# ifdef UART3 + if (UART3 == (Uart*)p_usart) { + sysclk_enable_peripheral_clock(ID_UART3); + /* Configure UART */ + uart_init((Uart*)p_usart, &uart_settings); + } +# endif +#endif /* ifdef UART */ + + +#ifdef USART + if (USART == p_usart) { +#if (!SAM4L) + sysclk_enable_peripheral_clock(ID_USART); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +#else +# ifdef USART0 + if (USART0 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM0); + flexcom_set_opmode(FLEXCOM0, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART0); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART1 + if (USART1 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM1); + flexcom_set_opmode(FLEXCOM1, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART1); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART2 + if (USART2 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM2); + flexcom_set_opmode(FLEXCOM2, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART2); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART3 + if (USART3 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM3); + flexcom_set_opmode(FLEXCOM3, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART3); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART4 + if (USART4 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM4); + flexcom_set_opmode(FLEXCOM4, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART4); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART5 + if (USART5 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM5); + flexcom_set_opmode(FLEXCOM5, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART5); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART6 + if (USART6 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM6); + flexcom_set_opmode(FLEXCOM6, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART6); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif +# ifdef USART7 + if (USART7 == p_usart) { +#if (!SAM4L) +#if (SAMG55) + flexcom_enable(FLEXCOM7); + flexcom_set_opmode(FLEXCOM7, FLEXCOM_USART); +#else + sysclk_enable_peripheral_clock(ID_USART7); +#endif + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_hz()); +#endif +#if (SAM4L) + sysclk_enable_peripheral_clock(p_usart); + /* Configure USART */ + usart_init_rs232(p_usart, &usart_settings, + sysclk_get_peripheral_bus_hz(p_usart)); +#endif + /* Enable the receiver and transmitter. */ + usart_enable_tx(p_usart); + usart_enable_rx(p_usart); + } +# endif + +#endif /* ifdef USART */ + +} + +/** + * \brief Sends a character with the USART. + * + * \param p_usart Base address of the USART instance. + * \param c Character to write. + * + * \return Status. + * \retval 1 The character was written. + * \retval 0 The function timed out before the USART transmitter became + * ready to send. + */ +static inline int usart_serial_putchar(usart_if p_usart, const uint8_t c) +{ +#ifdef UART + if (UART == (Uart*)p_usart) { + while (uart_write((Uart*)p_usart, c)!=0); + return 1; + } +#else +# ifdef UART0 + if (UART0 == (Uart*)p_usart) { + while (uart_write((Uart*)p_usart, c)!=0); + return 1; + } +# endif +# ifdef UART1 + if (UART1 == (Uart*)p_usart) { + while (uart_write((Uart*)p_usart, c)!=0); + return 1; + } +# endif +# ifdef UART2 + if (UART2 == (Uart*)p_usart) { + while (uart_write((Uart*)p_usart, c)!=0); + return 1; + } +# endif +# ifdef UART3 + if (UART3 == (Uart*)p_usart) { + while (uart_write((Uart*)p_usart, c)!=0); + return 1; + } +# endif +#endif /* ifdef UART */ + + +#ifdef USART + if (USART == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +#else +# ifdef USART0 + if (USART0 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART1 + if (USART1 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART2 + if (USART2 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART3 + if (USART3 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART4 + if (USART4 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART5 + if (USART5 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART6 + if (USART6 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +# ifdef USART7 + if (USART7 == p_usart) { + while (usart_write(p_usart, c)!=0); + return 1; + } +# endif +#endif /* ifdef USART */ + + return 0; +} +/** + * \brief Waits until a character is received, and returns it. + * + * \param p_usart Base address of the USART instance. + * \param data Data to read + * + */ +static inline void usart_serial_getchar(usart_if p_usart, uint8_t *data) +{ + uint32_t val = 0; + + /* Avoid Cppcheck Warning */ + UNUSED(val); + +#ifdef UART + if (UART == (Uart*)p_usart) { + while (uart_read((Uart*)p_usart, data)); + } +#else +# ifdef UART0 + if (UART0 == (Uart*)p_usart) { + while (uart_read((Uart*)p_usart, data)); + } +# endif +# ifdef UART1 + if (UART1 == (Uart*)p_usart) { + while (uart_read((Uart*)p_usart, data)); + } +# endif +# ifdef UART2 + if (UART2 == (Uart*)p_usart) { + while (uart_read((Uart*)p_usart, data)); + } +# endif +# ifdef UART3 + if (UART3 == (Uart*)p_usart) { + while (uart_read((Uart*)p_usart, data)); + } +# endif +#endif /* ifdef UART */ + + +#ifdef USART + if (USART == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +#else +# ifdef USART0 + if (USART0 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART1 + if (USART1 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART2 + if (USART2 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART3 + if (USART3 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART4 + if (USART4 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART5 + if (USART5 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART6 + if (USART6 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +# ifdef USART7 + if (USART7 == p_usart) { + while (usart_read(p_usart, &val)); + *data = (uint8_t)(val & 0xFF); + } +# endif +#endif /* ifdef USART */ + +} + +/** + * \brief Check if Received data is ready. + * + * \param p_usart Base address of the USART instance. + * + * \retval 1 One data has been received. + * \retval 0 No data has been received. + */ +static inline uint32_t usart_serial_is_rx_ready(usart_if p_usart) +{ +#ifdef UART + if (UART == (Uart*)p_usart) { + return uart_is_rx_ready((Uart*)p_usart); + } +#else +# ifdef UART0 + if (UART0 == (Uart*)p_usart) { + return uart_is_rx_ready((Uart*)p_usart); + } +# endif +# ifdef UART1 + if (UART1 == (Uart*)p_usart) { + return uart_is_rx_ready((Uart*)p_usart); + } +# endif +# ifdef UART2 + if (UART2 == (Uart*)p_usart) { + return uart_is_rx_ready((Uart*)p_usart); + } +# endif +# ifdef UART3 + if (UART3 == (Uart*)p_usart) { + return uart_is_rx_ready((Uart*)p_usart); + } +# endif +#endif /* ifdef UART */ + + +#ifdef USART + if (USART == p_usart) { + return usart_is_rx_ready(p_usart); + } +#else +# ifdef USART0 + if (USART0 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART1 + if (USART1 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART2 + if (USART2 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART3 + if (USART3 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART4 + if (USART4 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART5 + if (USART5 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART6 + if (USART6 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +# ifdef USART7 + if (USART7 == p_usart) { + return usart_is_rx_ready(p_usart); + } +# endif +#endif /* ifdef USART */ + + return 0; +} + +/** + * \brief Send a sequence of bytes to a USART device + * + * \param usart Base address of the USART instance. + * \param data data buffer to write + * \param len Length of data + * + */ +status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, + size_t len); + +/** + * \brief Receive a sequence of bytes to a USART device + * + * \param usart Base address of the USART instance. + * \param data data buffer to write + * \param len Length of data + * + */ +status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, + size_t len); + +#endif /* _UART_SERIAL_H_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/serial.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/serial.h new file mode 100644 index 0000000..abd2669 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/serial.h @@ -0,0 +1,269 @@ +/** + * \file + * + * \brief Serial Mode management + * + * Copyright (c) 2010 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef SERIAL_H_INCLUDED +#define SERIAL_H_INCLUDED + +#include +#include "status_codes.h" + +/** + * \typedef usart_if + * + * This type can be used independently to refer to USART module for the + * architecture used. It refers to the correct type definition for the + * architecture, ie. USART_t* for XMEGA or avr32_usart_t* for UC3. + */ + +#if XMEGA +# include "xmega_usart/usart_serial.h" +#elif MEGA_RF +# include "megarf_usart/usart_serial.h" +#elif UC3 +# include "uc3_usart/usart_serial.h" +#elif (SAM0) +#include "sam0_usart/usart_serial.h" +#elif SAM +# include "sam_uart/uart_serial.h" +#else +# error Unsupported chip type +#endif + +/** + * + * \defgroup serial_group Serial Interface (Serial) + * + * See \ref serial_quickstart. + * + * This is the common API for serial interface. Additional features are available + * in the documentation of the specific modules. + * + * \section serial_group_platform Platform Dependencies + * + * The serial API is partially chip- or platform-specific. While all + * platforms provide mostly the same functionality, there are some + * variations around how different bus types and clock tree structures + * are handled. + * + * The following functions are available on all platforms, but there may + * be variations in the function signature (i.e. parameters) and + * behaviour. These functions are typically called by platform-specific + * parts of drivers, and applications that aren't intended to be + * portable: + * - usart_serial_init() + * - usart_serial_putchar() + * - usart_serial_getchar() + * - usart_serial_write_packet() + * - usart_serial_read_packet() + * + * + * @{ + */ + +//! @} + +/** + * \page serial_quickstart Quick start guide for Serial Interface service + * + * This is the quick start guide for the \ref serial_group "Serial Interface module", with + * step-by-step instructions on how to configure and use the serial in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section serial_use_cases Serial use cases + * - \ref serial_basic_use_case + * - \subpage serial_use_case_1 + * + * \section serial_basic_use_case Basic use case - transmit a character + * In this use case, the serial module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section serial_basic_use_case_setup Setup steps + * + * \subsection serial_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclk)" + * + * \subsection serial_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_serial.h file, but it can also be added to your main application file.) + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * A variable for the received byte must be added: + * \code uint8_t received_byte; \endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + + usart_serial_init(USART_SERIAL, &usart_options); +\endcode + * + * \subsection serial_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * -# Create serial USART options struct: + * - \code + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Initialize the serial service: + * - \code usart_serial_init(USART_SERIAL, &usart_options);\endcode + * + * \section serial_basic_use_case_usage Usage steps + * + * \subsection serial_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + usart_serial_getchar(USART_SERIAL, &received_byte); + usart_serial_putchar(USART_SERIAL, received_byte); +\endcode + * + * \subsection serial_basic_use_case_usage_flow Workflow + * -# Wait for reception of a character: + * - \code usart_serial_getchar(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * - \code usart_serial_putchar(USART_SERIAL, received_byte); \endcode + */ + +/** + * \page serial_use_case_1 Advanced use case - Send a packet of serial data + * + * In this use case, the USART module is configured for: + * - Using USARTD0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case sends a string of text through the USART. + * + * \section serial_use_case_1_setup Setup steps + * + * \subsection serial_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclk)" + * + * \subsection serial_use_case_1_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_serial.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL &USARTD0 + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH USART_CHSIZE_8BIT_gc + #define USART_SERIAL_PARITY USART_PMODE_DISABLED_gc + #define USART_SERIAL_STOP_BIT false +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; + + usart_serial_init(USART_SERIAL, &usart_options); +\endcode + * + * \subsection serial_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * - \code sysclk_init(); \endcode + * -# Create USART options struct: + * - \code + static usart_serial_options_t usart_options = { + .baudrate = USART_SERIAL_BAUDRATE, + .charlength = USART_SERIAL_CHAR_LENGTH, + .paritytype = USART_SERIAL_PARITY, + .stopbits = USART_SERIAL_STOP_BIT + }; +\endcode + * -# Initialize in RS232 mode: + * - \code usart_serial_init(USART_SERIAL_EXAMPLE, &usart_options); \endcode + * + * \section serial_use_case_1_usage Usage steps + * + * \subsection serial_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); +\endcode + * + * \subsection serial_use_case_1_usage_flow Workflow + * -# Write a string of text to the USART: + * - \code usart_serial_write_packet(USART_SERIAL, "Test String", strlen("Test String")); \endcode + */ + +#endif /* SERIAL_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/usart_serial.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/usart_serial.c new file mode 100644 index 0000000..02e02ba --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/serial/usart_serial.c @@ -0,0 +1,87 @@ +/** + * + * \file + * + * \brief USART Serial driver functions. + * + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#include "serial.h" + +/** + * \brief Send a sequence of bytes to USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to read + * \param len Length of data + * + */ +status_code_t usart_serial_write_packet(usart_if usart, const uint8_t *data, + size_t len) +{ + while (len) { + usart_serial_putchar(usart, *data); + len--; + data++; + } + return STATUS_OK; +} + + +/** + * \brief Receive a sequence of bytes from USART device + * + * \param usart Base address of the USART instance. + * \param data Data buffer to write + * \param len Length of data + * + */ +status_code_t usart_serial_read_packet(usart_if usart, uint8_t *data, + size_t len) +{ + while (len) { + usart_serial_getchar(usart, data); + len--; + data++; + } + return STATUS_OK; +} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.c new file mode 100644 index 0000000..09be2d4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.c @@ -0,0 +1,644 @@ +/***************************************************************************** + * + * \file + * + * \brief Abstraction layer for memory interfaces. + * + * This module contains the interfaces: + * - MEM <-> USB; + * - MEM <-> RAM; + * - MEM <-> MEM. + * + * This module may be configured and expanded to support the following features: + * - write-protected globals; + * - password-protected data; + * - specific features; + * - etc. + * + * Copyright (c) 2009 - 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 + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + + +//_____ I N C L U D E S ____________________________________________________ + +#include "compiler.h" +#include "preprocessor.h" +#ifdef FREERTOS_USED +#include "FreeRTOS.h" +#include "semphr.h" +#endif +#include "ctrl_access.h" + + +//_____ D E F I N I T I O N S ______________________________________________ + +#ifdef FREERTOS_USED + +/*! \name LUN Access Protection Macros + */ +//! @{ + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +#define Ctrl_access_lock() ctrl_access_lock() + +/*! \brief Unlocks accesses to LUNs. + */ +#define Ctrl_access_unlock() xSemaphoreGive(ctrl_access_semphr) + +//! @} + +//! Handle to the semaphore protecting accesses to LUNs. +static xSemaphoreHandle ctrl_access_semphr = NULL; + +#else + +/*! \name LUN Access Protection Macros + */ +//! @{ + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +#define Ctrl_access_lock() true + +/*! \brief Unlocks accesses to LUNs. + */ +#define Ctrl_access_unlock() + +//! @} + +#endif // FREERTOS_USED + + +#if MAX_LUN + +/*! \brief Initializes an entry of the LUN descriptor table. + * + * \param lun Logical Unit Number. + * + * \return LUN descriptor table entry initializer. + */ +#if ACCESS_USB == true && ACCESS_MEM_TO_RAM == true +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _unload),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _usb_read_10),\ + TPASTE3(Lun_, lun, _usb_write_10),\ + TPASTE3(Lun_, lun, _mem_2_ram),\ + TPASTE3(Lun_, lun, _ram_2_mem),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#elif ACCESS_USB == true +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _unload),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _usb_read_10),\ + TPASTE3(Lun_, lun, _usb_write_10),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#elif ACCESS_MEM_TO_RAM == true +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _unload),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(Lun_, lun, _mem_2_ram),\ + TPASTE3(Lun_, lun, _ram_2_mem),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#else +#define Lun_desc_entry(lun) \ + {\ + TPASTE3(Lun_, lun, _test_unit_ready),\ + TPASTE3(Lun_, lun, _read_capacity),\ + TPASTE3(Lun_, lun, _unload),\ + TPASTE3(Lun_, lun, _wr_protect),\ + TPASTE3(Lun_, lun, _removal),\ + TPASTE3(LUN_, lun, _NAME)\ + } +#endif + +//! LUN descriptor table. +static const struct +{ + Ctrl_status (*test_unit_ready)(void); + Ctrl_status (*read_capacity)(U32 *); + bool (*unload)(bool); + bool (*wr_protect)(void); + bool (*removal)(void); +#if ACCESS_USB == true + Ctrl_status (*usb_read_10)(U32, U16); + Ctrl_status (*usb_write_10)(U32, U16); +#endif +#if ACCESS_MEM_TO_RAM == true + Ctrl_status (*mem_2_ram)(U32, void *); + Ctrl_status (*ram_2_mem)(U32, const void *); +#endif + const char *name; +} lun_desc[MAX_LUN] = +{ +#if LUN_0 == ENABLE +# ifndef Lun_0_unload +# define Lun_0_unload NULL +# endif + Lun_desc_entry(0), +#endif +#if LUN_1 == ENABLE +# ifndef Lun_1_unload +# define Lun_1_unload NULL +# endif + Lun_desc_entry(1), +#endif +#if LUN_2 == ENABLE +# ifndef Lun_2_unload +# define Lun_2_unload NULL +# endif + Lun_desc_entry(2), +#endif +#if LUN_3 == ENABLE +# ifndef Lun_3_unload +# define Lun_3_unload NULL +# endif + Lun_desc_entry(3), +#endif +#if LUN_4 == ENABLE +# ifndef Lun_4_unload +# define Lun_4_unload NULL +# endif + Lun_desc_entry(4), +#endif +#if LUN_5 == ENABLE +# ifndef Lun_5_unload +# define Lun_5_unload NULL +# endif + Lun_desc_entry(5), +#endif +#if LUN_6 == ENABLE +# ifndef Lun_6_unload +# define Lun_6_unload NULL +# endif + Lun_desc_entry(6), +#endif +#if LUN_7 == ENABLE +# ifndef Lun_7_unload +# define Lun_7_unload NULL +# endif + Lun_desc_entry(7) +#endif +}; + +#endif + + +#if GLOBAL_WR_PROTECT == true +bool g_wr_protect; +#endif + + +/*! \name Control Interface + */ +//! @{ + + +#ifdef FREERTOS_USED + +bool ctrl_access_init(void) +{ + // If the handle to the protecting semaphore is not valid, + if (!ctrl_access_semphr) + { + // try to create the semaphore. + vSemaphoreCreateBinary(ctrl_access_semphr); + + // If the semaphore could not be created, there is no backup solution. + if (!ctrl_access_semphr) return false; + } + + return true; +} + + +/*! \brief Locks accesses to LUNs. + * + * \return \c true if the access was successfully locked, else \c false. + */ +static bool ctrl_access_lock(void) +{ + // If the semaphore could not be created, there is no backup solution. + if (!ctrl_access_semphr) return false; + + // Wait for the semaphore. + while (!xSemaphoreTake(ctrl_access_semphr, portMAX_DELAY)); + + return true; +} + +#endif // FREERTOS_USED + + +U8 get_nb_lun(void) +{ +#if MEM_USB == ENABLE +# ifndef Lun_usb_get_lun +# define Lun_usb_get_lun() host_get_lun() +# endif + U8 nb_lun; + + if (!Ctrl_access_lock()) return MAX_LUN; + + nb_lun = MAX_LUN + Lun_usb_get_lun(); + + Ctrl_access_unlock(); + + return nb_lun; +#else + return MAX_LUN; +#endif +} + + +U8 get_cur_lun(void) +{ + return LUN_ID_0; +} + + +Ctrl_status mem_test_unit_ready(U8 lun) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].test_unit_ready() : +#endif +#if LUN_USB == ENABLE + Lun_usb_test_unit_ready(lun - LUN_ID_USB); +#else + CTRL_FAIL; +#endif + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].read_capacity(u32_nb_sector) : +#endif +#if LUN_USB == ENABLE + Lun_usb_read_capacity(lun - LUN_ID_USB, u32_nb_sector); +#else + CTRL_FAIL; +#endif + + Ctrl_access_unlock(); + + return status; +} + + +U8 mem_sector_size(U8 lun) +{ + U8 sector_size; + + if (!Ctrl_access_lock()) return 0; + + sector_size = +#if MAX_LUN + (lun < MAX_LUN) ? 1 : +#endif +#if LUN_USB == ENABLE + Lun_usb_read_sector_size(lun - LUN_ID_USB); +#else + 0; +#endif + + Ctrl_access_unlock(); + + return sector_size; +} + + +bool mem_unload(U8 lun, bool unload) +{ + bool unloaded; +#if !MAX_LUN || !defined(Lun_usb_unload) + UNUSED(lun); +#endif + + if (!Ctrl_access_lock()) return false; + + unloaded = +#if MAX_LUN + (lun < MAX_LUN) ? + (lun_desc[lun].unload ? + lun_desc[lun].unload(unload) : !unload) : +#endif +#if LUN_USB == ENABLE +# if defined(Lun_usb_unload) + Lun_usb_unload(lun - LUN_ID_USB, unload); +# else + !unload; /* Can not unload: load success, unload fail */ +# endif +#else + false; /* No mem, unload/load fail */ +#endif + + Ctrl_access_unlock(); + + return unloaded; +} + +bool mem_wr_protect(U8 lun) +{ + bool wr_protect; + + if (!Ctrl_access_lock()) return true; + + wr_protect = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].wr_protect() : +#endif +#if LUN_USB == ENABLE + Lun_usb_wr_protect(lun - LUN_ID_USB); +#else + true; +#endif + + Ctrl_access_unlock(); + + return wr_protect; +} + + +bool mem_removal(U8 lun) +{ + bool removal; +#if MAX_LUN==0 + UNUSED(lun); +#endif + + if (!Ctrl_access_lock()) return true; + + removal = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].removal() : +#endif +#if LUN_USB == ENABLE + Lun_usb_removal(); +#else + true; +#endif + + Ctrl_access_unlock(); + + return removal; +} + + +const char *mem_name(U8 lun) +{ +#if MAX_LUN==0 + UNUSED(lun); +#endif + return +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].name : +#endif +#if LUN_USB == ENABLE + LUN_USB_NAME; +#else + NULL; +#endif +} + + +//! @} + + +#if ACCESS_USB == true + +/*! \name MEM <-> USB Interface + */ +//! @{ + + +Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_read_action(nb_sector); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].usb_read_10(addr, nb_sector) : +#endif + CTRL_FAIL; + memory_stop_read_action(); + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector) +{ + Ctrl_status status; + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_write_action(nb_sector); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].usb_write_10(addr, nb_sector) : +#endif + CTRL_FAIL; + memory_stop_write_action(); + + Ctrl_access_unlock(); + + return status; +} + + +//! @} + +#endif // ACCESS_USB == true + + +#if ACCESS_MEM_TO_RAM == true + +/*! \name MEM <-> RAM Interface + */ +//! @{ + + +Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram) +{ + Ctrl_status status; +#if MAX_LUN==0 + UNUSED(lun); +#endif + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_read_action(1); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].mem_2_ram(addr, ram) : +#endif +#if LUN_USB == ENABLE + Lun_usb_mem_2_ram(addr, ram); +#else + CTRL_FAIL; +#endif + memory_stop_read_action(); + + Ctrl_access_unlock(); + + return status; +} + + +Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram) +{ + Ctrl_status status; +#if MAX_LUN==0 + UNUSED(lun); +#endif + + if (!Ctrl_access_lock()) return CTRL_FAIL; + + memory_start_write_action(1); + status = +#if MAX_LUN + (lun < MAX_LUN) ? lun_desc[lun].ram_2_mem(addr, ram) : +#endif +#if LUN_USB == ENABLE + Lun_usb_ram_2_mem(addr, ram); +#else + CTRL_FAIL; +#endif + memory_stop_write_action(); + + Ctrl_access_unlock(); + + return status; +} + + +//! @} + +#endif // ACCESS_MEM_TO_RAM == true + + +#if ACCESS_STREAM == true + +/*! \name Streaming MEM <-> MEM Interface + */ +//! @{ + + + #if ACCESS_MEM_TO_MEM == true + +#include "fat.h" + +Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector) +{ + COMPILER_ALIGNED(4) + static U8 sector_buf[FS_512B]; + Ctrl_status status = CTRL_GOOD; + + while (nb_sector--) + { + if ((status = memory_2_ram(src_lun, src_addr++, sector_buf)) != CTRL_GOOD) break; + if ((status = ram_2_memory(dest_lun, dest_addr++, sector_buf)) != CTRL_GOOD) break; + } + + return status; +} + + #endif // ACCESS_MEM_TO_MEM == true + + +Ctrl_status stream_state(U8 id) +{ + UNUSED(id); + return CTRL_GOOD; +} + + +U16 stream_stop(U8 id) +{ + UNUSED(id); + return 0; +} + + +//! @} + +#endif // ACCESS_STREAM == true diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.h new file mode 100644 index 0000000..8e1b520 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/services/storage/ctrl_access/ctrl_access.h @@ -0,0 +1,402 @@ +/***************************************************************************** + * + * \file + * + * \brief Abstraction layer for memory interfaces. + * + * This module contains the interfaces: + * - MEM <-> USB; + * - MEM <-> RAM; + * - MEM <-> MEM. + * + * This module may be configured and expanded to support the following features: + * - write-protected globals; + * - password-protected data; + * - specific features; + * - etc. + * + * Copyright (c) 2009 - 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 + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + + +#ifndef _CTRL_ACCESS_H_ +#define _CTRL_ACCESS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup group_common_services_storage_ctrl_access Memory Control Access + * + * Common abstraction layer for memory interfaces. It provides interfaces between: + * Memory and USB, Memory and RAM, Memory and Memory. Common API for XMEGA and UC3. + * + * \{ + */ + +#include "compiler.h" +#include "conf_access.h" + +#ifndef SECTOR_SIZE +#define SECTOR_SIZE 512 +#endif + +//! Status returned by CTRL_ACCESS interfaces. +typedef enum +{ + CTRL_GOOD = PASS, //!< Success, memory ready. + CTRL_FAIL = FAIL, //!< An error occurred. + CTRL_NO_PRESENT = FAIL + 1, //!< Memory unplugged. + CTRL_BUSY = FAIL + 2 //!< Memory not initialized or changed. +} Ctrl_status; + + +// FYI: Each Logical Unit Number (LUN) corresponds to a memory. + +// Check LUN defines. +#ifndef LUN_0 + #error LUN_0 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_1 + #error LUN_1 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_2 + #error LUN_2 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_3 + #error LUN_3 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_4 + #error LUN_4 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_5 + #error LUN_5 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_6 + #error LUN_6 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_7 + #error LUN_7 must be defined as ENABLE or DISABLE in conf_access.h +#endif +#ifndef LUN_USB + #error LUN_USB must be defined as ENABLE or DISABLE in conf_access.h +#endif + +/*! \name LUN IDs + */ +//! @{ +#define LUN_ID_0 (0) //!< First static LUN. +#define LUN_ID_1 (LUN_ID_0 + LUN_0) +#define LUN_ID_2 (LUN_ID_1 + LUN_1) +#define LUN_ID_3 (LUN_ID_2 + LUN_2) +#define LUN_ID_4 (LUN_ID_3 + LUN_3) +#define LUN_ID_5 (LUN_ID_4 + LUN_4) +#define LUN_ID_6 (LUN_ID_5 + LUN_5) +#define LUN_ID_7 (LUN_ID_6 + LUN_6) +#define MAX_LUN (LUN_ID_7 + LUN_7) //!< Number of static LUNs. +#define LUN_ID_USB (MAX_LUN) //!< First dynamic LUN (USB host mass storage). +//! @} + + +// Include LUN header files. +#if LUN_0 == ENABLE + #include LUN_0_INCLUDE +#endif +#if LUN_1 == ENABLE + #include LUN_1_INCLUDE +#endif +#if LUN_2 == ENABLE + #include LUN_2_INCLUDE +#endif +#if LUN_3 == ENABLE + #include LUN_3_INCLUDE +#endif +#if LUN_4 == ENABLE + #include LUN_4_INCLUDE +#endif +#if LUN_5 == ENABLE + #include LUN_5_INCLUDE +#endif +#if LUN_6 == ENABLE + #include LUN_6_INCLUDE +#endif +#if LUN_7 == ENABLE + #include LUN_7_INCLUDE +#endif +#if LUN_USB == ENABLE + #include LUN_USB_INCLUDE +#endif + + +// Check the configuration of write protection in conf_access.h. +#ifndef GLOBAL_WR_PROTECT + #error GLOBAL_WR_PROTECT must be defined as true or false in conf_access.h +#endif + + +#if GLOBAL_WR_PROTECT == true + +//! Write protect. +extern bool g_wr_protect; + +#endif + + +/*! \name Control Interface + */ +//! @{ + +#ifdef FREERTOS_USED + +/*! \brief Initializes the LUN access locker. + * + * \return \c true if the locker was successfully initialized, else \c false. + */ +extern bool ctrl_access_init(void); + +#endif // FREERTOS_USED + +/*! \brief Returns the number of LUNs. + * + * \return Number of LUNs in the system. + */ +extern U8 get_nb_lun(void); + +/*! \brief Returns the current LUN. + * + * \return Current LUN. + * + * \todo Implement. + */ +extern U8 get_cur_lun(void); + +/*! \brief Tests the memory state and initializes the memory if required. + * + * The TEST UNIT READY SCSI primary command allows an application client to poll + * a LUN until it is ready without having to allocate memory for returned data. + * + * This command may be used to check the media status of LUNs with removable + * media. + * + * \param lun Logical Unit Number. + * + * \return Status. + */ +extern Ctrl_status mem_test_unit_ready(U8 lun); + +/*! \brief Returns the address of the last valid sector (512 bytes) in the + * memory. + * + * \param lun Logical Unit Number. + * \param u32_nb_sector Pointer to the address of the last valid sector. + * + * \return Status. + */ +extern Ctrl_status mem_read_capacity(U8 lun, U32 *u32_nb_sector); + +/*! \brief Returns the size of the physical sector. + * + * \param lun Logical Unit Number. + * + * \return Sector size (unit: 512 bytes). + */ +extern U8 mem_sector_size(U8 lun); + +/*! \brief Unload/load the medium. + * + * \param lun Logical Unit Number. + * \param unload \c true to unload the medium, \c false to load the medium. + * + * \return \c true if unload/load success, else \c false. + */ +extern bool mem_unload(U8 lun, bool unload); + +/*! \brief Returns the write-protection state of the memory. + * + * \param lun Logical Unit Number. + * + * \return \c true if the memory is write-protected, else \c false. + * + * \note Only used by removable memories with hardware-specific write + * protection. + */ +extern bool mem_wr_protect(U8 lun); + +/*! \brief Tells whether the memory is removable. + * + * \param lun Logical Unit Number. + * + * \return \c true if the memory is removable, else \c false. + */ +extern bool mem_removal(U8 lun); + +/*! \brief Returns a pointer to the LUN name. + * + * \param lun Logical Unit Number. + * + * \return Pointer to the LUN name string. + */ +extern const char *mem_name(U8 lun); + +//! @} + + +#if ACCESS_USB == true + +/*! \name MEM <-> USB Interface + */ +//! @{ + +/*! \brief Transfers data from the memory to USB. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to read. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status memory_2_usb(U8 lun, U32 addr, U16 nb_sector); + +/*! \brief Transfers data from USB to the memory. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to write. + * \param nb_sector Number of sectors to transfer. + * + * \return Status. + */ +extern Ctrl_status usb_2_memory(U8 lun, U32 addr, U16 nb_sector); + +//! @} + +#endif // ACCESS_USB == true + + +#if ACCESS_MEM_TO_RAM == true + +/*! \name MEM <-> RAM Interface + */ +//! @{ + +/*! \brief Copies 1 data sector from the memory to RAM. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to read. + * \param ram Pointer to RAM buffer to write. + * + * \return Status. + */ +extern Ctrl_status memory_2_ram(U8 lun, U32 addr, void *ram); + +/*! \brief Copies 1 data sector from RAM to the memory. + * + * \param lun Logical Unit Number. + * \param addr Address of first memory sector to write. + * \param ram Pointer to RAM buffer to read. + * + * \return Status. + */ +extern Ctrl_status ram_2_memory(U8 lun, U32 addr, const void *ram); + +//! @} + +#endif // ACCESS_MEM_TO_RAM == true + + +#if ACCESS_STREAM == true + +/*! \name Streaming MEM <-> MEM Interface + */ +//! @{ + +//! Erroneous streaming data transfer ID. +#define ID_STREAM_ERR 0xFF + + #if ACCESS_MEM_TO_MEM == true + +/*! \brief Copies data from one memory to another. + * + * \param src_lun Source Logical Unit Number. + * \param src_addr Source address of first memory sector to read. + * \param dest_lun Destination Logical Unit Number. + * \param dest_addr Destination address of first memory sector to write. + * \param nb_sector Number of sectors to copy. + * + * \return Status. + */ +extern Ctrl_status stream_mem_to_mem(U8 src_lun, U32 src_addr, U8 dest_lun, U32 dest_addr, U16 nb_sector); + + #endif // ACCESS_MEM_TO_MEM == true + +/*! \brief Returns the state of a streaming data transfer. + * + * \param id Transfer ID. + * + * \return Status. + * + * \todo Implement. + */ +extern Ctrl_status stream_state(U8 id); + +/*! \brief Stops a streaming data transfer. + * + * \param id Transfer ID. + * + * \return Number of remaining sectors. + * + * \todo Implement. + */ +extern U16 stream_stop(U8 id); + +//! @} + +#endif // ACCESS_STREAM == true + +/** + * \} + */ + +#ifdef __cplusplus +} +#endif + +#endif // _CTRL_ACCESS_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt.h new file mode 100644 index 0000000..0f929e7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt.h @@ -0,0 +1,142 @@ +/** + * \file + * + * \brief Global interrupt management for 8- and 32-bit AVR + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef UTILS_INTERRUPT_H +#define UTILS_INTERRUPT_H + +#include + +#if XMEGA || MEGA || TINY +# include "interrupt/interrupt_avr8.h" +#elif UC3 +# include "interrupt/interrupt_avr32.h" +#elif SAM +# include "interrupt/interrupt_sam_nvic.h" +#else +# error Unsupported device. +#endif + +/** + * \defgroup interrupt_group Global interrupt management + * + * This is a driver for global enabling and disabling of interrupts. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \def CONFIG_INTERRUPT_FORCE_INTC + * \brief Force usage of the ASF INTC driver + * + * Predefine this symbol when preprocessing to force the use of the ASF INTC driver. + * This is useful to ensure compatibility across compilers and shall be used only when required + * by the application needs. + */ +# define CONFIG_INTERRUPT_FORCE_INTC +#endif + +//! \name Global interrupt flags +//@{ +/** + * \typedef irqflags_t + * \brief Type used for holding state of interrupt flag + */ + +/** + * \def cpu_irq_enable + * \brief Enable interrupts globally + */ + +/** + * \def cpu_irq_disable + * \brief Disable interrupts globally + */ + +/** + * \fn irqflags_t cpu_irq_save(void) + * \brief Get and clear the global interrupt flags + * + * Use in conjunction with \ref cpu_irq_restore. + * + * \return Current state of interrupt flags. + * + * \note This function leaves interrupts disabled. + */ + +/** + * \fn void cpu_irq_restore(irqflags_t flags) + * \brief Restore global interrupt flags + * + * Use in conjunction with \ref cpu_irq_save. + * + * \param flags State to set interrupt flag to. + */ + +/** + * \fn bool cpu_irq_is_enabled_flags(irqflags_t flags) + * \brief Check if interrupts are globally enabled in supplied flags + * + * \param flags Currents state of interrupt flags. + * + * \return True if interrupts are enabled. + */ + +/** + * \def cpu_irq_is_enabled + * \brief Check if interrupts are globally enabled + * + * \return True if interrupts are enabled. + */ +//@} + +//! @} + +/** + * \ingroup interrupt_group + * \defgroup interrupt_deprecated_group Deprecated interrupt definitions + */ + +#endif /* UTILS_INTERRUPT_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.c new file mode 100644 index 0000000..4b5abb4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.c @@ -0,0 +1,86 @@ +/** + * \file + * + * \brief 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "interrupt_sam_nvic.h" + +#if !defined(__DOXYGEN__) +/* Deprecated - global flag to determine the global interrupt state. Required by + * QTouch library, however new applications should use cpu_irq_is_enabled() + * which probes the true global interrupt state from the CPU special registers. + */ +volatile bool g_interrupt_enabled = true; +#endif + +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 */ + Assert(cpu_irq_critical_section_counter > 0); + + 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/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.h new file mode 100644 index 0000000..d56ba69 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/interrupt/interrupt_sam_nvic.h @@ -0,0 +1,189 @@ +/** + * \file + * + * \brief 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef UTILS_INTERRUPT_INTERRUPT_H +#define UTILS_INTERRUPT_INTERRUPT_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \weakgroup interrupt_group + * + * @{ + */ + +/** + * \name Interrupt Service Routine definition + * + * @{ + */ + +/** + * \brief Define service routine + * + * \note For NVIC devices the interrupt service routines are predefined to + * add to vector table in binary generation, so there is no service + * register at run time. The routine collections are in exceptions.h. + * + * Usage: + * \code + ISR(foo_irq_handler) + { + // Function definition + ... + } +\endcode + * + * \param func Name for the function. + */ +# define ISR(func) \ + void func (void) + +/** + * \brief Initialize interrupt vectors + * + * For NVIC the interrupt vectors are put in vector table. So nothing + * to do to initialize them, except defined the vector function with + * right name. + * + * This must be called prior to \ref irq_register_handler. + */ +# define irq_initialize_vectors() \ + do { \ + } while(0) + +/** + * \brief Register handler for interrupt + * + * For NVIC the interrupt vectors are put in vector table. So nothing + * to do to register them, except defined the vector function with + * right name. + * + * Usage: + * \code + irq_initialize_vectors(); + irq_register_handler(foo_irq_handler); +\endcode + * + * \note The function \a func must be defined with the \ref ISR macro. + * \note The functions prototypes can be found in the device exception header + * files (exceptions.h). + */ +# define irq_register_handler(int_num, int_prio) \ + NVIC_ClearPendingIRQ( (IRQn_Type)int_num); \ + NVIC_SetPriority( (IRQn_Type)int_num, int_prio); \ + NVIC_EnableIRQ( (IRQn_Type)int_num); \ + +//@} + +# define cpu_irq_enable() \ + do { \ + g_interrupt_enabled = true; \ + __DMB(); \ + __enable_irq(); \ + } while (0) +# define cpu_irq_disable() \ + do { \ + __disable_irq(); \ + __DMB(); \ + g_interrupt_enabled = false; \ + } while (0) + +typedef uint32_t irqflags_t; + +#if !defined(__DOXYGEN__) +extern volatile bool g_interrupt_enabled; +#endif + +#define cpu_irq_is_enabled() (__get_PRIMASK() == 0) + +static volatile uint32_t cpu_irq_critical_section_counter; +static volatile bool cpu_irq_prev_interrupt_state; + +static inline irqflags_t cpu_irq_save(void) +{ + irqflags_t flags = cpu_irq_is_enabled(); + cpu_irq_disable(); + return flags; +} + +static inline bool cpu_irq_is_enabled_flags(irqflags_t flags) +{ + return (flags); +} + +static inline void cpu_irq_restore(irqflags_t flags) +{ + if (cpu_irq_is_enabled_flags(flags)) + cpu_irq_enable(); +} + +void cpu_irq_enter_critical(void); +void cpu_irq_leave_critical(void); + +/** + * \weakgroup interrupt_deprecated_group + * @{ + */ + +#define Enable_global_interrupt() cpu_irq_enable() +#define Disable_global_interrupt() cpu_irq_disable() +#define Is_global_interrupt_enabled() cpu_irq_is_enabled() + +//@} + +//@} + +#ifdef __cplusplus +} +#endif + +#endif /* UTILS_INTERRUPT_INTERRUPT_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/parts.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/parts.h new file mode 100644 index 0000000..30d32ab --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/parts.h @@ -0,0 +1,1280 @@ +/** + * \file + * + * \brief Atmel part identification macros + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef ATMEL_PARTS_H +#define ATMEL_PARTS_H + +/** + * \defgroup part_macros_group Atmel part identification macros + * + * This collection of macros identify which series and families that the various + * Atmel parts belong to. These can be used to select part-dependent sections of + * code at compile time. + * + * @{ + */ + +/** + * \name Convenience macros for part checking + * @{ + */ +/* ! Check GCC and IAR part definition for 8-bit AVR */ +#define AVR8_PART_IS_DEFINED(part) \ + (defined(__ ## part ## __) || defined(__AVR_ ## part ## __)) + +/* ! Check GCC and IAR part definition for 32-bit AVR */ +#define AVR32_PART_IS_DEFINED(part) \ + (defined(__AT32 ## part ## __) || defined(__AVR32_ ## part ## __)) + +/* ! Check GCC and IAR part definition for SAM */ +#define SAM_PART_IS_DEFINED(part) (defined(__ ## part ## __)) +/** @} */ + +/** + * \defgroup uc3_part_macros_group AVR UC3 parts + * @{ + */ + +/** + * \name AVR UC3 A series + * @{ + */ +#define UC3A0 ( \ + AVR32_PART_IS_DEFINED(UC3A0128) || \ + AVR32_PART_IS_DEFINED(UC3A0256) || \ + AVR32_PART_IS_DEFINED(UC3A0512) \ + ) + +#define UC3A1 ( \ + AVR32_PART_IS_DEFINED(UC3A1128) || \ + AVR32_PART_IS_DEFINED(UC3A1256) || \ + AVR32_PART_IS_DEFINED(UC3A1512) \ + ) + +#define UC3A3 ( \ + AVR32_PART_IS_DEFINED(UC3A364) || \ + AVR32_PART_IS_DEFINED(UC3A364S) || \ + AVR32_PART_IS_DEFINED(UC3A3128) || \ + AVR32_PART_IS_DEFINED(UC3A3128S) || \ + AVR32_PART_IS_DEFINED(UC3A3256) || \ + AVR32_PART_IS_DEFINED(UC3A3256S) \ + ) + +#define UC3A4 ( \ + AVR32_PART_IS_DEFINED(UC3A464) || \ + AVR32_PART_IS_DEFINED(UC3A464S) || \ + AVR32_PART_IS_DEFINED(UC3A4128) || \ + AVR32_PART_IS_DEFINED(UC3A4128S) || \ + AVR32_PART_IS_DEFINED(UC3A4256) || \ + AVR32_PART_IS_DEFINED(UC3A4256S) \ + ) +/** @} */ + +/** + * \name AVR UC3 B series + * @{ + */ +#define UC3B0 ( \ + AVR32_PART_IS_DEFINED(UC3B064) || \ + AVR32_PART_IS_DEFINED(UC3B0128) || \ + AVR32_PART_IS_DEFINED(UC3B0256) || \ + AVR32_PART_IS_DEFINED(UC3B0512) \ + ) + +#define UC3B1 ( \ + AVR32_PART_IS_DEFINED(UC3B164) || \ + AVR32_PART_IS_DEFINED(UC3B1128) || \ + AVR32_PART_IS_DEFINED(UC3B1256) || \ + AVR32_PART_IS_DEFINED(UC3B1512) \ + ) +/** @} */ + +/** + * \name AVR UC3 C series + * @{ + */ +#define UC3C0 ( \ + AVR32_PART_IS_DEFINED(UC3C064C) || \ + AVR32_PART_IS_DEFINED(UC3C0128C) || \ + AVR32_PART_IS_DEFINED(UC3C0256C) || \ + AVR32_PART_IS_DEFINED(UC3C0512C) \ + ) + +#define UC3C1 ( \ + AVR32_PART_IS_DEFINED(UC3C164C) || \ + AVR32_PART_IS_DEFINED(UC3C1128C) || \ + AVR32_PART_IS_DEFINED(UC3C1256C) || \ + AVR32_PART_IS_DEFINED(UC3C1512C) \ + ) + +#define UC3C2 ( \ + AVR32_PART_IS_DEFINED(UC3C264C) || \ + AVR32_PART_IS_DEFINED(UC3C2128C) || \ + AVR32_PART_IS_DEFINED(UC3C2256C) || \ + AVR32_PART_IS_DEFINED(UC3C2512C) \ + ) +/** @} */ + +/** + * \name AVR UC3 D series + * @{ + */ +#define UC3D3 ( \ + AVR32_PART_IS_DEFINED(UC64D3) || \ + AVR32_PART_IS_DEFINED(UC128D3) \ + ) + +#define UC3D4 ( \ + AVR32_PART_IS_DEFINED(UC64D4) || \ + AVR32_PART_IS_DEFINED(UC128D4) \ + ) +/** @} */ + +/** + * \name AVR UC3 L series + * @{ + */ +#define UC3L0 ( \ + AVR32_PART_IS_DEFINED(UC3L016) || \ + AVR32_PART_IS_DEFINED(UC3L032) || \ + AVR32_PART_IS_DEFINED(UC3L064) \ + ) + +#define UC3L0128 ( \ + AVR32_PART_IS_DEFINED(UC3L0128) \ + ) + +#define UC3L0256 ( \ + AVR32_PART_IS_DEFINED(UC3L0256) \ + ) + +#define UC3L3 ( \ + AVR32_PART_IS_DEFINED(UC64L3U) || \ + AVR32_PART_IS_DEFINED(UC128L3U) || \ + AVR32_PART_IS_DEFINED(UC256L3U) \ + ) + +#define UC3L4 ( \ + AVR32_PART_IS_DEFINED(UC64L4U) || \ + AVR32_PART_IS_DEFINED(UC128L4U) || \ + AVR32_PART_IS_DEFINED(UC256L4U) \ + ) + +#define UC3L3_L4 (UC3L3 || UC3L4) +/** @} */ + +/** + * \name AVR UC3 families + * @{ + */ +/** AVR UC3 A family */ +#define UC3A (UC3A0 || UC3A1 || UC3A3 || UC3A4) + +/** AVR UC3 B family */ +#define UC3B (UC3B0 || UC3B1) + +/** AVR UC3 C family */ +#define UC3C (UC3C0 || UC3C1 || UC3C2) + +/** AVR UC3 D family */ +#define UC3D (UC3D3 || UC3D4) + +/** AVR UC3 L family */ +#define UC3L (UC3L0 || UC3L0128 || UC3L0256 || UC3L3_L4) +/** @} */ + +/** AVR UC3 product line */ +#define UC3 (UC3A || UC3B || UC3C || UC3D || UC3L) + +/** @} */ + +/** + * \defgroup xmega_part_macros_group AVR XMEGA parts + * @{ + */ + +/** + * \name AVR XMEGA A series + * @{ + */ +#define XMEGA_A1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1) \ + ) + +#define XMEGA_A3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3) \ + ) + +#define XMEGA_A3B ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3B) \ + ) + +#define XMEGA_A4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA AU series + * @{ + */ +#define XMEGA_A1U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A1U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A1U) \ + ) + +#define XMEGA_A3U ( \ + AVR8_PART_IS_DEFINED(ATxmega64A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega192A3U) || \ + AVR8_PART_IS_DEFINED(ATxmega256A3U) \ + ) + +#define XMEGA_A3BU ( \ + AVR8_PART_IS_DEFINED(ATxmega256A3BU) \ + ) + +#define XMEGA_A4U ( \ + AVR8_PART_IS_DEFINED(ATxmega16A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega32A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega64A4U) || \ + AVR8_PART_IS_DEFINED(ATxmega128A4U) \ + ) +/** @} */ + +/** + * \name AVR XMEGA B series + * @{ + */ +#define XMEGA_B1 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B1) || \ + AVR8_PART_IS_DEFINED(ATxmega128B1) \ + ) + +#define XMEGA_B3 ( \ + AVR8_PART_IS_DEFINED(ATxmega64B3) || \ + AVR8_PART_IS_DEFINED(ATxmega128B3) \ + ) +/** @} */ + +/** + * \name AVR XMEGA C series + * @{ + */ +#define XMEGA_C3 ( \ + AVR8_PART_IS_DEFINED(ATxmega384C3) || \ + AVR8_PART_IS_DEFINED(ATxmega256C3) || \ + AVR8_PART_IS_DEFINED(ATxmega192C3) || \ + AVR8_PART_IS_DEFINED(ATxmega128C3) || \ + AVR8_PART_IS_DEFINED(ATxmega64C3) || \ + AVR8_PART_IS_DEFINED(ATxmega32C3) \ + ) + +#define XMEGA_C4 ( \ + AVR8_PART_IS_DEFINED(ATxmega32C4) || \ + AVR8_PART_IS_DEFINED(ATxmega16C4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA D series + * @{ + */ +#define XMEGA_D3 ( \ + AVR8_PART_IS_DEFINED(ATxmega32D3) || \ + AVR8_PART_IS_DEFINED(ATxmega64D3) || \ + AVR8_PART_IS_DEFINED(ATxmega128D3) || \ + AVR8_PART_IS_DEFINED(ATxmega192D3) || \ + AVR8_PART_IS_DEFINED(ATxmega256D3) || \ + AVR8_PART_IS_DEFINED(ATxmega384D3) \ + ) + +#define XMEGA_D4 ( \ + AVR8_PART_IS_DEFINED(ATxmega16D4) || \ + AVR8_PART_IS_DEFINED(ATxmega32D4) || \ + AVR8_PART_IS_DEFINED(ATxmega64D4) || \ + AVR8_PART_IS_DEFINED(ATxmega128D4) \ + ) +/** @} */ + +/** + * \name AVR XMEGA E series + * @{ + */ +#define XMEGA_E5 ( \ + AVR8_PART_IS_DEFINED(ATxmega8E5) || \ + AVR8_PART_IS_DEFINED(ATxmega16E5) || \ + AVR8_PART_IS_DEFINED(ATxmega32E5) \ + ) +/** @} */ + + +/** + * \name AVR XMEGA families + * @{ + */ +/** AVR XMEGA A family */ +#define XMEGA_A (XMEGA_A1 || XMEGA_A3 || XMEGA_A3B || XMEGA_A4) + +/** AVR XMEGA AU family */ +#define XMEGA_AU (XMEGA_A1U || XMEGA_A3U || XMEGA_A3BU || XMEGA_A4U) + +/** AVR XMEGA B family */ +#define XMEGA_B (XMEGA_B1 || XMEGA_B3) + +/** AVR XMEGA C family */ +#define XMEGA_C (XMEGA_C3 || XMEGA_C4) + +/** AVR XMEGA D family */ +#define XMEGA_D (XMEGA_D3 || XMEGA_D4) + +/** AVR XMEGA E family */ +#define XMEGA_E (XMEGA_E5) +/** @} */ + + +/** AVR XMEGA product line */ +#define XMEGA (XMEGA_A || XMEGA_AU || XMEGA_B || XMEGA_C || XMEGA_D || XMEGA_E) + +/** @} */ + +/** + * \defgroup mega_part_macros_group megaAVR parts + * + * \note These megaAVR groupings are based on the groups in AVR Libc for the + * part header files. They are not names of official megaAVR device series or + * families. + * + * @{ + */ + +/** + * \name ATmegaxx0/xx1 subgroups + * @{ + */ +#define MEGA_XX0 ( \ + AVR8_PART_IS_DEFINED(ATmega640) || \ + AVR8_PART_IS_DEFINED(ATmega1280) || \ + AVR8_PART_IS_DEFINED(ATmega2560) \ + ) + +#define MEGA_XX1 ( \ + AVR8_PART_IS_DEFINED(ATmega1281) || \ + AVR8_PART_IS_DEFINED(ATmega2561) \ + ) +/** @} */ + +/** + * \name megaAVR groups + * @{ + */ +/** ATmegaxx0/xx1 group */ +#define MEGA_XX0_1 (MEGA_XX0 || MEGA_XX1) + +/** ATmegaxx4 group */ +#define MEGA_XX4 ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) || \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxx4 group */ +#define MEGA_XX4_A ( \ + AVR8_PART_IS_DEFINED(ATmega164A) || \ + AVR8_PART_IS_DEFINED(ATmega164PA) || \ + AVR8_PART_IS_DEFINED(ATmega324A) || \ + AVR8_PART_IS_DEFINED(ATmega324PA) || \ + AVR8_PART_IS_DEFINED(ATmega644A) || \ + AVR8_PART_IS_DEFINED(ATmega644PA) || \ + AVR8_PART_IS_DEFINED(ATmega1284P) \ + ) + +/** ATmegaxx8 group */ +#define MEGA_XX8 ( \ + AVR8_PART_IS_DEFINED(ATmega48) || \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx8A/P/PA group */ +#define MEGA_XX8_A ( \ + AVR8_PART_IS_DEFINED(ATmega48A) || \ + AVR8_PART_IS_DEFINED(ATmega48PA) || \ + AVR8_PART_IS_DEFINED(ATmega88A) || \ + AVR8_PART_IS_DEFINED(ATmega88PA) || \ + AVR8_PART_IS_DEFINED(ATmega168A) || \ + AVR8_PART_IS_DEFINED(ATmega168PA) || \ + AVR8_PART_IS_DEFINED(ATmega328P) \ + ) + +/** ATmegaxx group */ +#define MEGA_XX ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxxA/P/PA group */ +#define MEGA_XX_A ( \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32A) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) +/** ATmegaxxRFA1 group */ +#define MEGA_RFA1 ( \ + AVR8_PART_IS_DEFINED(ATmega128RFA1) \ + ) + +/** ATmegaxxRFR2 group */ +#define MEGA_RFR2 ( \ + AVR8_PART_IS_DEFINED(ATmega64RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega128RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega256RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega644RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega1284RFR2) || \ + AVR8_PART_IS_DEFINED(ATmega2564RFR2) \ + ) + + +/** ATmegaxxRFxx group */ +#define MEGA_RF (MEGA_RFA1 || MEGA_RFR2) + +/** + * \name ATmegaxx_un0/un1/un2 subgroups + * @{ + */ +#define MEGA_XX_UN0 ( \ + AVR8_PART_IS_DEFINED(ATmega16) || \ + AVR8_PART_IS_DEFINED(ATmega16A) || \ + AVR8_PART_IS_DEFINED(ATmega32) || \ + AVR8_PART_IS_DEFINED(ATmega32A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN1 ( \ + AVR8_PART_IS_DEFINED(ATmega64) || \ + AVR8_PART_IS_DEFINED(ATmega64A) || \ + AVR8_PART_IS_DEFINED(ATmega128) || \ + AVR8_PART_IS_DEFINED(ATmega128A) \ + ) + +/** ATmegaxx group without power reduction and + * And interrupt sense register. + */ +#define MEGA_XX_UN2 ( \ + AVR8_PART_IS_DEFINED(ATmega169P) || \ + AVR8_PART_IS_DEFINED(ATmega169PA) || \ + AVR8_PART_IS_DEFINED(ATmega329P) || \ + AVR8_PART_IS_DEFINED(ATmega329PA) \ + ) + +/** Devices added to complete megaAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define MEGA_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(AT90CAN128) || \ + AVR8_PART_IS_DEFINED(AT90CAN32) || \ + AVR8_PART_IS_DEFINED(AT90CAN64) || \ + AVR8_PART_IS_DEFINED(AT90PWM1) || \ + AVR8_PART_IS_DEFINED(AT90PWM216) || \ + AVR8_PART_IS_DEFINED(AT90PWM2B) || \ + AVR8_PART_IS_DEFINED(AT90PWM316) || \ + AVR8_PART_IS_DEFINED(AT90PWM3B) || \ + AVR8_PART_IS_DEFINED(AT90PWM81) || \ + AVR8_PART_IS_DEFINED(AT90USB1286) || \ + AVR8_PART_IS_DEFINED(AT90USB1287) || \ + AVR8_PART_IS_DEFINED(AT90USB162) || \ + AVR8_PART_IS_DEFINED(AT90USB646) || \ + AVR8_PART_IS_DEFINED(AT90USB647) || \ + AVR8_PART_IS_DEFINED(AT90USB82) || \ + AVR8_PART_IS_DEFINED(ATmega1284) || \ + AVR8_PART_IS_DEFINED(ATmega162) || \ + AVR8_PART_IS_DEFINED(ATmega164P) || \ + AVR8_PART_IS_DEFINED(ATmega165A) || \ + AVR8_PART_IS_DEFINED(ATmega165P) || \ + AVR8_PART_IS_DEFINED(ATmega165PA) || \ + AVR8_PART_IS_DEFINED(ATmega168P) || \ + AVR8_PART_IS_DEFINED(ATmega169A) || \ + AVR8_PART_IS_DEFINED(ATmega16M1) || \ + AVR8_PART_IS_DEFINED(ATmega16U2) || \ + AVR8_PART_IS_DEFINED(ATmega16U4) || \ + AVR8_PART_IS_DEFINED(ATmega256RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega324P) || \ + AVR8_PART_IS_DEFINED(ATmega325) || \ + AVR8_PART_IS_DEFINED(ATmega3250) || \ + AVR8_PART_IS_DEFINED(ATmega3250A) || \ + AVR8_PART_IS_DEFINED(ATmega3250P) || \ + AVR8_PART_IS_DEFINED(ATmega3250PA) || \ + AVR8_PART_IS_DEFINED(ATmega325A) || \ + AVR8_PART_IS_DEFINED(ATmega325P) || \ + AVR8_PART_IS_DEFINED(ATmega325PA) || \ + AVR8_PART_IS_DEFINED(ATmega329) || \ + AVR8_PART_IS_DEFINED(ATmega3290) || \ + AVR8_PART_IS_DEFINED(ATmega3290A) || \ + AVR8_PART_IS_DEFINED(ATmega3290P) || \ + AVR8_PART_IS_DEFINED(ATmega3290PA) || \ + AVR8_PART_IS_DEFINED(ATmega329A) || \ + AVR8_PART_IS_DEFINED(ATmega32M1) || \ + AVR8_PART_IS_DEFINED(ATmega32U2) || \ + AVR8_PART_IS_DEFINED(ATmega32U4) || \ + AVR8_PART_IS_DEFINED(ATmega48P) || \ + AVR8_PART_IS_DEFINED(ATmega644P) || \ + AVR8_PART_IS_DEFINED(ATmega645) || \ + AVR8_PART_IS_DEFINED(ATmega6450) || \ + AVR8_PART_IS_DEFINED(ATmega6450A) || \ + AVR8_PART_IS_DEFINED(ATmega6450P) || \ + AVR8_PART_IS_DEFINED(ATmega645A) || \ + AVR8_PART_IS_DEFINED(ATmega645P) || \ + AVR8_PART_IS_DEFINED(ATmega649) || \ + AVR8_PART_IS_DEFINED(ATmega6490) || \ + AVR8_PART_IS_DEFINED(ATmega6490A) || \ + AVR8_PART_IS_DEFINED(ATmega6490P) || \ + AVR8_PART_IS_DEFINED(ATmega649A) || \ + AVR8_PART_IS_DEFINED(ATmega649P) || \ + AVR8_PART_IS_DEFINED(ATmega64M1) || \ + AVR8_PART_IS_DEFINED(ATmega64RFA2) || \ + AVR8_PART_IS_DEFINED(ATmega8) || \ + AVR8_PART_IS_DEFINED(ATmega8515) || \ + AVR8_PART_IS_DEFINED(ATmega8535) || \ + AVR8_PART_IS_DEFINED(ATmega88P) || \ + AVR8_PART_IS_DEFINED(ATmega8A) || \ + AVR8_PART_IS_DEFINED(ATmega8U2) \ + ) + +/** Unspecified group */ +#define MEGA_UNSPECIFIED (MEGA_XX_UN0 || MEGA_XX_UN1 || MEGA_XX_UN2 || \ + MEGA_UNCATEGORIZED) + +/** @} */ + +/** megaAVR product line */ +#define MEGA (MEGA_XX0_1 || MEGA_XX4 || MEGA_XX8 || MEGA_XX || MEGA_RF || \ + MEGA_UNSPECIFIED) + +/** @} */ + +/** + * \defgroup tiny_part_macros_group tinyAVR parts + * + * @{ + */ + +/** + * \name tinyAVR groups + * @{ + */ + +/** Devices added to complete tinyAVR offering. + * Please do not use this group symbol as it is not intended + * to be permanent: the devices should be regrouped. + */ +#define TINY_UNCATEGORIZED ( \ + AVR8_PART_IS_DEFINED(ATtiny10) || \ + AVR8_PART_IS_DEFINED(ATtiny13) || \ + AVR8_PART_IS_DEFINED(ATtiny13A) || \ + AVR8_PART_IS_DEFINED(ATtiny1634) || \ + AVR8_PART_IS_DEFINED(ATtiny167) || \ + AVR8_PART_IS_DEFINED(ATtiny20) || \ + AVR8_PART_IS_DEFINED(ATtiny2313) || \ + AVR8_PART_IS_DEFINED(ATtiny2313A) || \ + AVR8_PART_IS_DEFINED(ATtiny24) || \ + AVR8_PART_IS_DEFINED(ATtiny24A) || \ + AVR8_PART_IS_DEFINED(ATtiny25) || \ + AVR8_PART_IS_DEFINED(ATtiny26) || \ + AVR8_PART_IS_DEFINED(ATtiny261) || \ + AVR8_PART_IS_DEFINED(ATtiny261A) || \ + AVR8_PART_IS_DEFINED(ATtiny4) || \ + AVR8_PART_IS_DEFINED(ATtiny40) || \ + AVR8_PART_IS_DEFINED(ATtiny4313) || \ + AVR8_PART_IS_DEFINED(ATtiny43U) || \ + AVR8_PART_IS_DEFINED(ATtiny44) || \ + AVR8_PART_IS_DEFINED(ATtiny44A) || \ + AVR8_PART_IS_DEFINED(ATtiny45) || \ + AVR8_PART_IS_DEFINED(ATtiny461) || \ + AVR8_PART_IS_DEFINED(ATtiny461A) || \ + AVR8_PART_IS_DEFINED(ATtiny48) || \ + AVR8_PART_IS_DEFINED(ATtiny5) || \ + AVR8_PART_IS_DEFINED(ATtiny828) || \ + AVR8_PART_IS_DEFINED(ATtiny84) || \ + AVR8_PART_IS_DEFINED(ATtiny84A) || \ + AVR8_PART_IS_DEFINED(ATtiny85) || \ + AVR8_PART_IS_DEFINED(ATtiny861) || \ + AVR8_PART_IS_DEFINED(ATtiny861A) || \ + AVR8_PART_IS_DEFINED(ATtiny87) || \ + AVR8_PART_IS_DEFINED(ATtiny88) || \ + AVR8_PART_IS_DEFINED(ATtiny9) \ + ) + +/** @} */ + +/** tinyAVR product line */ +#define TINY (TINY_UNCATEGORIZED) + +/** @} */ + +/** + * \defgroup sam_part_macros_group SAM parts + * @{ + */ + +/** + * \name SAM3S series + * @{ + */ +#define SAM3S1 ( \ + SAM_PART_IS_DEFINED(SAM3S1A) || \ + SAM_PART_IS_DEFINED(SAM3S1B) || \ + SAM_PART_IS_DEFINED(SAM3S1C) \ + ) + +#define SAM3S2 ( \ + SAM_PART_IS_DEFINED(SAM3S2A) || \ + SAM_PART_IS_DEFINED(SAM3S2B) || \ + SAM_PART_IS_DEFINED(SAM3S2C) \ + ) + +#define SAM3S4 ( \ + SAM_PART_IS_DEFINED(SAM3S4A) || \ + SAM_PART_IS_DEFINED(SAM3S4B) || \ + SAM_PART_IS_DEFINED(SAM3S4C) \ + ) + +#define SAM3S8 ( \ + SAM_PART_IS_DEFINED(SAM3S8B) || \ + SAM_PART_IS_DEFINED(SAM3S8C) \ + ) + +#define SAM3SD8 ( \ + SAM_PART_IS_DEFINED(SAM3SD8B) || \ + SAM_PART_IS_DEFINED(SAM3SD8C) \ + ) +/** @} */ + +/** + * \name SAM3U series + * @{ + */ +#define SAM3U1 ( \ + SAM_PART_IS_DEFINED(SAM3U1C) || \ + SAM_PART_IS_DEFINED(SAM3U1E) \ + ) + +#define SAM3U2 ( \ + SAM_PART_IS_DEFINED(SAM3U2C) || \ + SAM_PART_IS_DEFINED(SAM3U2E) \ + ) + +#define SAM3U4 ( \ + SAM_PART_IS_DEFINED(SAM3U4C) || \ + SAM_PART_IS_DEFINED(SAM3U4E) \ + ) +/** @} */ + +/** + * \name SAM3N series + * @{ + */ +#define SAM3N00 ( \ + SAM_PART_IS_DEFINED(SAM3N00A) || \ + SAM_PART_IS_DEFINED(SAM3N00B) \ + ) + +#define SAM3N0 ( \ + SAM_PART_IS_DEFINED(SAM3N0A) || \ + SAM_PART_IS_DEFINED(SAM3N0B) || \ + SAM_PART_IS_DEFINED(SAM3N0C) \ + ) + +#define SAM3N1 ( \ + SAM_PART_IS_DEFINED(SAM3N1A) || \ + SAM_PART_IS_DEFINED(SAM3N1B) || \ + SAM_PART_IS_DEFINED(SAM3N1C) \ + ) + +#define SAM3N2 ( \ + SAM_PART_IS_DEFINED(SAM3N2A) || \ + SAM_PART_IS_DEFINED(SAM3N2B) || \ + SAM_PART_IS_DEFINED(SAM3N2C) \ + ) + +#define SAM3N4 ( \ + SAM_PART_IS_DEFINED(SAM3N4A) || \ + SAM_PART_IS_DEFINED(SAM3N4B) || \ + SAM_PART_IS_DEFINED(SAM3N4C) \ + ) +/** @} */ + +/** + * \name SAM3X series + * @{ + */ +#define SAM3X4 ( \ + SAM_PART_IS_DEFINED(SAM3X4C) || \ + SAM_PART_IS_DEFINED(SAM3X4E) \ + ) + +#define SAM3X8 ( \ + SAM_PART_IS_DEFINED(SAM3X8C) || \ + SAM_PART_IS_DEFINED(SAM3X8E) || \ + SAM_PART_IS_DEFINED(SAM3X8H) \ + ) +/** @} */ + +/** + * \name SAM3A series + * @{ + */ +#define SAM3A4 ( \ + SAM_PART_IS_DEFINED(SAM3A4C) \ + ) + +#define SAM3A8 ( \ + SAM_PART_IS_DEFINED(SAM3A8C) \ + ) +/** @} */ + +/** + * \name SAM4S series + * @{ + */ +#define SAM4S2 ( \ + SAM_PART_IS_DEFINED(SAM4S2A) || \ + SAM_PART_IS_DEFINED(SAM4S2B) || \ + SAM_PART_IS_DEFINED(SAM4S2C) \ + ) + +#define SAM4S4 ( \ + SAM_PART_IS_DEFINED(SAM4S4A) || \ + SAM_PART_IS_DEFINED(SAM4S4B) || \ + SAM_PART_IS_DEFINED(SAM4S4C) \ + ) + +#define SAM4S8 ( \ + SAM_PART_IS_DEFINED(SAM4S8B) || \ + SAM_PART_IS_DEFINED(SAM4S8C) \ + ) + +#define SAM4S16 ( \ + SAM_PART_IS_DEFINED(SAM4S16B) || \ + SAM_PART_IS_DEFINED(SAM4S16C) \ + ) + +#define SAM4SA16 ( \ + SAM_PART_IS_DEFINED(SAM4SA16B) || \ + SAM_PART_IS_DEFINED(SAM4SA16C) \ + ) + +#define SAM4SD16 ( \ + SAM_PART_IS_DEFINED(SAM4SD16B) || \ + SAM_PART_IS_DEFINED(SAM4SD16C) \ + ) + +#define SAM4SD32 ( \ + SAM_PART_IS_DEFINED(SAM4SD32B) || \ + SAM_PART_IS_DEFINED(SAM4SD32C) \ + ) +/** @} */ + +/** + * \name SAM4L series + * @{ + */ +#define SAM4LS ( \ + SAM_PART_IS_DEFINED(SAM4LS2A) || \ + SAM_PART_IS_DEFINED(SAM4LS2B) || \ + SAM_PART_IS_DEFINED(SAM4LS2C) || \ + SAM_PART_IS_DEFINED(SAM4LS4A) || \ + SAM_PART_IS_DEFINED(SAM4LS4B) || \ + SAM_PART_IS_DEFINED(SAM4LS4C) || \ + SAM_PART_IS_DEFINED(SAM4LS8A) || \ + SAM_PART_IS_DEFINED(SAM4LS8B) || \ + SAM_PART_IS_DEFINED(SAM4LS8C) \ + ) + +#define SAM4LC ( \ + SAM_PART_IS_DEFINED(SAM4LC2A) || \ + SAM_PART_IS_DEFINED(SAM4LC2B) || \ + SAM_PART_IS_DEFINED(SAM4LC2C) || \ + SAM_PART_IS_DEFINED(SAM4LC4A) || \ + SAM_PART_IS_DEFINED(SAM4LC4B) || \ + SAM_PART_IS_DEFINED(SAM4LC4C) || \ + SAM_PART_IS_DEFINED(SAM4LC8A) || \ + SAM_PART_IS_DEFINED(SAM4LC8B) || \ + SAM_PART_IS_DEFINED(SAM4LC8C) \ + ) +/** @} */ + +/** + * \name SAMD20 series + * @{ + */ +#define SAMD20J ( \ + SAM_PART_IS_DEFINED(SAMD20J14) || \ + SAM_PART_IS_DEFINED(SAMD20J15) || \ + SAM_PART_IS_DEFINED(SAMD20J16) || \ + SAM_PART_IS_DEFINED(SAMD20J17) || \ + SAM_PART_IS_DEFINED(SAMD20J18) \ + ) + +#define SAMD20G ( \ + SAM_PART_IS_DEFINED(SAMD20G14) || \ + SAM_PART_IS_DEFINED(SAMD20G15) || \ + SAM_PART_IS_DEFINED(SAMD20G16) || \ + SAM_PART_IS_DEFINED(SAMD20G17) || \ + SAM_PART_IS_DEFINED(SAMD20G17U) || \ + SAM_PART_IS_DEFINED(SAMD20G18) || \ + SAM_PART_IS_DEFINED(SAMD20G18U) \ + ) + +#define SAMD20E ( \ + SAM_PART_IS_DEFINED(SAMD20E14) || \ + SAM_PART_IS_DEFINED(SAMD20E15) || \ + SAM_PART_IS_DEFINED(SAMD20E16) || \ + SAM_PART_IS_DEFINED(SAMD20E17) || \ + SAM_PART_IS_DEFINED(SAMD20E18) || \ + SAM_PART_IS_DEFINED(SAMD20E1F) \ + ) +/** @} */ + +/** + * \name SAMD21 series + * @{ + */ +#define SAMD21J ( \ + SAM_PART_IS_DEFINED(SAMD21J15A) || \ + SAM_PART_IS_DEFINED(SAMD21J16A) || \ + SAM_PART_IS_DEFINED(SAMD21J17A) || \ + SAM_PART_IS_DEFINED(SAMD21J18A) \ + ) + +#define SAMD21G ( \ + SAM_PART_IS_DEFINED(SAMD21G15A) || \ + SAM_PART_IS_DEFINED(SAMD21G16A) || \ + SAM_PART_IS_DEFINED(SAMD21G17A) || \ + SAM_PART_IS_DEFINED(SAMD21G18A) \ + ) + +#define SAMD21E ( \ + SAM_PART_IS_DEFINED(SAMD21E15A) || \ + SAM_PART_IS_DEFINED(SAMD21E16A) || \ + SAM_PART_IS_DEFINED(SAMD21E17A) || \ + SAM_PART_IS_DEFINED(SAMD21E18A) \ + ) +/** @} */ + +/** + * \name SAMR21 series + * @{ + */ +#define SAMR21G ( \ + SAM_PART_IS_DEFINED(SAMR21G16A) || \ + SAM_PART_IS_DEFINED(SAMR21G17A) || \ + SAM_PART_IS_DEFINED(SAMR21G18A) \ + ) + +#define SAMR21E ( \ + SAM_PART_IS_DEFINED(SAMR21E16A) || \ + SAM_PART_IS_DEFINED(SAMR21E17A) || \ + SAM_PART_IS_DEFINED(SAMR21E18A) \ + ) +/** @} */ + +/** + * \name SAMD10 series + * @{ + */ +#define SAMD10C ( \ + SAM_PART_IS_DEFINED(SAMD10C12A) || \ + SAM_PART_IS_DEFINED(SAMD10C13A) || \ + SAM_PART_IS_DEFINED(SAMD10C14A) \ + ) + +#define SAMD10DS ( \ + SAM_PART_IS_DEFINED(SAMD10D12AS) || \ + SAM_PART_IS_DEFINED(SAMD10D13AS) || \ + SAM_PART_IS_DEFINED(SAMD10D14AS) \ + ) + +#define SAMD10DM ( \ + SAM_PART_IS_DEFINED(SAMD10D12AM) || \ + SAM_PART_IS_DEFINED(SAMD10D13AM) || \ + SAM_PART_IS_DEFINED(SAMD10D14AM) \ + ) +/** @} */ + +/** + * \name SAMD11 series + * @{ + */ +#define SAMD11C ( \ + SAM_PART_IS_DEFINED(SAMD11C14A) \ + ) + +#define SAMD11DS ( \ + SAM_PART_IS_DEFINED(SAMD11D14AS) \ + ) + +#define SAMD11DM ( \ + SAM_PART_IS_DEFINED(SAMD11D14AM) \ + ) +/** @} */ + +/** + * \name SAML21 series + * @{ + */ +#define SAML21E ( \ + SAM_PART_IS_DEFINED(SAML21E15A) || \ + SAM_PART_IS_DEFINED(SAML21E16A) || \ + SAM_PART_IS_DEFINED(SAML21E17A) || \ + SAM_PART_IS_DEFINED(SAML21E18A) \ + ) + +#define SAML21G ( \ + SAM_PART_IS_DEFINED(SAML21G16A) || \ + SAM_PART_IS_DEFINED(SAML21G17A) || \ + SAM_PART_IS_DEFINED(SAML21G18A) \ + ) + +#define SAML21J ( \ + SAM_PART_IS_DEFINED(SAML21J16A) || \ + SAM_PART_IS_DEFINED(SAML21J17A) || \ + SAM_PART_IS_DEFINED(SAML21J18A) \ + ) +/** @} */ + +/** + * \name SAM4E series + * @{ + */ +#define SAM4E8 ( \ + SAM_PART_IS_DEFINED(SAM4E8C) || \ + SAM_PART_IS_DEFINED(SAM4E8E) \ + ) + +#define SAM4E16 ( \ + SAM_PART_IS_DEFINED(SAM4E16C) || \ + SAM_PART_IS_DEFINED(SAM4E16E) \ + ) +/** @} */ + +/** + * \name SAM4N series + * @{ + */ +#define SAM4N8 ( \ + SAM_PART_IS_DEFINED(SAM4N8A) || \ + SAM_PART_IS_DEFINED(SAM4N8B) || \ + SAM_PART_IS_DEFINED(SAM4N8C) \ + ) + +#define SAM4N16 ( \ + SAM_PART_IS_DEFINED(SAM4N16B) || \ + SAM_PART_IS_DEFINED(SAM4N16C) \ + ) +/** @} */ + +/** + * \name SAM4C series + * @{ + */ +#define SAM4C8_0 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_0) \ + ) + +#define SAM4C8_1 ( \ + SAM_PART_IS_DEFINED(SAM4C8C_1) \ + ) + +#define SAM4C8 (SAM4C8_0 || SAM4C8_1) + +#define SAM4C16_0 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_0) \ + ) + +#define SAM4C16_1 ( \ + SAM_PART_IS_DEFINED(SAM4C16C_1) \ + ) + +#define SAM4C16 (SAM4C16_0 || SAM4C16_1) + +#define SAM4C32_0 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_0) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_0) \ + ) + +#define SAM4C32_1 ( \ + SAM_PART_IS_DEFINED(SAM4C32C_1) ||\ + SAM_PART_IS_DEFINED(SAM4C32E_1) \ + ) + + +#define SAM4C32 (SAM4C32_0 || SAM4C32_1) + +/** @} */ + +/** + * \name SAM4CM series + * @{ + */ +#define SAM4CMP8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_0) \ + ) + +#define SAM4CMP8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP8C_1) \ + ) + +#define SAM4CMP8 (SAM4CMP8_0 || SAM4CMP8_1) + +#define SAM4CMP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_0) \ + ) + +#define SAM4CMP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP16C_1) \ + ) + +#define SAM4CMP16 (SAM4CMP16_0 || SAM4CMP16_1) + +#define SAM4CMP32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_0) \ + ) + +#define SAM4CMP32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMP32C_1) \ + ) + +#define SAM4CMP32 (SAM4CMP32_0 || SAM4CMP32_1) + +#define SAM4CMS8_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_0) \ + ) + +#define SAM4CMS8_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS8C_1) \ + ) + +#define SAM4CMS8 (SAM4CMS8_0 || SAM4CMS8_1) + +#define SAM4CMS16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_0) \ + ) + +#define SAM4CMS16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS16C_1) \ + ) + +#define SAM4CMS16 (SAM4CMS16_0 || SAM4CMS16_1) + +#define SAM4CMS32_0 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_0) \ + ) + +#define SAM4CMS32_1 ( \ + SAM_PART_IS_DEFINED(SAM4CMS32C_1) \ + ) + +#define SAM4CMS32 (SAM4CMS32_0 || SAM4CMS32_1) + +/** @} */ + +/** + * \name SAM4CP series + * @{ + */ +#define SAM4CP16_0 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_0) \ + ) + +#define SAM4CP16_1 ( \ + SAM_PART_IS_DEFINED(SAM4CP16B_1) \ + ) + +#define SAM4CP16 (SAM4CP16_0 || SAM4CP16_1) +/** @} */ + +/** + * \name SAMG series + * @{ + */ +#define SAMG51 ( \ + SAM_PART_IS_DEFINED(SAMG51G18) \ + ) + +#define SAMG53 ( \ + SAM_PART_IS_DEFINED(SAMG53G19) ||\ + SAM_PART_IS_DEFINED(SAMG53N19) \ + ) + +#define SAMG54 ( \ + SAM_PART_IS_DEFINED(SAMG54G19) ||\ + SAM_PART_IS_DEFINED(SAMG54J19) ||\ + SAM_PART_IS_DEFINED(SAMG54N19) \ + ) + +#define SAMG55 ( \ + SAM_PART_IS_DEFINED(SAMG55G18) ||\ + SAM_PART_IS_DEFINED(SAMG55G19) ||\ + SAM_PART_IS_DEFINED(SAMG55J18) ||\ + SAM_PART_IS_DEFINED(SAMG55J19) ||\ + SAM_PART_IS_DEFINED(SAMG55N19) \ + ) +/** @} */ +/** + * \name SAM families + * @{ + */ +/** SAM3S Family */ +#define SAM3S (SAM3S1 || SAM3S2 || SAM3S4 || SAM3S8 || SAM3SD8) + +/** SAM3U Family */ +#define SAM3U (SAM3U1 || SAM3U2 || SAM3U4) + +/** SAM3N Family */ +#define SAM3N (SAM3N00 || SAM3N0 || SAM3N1 || SAM3N2 || SAM3N4) + +/** SAM3XA Family */ +#define SAM3XA (SAM3X4 || SAM3X8 || SAM3A4 || SAM3A8) + +/** SAM4S Family */ +#define SAM4S (SAM4S2 || SAM4S4 || SAM4S8 || SAM4S16 || SAM4SA16 || SAM4SD16 || SAM4SD32) + +/** SAM4L Family */ +#define SAM4L (SAM4LS || SAM4LC) + +/** SAMD20 Family */ +#define SAMD20 (SAMD20J || SAMD20G || SAMD20E) + +/** SAMD21 Family */ +#define SAMD21 (SAMD21J || SAMD21G || SAMD21E) + +/** SAMD10 Family */ +#define SAMD10 (SAMD10C || SAMD10DS || SAMD10DM) + +/** SAMD11 Family */ +#define SAMD11 (SAMD11C || SAMD11DS || SAMD11DM) + +/** SAMD Family */ +#define SAMD (SAMD20 || SAMD21 || SAMD10 || SAMD11) + +/** SAMR21 Family */ +#define SAMR21 (SAMR21G || SAMR21E) + +/** SAML21 Family */ +#define SAML21 (SAML21J || SAML21G || SAML21E) + +/** SAM4E Family */ +#define SAM4E (SAM4E8 || SAM4E16) + +/** SAM4N Family */ +#define SAM4N (SAM4N8 || SAM4N16) + +/** SAM4C Family */ +#define SAM4C_0 (SAM4C8_0 || SAM4C16_0 || SAM4C32_0) +#define SAM4C_1 (SAM4C8_1 || SAM4C16_1 || SAM4C32_1) +#define SAM4C (SAM4C8 || SAM4C16 || SAM4C32) + +/** SAM4CM Family */ +#define SAM4CM_0 (SAM4CMP8_0 || SAM4CMP16_0 || SAM4CMP32_0 || SAM4CMS8_0 || \ + SAM4CMS16_0 || SAM4CMS32_0) +#define SAM4CM_1 (SAM4CMP8_1 || SAM4CMP16_1 || SAM4CMP32_1 || SAM4CMS8_1 || \ + SAM4CMS16_1 || SAM4CMS32_1) +#define SAM4CM (SAM4CMP8 || SAM4CMP16 || SAM4CMP32 || SAM4CMS8 || \ + SAM4CMS16 || SAM4CMS32) + +/** SAM4CP Family */ +#define SAM4CP_0 (SAM4CP16_0) +#define SAM4CP_1 (SAM4CP16_1) +#define SAM4CP (SAM4CP16) + +/** SAMG Family */ +#define SAMG (SAMG51 || SAMG53 || SAMG54 || SAMG55) + +/** SAM0 product line (cortex-m0+) */ +#define SAM0 (SAMD20 || SAMD21 || SAMR21 || SAMD10 || SAMD11 || SAML21) + +/** @} */ + +/** SAM product line */ +#define SAM (SAM3S || SAM3U || SAM3N || SAM3XA || SAM4S || SAM4L || SAM4E || \ + SAM0 || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG) + +/** @} */ + +/** @} */ + +/** @} */ + +#endif /* ATMEL_PARTS_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/read.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/read.c new file mode 100644 index 0000000..608cf50 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/read.c @@ -0,0 +1,167 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _read function used by + * the standard library. + * + * Copyright (c) 2009-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "compiler.h" + +/** + * \defgroup group_common_utils_stdio Standard I/O (stdio) + * + * Common standard I/O driver that implements the stdio + * read and write functions on AVR and SAM devices. + * + * \{ + */ + +extern volatile void *volatile stdio_base; +void (*ptr_get)(void volatile*, char*); + + +// IAR common implementation +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__) ) + +#include + +_STD_BEGIN + +#pragma module_name = "?__read" + +/*! \brief Reads a number of bytes, at most \a size, into the memory area + * pointed to by \a buffer. + * + * \param handle File handle to read from. + * \param buffer Pointer to buffer to write read bytes to. + * \param size Number of bytes to read. + * + * \return The number of bytes read, \c 0 at the end of the file, or + * \c _LLIO_ERROR on failure. + */ +size_t __read(int handle, unsigned char *buffer, size_t size) +{ + int nChars = 0; + // This implementation only reads from stdin. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDIN) { + return _LLIO_ERROR; + } + for (; size > 0; --size) { + ptr_get(stdio_base, (char*)buffer); + buffer++; + nChars++; + } + return nChars; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int __close(int handle) +{ + UNUSED(handle); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +int remove(const char* val) +{ + UNUSED(val); + return 0; +} + +/*! \brief This routine is required by IAR DLIB library since EWAVR V6.10 + * the implementation is empty to be compatible with old IAR version. + */ +long __lseek(int handle, long val, int val2) +{ + UNUSED(handle); + UNUSED(val2); + return val; +} + +_STD_END + +// GCC AVR32 and SAM implementation +#elif (defined(__GNUC__) && !XMEGA && !MEGA) + +int __attribute__((weak)) +_read (int file, char * ptr, int len); // Remove GCC compiler warning + +int __attribute__((weak)) +_read (int file, char * ptr, int len) +{ + int nChars = 0; + + if (file != 0) { + return -1; + } + + for (; len > 0; --len) { + ptr_get(stdio_base, ptr); + ptr++; + nChars++; + } + return nChars; +} + +// GCC AVR implementation +#elif (defined(__GNUC__) && (XMEGA || MEGA) ) + +int _read (int *f); // Remove GCC compiler warning + +int _read (int *f) +{ + char c; + ptr_get(stdio_base,&c); + return c; +} +#endif + +/** + * \} + */ + diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/stdio_serial/stdio_serial.h b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/stdio_serial/stdio_serial.h new file mode 100644 index 0000000..92c7fc3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/stdio_serial/stdio_serial.h @@ -0,0 +1,129 @@ +/** + * + * \file + * + * \brief Common Standard I/O Serial Management. + * + * This file defines a useful set of functions for the Stdio Serial interface on AVR + * and SAM devices. + * + * Copyright (c) 2009-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 + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + + +#ifndef _STDIO_SERIAL_H_ +#define _STDIO_SERIAL_H_ + +/** + * \defgroup group_common_utils_stdio_stdio_serial Standard serial I/O (stdio) + * \ingroup group_common_utils_stdio + * + * Common standard serial I/O management driver that + * implements a stdio serial interface on AVR and SAM devices. + * + * \{ + */ + +#include +#include "compiler.h" +#ifndef SAMD20 +# include "sysclk.h" +#endif +#include "serial.h" + +#if (XMEGA || MEGA_RF) && defined(__GNUC__) + extern int _write (char c, int *f); + extern int _read (int *f); +#endif + + +//! Pointer to the base of the USART module instance to use for stdio. +extern volatile void *volatile stdio_base; +//! Pointer to the external low level write function. +extern int (*ptr_put)(void volatile*, char); + +//! Pointer to the external low level read function. +extern void (*ptr_get)(void volatile*, char*); + +/*! \brief Initializes the stdio in Serial Mode. + * + * \param usart Base address of the USART instance. + * \param opt Options needed to set up RS232 communication (see \ref usart_options_t). + * + */ +static inline void stdio_serial_init(volatile void *usart, const usart_serial_options_t *opt) +{ + stdio_base = (void *)usart; + ptr_put = (int (*)(void volatile*,char))&usart_serial_putchar; + ptr_get = (void (*)(void volatile*,char*))&usart_serial_getchar; +# if (XMEGA || MEGA_RF) + usart_serial_init((USART_t *)usart,opt); +# elif UC3 + usart_serial_init(usart,(usart_serial_options_t *)opt); +# elif SAM + usart_serial_init((Usart *)usart,(usart_serial_options_t *)opt); +# else +# error Unsupported chip type +# endif + +# if defined(__GNUC__) +# if (XMEGA || MEGA_RF) + // For AVR GCC libc print redirection uses fdevopen. + fdevopen((int (*)(char, FILE*))(_write),(int (*)(FILE*))(_read)); +# endif +# if UC3 || SAM + // For AVR32 and SAM GCC + // Specify that stdout and stdin should not be buffered. + setbuf(stdout, NULL); + setbuf(stdin, NULL); + // Note: Already the case in IAR's Normal DLIB default configuration + // and AVR GCC library: + // - printf() emits one character at a time. + // - getchar() requests only 1 byte to exit. +# endif +# endif +} + +/** + * \} + */ + +#endif // _STDIO_SERIAL_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/write.c b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/write.c new file mode 100644 index 0000000..e1e34c8 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/common/utils/stdio/write.c @@ -0,0 +1,147 @@ +/** + * \file + * + * \brief System-specific implementation of the \ref _write function used by + * the standard library. + * + * Copyright (c) 2009-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "compiler.h" + +/** + * \addtogroup group_common_utils_stdio + * + * \{ + */ + +volatile void *volatile stdio_base; +int (*ptr_put)(void volatile*, char); + + +#if ( defined(__ICCAVR32__) || defined(__ICCAVR__) || defined(__ICCARM__)) + +#include + +_STD_BEGIN + +#pragma module_name = "?__write" + +/*! \brief Writes a number of bytes, at most \a size, from the memory area + * pointed to by \a buffer. + * + * If \a buffer is zero then \ref __write performs flushing of internal buffers, + * if any. In this case, \a handle can be \c -1 to indicate that all handles + * should be flushed. + * + * \param handle File handle to write to. + * \param buffer Pointer to buffer to read bytes to write from. + * \param size Number of bytes to write. + * + * \return The number of bytes written, or \c _LLIO_ERROR on failure. + */ +size_t __write(int handle, const unsigned char *buffer, size_t size) +{ + size_t nChars = 0; + + if (buffer == 0) { + // This means that we should flush internal buffers. + return 0; + } + + // This implementation only writes to stdout and stderr. + // For all other file handles, it returns failure. + if (handle != _LLIO_STDOUT && handle != _LLIO_STDERR) { + return _LLIO_ERROR; + } + + for (; size != 0; --size) { + if (ptr_put(stdio_base, *buffer++) < 0) { + return _LLIO_ERROR; + } + ++nChars; + } + return nChars; +} + +_STD_END + + +#elif (defined(__GNUC__) && !XMEGA && !MEGA) + +int __attribute__((weak)) +_write (int file, const char *ptr, int len); + +int __attribute__((weak)) +_write (int file, const char *ptr, int len) +{ + int nChars = 0; + + if ((file != 1) && (file != 2) && (file!=3)) { + return -1; + } + + for (; len != 0; --len) { + if (ptr_put(stdio_base, *ptr++) < 0) { + return -1; + } + ++nChars; + } + return nChars; +} + +#elif (defined(__GNUC__) && (XMEGA || MEGA)) + +int _write (char c, int *f); + +int _write (char c, int *f) +{ + if (ptr_put(stdio_base, c) < 0) { + return -1; + } + return 1; +} +#endif + +/** + * \} + */ + diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/init.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/init.c new file mode 100644 index 0000000..ad3a739 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/init.c @@ -0,0 +1,373 @@ +/** + * \file + * + * \brief SAM4E-EK board init. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "compiler.h" +#include "board.h" +#include "conf_board.h" +#include "ioport.h" + +/** + * \brief Set peripheral mode for IOPORT pins. + * It will configure port mode and disable pin mode (but enable peripheral). + * \param port IOPORT port to configure + * \param masks IOPORT pin masks to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +#define ioport_set_port_peripheral_mode(port, masks, mode) \ + do {\ + ioport_set_port_mode(port, masks, mode);\ + ioport_disable_port(port, masks);\ + } while (0) + +/** + * \brief Set peripheral mode for one single IOPORT pin. + * It will configure port mode and disable pin mode (but enable peripheral). + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + */ +#define ioport_set_pin_peripheral_mode(pin, mode) \ + do {\ + ioport_set_pin_mode(pin, mode);\ + ioport_disable_pin(pin);\ + } while (0) + +/** + * \brief Set input mode for one single IOPORT pin. + * It will configure port mode and disable pin mode (but enable peripheral). + * \param pin IOPORT pin to configure + * \param mode Mode masks to configure for the specified pin (\ref ioport_modes) + * \param sense Sense for interrupt detection (\ref ioport_sense) + */ +#define ioport_set_pin_input_mode(pin, mode, sense) \ + do {\ + ioport_set_pin_dir(pin, IOPORT_DIR_INPUT);\ + ioport_set_pin_mode(pin, mode);\ + ioport_set_pin_sense_mode(pin, sense);\ + } while (0) + +void board_init(void) +{ +#ifndef CONF_BOARD_KEEP_WATCHDOG_AT_INIT + /* Disable the watchdog */ + WDT->WDT_MR = WDT_MR_WDDIS; +#endif + + /* Initialize IOPORTs */ + ioport_init(); + + /* Configure the pins connected to LEDs as output and set their + * default initial state to high (LEDs off). + */ + ioport_set_pin_dir(LED0_GPIO, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(LED0_GPIO, LED0_INACTIVE_LEVEL); + ioport_set_pin_dir(LED1_GPIO, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(LED1_GPIO, LED0_INACTIVE_LEVEL); + ioport_set_pin_dir(LED2_GPIO, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(LED2_GPIO, LED0_INACTIVE_LEVEL); + + /* Configure Push Button pins */ + ioport_set_pin_input_mode(GPIO_PUSH_BUTTON_1, GPIO_PUSH_BUTTON_1_FLAGS, + GPIO_PUSH_BUTTON_1_SENSE); + ioport_set_pin_input_mode(GPIO_PUSH_BUTTON_2, GPIO_PUSH_BUTTON_2_FLAGS, + GPIO_PUSH_BUTTON_2_SENSE); + ioport_set_pin_input_mode(GPIO_PUSH_BUTTON_3, GPIO_PUSH_BUTTON_3_FLAGS, + GPIO_PUSH_BUTTON_3_SENSE); + ioport_set_pin_input_mode(GPIO_PUSH_BUTTON_4, GPIO_PUSH_BUTTON_4_FLAGS, + GPIO_PUSH_BUTTON_4_SENSE); + +#ifdef CONF_BOARD_UART_CONSOLE + /* Configure UART pins */ + ioport_set_port_peripheral_mode(PINS_UART0_PORT, PINS_UART0, + PINS_UART0_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED0 + /* Configure PWM LED0 pin */ + ioport_set_pin_peripheral_mode(PIN_PWM_LED0_GPIO, PIN_PWM_LED0_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED1 + /* Configure PWM LED1 pin */ + ioport_set_pin_peripheral_mode(PIN_PWM_LED1_GPIO, PIN_PWM_LED1_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED2 + /* Configure PWM LED2 pin */ + ioport_set_pin_peripheral_mode(PIN_PWM_LED2_GPIO, PIN_PWM_LED2_FLAGS); +#endif + +#ifdef CONF_BOARD_PWM_LED3 + /* Configure PWM LED3 pin */ + ioport_set_pin_peripheral_mode(PIN_PWM_LED3_GPIO, PIN_PWM_LED3_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_RXD + /* Configure USART RXD pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_RXD_IDX, + PIN_USART1_RXD_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_TXD + /* Configure USART TXD pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_TXD_IDX, + PIN_USART1_TXD_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_CTS + /* Configure USART CTS pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_CTS_IDX, + PIN_USART1_CTS_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_RTS + /* Configure USART RTS pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_RTS_IDX, + PIN_USART1_RTS_FLAGS); +#endif + +#ifdef CONF_BOARD_USART_SCK + /* Configure USART synchronous communication SCK pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_SCK_IDX, + PIN_USART1_SCK_FLAGS); +#endif + +#ifdef CONF_BOARD_ADM3312_EN + /* Configure ADM3312 enable pin */ + ioport_set_pin_dir(PIN_USART1_EN_IDX, IOPORT_DIR_OUTPUT); +#ifdef CONF_BOARD_ADM3312_EN_DISABLE_AT_INIT + ioport_set_pin_level(PIN_USART1_EN_IDX, PIN_USART1_EN_INACTIVE_LEVEL); +#else + ioport_set_pin_level(PIN_USART1_EN_IDX, PIN_USART1_EN_ACTIVE_LEVEL); +#endif +#endif + +#ifdef CONF_BOARD_ADS7843 + /* Configure Touchscreen SPI pins */ + ioport_set_pin_dir(BOARD_ADS7843_IRQ_GPIO, IOPORT_DIR_INPUT); + ioport_set_pin_mode(BOARD_ADS7843_IRQ_GPIO, BOARD_ADS7843_IRQ_FLAGS); + ioport_set_pin_dir(BOARD_ADS7843_BUSY_GPIO, IOPORT_DIR_INPUT); + ioport_set_pin_mode(BOARD_ADS7843_BUSY_GPIO, BOARD_ADS7843_BUSY_FLAGS); + ioport_set_pin_peripheral_mode(SPI_MISO_GPIO, SPI_MISO_FLAGS); + ioport_set_pin_peripheral_mode(SPI_MOSI_GPIO, SPI_MOSI_FLAGS); + ioport_set_pin_peripheral_mode(SPI_SPCK_GPIO, SPI_SPCK_FLAGS); + ioport_set_pin_peripheral_mode(SPI_NPCS0_GPIO, SPI_NPCS0_FLAGS); +#endif + +#ifdef CONF_BOARD_CAN0 + /* Configure the CAN0 TX and RX pins. */ + ioport_set_pin_peripheral_mode(PIN_CAN0_RX_IDX, PIN_CAN0_RX_FLAGS); + ioport_set_pin_peripheral_mode(PIN_CAN0_TX_IDX, PIN_CAN0_TX_FLAGS); + /* Configure the transiver0 RS & EN pins. */ + ioport_set_pin_dir(PIN_CAN0_TR_RS_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(PIN_CAN0_TR_EN_IDX, IOPORT_DIR_OUTPUT); +#endif + +#ifdef CONF_BOARD_CAN1 + /* Configure the CAN1 TX and RX pin. */ + ioport_set_pin_peripheral_mode(PIN_CAN1_RX_IDX, PIN_CAN1_RX_FLAGS); + ioport_set_pin_peripheral_mode(PIN_CAN1_TX_IDX, PIN_CAN1_TX_FLAGS); + /* Configure the transiver1 RS & EN pins. */ + ioport_set_pin_dir(PIN_CAN1_TR_RS_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(PIN_CAN1_TR_EN_IDX, IOPORT_DIR_OUTPUT); +#endif + +#if defined(CONF_BOARD_USB_PORT) +# if defined(CONF_BOARD_USB_VBUS_DETECT) + gpio_configure_pin(USB_VBUS_PIN, USB_VBUS_FLAGS); +# endif +#endif + +#if defined(CONF_BOARD_ILI9325) || defined(CONF_BOARD_ILI93XX) + /* Configure LCD EBI pins */ + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D0,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D1,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D2,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D3,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D4,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D5,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D6,PIN_EBI_DATA_BUS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_DATA_BUS_D7,PIN_EBI_DATA_BUS_FLAGS); + + ioport_set_pin_peripheral_mode(PIN_EBI_NRD,PIN_EBI_NRD_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NWE,PIN_EBI_NWE_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NCS1,PIN_EBI_NCS1_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_LCD_RS,PIN_EBI_LCD_RS_FLAGS); +#endif + +#ifdef CONF_BOARD_AAT3155 + /* Configure Backlight control pin */ + ioport_set_pin_dir(BOARD_AAT31XX_SET_GPIO, IOPORT_DIR_OUTPUT); +#endif + +#ifdef CONF_BOARD_SPI + ioport_set_pin_peripheral_mode(SPI_MISO_GPIO, SPI_MISO_FLAGS); + ioport_set_pin_peripheral_mode(SPI_MOSI_GPIO, SPI_MOSI_FLAGS); + ioport_set_pin_peripheral_mode(SPI_SPCK_GPIO, SPI_SPCK_FLAGS); + +#ifdef CONF_BOARD_SPI_NPCS0 + ioport_set_pin_peripheral_mode(SPI_NPCS0_GPIO, SPI_NPCS0_FLAGS); +#endif + +#ifdef CONF_BOARD_SPI_NPCS3 +#if defined(CONF_BOARD_SPI_NPCS3_GPIO) && defined(CONF_BOARD_SPI_NPCS3_FLAGS) + ioport_set_pin_peripheral_mode(CONF_BOARD_SPI_NPCS3_GPIO, + CONF_BOARD_SPI_NPCS3_FLAGS); +#else + ioport_set_pin_peripheral_mode(SPI_NPCS3_PA5_GPIO, SPI_NPCS3_PA5_FLAGS); +#endif +#endif +#endif + +#if (defined(CONF_BOARD_TWI0) || defined(CONF_BOARD_QTOUCH)) + ioport_set_pin_peripheral_mode(TWI0_DATA_GPIO, TWI0_DATA_FLAGS); + ioport_set_pin_peripheral_mode(TWI0_CLK_GPIO, TWI0_CLK_FLAGS); +#endif + +#if defined (CONF_BOARD_SD_MMC_HSMCI) + /* Configure HSMCI pins */ + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCCDA_GPIO, PIN_HSMCI_MCCDA_FLAGS); + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCCK_GPIO, PIN_HSMCI_MCCK_FLAGS); + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCDA0_GPIO, PIN_HSMCI_MCDA0_FLAGS); + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCDA1_GPIO, PIN_HSMCI_MCDA1_FLAGS); + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCDA2_GPIO, PIN_HSMCI_MCDA2_FLAGS); + ioport_set_pin_peripheral_mode(PIN_HSMCI_MCDA3_GPIO, PIN_HSMCI_MCDA3_FLAGS); + + /* Configure SD/MMC card detect pin */ + ioport_set_pin_peripheral_mode(SD_MMC_0_CD_GPIO, SD_MMC_0_CD_FLAGS); +#endif + +#ifdef CONF_BOARD_TWI1 + ioport_set_pin_peripheral_mode(TWI1_DATA_GPIO, TWI1_DATA_FLAGS); + ioport_set_pin_peripheral_mode(TWI1_CLK_GPIO, TWI1_CLK_FLAGS); +#endif + +#ifdef CONF_BOARD_KSZ8051MNL + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXC_IDX, + PIN_KSZ8051MNL_RXC_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXC_IDX, + PIN_KSZ8051MNL_TXC_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXEN_IDX, + PIN_KSZ8051MNL_TXEN_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXD3_IDX, + PIN_KSZ8051MNL_TXD3_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXD2_IDX, + PIN_KSZ8051MNL_TXD2_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXD1_IDX, + PIN_KSZ8051MNL_TXD1_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_TXD0_IDX, + PIN_KSZ8051MNL_TXD0_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXD3_IDX, + PIN_KSZ8051MNL_RXD3_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXD2_IDX, + PIN_KSZ8051MNL_RXD2_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXD1_IDX, + PIN_KSZ8051MNL_RXD1_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXD0_IDX, + PIN_KSZ8051MNL_RXD0_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXER_IDX, + PIN_KSZ8051MNL_RXER_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_RXDV_IDX, + PIN_KSZ8051MNL_RXDV_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_CRS_IDX, + PIN_KSZ8051MNL_CRS_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_COL_IDX, + PIN_KSZ8051MNL_COL_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_MDC_IDX, + PIN_KSZ8051MNL_MDC_FLAGS); + ioport_set_pin_peripheral_mode(PIN_KSZ8051MNL_MDIO_IDX, + PIN_KSZ8051MNL_MDIO_FLAGS); + ioport_set_pin_dir(PIN_KSZ8051MNL_INTRP_IDX, IOPORT_DIR_INPUT); +#endif + +#ifdef CONF_BOARD_TFDU4300_SD + /* Configure IrDA transceiver shutdown pin */ + ioport_set_pin_dir(PIN_IRDA_SD_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(PIN_IRDA_SD_IDX, IOPORT_PIN_LEVEL_HIGH); +#endif + +#ifdef CONF_BOARD_ADM3485_RE + /* Configure RS485 transceiver RE pin */ + ioport_set_pin_dir(PIN_RE_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(PIN_RE_IDX, IOPORT_PIN_LEVEL_LOW); +#endif + +#ifdef CONF_BOARD_ISO7816_RST + /* Configure ISO7816 card reset pin */ + ioport_set_pin_dir(PIN_ISO7816_RST_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_level(PIN_ISO7816_RST_IDX, IOPORT_PIN_LEVEL_LOW); +#endif + +#ifdef CONF_BOARD_ISO7816 + /* Configure ISO7816 interface TXD & SCK pin */ + ioport_set_pin_peripheral_mode(PIN_USART1_TXD_IDX, PIN_USART1_TXD_FLAGS); + ioport_set_pin_peripheral_mode(PIN_USART1_SCK_IDX, PIN_USART1_SCK_FLAGS); +#endif + +#ifdef CONF_BOARD_NAND + ioport_set_pin_peripheral_mode(PIN_EBI_NANDOE, PIN_EBI_NANDOE_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDWE, PIN_EBI_NANDWE_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDCLE, PIN_EBI_NANDCLE_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDALE, PIN_EBI_NANDALE_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_0, PIN_EBI_NANDIO_0_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_1, PIN_EBI_NANDIO_1_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_2, PIN_EBI_NANDIO_2_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_3, PIN_EBI_NANDIO_3_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_4, PIN_EBI_NANDIO_4_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_5, PIN_EBI_NANDIO_5_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_6, PIN_EBI_NANDIO_6_FLAGS); + ioport_set_pin_peripheral_mode(PIN_EBI_NANDIO_7, PIN_EBI_NANDIO_7_FLAGS); + ioport_set_pin_dir(PIN_NF_CE_IDX, IOPORT_DIR_OUTPUT); + ioport_set_pin_dir(PIN_NF_RB_IDX, IOPORT_DIR_INPUT); + ioport_set_pin_mode(PIN_NF_RB_IDX, IOPORT_MODE_PULLUP); +#endif + + +#ifdef CONF_BOARD_QTOUCH + /* Configure CHANGE pin for QTouch device */ + ioport_set_pin_input_mode(BOARD_QT_CHANGE_PIN_IDX, BOARD_QT_CHANGE_PIN_FLAGS, + BOARD_QT_CHANGE_PIN_SENSE); +#endif +} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/led.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/led.h new file mode 100644 index 0000000..9d5f1d3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/led.h @@ -0,0 +1,81 @@ +/** + * \file + * + * \brief SAM4E-EK LEDs support package. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef LED_H_INCLUDED +#define LED_H_INCLUDED + +#include "compiler.h" +#include "ioport.h" + +/** + * \brief Turns off the specified LEDs. + * + * \param led LED to turn off (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_Off(led) ioport_set_pin_level(led##_GPIO, led##_INACTIVE_LEVEL) + +/** + * \brief Turns on the specified LEDs. + * + * \param led LED to turn on (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_On(led) ioport_set_pin_level(led##_GPIO, led##_ACTIVE_LEVEL) + +/** + * \brief Toggles the specified LEDs. + * + * \param led LED to toggle (LEDx_GPIO). + * + * \note The pins of the specified LEDs are set to GPIO output mode. + */ +#define LED_Toggle(led) ioport_toggle_pin_level(led##_GPIO) + + +#endif // LED_H_INCLUDED diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/sam4e_ek.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/sam4e_ek.h new file mode 100644 index 0000000..683b313 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/boards/sam4e_ek/sam4e_ek.h @@ -0,0 +1,814 @@ +/** + * \file + * + * \brief SAM4E-EK Board Definition. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_EK_H_ +#define _SAM4E_EK_H_ + +#include "compiler.h" +#include "system_sam4e.h" +#include "exceptions.h" + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_opfreq "SAM4E-EK - Operating frequencies" + * This page lists several definition related to the board operating frequency + * + * \section Definitions + * - \ref BOARD_FREQ_* + * - \ref BOARD_MCK + */ + +/** Board oscillator settings */ +#define BOARD_FREQ_SLCK_XTAL (32768U) +#define BOARD_FREQ_SLCK_BYPASS (32768U) +#define BOARD_FREQ_MAINCK_XTAL (12000000U) +#define BOARD_FREQ_MAINCK_BYPASS (12000000U) + +/** Master clock frequency */ +#define BOARD_MCK CHIP_FREQ_CPU_MAX + +/** board main clock xtal startup time */ +#define BOARD_OSC_STARTUP_US 15625 + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_board_info "SAM4E-EK - Board informations" + * This page lists several definition related to the board description. + * + * \section Definitions + * - \ref BOARD_NAME + */ + +/** Name of the board */ +#define BOARD_NAME "SAM4E-EK" +/** Board definition */ +#define sam4eek +/** Family definition (already defined) */ +#define sam4e +/** Core definition */ +#define cortexm4 + +/*----------------------------------------------------------------------------*/ + +/** UART0 pins (UTXD0 and URXD0) definitions, PA10,9. */ +#define PINS_UART0 (PIO_PA9A_URXD0 | PIO_PA10A_UTXD0) +#define PINS_UART0_FLAGS (IOPORT_MODE_MUX_A) + +#define PINS_UART0_PORT IOPORT_PIOA +#define PINS_UART0_MASK (PIO_PA9A_URXD0 | PIO_PA10A_UTXD0) +#define PINS_UART0_PIO PIOA +#define PINS_UART0_ID ID_PIOA +#define PINS_UART0_TYPE PIO_PERIPH_A +#define PINS_UART0_ATTR PIO_DEFAULT + +/** UART1 pins (UTXD1 and URXD1) definitions, PA6,5. */ +#define PINS_UART1 (PIO_PA6C_URXD1 | PIO_PA5C_UTXD1) +#define PINS_UART1_FLAGS (IOPORT_MODE_MUX_C) + +#define PINS_UART1_PORT IOPORT_PIOA +#define PINS_UART1_MASK (PIO_PA6C_URXD1 | PIO_PA5C_UTXD1) +#define PINS_UART1_PIO PIOA +#define PINS_UART1_ID ID_PIOA +#define PINS_UART1_TYPE PIO_PERIPH_C +#define PINS_UART1_ATTR PIO_DEFAULT + +/** LED #0 pin definition (Blue). */ +#define LED_0_NAME "Blue LED D2" +#define PIN_LED_0 {PIO_PA0, PIOA, ID_PIOA, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_LED_0_MASK PIO_PA0 +#define PIN_LED_0_PIO PIOA +#define PIN_LED_0_ID ID_PIOA +#define PIN_LED_0_TYPE PIO_OUTPUT_1 +#define PIN_LED_0_ATTR PIO_DEFAULT + +#define LED0_GPIO (PIO_PA0_IDX) +#define LED0_FLAGS (0) +#define LED0_ACTIVE_LEVEL IOPORT_PIN_LEVEL_LOW +#define LED0_INACTIVE_LEVEL IOPORT_PIN_LEVEL_HIGH + +/** LED #1 pin definition (Amber). */ +#define LED_1_NAME "Amber LED D3" +#define PIN_LED_1 {PIO_PD20, PIOD, ID_PIOD, PIO_OUTPUT_1, PIO_DEFAULT} +#define PIN_LED_1_MASK PIO_PD20 +#define PIN_LED_1_PIO PIOD +#define PIN_LED_1_ID ID_PIOD +#define PIN_LED_1_TYPE PIO_OUTPUT_1 +#define PIN_LED_1_ATTR PIO_DEFAULT + +#define LED1_GPIO (PIO_PD20_IDX) +#define LED1_FLAGS (0) +#define LED1_ACTIVE_LEVEL IOPORT_PIN_LEVEL_LOW +#define LED1_INACTIVE_LEVEL IOPORT_PIN_LEVEL_HIGH + +/** LED #2 pin definition (Green). */ +#define LED_2_NAME "Green LED D4" +#define PIN_LED_2_MASK PIO_PD21 +#define PIN_LED_2_PIO PIOD +#define PIN_LED_2_ID ID_PIOD +#define PIN_LED_2_TYPE PIO_OUTPUT_1 +#define PIN_LED_2_ATTR PIO_DEFAULT + +#define LED2_GPIO (PIO_PD21_IDX) +#define LED2_FLAGS (0) +#define LED2_ACTIVE_LEVEL IOPORT_PIN_LEVEL_LOW +#define LED2_INACTIVE_LEVEL IOPORT_PIN_LEVEL_HIGH + +/** LED #3 pin definition (Red). */ +#define LED_3_NAME "Red LED D5" +#define PIN_LED_3_MASK PIO_PD22 +#define PIN_LED_3_PIO PIOD +#define PIN_LED_3_ID ID_PIOD +#define PIN_LED_3_TYPE PIO_OUTPUT_0 +#define PIN_LED_3_ATTR PIO_DEFAULT + +#define LED3_GPIO (PIO_PD22_IDX) +#define LED3_FLAGS (0) +#define LED3_ACTIVE_LEVEL IOPORT_PIN_LEVEL_HIGH +#define LED3_INACTIVE_LEVEL IOPORT_PIN_LEVEL_LOW + +#define BOARD_NUM_OF_LED 4 + +/** HSMCI pins definition. */ +/*! Number of slot connected on HSMCI interface */ +#define SD_MMC_HSMCI_MEM_CNT 1 +#define SD_MMC_HSMCI_SLOT_0_SIZE 4 +#define PINS_HSMCI {0x3fUL << 26, PIOA, ID_PIOA, PIO_PERIPH_C, PIO_PULLUP} +/** HSMCI MCCDA pin definition. */ +#define PIN_HSMCI_MCCDA_GPIO (PIO_PA28_IDX) +#define PIN_HSMCI_MCCDA_FLAGS (IOPORT_MODE_MUX_C) +/** HSMCI MCCK pin definition. */ +#define PIN_HSMCI_MCCK_GPIO (PIO_PA29_IDX) +#define PIN_HSMCI_MCCK_FLAGS (IOPORT_MODE_MUX_C) +/** HSMCI MCDA0 pin definition. */ +#define PIN_HSMCI_MCDA0_GPIO (PIO_PA30_IDX) +#define PIN_HSMCI_MCDA0_FLAGS (IOPORT_MODE_MUX_C) +/** HSMCI MCDA1 pin definition. */ +#define PIN_HSMCI_MCDA1_GPIO (PIO_PA31_IDX) +#define PIN_HSMCI_MCDA1_FLAGS (IOPORT_MODE_MUX_C) +/** HSMCI MCDA2 pin definition. */ +#define PIN_HSMCI_MCDA2_GPIO (PIO_PA26_IDX) +#define PIN_HSMCI_MCDA2_FLAGS (IOPORT_MODE_MUX_C) +/** HSMCI MCDA3 pin definition. */ +#define PIN_HSMCI_MCDA3_GPIO (PIO_PA27_IDX) +#define PIN_HSMCI_MCDA3_FLAGS (IOPORT_MODE_MUX_C) + +/** SD/MMC card detect pin definition. */ +#define PIN_HSMCI_CD {PIO_PA6, PIOA, ID_PIOA, PIO_INPUT, PIO_PULLUP} +#define SD_MMC_0_CD_GPIO (PIO_PA6_IDX) +#define SD_MMC_0_CD_PIO_ID ID_PIOA +#define SD_MMC_0_CD_FLAGS (IOPORT_MODE_PULLUP) +#define SD_MMC_0_CD_DETECT_VALUE 0 + +/** + * Push button #0 definition. Attributes = pull-up + debounce + interrupt on + * rising edge. + */ +#define PUSHBUTTON_1_NAME "BP2 WAKU" +#define PUSHBUTTON_1_WKUP_LINE (9) +#define PUSHBUTTON_1_WKUP_FSTT (PMC_FSMR_FSTT9) +#define GPIO_PUSH_BUTTON_1 (PIO_PA19_IDX) +#define GPIO_PUSH_BUTTON_1_FLAGS (IOPORT_MODE_PULLUP | IOPORT_MODE_DEBOUNCE) +#define GPIO_PUSH_BUTTON_1_SENSE (IOPORT_SENSE_RISING) + +#define PIN_PUSHBUTTON_1 {PIO_PA19, PIOA, ID_PIOA, PIO_INPUT, \ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE} +#define PIN_PUSHBUTTON_1_MASK PIO_PA19 +#define PIN_PUSHBUTTON_1_PIO PIOA +#define PIN_PUSHBUTTON_1_ID ID_PIOA +#define PIN_PUSHBUTTON_1_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_1_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE) +#define PIN_PUSHBUTTON_1_IRQn PIOA_IRQn + +/** + * Push button #1 definition. Attributes = pull-up + debounce + interrupt on + * falling edge. + */ +#define PUSHBUTTON_2_NAME "BP3 TAMP" +#define PUSHBUTTON_2_WKUP_LINE (10) +#define PUSHBUTTON_2_WKUP_FSTT (PMC_FSMR_FSTT10) +#define GPIO_PUSH_BUTTON_2 (PIO_PA20_IDX) +#define GPIO_PUSH_BUTTON_2_FLAGS (IOPORT_MODE_PULLUP | IOPORT_MODE_DEBOUNCE) +#define GPIO_PUSH_BUTTON_2_SENSE (IOPORT_SENSE_FALLING) + +#define PIN_PUSHBUTTON_2 {PIO_PA20, PIOA, ID_PIOA, PIO_INPUT, \ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE} +#define PIN_PUSHBUTTON_2_MASK PIO_PA20 +#define PIN_PUSHBUTTON_2_PIO PIOA +#define PIN_PUSHBUTTON_2_ID ID_PIOA +#define PIN_PUSHBUTTON_2_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_2_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_FALL_EDGE) +#define PIN_PUSHBUTTON_2_IRQn PIOA_IRQn + +/** + * Push button #2 definition. Attributes = pull-up + debounce + interrupt on + * both edges. + */ +#define PUSHBUTTON_3_NAME "BP4 SCROLL-UP" +#define PUSHBUTTON_3_WKUP_LINE (1) +#define PUSHBUTTON_3_WKUP_FSTT (PMC_FSMR_FSTT1) +#define GPIO_PUSH_BUTTON_3 (PIO_PA1_IDX) +#define GPIO_PUSH_BUTTON_3_FLAGS (IOPORT_MODE_PULLUP | IOPORT_MODE_DEBOUNCE) +#define GPIO_PUSH_BUTTON_3_SENSE (IOPORT_SENSE_BOTHEDGES) + +#define PIN_PUSHBUTTON_3 {PIO_PA1, PIOA, ID_PIOA, PIO_INPUT, \ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE} +#define PIN_PUSHBUTTON_3_MASK PIO_PA1 +#define PIN_PUSHBUTTON_3_PIO PIOA +#define PIN_PUSHBUTTON_3_ID ID_PIOA +#define PIN_PUSHBUTTON_3_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_3_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE) +#define PIN_PUSHBUTTON_3_IRQn PIOA_IRQn + +/** + * Push button #3 definition. Attributes = pull-up + debounce + interrupt on + * rising edge. + */ +#define PUSHBUTTON_4_NAME "BP5 SCROLL-DOWN" +#define PUSHBUTTON_4_WKUP_LINE (2) +#define PUSHBUTTON_4_WKUP_FSTT (PMC_FSMR_FSTT2) +#define GPIO_PUSH_BUTTON_4 (PIO_PA2_IDX) +#define GPIO_PUSH_BUTTON_4_FLAGS (IOPORT_MODE_PULLUP | IOPORT_MODE_DEBOUNCE) +#define GPIO_PUSH_BUTTON_4_SENSE (IOPORT_SENSE_RISING) + +#define PIN_PUSHBUTTON_4 {PIO_PA2, PIOA, ID_PIOA, PIO_INPUT, \ + PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE} +#define PIN_PUSHBUTTON_4_MASK PIO_PA2 +#define PIN_PUSHBUTTON_4_PIO PIOA +#define PIN_PUSHBUTTON_4_ID ID_PIOA +#define PIN_PUSHBUTTON_4_TYPE PIO_INPUT +#define PIN_PUSHBUTTON_4_ATTR (PIO_PULLUP | PIO_DEBOUNCE | PIO_IT_RISE_EDGE) +#define PIN_PUSHBUTTON_4_IRQn PIOA_IRQn + +/** List of all push button definitions. */ +#define PINS_PUSHBUTTONS {PIN_PUSHBUTTON_1, PIN_PUSHBUTTON_2,\ + PIN_PUSHBUTTON_3, PIN_PUSHBUTTON_4} + +#define PIN_TC0_TIOA0 (PIO_PA0_IDX) +#define PIN_TC0_TIOA0_MUX (IOPORT_MODE_MUX_B) +#define PIN_TC0_TIOA0_FLAGS (IOPORT_MODE_MUX_B) + +#define PIN_TC0_TIOA1 (PIO_PA15_IDX) +#define PIN_TC0_TIOA1_MUX (IOPORT_MODE_MUX_B) +#define PIN_TC0_TIOA1_FLAGS (IOPORT_MODE_MUX_B) + +#define PIN_TC0_TIOA1_PIO PIOA +#define PIN_TC0_TIOA1_MASK PIO_PA15 +#define PIN_TC0_TIOA1_ID ID_PIOA +#define PIN_TC0_TIOA1_TYPE PIO_PERIPH_B +#define PIN_TC0_TIOA1_ATTR PIO_DEFAULT + +#define PIN_TC0_TIOA2 (PIO_PA26_IDX) +#define PIN_TC0_TIOA2_MUX (IOPORT_MODE_MUX_B) +#define PIN_TC0_TIOA2_FLAGS (IOPORT_MODE_MUX_B) + +#define PIN_TC0_TIOA2_PIO PIOA +#define PIN_TC0_TIOA2_MASK PIO_PA26 +#define PIN_TC0_TIOA2_ID ID_PIOA +#define PIN_TC0_TIOA2_TYPE PIO_PERIPH_B +#define PIN_TC0_TIOA2_ATTR PIO_DEFAULT + +/** PWM LED0 pin definitions. */ +#define PIN_PWM_LED0_GPIO PIO_PD20_IDX +#define PIN_PWM_LED0_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_PWM_LED0_CHANNEL PWM_CHANNEL_0 + +/** PWM LED1 pin definitions. */ +#define PIN_PWM_LED1_GPIO PIO_PD21_IDX +#define PIN_PWM_LED1_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_PWM_LED1_CHANNEL PWM_CHANNEL_1 + +/** PWM LED2 pin definitions. */ +#define PIN_PWM_LED2_GPIO PIO_PD22_IDX +#define PIN_PWM_LED2_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_PWM_LED2_CHANNEL PWM_CHANNEL_2 + +/** PWM LED3 pin definitions. */ +#define PIN_PWM_LED3_GPIO PIO_PA0_IDX +#define PIN_PWM_LED3_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_PWM_LED3_CHANNEL PWM_CHANNEL_0 + + +/** SPI MISO pin definition. */ +#define SPI_MISO_GPIO (PIO_PA12_IDX) +#define SPI_MISO_FLAGS (IOPORT_MODE_MUX_A) +/** SPI MOSI pin definition. */ +#define SPI_MOSI_GPIO (PIO_PA13_IDX) +#define SPI_MOSI_FLAGS (IOPORT_MODE_MUX_A) +/** SPI SPCK pin definition. */ +#define SPI_SPCK_GPIO (PIO_PA14_IDX) +#define SPI_SPCK_FLAGS (IOPORT_MODE_MUX_A) + +/** SPI chip select 0 pin definition. (Only one configuration is possible) */ +#define SPI_NPCS0_GPIO (PIO_PA11_IDX) +#define SPI_NPCS0_FLAGS (IOPORT_MODE_MUX_A) +/** SPI chip select 1 pin definition. (multiple configurations are possible) */ +#define SPI_NPCS1_PA9_GPIO (PIO_PA9_IDX) +#define SPI_NPCS1_PA9_FLAGS (IOPORT_MODE_MUX_B) +#define SPI_NPCS1_PA31_GPIO (PIO_PA31_IDX) +#define SPI_NPCS1_PA31_FLAGS (IOPORT_MODE_MUX_A) +#define SPI_NPCS1_PB14_GPIO (PIO_PB14_IDX) +#define SPI_NPCS1_PB14_FLAGS (IOPORT_MODE_MUX_A) +#define SPI_NPCS1_PC4_GPIO (PIO_PC4_IDX) +#define SPI_NPCS1_PC4_FLAGS (IOPORT_MODE_MUX_B) +/** SPI chip select 2 pin definition. (multiple configurations are possible) */ +#define SPI_NPCS2_PA10_GPIO (PIO_PA10_IDX) +#define SPI_NPCS2_PA10_FLAGS (IOPORT_MODE_MUX_B) +#define SPI_NPCS2_PA30_GPIO (PIO_PA30_IDX) +#define SPI_NPCS2_PA30_FLAGS (IOPORT_MODE_MUX_B) +#define SPI_NPCS2_PB2_GPIO (PIO_PB2_IDX) +#define SPI_NPCS2_PB2_FLAGS (IOPORT_MODE_MUX_B) +/** SPI chip select 3 pin definition. (multiple configurations are possible) */ +#define SPI_NPCS3_PA3_GPIO (PIO_PA3_IDX) +#define SPI_NPCS3_PA3_FLAGS (IOPORT_MODE_MUX_B) +#define SPI_NPCS3_PA5_GPIO (PIO_PA5_IDX) +#define SPI_NPCS3_PA5_FLAGS (IOPORT_MODE_MUX_B) +#define SPI_NPCS3_PA22_GPIO (PIO_PA22_IDX) +#define SPI_NPCS3_PA22_FLAGS (IOPORT_MODE_MUX_B) + +/* Select the SPI module that AT25DFx is connected to */ +#define AT25DFX_SPI_MODULE SPI + +/* Chip select used by AT25DFx components on the SPI module instance */ +#define AT25DFX_CS 3 + +/* Touch screen IRQ & Busy pin definition */ +#define BOARD_ADS7843_IRQ_GPIO (PIO_PA16_IDX) +#define BOARD_ADS7843_IRQ_FLAGS IOPORT_MODE_PULLUP +#define BOARD_ADS7843_BUSY_GPIO (PIO_PA17_IDX) +#define BOARD_ADS7843_BUSY_FLAGS IOPORT_MODE_PULLUP +/** +* SPI instance, which can be SPI, SPI0 or SPI1, depends on which SPI +* channel is used. +*/ +#define BOARD_ADS7843_SPI_BASE SPI +/* SPI chip select NO., depends on which SPI CS pin is used by ADS7843. */ +#define BOARD_ADS7843_SPI_NPCS 0 + +/** TWI0 pins definition */ +#define TWI0_DATA_GPIO PIO_PA3_IDX +#define TWI0_DATA_FLAGS (IOPORT_MODE_MUX_A) +#define TWI0_CLK_GPIO PIO_PA4_IDX +#define TWI0_CLK_FLAGS (IOPORT_MODE_MUX_A) + +/** TWI1 pins definition */ +#define TWI1_DATA_GPIO PIO_PB4_IDX +#define TWI1_DATA_FLAGS (IOPORT_MODE_MUX_A) +#define TWI1_CLK_GPIO PIO_PB5_IDX +#define TWI1_CLK_FLAGS (IOPORT_MODE_MUX_A) + +/** PCK0 pin definition (PA6) */ +#define PIN_PCK0 (PIO_PA6_IDX) +#define PIN_PCK0_MUX (IOPORT_MODE_MUX_B) +#define PIN_PCK0_FLAGS (IOPORT_MODE_MUX_B) +#define PIN_PCK0_PORT IOPORT_PIOA +#define PIN_PCK0_MASK PIO_PA6B_PCK0 +#define PIN_PCK0_PIO PIOA +#define PIN_PCK0_ID ID_PIOA +#define PIN_PCK0_TYPE PIO_PERIPH_B +#define PIN_PCK0_ATTR PIO_DEFAULT + +/** USART0 pin RX */ +#define PIN_USART0_RXD {PIO_PB0C_RXD0, PIOB, ID_PIOB, PIO_PERIPH_C, \ + PIO_DEFAULT} +#define PIN_USART0_RXD_IDX (PIO_PB0_IDX) +#define PIN_USART0_RXD_FLAGS (IOPORT_MODE_MUX_C) +/** USART0 pin TX */ +#define PIN_USART0_TXD {PIO_PB1C_TXD0, PIOB, ID_PIOB, PIO_PERIPH_C, \ + PIO_DEFAULT} +#define PIN_USART0_TXD_IDX (PIO_PB1_IDX) +#define PIN_USART0_TXD_FLAGS (IOPORT_MODE_MUX_C) +/** USART0 pin CTS */ +#define PIN_USART0_CTS {PIO_PB2C_CTS0, PIOB, ID_PIOB, PIO_PERIPH_C, \ + PIO_DEFAULT} +#define PIN_USART0_CTS_IDX (PIO_PB2_IDX) +#define PIN_USART0_CTS_FLAGS (IOPORT_MODE_MUX_C) +/** USART0 pin RTS */ +#define PIN_USART0_RTS {PIO_PB3C_RTS0, PIOB, ID_PIOB, PIO_PERIPH_C, \ + PIO_DEFAULT} +#define PIN_USART0_RTS_IDX (PIO_PB3_IDX) +#define PIN_USART0_RTS_FLAGS (IOPORT_MODE_MUX_C) +/** USART0 pin SCK */ +#define PIN_USART0_SCK {PIO_PB13C_SCK0, PIOB, ID_PIOB, PIO_PERIPH_C, \ + PIO_DEFAULT} +#define PIN_USART0_SCK_IDX (PIO_PB13_IDX) +#define PIN_USART0_SCK_FLAGS (IOPORT_MODE_MUX_C) + +/** USART1 pin RX */ +#define PIN_USART1_RXD {PIO_PA21A_RXD1, PIOA, ID_PIOA, PIO_PERIPH_A, \ + PIO_DEFAULT} +#define PIN_USART1_RXD_IDX (PIO_PA21_IDX) +#define PIN_USART1_RXD_FLAGS (IOPORT_MODE_MUX_A) +/** USART1 pin TX */ +#define PIN_USART1_TXD {PIO_PA22A_TXD1, PIOA, ID_PIOA, PIO_PERIPH_A, \ + PIO_DEFAULT} +#define PIN_USART1_TXD_IDX (PIO_PA22_IDX) +#define PIN_USART1_TXD_FLAGS (IOPORT_MODE_MUX_A) +/** USART1 pin CTS */ +#define PIN_USART1_CTS {PIO_PA25A_CTS1, PIOA, ID_PIOA, PIO_PERIPH_A, \ + PIO_DEFAULT} +#define PIN_USART1_CTS_IDX (PIO_PA25_IDX) +#define PIN_USART1_CTS_FLAGS (IOPORT_MODE_MUX_A) +/** USART1 pin RTS */ +#define PIN_USART1_RTS {PIO_PA24A_RTS1, PIOA, ID_PIOA, PIO_PERIPH_A, \ + PIO_DEFAULT} +#define PIN_USART1_RTS_IDX (PIO_PA24_IDX) +#define PIN_USART1_RTS_FLAGS (IOPORT_MODE_MUX_A) +/** USART1 pin SCK */ +#define PIN_USART1_SCK {PIO_PA23A_SCK1, PIOA, ID_PIOA, PIO_PERIPH_A, \ + PIO_DEFAULT} +#define PIN_USART1_SCK_IDX (PIO_PA23_IDX) +#define PIN_USART1_SCK_FLAGS (IOPORT_MODE_MUX_A) +/** USART1 pin ENABLE */ +#define PIN_USART1_EN {PIO_PA23, PIOA, ID_PIOA, PIO_OUTPUT_0, \ + PIO_DEFAULT} +#define PIN_USART1_EN_IDX (PIO_PA23_IDX) +#define PIN_USART1_EN_FLAGS (0) +#define PIN_USART1_EN_ACTIVE_LEVEL IOPORT_PIN_LEVEL_LOW +#define PIN_USART1_EN_INACTIVE_LEVEL IOPORT_PIN_LEVEL_HIGH + +/** USB VBus monitoring pin definition. */ +#define PIN_USB_VBUS {PIO_PC21, PIOC, ID_PIOC, PIO_INPUT, PIO_PULLUP} +#define USB_VBUS_FLAGS (PIO_INPUT | PIO_DEBOUNCE | PIO_IT_EDGE) +#define USB_VBUS_PIN_IRQn (PIOC_IRQn) +#define USB_VBUS_PIN (PIO_PC21_IDX) +#define USB_VBUS_PIO_ID (ID_PIOC) +#define USB_VBUS_PIO_MASK (PIO_PC21) +/* This pin can not be used as fast wakeup source such as + * USB_VBUS_WKUP PMC_FSMR_FSTT7 */ + +/** USB D- pin (System function) */ +#define PIN_USB_DM {PIO_PB10} +/** USB D+ pin (System function) */ +#define PIN_USB_DP {PIO_PB11} + +/** EBI Data Bus pins */ +#define PIN_EBI_DATA_BUS_D0 PIO_PC0_IDX +#define PIN_EBI_DATA_BUS_D1 PIO_PC1_IDX +#define PIN_EBI_DATA_BUS_D2 PIO_PC2_IDX +#define PIN_EBI_DATA_BUS_D3 PIO_PC3_IDX +#define PIN_EBI_DATA_BUS_D4 PIO_PC4_IDX +#define PIN_EBI_DATA_BUS_D5 PIO_PC5_IDX +#define PIN_EBI_DATA_BUS_D6 PIO_PC6_IDX +#define PIN_EBI_DATA_BUS_D7 PIO_PC7_IDX +#define PIN_EBI_DATA_BUS_FLAGS (IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP) + +#define PIN_EBI_NRD PIO_PC11_IDX +#define PIN_EBI_NRD_FLAGS (IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP) +#define PIN_EBI_NWE PIO_PC8_IDX +#define PIN_EBI_NWE_FLAGS (IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP) + +/** EBI pin for LCD CS and RS **/ +#define PIN_EBI_NCS1 PIO_PD18_IDX +#define PIN_EBI_NCS1_FLAGS (IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP) +#define PIN_EBI_LCD_RS PIO_PC19_IDX +#define PIN_EBI_LCD_RS_FLAGS (IOPORT_MODE_MUX_A | IOPORT_MODE_PULLUP) + +/** Indicates board has an ILI9325 external component to manage LCD. */ +#define BOARD_LCD_ILI93XX + +/** Backlight pin definition. */ +#define BOARD_AAT31XX_SET_GPIO PIO_PC13_IDX +/** Define ILI93xx base address. */ +#define BOARD_ILI93XX_ADDR 0x61000000 +/** Define ILI9325 register select signal. */ +#define BOARD_ILI93XX_RS (1 << 1) +/** Display width in pixels. */ +#define BOARD_LCD_WIDTH 240 +/** Display height in pixels. */ +#define BOARD_LCD_HEIGHT 320 + +/* KSZ8051MNL relate PIN definition */ +#define PIN_KSZ8051MNL_RXC_IDX PIO_PD14_IDX +#define PIN_KSZ8051MNL_RXC_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXC_IDX PIO_PD0_IDX +#define PIN_KSZ8051MNL_TXC_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXEN_IDX PIO_PD1_IDX +#define PIN_KSZ8051MNL_TXEN_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXD3_IDX PIO_PD16_IDX +#define PIN_KSZ8051MNL_TXD3_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXD2_IDX PIO_PD15_IDX +#define PIN_KSZ8051MNL_TXD2_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXD1_IDX PIO_PD3_IDX +#define PIN_KSZ8051MNL_TXD1_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_TXD0_IDX PIO_PD2_IDX +#define PIN_KSZ8051MNL_TXD0_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXD3_IDX PIO_PD12_IDX +#define PIN_KSZ8051MNL_RXD3_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXD2_IDX PIO_PD11_IDX +#define PIN_KSZ8051MNL_RXD2_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXD1_IDX PIO_PD6_IDX +#define PIN_KSZ8051MNL_RXD1_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXD0_IDX PIO_PD5_IDX +#define PIN_KSZ8051MNL_RXD0_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXER_IDX PIO_PD7_IDX +#define PIN_KSZ8051MNL_RXER_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_RXDV_IDX PIO_PD4_IDX +#define PIN_KSZ8051MNL_RXDV_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_CRS_IDX PIO_PD10_IDX +#define PIN_KSZ8051MNL_CRS_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_COL_IDX PIO_PD13_IDX +#define PIN_KSZ8051MNL_COL_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_MDC_IDX PIO_PD8_IDX +#define PIN_KSZ8051MNL_MDC_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_MDIO_IDX PIO_PD9_IDX +#define PIN_KSZ8051MNL_MDIO_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_KSZ8051MNL_INTRP_IDX PIO_PD28_IDX + +/** NandFlash pins definition: OE. */ +#define PIN_EBI_NANDOE (PIO_PC9_IDX) +#define PIN_EBI_NANDOE_FLAGS (IOPORT_MODE_MUX_A) + +/** NandFlash pins definition: WE. */ +#define PIN_EBI_NANDWE (PIO_PC10_IDX) +#define PIN_EBI_NANDWE_FLAGS (IOPORT_MODE_MUX_A) + +/** NandFlash pins definition: CLE. */ +#define PIN_EBI_NANDCLE (PIO_PC17_IDX) +#define PIN_EBI_NANDCLE_FLAGS (IOPORT_MODE_MUX_A) + +/** NandFlash pins definition: ALE. */ +#define PIN_EBI_NANDALE (PIO_PC16_IDX) +#define PIN_EBI_NANDALE_FLAGS (IOPORT_MODE_MUX_A) + +/** NandFlash pins definition: DATA. */ +#define PIN_EBI_NANDIO_0 (PIO_PC0_IDX) +#define PIN_EBI_NANDIO_0_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_1 (PIO_PC1_IDX) +#define PIN_EBI_NANDIO_1_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_2 (PIO_PC2_IDX) +#define PIN_EBI_NANDIO_2_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_3 (PIO_PC3_IDX) +#define PIN_EBI_NANDIO_3_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_4 (PIO_PC4_IDX) +#define PIN_EBI_NANDIO_4_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_5 (PIO_PC5_IDX) +#define PIN_EBI_NANDIO_5_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_6 (PIO_PC6_IDX) +#define PIN_EBI_NANDIO_6_FLAGS (IOPORT_MODE_MUX_A) + +#define PIN_EBI_NANDIO_7 (PIO_PC7_IDX) +#define PIN_EBI_NANDIO_7_FLAGS (IOPORT_MODE_MUX_A) + +/** Nandflash chip enable pin definition. */ +#define PIN_NF_CE_IDX (PIO_PC14_IDX) + +/** Nandflash ready/busy pin definition. */ +#define PIN_NF_RB_IDX (PIO_PC18_IDX) + +/* Chip select number for nand */ +#define BOARD_NAND_CS 0 + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_usb "SAM4E-EK - USB device" + * + * \section Definitions + * - \ref BOARD_USB_BMATTRIBUTES + * - \ref CHIP_USB_UDP + * - \ref CHIP_USB_PULLUP_INTERNAL + * - \ref CHIP_USB_NUMENDPOINTS + * - \ref CHIP_USB_ENDPOINTS_MAXPACKETSIZE + * - \ref CHIP_USB_ENDPOINTS_BANKS + */ + +/** + * USB attributes configuration descriptor (bus or self powered, + * remote wakeup) + */ +#define BOARD_USB_BMATTRIBUTES USBConfigurationDescriptor_SELFPOWERED_RWAKEUP + +/** Indicates chip has an UDP Full Speed. */ +#define CHIP_USB_UDP + +/** Indicates chip has an internal pull-up. */ +#define CHIP_USB_PULLUP_INTERNAL + +/** Number of USB endpoints */ +#define CHIP_USB_NUMENDPOINTS 8 + +/** Endpoints max packet size */ +#define CHIP_USB_ENDPOINTS_MAXPACKETSIZE(i) \ + ((i == 0) ? 64 : \ + ((i == 1) ? 64 : \ + ((i == 2) ? 64 : \ + ((i == 3) ? 64 : \ + ((i == 4) ? 512 : \ + ((i == 5) ? 512 : \ + ((i == 6) ? 64 : \ + ((i == 7) ? 64 : 0 )))))))) + +/** Endpoints Number of Bank */ +#define CHIP_USB_ENDPOINTS_BANKS(i) \ + ((i == 0) ? 1 : \ + ((i == 1) ? 2 : \ + ((i == 2) ? 2 : \ + ((i == 3) ? 1 : \ + ((i == 4) ? 2 : \ + ((i == 5) ? 2 : \ + ((i == 6) ? 2 : \ + ((i == 7) ? 2 : 0 )))))))) + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_extcomp "SAM4E-EK - External components" + * This page lists the definitions related to external on-board components + * located in the board.h file for the SAM4E-EK. + * + * SD Card + * - \ref BOARD_SD_PINS + * - \ref BOARD_SD_PIN_CD + * + * QTouch component (QT2160) + * - \ref BOARD_QT_TWI_INSTANCE + * - \ref BOARD_QT_DEVICE_ADDRESS + * - \ref BOARD_QT_CHANGE_PIN_IDX + * - \ref BOARD_QT_CHANGE_PIN_FLAGS + * - \ref BOARD_QT_CHANGE_PIN_SENSE + */ + +/** HSMCI pins that shall be configured to access the SD card. */ +#define BOARD_SD_PINS PINS_HSMCI +/** HSMCI Card Detect pin. */ +#define BOARD_SD_PIN_CD PIN_HSMCI_CD + +/** TWI instance for QTouch device */ +#define BOARD_QT_TWI_INSTANCE TWI0 +/* QTouch device address (I2CA1 = I2CA0 = 0) */ +#define BOARD_QT_DEVICE_ADDRESS 0x0D +/** QTouch component pin definition */ +#define BOARD_QT_CHANGE_PIN_IDX (PIO_PE4_IDX) +#define BOARD_QT_CHANGE_PIN_FLAGS (IOPORT_MODE_PULLUP | IOPORT_MODE_DEBOUNCE) +#define BOARD_QT_CHANGE_PIN_SENSE (IOPORT_SENSE_FALLING) + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_mem "SAM4E-EK - Memories" + * This page lists definitions related to internal & external on-board memories. + * + * \section NandFlash + * - \ref BOARD_NF_COMMAND_ADDR + * - \ref BOARD_NF_ADDRESS_ADDR + * - \ref BOARD_NF_DATA_ADDR + * + * \section NorFlash + * - \ref BOARD_NORFLASH_ADDR + * - \ref BOARD_NORFLASH_DFT_BUS_SIZE + */ + +/** Address for transferring command bytes to the nandflash. */ +#define BOARD_NF_COMMAND_ADDR 0x60400000 +/** Address for transferring address bytes to the nandflash. */ +#define BOARD_NF_ADDRESS_ADDR 0x60200000 +/** Address for transferring data bytes to the nandflash. */ +#define BOARD_NF_DATA_ADDR 0x60000000 +/* Bus width for NAND */ +#define CONF_NF_BUSWIDTH 8 +/* Access timing for NAND */ +#define CONF_NF_SETUP_TIMING (SMC_SETUP_NWE_SETUP(0) \ + | SMC_SETUP_NCS_WR_SETUP(1) \ + | SMC_SETUP_NRD_SETUP(0) \ + | SMC_SETUP_NCS_RD_SETUP(1)) +#define CONF_NF_PULSE_TIMING (SMC_PULSE_NWE_PULSE(2) \ + | SMC_PULSE_NCS_WR_PULSE(3) \ + | SMC_PULSE_NRD_PULSE(4) \ + | SMC_PULSE_NCS_RD_PULSE(4)) +#define CONF_NF_CYCLE_TIMING (SMC_CYCLE_NWE_CYCLE(4) \ + | SMC_CYCLE_NRD_CYCLE(7)) + +/** Address for transferring command bytes to the norflash. */ +#define BOARD_NORFLASH_ADDR 0x63000000 +/** Default NOR bus size after power up reset */ +#define BOARD_NORFLASH_DFT_BUS_SIZE 8 + +/*----------------------------------------------------------------------------*/ + +#define CONSOLE_UART UART0 +#define CONSOLE_UART_ID ID_UART0 + +/* RE pin. */ +#define PIN_RE_IDX PIN_USART1_CTS_IDX +#define PIN_RE_FLAGS (0) + +/* IRDA SD pin. */ +#define PIN_IRDA_SD_IDX PIN_USART1_CTS_IDX +#define PIN_IRDA_SD_FLAGS (0) + +/* TXD pin configuration. */ +#define PIN_USART_TXD_IDX PIN_USART1_TXD_IDX +#define PIN_USART_TXD_FLAGS (IOPORT_MODE_MUX_A) +#define PIN_USART_TXD_IO_FLAGS (0) + +/* ISO7816 example relate PIN definition. */ +#define ISO7816_USART_ID ID_USART1 +#define ISO7816_USART USART1 +#define PIN_ISO7816_RST_IDX PIO_PA15_IDX +#define PIN_ISO7816_RST_FLAG (0) + +/*----------------------------------------------------------------------------*/ +/* GMAC HW configurations */ +#define BOARD_GMAC_PHY_ADDR 0 + +/*----------------------------------------------------------------------------*/ +/** + * \page sam4e_ek_CAN "SAM4E-EK - CAN" + * This page lists definitions related to CAN0 and CAN1. + * + * CAN + * - \ref PIN_CAN0_TRANSCEIVER_RXEN + * - \ref PIN_CAN0_TRANSCEIVER_RS + * - \ref PIN_CAN0_TXD + * - \ref PIN_CAN0_RXD + * - \ref PINS_CAN0 + * + * - \ref PIN_CAN1_TRANSCEIVER_RXEN + * - \ref PIN_CAN1_TRANSCEIVER_RS + * - \ref PIN_CAN1_TXD + * - \ref PIN_CAN1_RXD + * - \ref PINS_CAN1 + */ +/** CAN0 transceiver PIN RS. */ +#define PIN_CAN0_TR_RS_IDX PIO_PE0_IDX +#define PIN_CAN0_TR_RS_FLAGS IOPORT_DIR_OUTPUT + +/** CAN0 transceiver PIN EN. */ +#define PIN_CAN0_TR_EN_IDX PIO_PE1_IDX +#define PIN_CAN0_TR_EN_FLAGS IOPORT_DIR_OUTPUT + +/** CAN0 PIN RX. */ +#define PIN_CAN0_RX_IDX PIO_PB3_IDX +#define PIN_CAN0_RX_FLAGS IOPORT_MODE_MUX_A + +/** CAN0 PIN TX. */ +#define PIN_CAN0_TX_IDX PIO_PB2_IDX +#define PIN_CAN0_TX_FLAGS IOPORT_MODE_MUX_A + +/** CAN1 transceiver PIN RS. */ +#define PIN_CAN1_TR_RS_IDX PIO_PE2_IDX +#define PIN_CAN1_TR_RS_FLAGS IOPORT_DIR_OUTPUT + +/** CAN1 transceiver PIN EN. */ +#define PIN_CAN1_TR_EN_IDX PIO_PE3_IDX +#define PIN_CAN1_TR_EN_FLAGS IOPORT_DIR_OUTPUT + +/** CAN1 PIN RX. */ +#define PIN_CAN1_RX_IDX PIO_PC12_IDX +#define PIN_CAN1_RX_FLAGS IOPORT_MODE_MUX_C + +/** CAN1 PIN TX. */ +#define PIN_CAN1_TX_IDX PIO_PC15_IDX +#define PIN_CAN1_TX_FLAGS IOPORT_MODE_MUX_C + +/** AFEC channel for potentiometer */ +#define AFEC_CHANNEL_POTENTIOMETER AFEC_CHANNEL_5 + +/*----------------------------------------------------------------------------*/ +#endif /* _SAM4E_EK_H_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.c new file mode 100644 index 0000000..dbf1849 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.c @@ -0,0 +1,862 @@ +/** + * \file + * + * \brief SAM HSMCI 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include +#include "conf_board.h" +#include "sd_mmc_protocol.h" +#include "sysclk.h" +#include "pmc.h" +#include "hsmci.h" + +/** + * \ingroup sam_drivers_hsmci + * \defgroup sam_drivers_hsmci_internal High Speed MultiMedia Card Interface + * (HSMCI) implementation + * + * @{ + */ + +// Check configurations +#if (!defined SD_MMC_HSMCI_MEM_CNT) || (SD_MMC_HSMCI_MEM_CNT == 0) +# warning SD_MMC_HSMCI_MEM_CNT must be defined in board.h file. +# define SD_MMC_HSMCI_MEM_CNT 1 +#endif +#ifndef CONF_BOARD_SD_MMC_HSMCI +# warning CONF_BOARD_SD_MMC_HSMCI must be defined in conf_board.h file. +#endif +#if (SAM3XA) +# if (SD_MMC_HSMCI_MEM_CNT > 2) +# warning Wrong define SD_MMC_HSMCI_MEM_CNT in board.h,\ + this part have 2 slots maximum on HSMCI. +# endif +#else +# if (SD_MMC_HSMCI_MEM_CNT > 1) +# warning Wrong define SD_MMC_HSMCI_MEM_CNT in board.h,\ + this part have 1 slots maximum on HSMCI. +# endif +#endif +#ifndef SD_MMC_HSMCI_SLOT_0_SIZE +# warning SD_MMC_HSMCI_SLOT_0_SIZE must be defined in board.h. +# define SD_MMC_HSMCI_SLOT_0_SIZE 1 +#endif +#if (SD_MMC_HSMCI_MEM_CNT > 2) +# ifndef SD_MMC_HSMCI_SLOT_1_SIZE +# warning SD_MMC_HSMCI_SLOT_1_SIZE must be defined in board.h. +# define SD_MMC_HSMCI_SLOT_1_SIZE 1 +# endif +#endif + +// Enable debug information for SD/MMC SPI module +#ifdef HSMCI_DEBUG +# include +# define hsmci_debug(...) printf(__VA_ARGS__) +#else +# define hsmci_debug(...) +#endif + +#if (SAM3S || SAM4S || SAM4E) + // PDC is used for transferts +#elif (SAM3U || SAM3XA) + // DMA is used for transferts +# include "dmac.h" +# define DMA_HW_ID_HSMCI 0 +# ifndef CONF_HSMCI_DMA_CHANNEL +# define CONF_HSMCI_DMA_CHANNEL 0 +# endif +#else +# error Not supported device +#endif + +//! Current position (byte) of the transfer started by hsmci_adtc_start() +static uint32_t hsmci_transfert_pos; +//! Size block requested by last hsmci_adtc_start() +static uint16_t hsmci_block_size; +//! Total number of block requested by last hsmci_adtc_start() +static uint16_t hsmci_nb_block; + +static void hsmci_reset(void); +static void hsmci_set_speed(uint32_t speed, uint32_t mck); +static bool hsmci_wait_busy(void); +static bool hsmci_send_cmd_execute(uint32_t cmdr, sdmmc_cmd_def_t cmd, + uint32_t arg); + +/** + * \brief Reset the HSMCI interface + */ +static void hsmci_reset(void) +{ + uint32_t mr = HSMCI->HSMCI_MR; + uint32_t dtor = HSMCI->HSMCI_DTOR; + uint32_t sdcr = HSMCI->HSMCI_SDCR; + uint32_t cstor = HSMCI->HSMCI_CSTOR; + uint32_t cfg = HSMCI->HSMCI_CFG; + HSMCI->HSMCI_CR = HSMCI_CR_SWRST; + HSMCI->HSMCI_MR = mr; + HSMCI->HSMCI_DTOR = dtor; + HSMCI->HSMCI_SDCR = sdcr; + HSMCI->HSMCI_CSTOR = cstor; + HSMCI->HSMCI_CFG = cfg; +#ifdef HSMCI_SR_DMADONE + HSMCI->HSMCI_DMA = 0; +#endif + // Enable the HSMCI + HSMCI->HSMCI_CR = HSMCI_CR_PWSEN | HSMCI_CR_MCIEN; +} + +/** + * \brief Set speed of the HSMCI clock. + * + * \param speed HSMCI clock speed in Hz. + * \param mck MCK clock speed in Hz. + */ +static void hsmci_set_speed(uint32_t speed, uint32_t mck) +{ + uint32_t clkdiv; + uint32_t rest; + + // Speed = MCK clock / (2 * (CLKDIV + 1)) + if (speed > 0) { + clkdiv = mck / (2 * speed); + rest = mck % (2 * speed); + if (rest > 0) { + // Ensure that the card speed not be higher than expected. + clkdiv++; + } + if (clkdiv > 0) { + clkdiv -= 1; + } + } else { + clkdiv = 0; + } + HSMCI->HSMCI_MR &= ~HSMCI_MR_CLKDIV_Msk; + HSMCI->HSMCI_MR |= HSMCI_MR_CLKDIV(clkdiv); +} + +/** \brief Wait the end of busy signal on data line + * + * \return true if success, otherwise false + */ +static bool hsmci_wait_busy(void) +{ + uint32_t busy_wait = 1000000; + uint32_t sr; + + do { + sr = HSMCI->HSMCI_SR; + if (busy_wait-- == 0) { + hsmci_debug("%s: timeout\n\r", __func__); + hsmci_reset(); + return false; + } + } while (!((sr & HSMCI_SR_NOTBUSY) && ((sr & HSMCI_SR_DTIP) == 0))); + return true; +} + + +/** \brief Send a command + * + * \param cmdr CMDR resgister bit to use for this command + * \param cmd Command definition + * \param arg Argument of the command + * + * \return true if success, otherwise false + */ +static bool hsmci_send_cmd_execute(uint32_t cmdr, sdmmc_cmd_def_t cmd, + uint32_t arg) +{ + uint32_t sr; + + cmdr |= HSMCI_CMDR_CMDNB(cmd) | HSMCI_CMDR_SPCMD_STD; + if (cmd & SDMMC_RESP_PRESENT) { + cmdr |= HSMCI_CMDR_MAXLAT; + if (cmd & SDMMC_RESP_136) { + cmdr |= HSMCI_CMDR_RSPTYP_136_BIT; + } else if (cmd & SDMMC_RESP_BUSY) { + cmdr |= HSMCI_CMDR_RSPTYP_R1B; + } else { + cmdr |= HSMCI_CMDR_RSPTYP_48_BIT; + } + } + if (cmd & SDMMC_CMD_OPENDRAIN) { + cmdr |= HSMCI_CMDR_OPDCMD_OPENDRAIN; + } + + // Write argument + HSMCI->HSMCI_ARGR = arg; + // Write and start command + HSMCI->HSMCI_CMDR = cmdr; + + // Wait end of command + do { + sr = HSMCI->HSMCI_SR; + if (cmd & SDMMC_RESP_CRC) { + if (sr & (HSMCI_SR_CSTOE | HSMCI_SR_RTOE + | HSMCI_SR_RENDE | HSMCI_SR_RCRCE + | HSMCI_SR_RDIRE | HSMCI_SR_RINDE)) { + hsmci_debug("%s: CMD 0x%08x sr 0x%08x error\n\r", + __func__, cmd, sr); + hsmci_reset(); + return false; + } + } else { + if (sr & (HSMCI_SR_CSTOE | HSMCI_SR_RTOE + | HSMCI_SR_RENDE + | HSMCI_SR_RDIRE | HSMCI_SR_RINDE)) { + hsmci_debug("%s: CMD 0x%08x sr 0x%08x error\n\r", + __func__, cmd, sr); + hsmci_reset(); + return false; + } + } + } while (!(sr & HSMCI_SR_CMDRDY)); + + if (cmd & SDMMC_RESP_BUSY) { + if (!hsmci_wait_busy()) { + return false; + } + } + return true; +} + + +//------------------------------------------------------------------- +//--------------------- PUBLIC FUNCTIONS ---------------------------- + +void hsmci_init(void) +{ + pmc_enable_periph_clk(ID_HSMCI); +#ifdef HSMCI_SR_DMADONE + // Enable clock for DMA controller + pmc_enable_periph_clk(ID_DMAC); +#endif + + // Set the Data Timeout Register to 2 Mega Cycles + HSMCI->HSMCI_DTOR = HSMCI_DTOR_DTOMUL_1048576 | HSMCI_DTOR_DTOCYC(2); + // Set Completion Signal Timeout to 2 Mega Cycles + HSMCI->HSMCI_CSTOR = HSMCI_CSTOR_CSTOMUL_1048576 | HSMCI_CSTOR_CSTOCYC(2); + // Set Configuration Register + HSMCI->HSMCI_CFG = HSMCI_CFG_FIFOMODE | HSMCI_CFG_FERRCTRL; + // Set power saving to maximum value + HSMCI->HSMCI_MR = HSMCI_MR_PWSDIV_Msk; + + // Enable the HSMCI and the Power Saving + HSMCI->HSMCI_CR = HSMCI_CR_MCIEN | HSMCI_CR_PWSEN; +} + +uint8_t hsmci_get_bus_width(uint8_t slot) +{ + switch (slot) { + case 0: + return SD_MMC_HSMCI_SLOT_0_SIZE; +#if (SD_MMC_HSMCI_MEM_CNT == 2) + case 1: + return SD_MMC_HSMCI_SLOT_1_SIZE; +#endif + default: + return 0; // Slot number wrong + } +} + +bool hsmci_is_high_speed_capable(void) +{ + return true; +} + +void hsmci_select_device(uint8_t slot, uint32_t clock, uint8_t bus_width, bool high_speed) +{ + uint32_t hsmci_slot = HSMCI_SDCR_SDCSEL_SLOTA; + uint32_t hsmci_bus_width = HSMCI_SDCR_SDCBUS_1; + + if (high_speed) { + HSMCI->HSMCI_CFG |= HSMCI_CFG_HSMODE; + } else { + HSMCI->HSMCI_CFG &= ~HSMCI_CFG_HSMODE; + } + + hsmci_set_speed(clock, sysclk_get_cpu_hz()); + + switch (slot) { + case 0: + hsmci_slot = HSMCI_SDCR_SDCSEL_SLOTA; + break; +#if (SD_MMC_HSMCI_MEM_CNT == 2) + case 1: + hsmci_slot = HSMCI_SDCR_SDCSEL_SLOTB; + break; +#endif + default: + Assert(false); // Slot number wrong + } + + switch (bus_width) { + case 1: + hsmci_bus_width = HSMCI_SDCR_SDCBUS_1; + break; + + case 4: + hsmci_bus_width = HSMCI_SDCR_SDCBUS_4; + break; + + case 8: + hsmci_bus_width = HSMCI_SDCR_SDCBUS_8; + break; + + default: + Assert(false); // Bus width wrong + } + HSMCI->HSMCI_SDCR = hsmci_slot | hsmci_bus_width; +} + +void hsmci_deselect_device(uint8_t slot) +{ + UNUSED(slot); + // Nothing to do +} + +void hsmci_send_clock(void) +{ + // Configure command + HSMCI->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE); + // Write argument + HSMCI->HSMCI_ARGR = 0; + // Write and start initialization command + HSMCI->HSMCI_CMDR = HSMCI_CMDR_RSPTYP_NORESP + | HSMCI_CMDR_SPCMD_INIT + | HSMCI_CMDR_OPDCMD_OPENDRAIN; + // Wait end of initialization command + while (!(HSMCI->HSMCI_SR & HSMCI_SR_CMDRDY)); +} + +bool hsmci_send_cmd(sdmmc_cmd_def_t cmd, uint32_t arg) +{ + // Configure command + HSMCI->HSMCI_MR &= ~(HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF | HSMCI_MR_FBYTE); +#ifdef HSMCI_SR_DMADONE + // Disable DMA for HSMCI + HSMCI->HSMCI_DMA = 0; +#endif +#ifdef HSMCI_MR_PDCMODE + // Disable PDC for HSMCI + HSMCI->HSMCI_MR &= ~HSMCI_MR_PDCMODE; +#endif + HSMCI->HSMCI_BLKR = 0; + return hsmci_send_cmd_execute(0, cmd, arg); +} + +uint32_t hsmci_get_response(void) +{ + return HSMCI->HSMCI_RSPR[0]; +} + +void hsmci_get_response_128(uint8_t* response) +{ + uint32_t response_32; + + for (uint8_t i = 0; i < 4; i++) { + response_32 = HSMCI->HSMCI_RSPR[0]; + *response = (response_32 >> 24) & 0xFF; + response++; + *response = (response_32 >> 16) & 0xFF; + response++; + *response = (response_32 >> 8) & 0xFF; + response++; + *response = (response_32 >> 0) & 0xFF; + response++; + } +} + +bool hsmci_adtc_start(sdmmc_cmd_def_t cmd, uint32_t arg, uint16_t block_size, uint16_t nb_block, bool access_block) +{ + uint32_t cmdr; + +#ifdef HSMCI_SR_DMADONE + if (access_block) { + // Enable DMA for HSMCI + HSMCI->HSMCI_DMA = HSMCI_DMA_DMAEN; + } else { + // Disable DMA for HSMCI + HSMCI->HSMCI_DMA = 0; + } +#endif + +#ifdef HSMCI_MR_PDCMODE + if (access_block) { + // Enable PDC for HSMCI + HSMCI->HSMCI_MR |= HSMCI_MR_PDCMODE; + } else { + // Disable PDC for HSMCI + HSMCI->HSMCI_MR &= ~HSMCI_MR_PDCMODE; + } +#endif + + // Enabling Read/Write Proof allows to stop the HSMCI Clock during + // read/write access if the internal FIFO is full. + // This will guarantee data integrity, not bandwidth. + HSMCI->HSMCI_MR |= HSMCI_MR_WRPROOF | HSMCI_MR_RDPROOF; + // Force byte transfer if needed + if (block_size & 0x3) { + HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE; + } else { + HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE; + } + + if (cmd & SDMMC_CMD_WRITE) { + cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_WRITE; + } else { + cmdr = HSMCI_CMDR_TRCMD_START_DATA | HSMCI_CMDR_TRDIR_READ; + } + + if (cmd & SDMMC_CMD_SDIO_BYTE) { + cmdr |= HSMCI_CMDR_TRTYP_BYTE; + // Value 0 corresponds to a 512-byte transfer + HSMCI->HSMCI_BLKR = ((block_size % 512) << HSMCI_BLKR_BCNT_Pos); + } else { + HSMCI->HSMCI_BLKR = (block_size << HSMCI_BLKR_BLKLEN_Pos) | + (nb_block << HSMCI_BLKR_BCNT_Pos); + if (cmd & SDMMC_CMD_SDIO_BLOCK) { + cmdr |= HSMCI_CMDR_TRTYP_BLOCK; + } else if (cmd & SDMMC_CMD_STREAM) { + cmdr |= HSMCI_CMDR_TRTYP_STREAM; + } else if (cmd & SDMMC_CMD_SINGLE_BLOCK) { + cmdr |= HSMCI_CMDR_TRTYP_SINGLE; + } else if (cmd & SDMMC_CMD_MULTI_BLOCK) { + cmdr |= HSMCI_CMDR_TRTYP_MULTIPLE; + } else { + Assert(false); // Incorrect flags + } + } + hsmci_transfert_pos = 0; + hsmci_block_size = block_size; + hsmci_nb_block = nb_block; + + return hsmci_send_cmd_execute(cmdr, cmd, arg); +} + +bool hsmci_adtc_stop(sdmmc_cmd_def_t cmd, uint32_t arg) +{ + return hsmci_send_cmd_execute(HSMCI_CMDR_TRCMD_STOP_DATA, cmd, arg); +} + +bool hsmci_read_word(uint32_t* value) +{ + uint32_t sr; + + Assert(((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos); + + // Wait data available + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_RXRDY)); + + // Read data + *value = HSMCI->HSMCI_RDR; + hsmci_transfert_pos += 4; + if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos) { + return true; + } + + // Wait end of transfer + // Note: no need of timeout, because it is include in HSMCI + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_XFRDONE)); + return true; +} + +bool hsmci_write_word(uint32_t value) +{ + uint32_t sr; + + Assert(((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos); + + // Wait data available + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_TXRDY)); + + // Write data + HSMCI->HSMCI_TDR = value; + hsmci_transfert_pos += 4; + if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos) { + return true; + } + + // Wait end of transfer + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_NOTBUSY)); + Assert(HSMCI->HSMCI_SR & HSMCI_SR_FIFOEMPTY); + return true; +} + +#ifdef HSMCI_SR_DMADONE +bool hsmci_start_read_blocks(void *dest, uint16_t nb_block) +{ + uint32_t cfg, nb_data; + dma_transfer_descriptor_t desc; + bool transfert_byte; + + nb_data = nb_block * hsmci_block_size; + transfert_byte = ((HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) || (((uint32_t)dest & 0x3) > 0)) ? 1 : 0; + + Assert(nb_data <= (((uint32_t)hsmci_block_size * hsmci_nb_block) - hsmci_transfert_pos)); + Assert(nb_data <= (transfert_byte ? + DMAC_CTRLA_BTSIZE_Msk >> DMAC_CTRLA_BTSIZE_Pos : + ((DMAC_CTRLA_BTSIZE_Msk >> DMAC_CTRLA_BTSIZE_Pos) * 4))); + + /* Set channel configuration register + * - Enable stop on done + * - Hardware Selection for the Source + * - Source with Peripheral identifier + * - Set AHB Protection + * - FIFO Configuration + */ + dmac_enable(DMAC); + dmac_channel_disable(DMAC, CONF_HSMCI_DMA_CHANNEL); + cfg = DMAC_CFG_SOD_ENABLE | DMAC_CFG_SRC_H2SEL | + DMAC_CFG_SRC_PER(DMA_HW_ID_HSMCI) | + DMAC_CFG_AHB_PROT(1) | DMAC_CFG_FIFOCFG_ALAP_CFG; + dmac_channel_set_configuration(DMAC, CONF_HSMCI_DMA_CHANNEL, cfg); + + // Prepare DMA transfer + desc.ul_source_addr = (uint32_t)&(HSMCI->HSMCI_RDR); + desc.ul_destination_addr = (uint32_t)dest; + if (transfert_byte) { + desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_data) + | DMAC_CTRLA_SRC_WIDTH_BYTE + | DMAC_CTRLA_DST_WIDTH_BYTE; + } else { + desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_data / 4) + | DMAC_CTRLA_SRC_WIDTH_WORD + | DMAC_CTRLA_DST_WIDTH_WORD; + } + desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE + | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE + | DMAC_CTRLB_FC_PER2MEM_DMA_FC + | DMAC_CTRLB_SRC_INCR_FIXED + | DMAC_CTRLB_DST_INCR_INCREMENTING + | DMAC_CTRLB_IEN; + desc.ul_descriptor_addr = (uint32_t)NULL; + dmac_channel_single_buf_transfer_init(DMAC, CONF_HSMCI_DMA_CHANNEL, + &desc); + + // Start DMA transfer + dmac_channel_enable(DMAC, CONF_HSMCI_DMA_CHANNEL); + hsmci_transfert_pos += nb_data; + return true; +} + +bool hsmci_wait_end_of_read_blocks(void) +{ + uint32_t sr; + // Wait end of transfer + // Note: no need of timeout, because it is include in HSMCI + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + // Disable DMA + dmac_channel_disable(DMAC, CONF_HSMCI_DMA_CHANNEL); + return false; + } + if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos) { + // It is not the end of all transfers + // then just wait end of DMA + if (sr & HSMCI_SR_DMADONE) { + return true; + } + } + } while (!(sr & HSMCI_SR_XFRDONE)); + return true; +} + +bool hsmci_start_write_blocks(const void *src, uint16_t nb_block) +{ + bool transfert_byte; + uint32_t cfg, nb_data; + dma_transfer_descriptor_t desc; + + nb_data = nb_block * hsmci_block_size; + transfert_byte = ((HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) || (((uint32_t)src & 0x3) > 0)) ? 1 : 0; + + Assert(nb_data <= (((uint32_t)hsmci_block_size * hsmci_nb_block) - hsmci_transfert_pos)); + Assert(nb_data <= (transfert_byte ? + DMAC_CTRLA_BTSIZE_Msk >> DMAC_CTRLA_BTSIZE_Pos : + ((DMAC_CTRLA_BTSIZE_Msk >> DMAC_CTRLA_BTSIZE_Pos) * 4))); + + /* Set channel configuration register: + * - Enable stop on done + * - Hardware Selection for the Destination + * - Destination with Peripheral identifier + * - Set AHB Protection + * - FIFO Configuration + */ + dmac_enable(DMAC); + Assert(!dmac_channel_is_enable(DMAC, CONF_HSMCI_DMA_CHANNEL)); + cfg = DMAC_CFG_SOD_ENABLE | DMAC_CFG_DST_H2SEL | + DMAC_CFG_DST_PER(DMA_HW_ID_HSMCI) | + DMAC_CFG_AHB_PROT(1) | DMAC_CFG_FIFOCFG_ALAP_CFG; + dmac_channel_set_configuration(DMAC, CONF_HSMCI_DMA_CHANNEL, cfg); + + // Prepare DMA transfer + desc.ul_source_addr = (uint32_t)src; + desc.ul_destination_addr = (uint32_t)&(HSMCI->HSMCI_TDR); + if (transfert_byte) { + desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_data) + | DMAC_CTRLA_SRC_WIDTH_BYTE + | DMAC_CTRLA_DST_WIDTH_BYTE; + } else { + desc.ul_ctrlA = DMAC_CTRLA_BTSIZE(nb_data / 4) + | DMAC_CTRLA_SRC_WIDTH_WORD + | DMAC_CTRLA_DST_WIDTH_WORD; + } + desc.ul_ctrlB = DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE + | DMAC_CTRLB_DST_DSCR_FETCH_DISABLE + | DMAC_CTRLB_FC_MEM2PER_DMA_FC + | DMAC_CTRLB_SRC_INCR_INCREMENTING + | DMAC_CTRLB_DST_INCR_FIXED + | DMAC_CTRLB_IEN; + desc.ul_descriptor_addr = (uint32_t)NULL; + dmac_channel_single_buf_transfer_init(DMAC, CONF_HSMCI_DMA_CHANNEL, + &desc); + + // Start DMA transfer + dmac_channel_enable(DMAC, CONF_HSMCI_DMA_CHANNEL); + hsmci_transfert_pos += nb_data; + return true; +} + +bool hsmci_wait_end_of_write_blocks(void) +{ + uint32_t sr; + // Wait end of transfer + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: DMA sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + // Disable DMA + dmac_channel_disable(DMAC, CONF_HSMCI_DMA_CHANNEL); + return false; + } + if (((uint32_t)hsmci_block_size * hsmci_nb_block) > hsmci_transfert_pos) { + // It is not the end of all transfers + // then just wait end of DMA + if (sr & HSMCI_SR_DMADONE) { + return true; + } + } + } while (!(sr & HSMCI_SR_NOTBUSY)); + Assert(HSMCI->HSMCI_SR & HSMCI_SR_FIFOEMPTY); + Assert(!dmac_channel_is_enable(DMAC, CONF_HSMCI_DMA_CHANNEL)); + return true; + +} +#endif // HSMCI_SR_DMADONE + +#ifdef HSMCI_MR_PDCMODE +bool hsmci_start_read_blocks(void *dest, uint16_t nb_block) +{ + uint32_t nb_data; + + nb_data = nb_block * hsmci_block_size; + Assert(nb_data <= (((uint32_t)hsmci_block_size * hsmci_nb_block) - hsmci_transfert_pos)); + Assert(nb_data <= (PERIPH_RCR_RXCTR_Msk >> PERIPH_RCR_RXCTR_Pos)); + + // Handle unaligned memory address + if (((uint32_t)dest & 0x3) || (hsmci_block_size & 0x3)) { + HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE; + } else { + HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE; + } + + // Configure PDC transfert + HSMCI->HSMCI_RPR = (uint32_t)dest; + HSMCI->HSMCI_RCR = (HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) ? + nb_data : nb_data / 4; + HSMCI->HSMCI_RNCR = 0; + // Start transfert + HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTEN; + hsmci_transfert_pos += nb_data; + return true; +} + +bool hsmci_wait_end_of_read_blocks(void) +{ + uint32_t sr; + // Wait end of transfert + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: PDC sr 0x%08x error\n\r", + __func__, sr); + HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS; + hsmci_reset(); + return false; + } + + } while (!(sr & HSMCI_SR_RXBUFF)); + + if (hsmci_transfert_pos < ((uint32_t)hsmci_block_size * hsmci_nb_block)) { + return true; + } + // It is the last transfer, then wait command completed + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: PDC sr 0x%08x last transfer error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_XFRDONE)); + return true; +} + +bool hsmci_start_write_blocks(const void *src, uint16_t nb_block) +{ + uint32_t nb_data; + + nb_data = nb_block * hsmci_block_size; + Assert(nb_data <= (((uint32_t)hsmci_block_size * hsmci_nb_block) - hsmci_transfert_pos)); + Assert(nb_data <= (PERIPH_TCR_TXCTR_Msk >> PERIPH_TCR_TXCTR_Pos)); + + // Handle unaligned memory address + if (((uint32_t)src & 0x3) || (hsmci_block_size & 0x3)) { + HSMCI->HSMCI_MR |= HSMCI_MR_FBYTE; + } else { + HSMCI->HSMCI_MR &= ~HSMCI_MR_FBYTE; + } + + // Configure PDC transfert + HSMCI->HSMCI_TPR = (uint32_t)src; + HSMCI->HSMCI_TCR = (HSMCI->HSMCI_MR & HSMCI_MR_FBYTE) ? + nb_data : nb_data / 4; + HSMCI->HSMCI_TNCR = 0; + // Start transfert + HSMCI->HSMCI_PTCR = HSMCI_PTCR_TXTEN; + hsmci_transfert_pos += nb_data; + return true; +} + +bool hsmci_wait_end_of_write_blocks(void) +{ + uint32_t sr; + + // Wait end of transfert + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & + (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: PDC sr 0x%08x error\n\r", + __func__, sr); + hsmci_reset(); + HSMCI->HSMCI_PTCR = HSMCI_PTCR_RXTDIS | HSMCI_PTCR_TXTDIS; + return false; + } + } while (!(sr & HSMCI_SR_TXBUFE)); + + + if (hsmci_transfert_pos < ((uint32_t)hsmci_block_size * hsmci_nb_block)) { + return true; + } + // It is the last transfer, then wait command completed + // Note: no need of timeout, because it is include in HSMCI, see DTOE bit. + do { + sr = HSMCI->HSMCI_SR; + if (sr & (HSMCI_SR_UNRE | HSMCI_SR_OVRE | \ + HSMCI_SR_DTOE | HSMCI_SR_DCRCE)) { + hsmci_debug("%s: PDC sr 0x%08x last transfer error\n\r", + __func__, sr); + hsmci_reset(); + return false; + } + } while (!(sr & HSMCI_SR_NOTBUSY)); + Assert(HSMCI->HSMCI_SR & HSMCI_SR_FIFOEMPTY); + return true; +} +#endif // HSMCI_MR_PDCMODE diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.h new file mode 100644 index 0000000..53ced40 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/hsmci/hsmci.h @@ -0,0 +1,211 @@ +/** + * \file + * + * \brief SAM HSMCI driver + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef HSMCI_H_INCLUDED +#define HSMCI_H_INCLUDED + +#include "compiler.h" +#include "sd_mmc_protocol.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/** + * \defgroup sam_drivers_hsmci High Speed MultiMedia Card Interface (HSMCI) + * + * This driver interfaces the HSMCI module. + * It will add functions for SD/MMC card reading, writing and management. + * + * @{ + */ + +/** \brief Initializes the low level driver + * + * This enable the clock required and the hardware interface. + */ +void hsmci_init(void); + +/** \brief Return the maximum bus width of a slot + * + * \param slot Selected slot + * + * \return 1, 4 or 8 lines. + */ +uint8_t hsmci_get_bus_width(uint8_t slot); + +/** \brief Return the high speed capability of the driver + * + * \return true, if the high speed is supported + */ +bool hsmci_is_high_speed_capable(void); + +/** + * \brief Select a slot and initialize it + * + * \param slot Selected slot + * \param clock Maximum clock to use (Hz) + * \param bus_width Bus width to use (1, 4 or 8) + * \param high_speed true, to enable high speed mode + */ +void hsmci_select_device(uint8_t slot, uint32_t clock, uint8_t bus_width, + bool high_speed); + +/** + * \brief Deselect a slot + * + * \param slot Selected slot + */ +void hsmci_deselect_device(uint8_t slot); + +/** \brief Send 74 clock cycles on the line of selected slot + * Note: It is required after card plug and before card install. + */ +void hsmci_send_clock(void); + +/** \brief Send a command on the selected slot + * + * \param cmd Command definition + * \param arg Argument of the command + * + * \return true if success, otherwise false + */ +bool hsmci_send_cmd(sdmmc_cmd_def_t cmd, uint32_t arg); + +/** \brief Return the 32 bits response of the last command + * + * \return 32 bits response + */ +uint32_t hsmci_get_response(void); + +/** \brief Return the 128 bits response of the last command + * + * \param response Pointer on the array to fill with the 128 bits response + */ +void hsmci_get_response_128(uint8_t* response); + +/** \brief Send an ADTC command on the selected slot + * An ADTC (Addressed Data Transfer Commands) command is used + * for read/write access. + * + * \param cmd Command definition + * \param arg Argument of the command + * \param block_size Block size used for the transfer + * \param nb_block Total number of block for this transfer + * \param access_block if true, the x_read_blocks() and x_write_blocks() + * functions must be used after this function. + * If false, the mci_read_word() and mci_write_word() + * functions must be used after this function. + * + * \return true if success, otherwise false + */ +bool hsmci_adtc_start(sdmmc_cmd_def_t cmd, uint32_t arg, uint16_t block_size, + uint16_t nb_block, bool access_block); + +/** \brief Send a command to stop an ADTC command on the selected slot + * + * \param cmd Command definition + * \param arg Argument of the command + * + * \return true if success, otherwise false + */ +bool hsmci_adtc_stop(sdmmc_cmd_def_t cmd, uint32_t arg); + +/** \brief Read a word on the line + * + * \param value Pointer on a word to fill + * + * \return true if success, otherwise false + */ +bool hsmci_read_word(uint32_t* value); + +/** \brief Write a word on the line + * + * \param value Word to send + * + * \return true if success, otherwise false + */ +bool hsmci_write_word(uint32_t value); + +/** \brief Start a read blocks transfer on the line + * Note: The driver will use the DMA available to speed up the transfer. + * + * \param dest Pointer on the buffer to fill + * \param nb_block Number of block to transfer + * + * \return true if started, otherwise false + */ +bool hsmci_start_read_blocks(void *dest, uint16_t nb_block); + +/** \brief Wait the end of transfer initiated by mci_start_read_blocks() + * + * \return true if success, otherwise false + */ +bool hsmci_wait_end_of_read_blocks(void); + +/** \brief Start a write blocks transfer on the line + * Note: The driver will use the DMA available to speed up the transfer. + * + * \param src Pointer on the buffer to send + * \param nb_block Number of block to transfer + * + * \return true if started, otherwise false + */ +bool hsmci_start_write_blocks(const void *src, uint16_t nb_block); + +/** \brief Wait the end of transfer initiated by mci_start_write_blocks() + * + * \return true if success, otherwise false + */ +bool hsmci_wait_end_of_write_blocks(void); + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* HSMCI_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.c new file mode 100644 index 0000000..4d842cf --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.c @@ -0,0 +1,334 @@ +/** + * \file + * + * \brief SAM4 Peripheral DMA Controller (PDC) driver. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "pdc.h" + +/// @cond +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \brief Configure PDC for data transmit. + * + * \param[out] p_pdc Device structure pointer + * \param[in] p_packet Pointer to packet information for current buffer register + * set, NULL to let them as is. + * \param[in] p_next_packet Pointer to packet information for next buffer register + * set, NULL to let them as is. + */ +void pdc_tx_init( + Pdc *p_pdc, + pdc_packet_t *p_packet, + pdc_packet_t *p_next_packet) +{ + /* Validate inputs. */ + Assert(p_pdc); + + if (p_packet) { + p_pdc->PERIPH_TPR = p_packet->ul_addr; + p_pdc->PERIPH_TCR = p_packet->ul_size; + } + if (p_next_packet) { + p_pdc->PERIPH_TNPR = p_next_packet->ul_addr; + p_pdc->PERIPH_TNCR = p_next_packet->ul_size; + } +} + +/** + * \brief Configure PDC for data receive. + * + * \param[out] p_pdc Device structure pointer + * \param[in] p_packet Pointer to packet information for current buffer register + * set, NULL to let them as is. + * \param[in] p_next_packet Pointer to packet information for next buffer register + * set, NULL to let them as is. + */ +void pdc_rx_init( + Pdc *p_pdc, + pdc_packet_t *p_packet, + pdc_packet_t *p_next_packet) +{ + /* Validate inputs. */ + Assert(p_pdc); + + if (p_packet) { + p_pdc->PERIPH_RPR = p_packet->ul_addr; + p_pdc->PERIPH_RCR = p_packet->ul_size; + } + if (p_next_packet) { + p_pdc->PERIPH_RNPR = p_next_packet->ul_addr; + p_pdc->PERIPH_RNCR = p_next_packet->ul_size; + } +} + +/** + * \brief Clear PDC buffer receive counter. + * + * \param[out] p_pdc Device structure pointer + */ +void pdc_rx_clear_cnt( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + p_pdc->PERIPH_RNCR = 0; + p_pdc->PERIPH_RCR = 0; +} + +/** + * \brief Enable PDC transfers (TX and/or RX). + * + * \note It is forbidden to set both TXTEN and RXTEN for a half duplex + * peripheral. + * + * \param[out] p_pdc Device structure pointer + * \param[in] ul_controls Transfer directions + * (bit PERIPH_PTCR_RXTEN and bit PERIPH_PTCR_TXTEN) + */ +void pdc_enable_transfer( + Pdc *p_pdc, + uint32_t ul_controls) +{ + /* Validate inputs. */ + Assert(p_pdc); + + p_pdc->PERIPH_PTCR = + ul_controls & (PERIPH_PTCR_RXTEN | PERIPH_PTCR_TXTEN); +} + +/** + * \brief Disable PDC transfers (TX and/or RX). + * + * \param[out] p_pdc Device structure pointer + * \param[in] ul_controls Transfer directions + * (bit PERIPH_PTCR_TXTDIS, bit PERIPH_PTCR_TXTDIS) + */ +void pdc_disable_transfer( + Pdc *p_pdc, + uint32_t ul_controls) +{ + /* Validate inputs. */ + Assert(p_pdc); + + p_pdc->PERIPH_PTCR = + ul_controls & (PERIPH_PTCR_RXTDIS | PERIPH_PTCR_TXTDIS); +} + +/** + * \brief Read PDC status. + * + * \param[in] p_pdc Device structure pointer + * + * \return PDC status register bit map. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
NameDescriptionBit
RXTENReceiver Transfer Enabled8
TXTENTransmitter Transfer Enabled1
+ * + */ +uint32_t pdc_read_status( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_PTSR; +} + +/** + * \brief Return Receive Pointer Register (RPR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Receive Pointer Register value. + */ +uint32_t pdc_read_rx_ptr( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_RPR; +} + +/** + * \brief Return Receive Counter Register (RCR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Receive Counter Register value. + */ +uint32_t pdc_read_rx_counter( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_RCR; +} + +/** + * \brief Return Transmit Pointer Register (TPR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Transmit Pointer Register value. + */ +uint32_t pdc_read_tx_ptr( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_TPR; +} + +/** + * \brief Return Transmit Counter Register (TCR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Transmit Counter Register value. + */ +uint32_t pdc_read_tx_counter( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_TCR; +} + +/** + * \brief Return Receive Next Pointer Register (RNPR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Receive Next Pointer Register value. + */ +uint32_t pdc_read_rx_next_ptr( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_RNPR; +} + +/** + * \brief Return Receive Next Counter Register (RNCR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Receive Next Counter Register value. + */ +uint32_t pdc_read_rx_next_counter( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_RNCR; +} + +/** + * \brief Return Transmit Next Pointer Register (TNPR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Transmit Next Pointer Register value. + */ +uint32_t pdc_read_tx_next_ptr( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_TNPR; +} + +/** + * \brief Return Transmit Next Counter Register (TNCR) value. + * + * \param[in] p_pdc Device structure pointer + * + * \return Transmit Next Counter Register value. + */ +uint32_t pdc_read_tx_next_counter( + Pdc *p_pdc) +{ + /* Validate inputs. */ + Assert(p_pdc); + + return p_pdc->PERIPH_TNCR; +} + +/// @cond +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.h new file mode 100644 index 0000000..373992e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc.h @@ -0,0 +1,305 @@ +/** + * \file + * + * \brief SAM4 Peripheral DMA Controller (PDC) driver. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef PDC_H_INCLUDED +#define PDC_H_INCLUDED + +/** + * \defgroup asfdoc_sam_drivers_pdc_group Peripheral DMA Controller (PDC) + * This driver for SAM4 devices provides an interface for the configuration and + * management of the the Peripheral DMA Controller (PDC) module. + * + * The PDC transfers data between on-chip serial peripherals and the on and/or + * off-chip memories. The link between the PDC and a serial peripheral is + * operated by the AHB to ABP bridge. + * + * This module: + * - Performs transfers to/from APB communication serial peripherals + * - Supports half-duplex and full-duplex peripherals + * + * The outline of this documentation is as follows: + * - \ref asfdoc_sam_drivers_pdc_prerequisites + * - \ref asfdoc_sam_drivers_pdc_module_overview + * - \ref asfdoc_sam_drivers_pdc_special_considerations + * - \ref asfdoc_sam_drivers_pdc_extra_info + * - \ref asfdoc_sam_drivers_pdc_examples + * - \ref asfdoc_sam_drivers_pdc_api_overview + * + * + * \section asfdoc_sam_drivers_pdc_prerequisites Prerequisites + * + * There are no prerequisites for this module. + * + * + * \section asfdoc_sam_drivers_pdc_module_overview Module Overview + * The user interface of each PDC channel is integrated into the user interface + * of the peripheral it serves. The user interface of unidirectional channels + * (receive only or transmit only), contains two 32-bit memory pointers and + * two 16-bit counters, one set (pointer, counter) for current transfer and + * one set (pointer, counter) for next transfer. The bidirectional channel + * user interface contains four 32-bit memory pointers and four 16-bit counters. + * Each set (pointer, counter) is used by current transmit, next transmit, + * current receive and next receive. Using the PDC removes processor overhead + * by reducing its intervention during the transfer. This significantly reduces + * the number of clock cycles required for a data transfer, which improves + * microcontroller performance. To launch a transfer, the peripheral triggers + * its associated PDC channels by using transmit and receive signals. + * When the programmed data is transferred, an end of transfer interrupt is + * generated by the peripheral itself. + * + * \section asfdoc_sam_drivers_pdc_special_considerations Special Considerations + * + * + * \section asfdoc_sam_drivers_pdc_extra_info Extra Information + + * For extra information, see \ref asfdoc_sam_drivers_pdc_extra. This includes: + * - \ref asfdoc_sam_drivers_pdc_extra_acronyms + * - \ref asfdoc_sam_drivers_pdc_extra_dependencies + * - \ref asfdoc_sam_drivers_pdc_extra_errata + * - \ref asfdoc_sam_drivers_pdc_extra_history + * + * \section asfdoc_sam_drivers_pdc_examples Examples + * + * For a list of examples related to this driver, see + * \ref asfdoc_sam_drivers_pdc_exqsg. + * + * + * \section asfdoc_sam_drivers_pdc_api_overview API Overview + * @{ + */ + +#include + +/// @cond +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \brief PDC data packet for transfer. + */ +typedef struct pdc_packet { + /** Start address of the transfer packet data. */ + uint32_t ul_addr; + /** Transfer packet size (in units of the peripheral data width). */ + uint32_t ul_size; +} pdc_packet_t; + +void pdc_tx_init(Pdc *p_pdc, pdc_packet_t *p_packet, + pdc_packet_t *p_next_packet); +void pdc_rx_init(Pdc *p_pdc, pdc_packet_t *p_packet, + pdc_packet_t *p_next_packet); +void pdc_rx_clear_cnt(Pdc *p_pdc); +void pdc_enable_transfer(Pdc *p_pdc, uint32_t ul_controls); +void pdc_disable_transfer(Pdc *p_pdc, uint32_t ul_controls); +uint32_t pdc_read_status(Pdc *p_pdc); +uint32_t pdc_read_rx_ptr(Pdc *p_pdc); +uint32_t pdc_read_rx_counter(Pdc *p_pdc); +uint32_t pdc_read_tx_ptr(Pdc *p_pdc); +uint32_t pdc_read_tx_counter(Pdc *p_pdc); +uint32_t pdc_read_rx_next_ptr(Pdc *p_pdc); +uint32_t pdc_read_rx_next_counter(Pdc *p_pdc); +uint32_t pdc_read_tx_next_ptr(Pdc *p_pdc); +uint32_t pdc_read_tx_next_counter(Pdc *p_pdc); + +/// @cond +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +/** @} */ + +/** + * \page asfdoc_sam_drivers_pdc_extra Extra Information for Peripheral DMA Controller + * + * \section asfdoc_sam_drivers_pdc_extra_acronyms Acronyms + * Below is a table listing the acronyms used in this module, along with their + * intended meanings. + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
AcronymDefinition
AHBAdvanced High-performance Bus
AMBA Advanced Microcontroller Bus Architecture
QSGQuick Start Guide
RCRReceive Counter Register
RNCRReturn Receive Next Counter Register
RNPRReceive Next Pointer Register
RPRReceive Pointer Register
TCRTransmit Counter Register
TNCRTransmit Next Counter Register
TNPRTransmit Next Pointer Register
TPRTransmit Pointer Register
+ * + * + * \section asfdoc_sam_drivers_pdc_extra_dependencies Dependencies + * This driver has the following dependencies: + * + * - None + * + * + * \section asfdoc_sam_drivers_pdc_extra_errata Errata + * There are no errata related to this driver. + * + * + * \section asfdoc_sam_drivers_pdc_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
Initial document release
+ * + * + * + * \page asfdoc_sam_pmc_quickstart Quickstart guide for SAM4 + * This is the quickstart guide for the "PDC driver" with step-by-step + * instructions on how to configure and use the driver. + * + * \section asfdoc_sam_pmc_quickstart_basic_use_case Basic Use Case + * + * A handler is required for the interrupt, below is a simple example + * \snippet pdc_uart_example.c int_handler + * + * First initialise the board: + * + * \snippet pdc_uart_example.c board_setup + * + * Now setup the PDC registers + * \snippet pdc_uart_example.c pdc_config + * + * Enable UART IRQ + * \snippet pdc_uart_example.c uart_irq + * + * and enable UART interrupt + * \snippet pdc_uart_example.c uart_nvic_irq + * + * Once the required number of bytes have been transferred an interupt is + * triggered and the handler will run. In the interim programme to do + * something else, or be busy waiting + * + * \snippet pdc_uart_example.c busy_waiting + * + * \page asfdoc_sam_drivers_pdc_exqsg Examples for Peripheral DMA Controller + * + * This is a list of the available Quick Start guides (QSGs) and example + * applications for \ref asfdoc_sam_drivers_pdc_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_sam_drivers_pdc_example + * + * + * \page asfdoc_sam_drivers_pdc_document_revision_history Document Revision History + * + * + * + * + * + * + * + * + * + *
Doc. Rev. + * Date + * Comments + *
42316A05/2014Initial document release
+ * + */ + +#endif /* PDC_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc_uart_example/pdc_uart_example.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc_uart_example/pdc_uart_example.h new file mode 100644 index 0000000..d8a35e2 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pdc/pdc_uart_example/pdc_uart_example.h @@ -0,0 +1,89 @@ +/** + * \file + * + * \brief SAM Peripheral DMA Controller Example. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef PDC_UART_EXAMPLE_H_INCLUDED +#define PDC_UART_EXAMPLE_H_INCLUDED + +/** + * \page asfdoc_sam_drivers_pdc_example Peripheral DMA Controller Example + * + * \section asfdoc_sam_drivers_pdc_example_purpose Purpose + * + * The pdc_uart example demonstrates how to use PDC driver to receive/send + * data from/to the UART. + * + * \section asfdoc_sam_drivers_pdc_example_requirements Requirements + * + * This example can be used on any SAM3/4 boards. + * + * \section asfdoc_sam_drivers_pdc_example_description Description + * + * The SAM controller waits for BUFFER_SIZE data to receive from the UART. + * As soon as the expected amount of data is received, the whole buffer is + * sent back to the terminal. + * + * \section asfdoc_sam_drivers_pdc_example_usage Usage + * + * -# Build the program and download it into the evaluation board. + * -# On the computer, open, and configure a terminal application + * (e.g., HyperTerminal on Microsoft® Windows®) with these settings: + * - 115200 baud + * - 8 bits of data + * - No parity + * - 1 stop bit + * - No flow control + * -# In the terminal window, the following text should appear (values depend + * on the board and chip used): + \verbatim + -- PDC Uart Example xxx -- + -- xxxxxx-xx + -- Compiled: xxx xx xxxx xx:xx:xx -- + \endverbatim + * -# The sent text should appear. + */ + + #endif /* PDC_UART_EXAMPLE_H_INCLUDED */ + diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.c new file mode 100644 index 0000000..c4e41fe --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.c @@ -0,0 +1,1552 @@ +/** + * \file + * + * \brief Power Management Controller (PMC) driver for SAM. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "pmc.h" + +#if (SAM3N) +# define MAX_PERIPH_ID 31 +#elif (SAM3XA) +# define MAX_PERIPH_ID 44 +#elif (SAM3U) +# define MAX_PERIPH_ID 29 +#elif (SAM3S || SAM4S) +# define MAX_PERIPH_ID 34 +#elif (SAM4E) +# define MAX_PERIPH_ID 47 +#elif (SAM4N) +# define MAX_PERIPH_ID 31 +#elif (SAM4C || SAM4CM || SAM4CP) +# define MAX_PERIPH_ID 43 +#elif (SAMG51) +# define MAX_PERIPH_ID 47 +#elif (SAMG53) +# define MAX_PERIPH_ID 47 +#elif (SAMG54) +# define MAX_PERIPH_ID 47 +#elif (SAMG55) +# define MAX_PERIPH_ID 50 +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_pmc_group Power Management Controller (PMC) + * + * \par Purpose + * + * The Power Management Controller (PMC) optimizes power consumption by + * controlling all system and user peripheral clocks. The PMC enables/disables + * the clock inputs to many of the peripherals and the Cortex-M Processor. + * + * @{ + */ + +/** + * \brief Set the prescaler of the MCK. + * + * \param ul_pres Prescaler value. + */ +void pmc_mck_set_prescaler(uint32_t ul_pres) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); +} + +/** + * \brief Set the source of the MCK. + * + * \param ul_source Source selection value. + */ +void pmc_mck_set_source(uint32_t ul_source) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | ul_source; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); +} + +/** + * \brief Switch master clock source selection to slow clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_SLOW_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch master clock source selection to main clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_MAIN_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch master clock source selection to PLLA clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_PLLA_CLK; + + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +/** + * \brief Switch master clock source selection to PLLB clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_PLLB_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Switch master clock source selection to UPLL clock. + * + * \param ul_pres Processor clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_PRES_Msk)) | ul_pres; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & (~PMC_MCKR_CSS_Msk)) | + PMC_MCKR_CSS_UPLL_CLK; + for (ul_timeout = PMC_TIMEOUT; !(PMC->PMC_SR & PMC_SR_MCKRDY); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +/** + * \brief Switch slow clock source selection to external 32k (Xtal or Bypass). + * + * \note Switching SCLK back to 32krc is only possible by shutting down the + * VDDIO power supply. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + */ +void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass) +{ + /* Set Bypass mode if required */ + if (ul_bypass == 1) { + SUPC->SUPC_MR |= SUPC_MR_KEY_PASSWD | + SUPC_MR_OSCBYPASS; + } + + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_XTALSEL; +} + +/** + * \brief Check if the external 32k Xtal is ready. + * + * \retval 1 External 32k Xtal is ready. + * \retval 0 External 32k Xtal is not ready. + */ +uint32_t pmc_osc_is_ready_32kxtal(void) +{ + return ((SUPC->SUPC_SR & SUPC_SR_OSCSEL) + && (PMC->PMC_SR & PMC_SR_OSCSELS)); +} + +/** + * \brief Switch main clock source selection to internal fast RC. + * + * \param ul_moscrcf Fast RC oscillator(4/8/12Mhz). + * + * \retval 0 Success. + * \retval 1 Timeout error. + * \retval 2 Invalid frequency. + */ +void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf) +{ + /* Enable Fast RC oscillator but DO NOT switch to RC now */ + PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN); + + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); + + /* Change Fast RC oscillator frequency */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | + CKGR_MOR_KEY_PASSWD | ul_moscrcf; + + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); + + /* Switch to Fast RC */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | + CKGR_MOR_KEY_PASSWD; +} + +/** + * \brief Enable fast RC oscillator. + * + * \param ul_rc Fast RC oscillator(4/8/12Mhz). + */ +void pmc_osc_enable_fastrc(uint32_t ul_rc) +{ + /* Enable Fast RC oscillator but DO NOT switch to RC */ + PMC->CKGR_MOR |= (CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCRCEN); + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); + + /* Change Fast RC oscillator frequency */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCF_Msk) | + CKGR_MOR_KEY_PASSWD | ul_rc; + /* Wait the Fast RC to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); +} + +/** + * \brief Disable the internal fast RC. + */ +void pmc_osc_disable_fastrc(void) +{ + /* Disable Fast RC oscillator */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & + ~CKGR_MOR_MOSCRCF_Msk) + | CKGR_MOR_KEY_PASSWD; +} + +/** + * \brief Check if the main fastrc is ready. + * + * \retval 0 Xtal is not ready, otherwise ready. + */ +uint32_t pmc_osc_is_ready_fastrc(void) +{ + return (PMC->PMC_SR & PMC_SR_MOSCRCS); +} + +/** + * \brief Enable main XTAL oscillator. + * + * \param ul_xtal_startup_time Xtal start-up time, in number of slow clocks. + */ +void pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time) +{ + uint32_t mor = PMC->CKGR_MOR; + mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); + mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN | + CKGR_MOR_MOSCXTST(ul_xtal_startup_time); + PMC->CKGR_MOR = mor; + /* Wait the main Xtal to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); +} + +/** + * \brief Bypass main XTAL. + */ +void pmc_osc_bypass_main_xtal(void) +{ + uint32_t mor = PMC->CKGR_MOR; + mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); + mor |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY; + /* Enable Crystal oscillator but DO NOT switch now. Keep MOSCSEL to 0 */ + PMC->CKGR_MOR = mor; + /* The MOSCXTS in PMC_SR is automatically set */ +} + +/** + * \brief Disable the main Xtal. + */ +void pmc_osc_disable_main_xtal(void) +{ + uint32_t mor = PMC->CKGR_MOR; + mor &= ~(CKGR_MOR_MOSCXTBY|CKGR_MOR_MOSCXTEN); + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor; +} + +/** + * \brief Check if the main crystal is bypassed. + * + * \retval 0 Xtal is bypassed, otherwise not. + */ +uint32_t pmc_osc_is_bypassed_main_xtal(void) +{ + return (PMC->CKGR_MOR & CKGR_MOR_MOSCXTBY); +} + +/** + * \brief Check if the main crystal is ready. + * + * \note If main crystal is bypassed, it's always ready. + * + * \retval 0 main crystal is not ready, otherwise ready. + */ +uint32_t pmc_osc_is_ready_main_xtal(void) +{ + return (PMC->PMC_SR & PMC_SR_MOSCXTS); +} + +/** + * \brief Switch main clock source selection to external Xtal/Bypass. + * + * \note The function may switch MCK to SCLK if MCK source is MAINCK to avoid + * any system crash. + * + * \note If used in Xtal mode, the Xtal is automatically enabled. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +void pmc_switch_mainck_to_xtal(uint32_t ul_bypass, + uint32_t ul_xtal_startup_time) +{ + /* Enable Main Xtal oscillator */ + if (ul_bypass) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY | + CKGR_MOR_MOSCSEL; + } else { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | + CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN | + CKGR_MOR_MOSCXTST(ul_xtal_startup_time); + /* Wait the Xtal to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); + + PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL; + } +} + +/** + * \brief Disable the external Xtal. + * + * \param ul_bypass 0 for Xtal, 1 for bypass. + */ +void pmc_osc_disable_xtal(uint32_t ul_bypass) +{ + /* Disable xtal oscillator */ + if (ul_bypass) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | + CKGR_MOR_KEY_PASSWD; + } else { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + CKGR_MOR_KEY_PASSWD; + } +} + +/** + * \brief Check if the MAINCK is ready. Depending on MOSCEL, MAINCK can be one + * of Xtal, bypass or internal RC. + * + * \retval 1 Xtal is ready. + * \retval 0 Xtal is not ready. + */ +uint32_t pmc_osc_is_ready_mainck(void) +{ + return PMC->PMC_SR & PMC_SR_MOSCSELS; +} + +/** + * \brief Select Main Crystal or internal RC as main clock source. + * + * \note This function will not enable/disable RC or Main Crystal. + * + * \param ul_xtal_rc 0 internal RC is selected, otherwise Main Crystal. + */ +void pmc_mainck_osc_select(uint32_t ul_xtal_rc) +{ + uint32_t mor = PMC->CKGR_MOR; + if (ul_xtal_rc) { + mor |= CKGR_MOR_MOSCSEL; + } else { + mor &= ~CKGR_MOR_MOSCSEL; + } + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor; +} + +/** + * \brief Enable PLLA clock. + * + * \param mula PLLA multiplier. + * \param pllacount PLLA counter. + * \param diva Divider. + */ +void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva) +{ + /* first disable the PLL to unlock the lock */ + pmc_disable_pllack(); + +#if (SAM4C || SAM4CM || SAM4CP || SAMG) + PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(diva) | + CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula); +#else + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_DIVA(diva) | + CKGR_PLLAR_PLLACOUNT(pllacount) | CKGR_PLLAR_MULA(mula); +#endif + while ((PMC->PMC_SR & PMC_SR_LOCKA) == 0); +} + +/** + * \brief Disable PLLA clock. + */ +void pmc_disable_pllack(void) +{ +#if (SAM4C || SAM4CM || SAM4CP || SAMG) + PMC->CKGR_PLLAR = CKGR_PLLAR_MULA(0); +#else + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | CKGR_PLLAR_MULA(0); +#endif +} + +/** + * \brief Is PLLA locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_pllack(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKA); +} + +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +/** + * \brief Enable PLLB clock. + * + * \param mulb PLLB multiplier. + * \param pllbcount PLLB counter. + * \param divb Divider. + */ +void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb) +{ + /* first disable the PLL to unlock the lock */ + pmc_disable_pllbck(); + +#if SAMG55 + PMC->CKGR_PLLAR = CKGR_PLLAR_PLLAEN(divb) | + CKGR_PLLAR_PLLACOUNT(pllbcount) | CKGR_PLLAR_MULA(mulb); +#else + PMC->CKGR_PLLBR = + CKGR_PLLBR_DIVB(divb) | CKGR_PLLBR_PLLBCOUNT(pllbcount) + | CKGR_PLLBR_MULB(mulb); +#endif + while ((PMC->PMC_SR & PMC_SR_LOCKB) == 0); +} + +/** + * \brief Disable PLLB clock. + */ +void pmc_disable_pllbck(void) +{ + PMC->CKGR_PLLBR = CKGR_PLLBR_MULB(0); +} + +/** + * \brief Is PLLB locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_pllbck(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKB); +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Enable UPLL clock. + */ +void pmc_enable_upll_clock(void) +{ + PMC->CKGR_UCKR = CKGR_UCKR_UPLLCOUNT(3) | CKGR_UCKR_UPLLEN; + + /* Wait UTMI PLL Lock Status */ + while (!(PMC->PMC_SR & PMC_SR_LOCKU)); +} + +/** + * \brief Disable UPLL clock. + */ +void pmc_disable_upll_clock(void) +{ + PMC->CKGR_UCKR &= ~CKGR_UCKR_UPLLEN; +} + +/** + * \brief Is UPLL locked? + * + * \retval 0 Not locked. + * \retval 1 Locked. + */ +uint32_t pmc_is_locked_upll(void) +{ + return (PMC->PMC_SR & PMC_SR_LOCKU); +} +#endif + +/** + * \brief Enable the specified peripheral clock. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Invalid parameter. + */ +uint32_t pmc_enable_periph_clk(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 1; + } + + if (ul_id < 32) { + if ((PMC->PMC_PCSR0 & (1u << ul_id)) != (1u << ul_id)) { + PMC->PMC_PCER0 = 1 << ul_id; + } +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id)) != (1u << ul_id)) { + PMC->PMC_PCER1 = 1 << ul_id; + } +#endif + } + + return 0; +} + +/** + * \brief Disable the specified peripheral clock. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Invalid parameter. + */ +uint32_t pmc_disable_periph_clk(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 1; + } + + if (ul_id < 32) { + if ((PMC->PMC_PCSR0 & (1u << ul_id)) == (1u << ul_id)) { + PMC->PMC_PCDR0 = 1 << ul_id; + } +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP || SAMG55) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id)) == (1u << ul_id)) { + PMC->PMC_PCDR1 = 1 << ul_id; + } +#endif + } + return 0; +} + +/** + * \brief Enable all peripheral clocks. + */ +void pmc_enable_all_periph_clk(void) +{ + PMC->PMC_PCER0 = PMC_MASK_STATUS0; + while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != PMC_MASK_STATUS0); + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP) + PMC->PMC_PCER1 = PMC_MASK_STATUS1; + while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != PMC_MASK_STATUS1); +#endif +} + +/** + * \brief Disable all peripheral clocks. + */ +void pmc_disable_all_periph_clk(void) +{ + PMC->PMC_PCDR0 = PMC_MASK_STATUS0; + while ((PMC->PMC_PCSR0 & PMC_MASK_STATUS0) != 0); + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP) + PMC->PMC_PCDR1 = PMC_MASK_STATUS1; + while ((PMC->PMC_PCSR1 & PMC_MASK_STATUS1) != 0); +#endif +} + +/** + * \brief Check if the specified peripheral clock is enabled. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Peripheral clock is disabled or unknown. + * \retval 1 Peripheral clock is enabled. + */ +uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id) +{ + if (ul_id > MAX_PERIPH_ID) { + return 0; + } + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP) + if (ul_id < 32) { +#endif + if ((PMC->PMC_PCSR0 & (1u << ul_id))) { + return 1; + } else { + return 0; + } +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAM4C || SAM4CM || SAM4CP) + } else { + ul_id -= 32; + if ((PMC->PMC_PCSR1 & (1u << ul_id))) { + return 1; + } else { + return 0; + } + } +#endif +} + +/** + * \brief Set the prescaler for the specified programmable clock. + * + * \param ul_id Peripheral ID. + * \param ul_pres Prescaler value. + */ +void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres) +{ + PMC->PMC_PCK[ul_id] = + (PMC->PMC_PCK[ul_id] & ~PMC_PCK_PRES_Msk) | ul_pres; + while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) + && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); +} + +/** + * \brief Set the source oscillator for the specified programmable clock. + * + * \param ul_id Peripheral ID. + * \param ul_source Source selection value. + */ +void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source) +{ + PMC->PMC_PCK[ul_id] = + (PMC->PMC_PCK[ul_id] & ~PMC_PCK_CSS_Msk) | ul_source; + while ((PMC->PMC_SCER & (PMC_SCER_PCK0 << ul_id)) + && !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id))); +} + +/** + * \brief Switch programmable clock source selection to slow clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_SLOW_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch programmable clock source selection to main clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MAIN_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Switch programmable clock source selection to PLLA clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLA_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +/** + * \brief Switch programmable clock source selection to PLLB clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_PLLB_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +#if (SAM3XA || SAM3U) +/** + * \brief Switch programmable clock source selection to UPLL clock. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_UPLL_CLK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); + --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} +#endif + +/** + * \brief Switch programmable clock source selection to mck. + * + * \param ul_id Id of the programmable clock. + * \param ul_pres Programmable clock prescaler. + * + * \retval 0 Success. + * \retval 1 Timeout error. + */ +uint32_t pmc_switch_pck_to_mck(uint32_t ul_id, uint32_t ul_pres) +{ + uint32_t ul_timeout; + + PMC->PMC_PCK[ul_id] = PMC_PCK_CSS_MCK | ul_pres; + for (ul_timeout = PMC_TIMEOUT; + !(PMC->PMC_SR & (PMC_SR_PCKRDY0 << ul_id)); --ul_timeout) { + if (ul_timeout == 0) { + return 1; + } + } + + return 0; +} + +/** + * \brief Enable the specified programmable clock. + * + * \param ul_id Id of the programmable clock. + */ +void pmc_enable_pck(uint32_t ul_id) +{ + PMC->PMC_SCER = PMC_SCER_PCK0 << ul_id; +} + +/** + * \brief Disable the specified programmable clock. + * + * \param ul_id Id of the programmable clock. + */ +void pmc_disable_pck(uint32_t ul_id) +{ + PMC->PMC_SCDR = PMC_SCER_PCK0 << ul_id; +} + +/** + * \brief Enable all programmable clocks. + */ +void pmc_enable_all_pck(void) +{ + PMC->PMC_SCER = PMC_SCER_PCK0 | PMC_SCER_PCK1 | PMC_SCER_PCK2; +} + +/** + * \brief Disable all programmable clocks. + */ +void pmc_disable_all_pck(void) +{ + PMC->PMC_SCDR = PMC_SCDR_PCK0 | PMC_SCDR_PCK1 | PMC_SCDR_PCK2; +} + +/** + * \brief Check if the specified programmable clock is enabled. + * + * \param ul_id Id of the programmable clock. + * + * \retval 0 Programmable clock is disabled or unknown. + * \retval 1 Programmable clock is enabled. + */ +uint32_t pmc_is_pck_enabled(uint32_t ul_id) +{ + if (ul_id > 2) { + return 0; + } + + return (PMC->PMC_SCSR & (PMC_SCSR_PCK0 << ul_id)); +} + +#if (SAM4C || SAM4CM || SAM4CP) +/** + * \brief Enable Coprocessor Clocks. + */ +void pmc_enable_cpck(void) +{ + PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD; +} + +/** + * \brief Disable Coprocessor Clocks. + */ +void pmc_disable_cpck(void) +{ + PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD; +} + +/** + * \brief Check if the Coprocessor Clocks is enabled. + * + * \retval 0 Coprocessor Clocks is disabled. + * \retval 1 Coprocessor Clocks is enabled. + */ +bool pmc_is_cpck_enabled(void) +{ + if(PMC->PMC_SCSR & PMC_SCSR_CPCK) { + return 1; + } else { + return 0; + } +} + +/** + * \brief Enable Coprocessor Bus Master Clocks. + */ +void pmc_enable_cpbmck(void) +{ + PMC->PMC_SCER = PMC_SCER_CPCK | PMC_SCER_CPKEY_PASSWD; +} + +/** + * \brief Disable Coprocessor Bus Master Clocks. + */ +void pmc_disable_cpbmck(void) +{ + PMC->PMC_SCDR = PMC_SCDR_CPCK | PMC_SCDR_CPKEY_PASSWD; +} + +/** + * \brief Check if the Coprocessor Bus Master Clocks is enabled. + * + * \retval 0 Coprocessor Bus Master Clocks is disabled. + * \retval 1 Coprocessor Bus Master Clocks is enabled. + */ +bool pmc_is_cpbmck_enabled(void) +{ + if(PMC->PMC_SCSR & PMC_SCSR_CPBMCK) { + return 1; + } else { + return 0; + } +} + +/** + * \brief Set the prescaler for the Coprocessor Master Clock. + * + * \param ul_pres Prescaler value. + */ +void pmc_cpck_set_prescaler(uint32_t ul_pres) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_CPPRES_Msk)) | PMC_MCKR_CPPRES(ul_pres); +} + +/** + * \brief Set the source for the Coprocessor Master Clock. + * + * \param ul_source Source selection value. + */ +void pmc_cpck_set_source(uint32_t ul_source) +{ + PMC->PMC_MCKR = + (PMC->PMC_MCKR & (~PMC_MCKR_CPCSS_Msk)) | ul_source; +} +#endif + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55) +/** + * \brief Switch UDP (USB) clock source selection to PLLA clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv); +} +#endif + +#if (SAM3S || SAM4S || SAMG55) +/** + * \brief Switch UDP (USB) clock source selection to PLLB clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS; +} +#endif + +#if (SAM3XA) +/** + * \brief Switch UDP (USB) clock source selection to UPLL clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBS | PMC_USB_USBDIV(ul_usbdiv); +} +#endif + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55) +/** + * \brief Enable UDP (USB) clock. + */ +void pmc_enable_udpck(void) +{ +# if (SAM3S || SAM4S || SAM4E || SAMG55) + PMC->PMC_SCER = PMC_SCER_UDP; +# else + PMC->PMC_SCER = PMC_SCER_UOTGCLK; +# endif +} + +/** + * \brief Disable UDP (USB) clock. + */ +void pmc_disable_udpck(void) +{ +# if (SAM3S || SAM4S || SAM4E || SAMG55) + PMC->PMC_SCDR = PMC_SCDR_UDP; +# else + PMC->PMC_SCDR = PMC_SCDR_UOTGCLK; +# endif +} +#endif + +#if SAMG55 +/** + * \brief Switch UHP (USB) clock source selection to PLLA clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv); +} + +/** + * \brief Switch UHP (USB) clock source selection to PLLB clock. + * + * \param ul_usbdiv Clock divisor. + */ +void pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv) +{ + PMC->PMC_USB = PMC_USB_USBDIV(ul_usbdiv) | PMC_USB_USBS; +} + +/** + * \brief Enable UHP (USB) clock. + */ +void pmc_enable_uhpck(void) +{ + PMC->PMC_SCER = PMC_SCER_UHP; +} +#endif + +/** + * \brief Enable PMC interrupts. + * + * \param ul_sources Interrupt sources bit map. + */ +void pmc_enable_interrupt(uint32_t ul_sources) +{ + PMC->PMC_IER = ul_sources; +} + +/** + * \brief Disable PMC interrupts. + * + * \param ul_sources Interrupt sources bit map. + */ +void pmc_disable_interrupt(uint32_t ul_sources) +{ + PMC->PMC_IDR = ul_sources; +} + +/** + * \brief Get PMC interrupt mask. + * + * \return The interrupt mask value. + */ +uint32_t pmc_get_interrupt_mask(void) +{ + return PMC->PMC_IMR; +} + +/** + * \brief Get current status. + * + * \return The current PMC status. + */ +uint32_t pmc_get_status(void) +{ + return PMC->PMC_SR; +} + +/** + * \brief Set the wake-up inputs for fast startup mode registers + * (event generation). + * + * \param ul_inputs Wake up inputs to enable. + */ +void pmc_set_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= PMC_FAST_STARTUP_Msk; + PMC->PMC_FSMR |= ul_inputs; +} + +/** + * \brief Clear the wake-up inputs for fast startup mode registers + * (remove event generation). + * + * \param ul_inputs Wake up inputs to disable. + */ +void pmc_clr_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= PMC_FAST_STARTUP_Msk; + PMC->PMC_FSMR &= ~ul_inputs; +} + +#if (SAM4C || SAM4CM || SAM4CP) +/** + * \brief Set the wake-up inputs of coprocessor for fast startup mode registers + * (event generation). + * + * \param ul_inputs Wake up inputs to enable. + */ +void pmc_cp_set_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= PMC_FAST_STARTUP_Msk; + PMC->PMC_CPFSMR |= ul_inputs; +} + +/** + * \brief Clear the wake-up inputs of coprocessor for fast startup mode registers + * (remove event generation). + * + * \param ul_inputs Wake up inputs to disable. + */ +void pmc_cp_clr_fast_startup_input(uint32_t ul_inputs) +{ + ul_inputs &= PMC_FAST_STARTUP_Msk; + PMC->PMC_CPFSMR &= ~ul_inputs; +} +#endif + +#if (!(SAMG51 || SAMG53 || SAMG54)) +/** + * \brief Enable Sleep Mode. + * Enter condition: (WFE or WFI) + (SLEEPDEEP bit = 0) + (LPM bit = 0) + * + * \param uc_type 0 for wait for interrupt, 1 for wait for event. + * \note For SAM4S, SAM4C, SAM4CM, SAM4CP and SAM4E series, + * since only WFI is effective, uc_type = 1 will be treated as uc_type = 0. + */ +void pmc_enable_sleepmode(uint8_t uc_type) +{ +#if !(SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP) + PMC->PMC_FSMR &= (uint32_t) ~ PMC_FSMR_LPM; // Enter Sleep mode +#endif + SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; // Deep sleep + +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP) + UNUSED(uc_type); + __WFI(); +#else + if (uc_type == 0) { + __WFI(); + } else { + __WFE(); + } +#endif +} +#endif + +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP) +static uint32_t ul_flash_in_wait_mode = PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN; +/** + * \brief Set the embedded flash state in wait mode + * + * \param ul_flash_state PMC_WAIT_MODE_FLASH_STANDBY flash in standby mode, + * PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN flash in deep power down mode. + */ +void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state) +{ + ul_flash_in_wait_mode = ul_flash_state; +} + +/** + * \brief Enable Wait Mode. Enter condition: (WAITMODE bit = 1) + FLPM + * + * \note In this function, FLPM will retain, WAITMODE bit will be set, + * Generally, this function will be called by pmc_sleep() in order to + * complete all sequence entering wait mode. + * See \ref pmc_sleep() for entering different sleep modes. + */ +void pmc_enable_waitmode(void) +{ + uint32_t i; + + /* Flash in wait mode */ + i = PMC->PMC_FSMR; + i &= ~PMC_FSMR_FLPM_Msk; + i |= ul_flash_in_wait_mode; + PMC->PMC_FSMR = i; + + /* Set the WAITMODE bit = 1 */ + PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_WAITMODE; + + /* Waiting for Master Clock Ready MCKRDY = 1 */ + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); + + /* Waiting for MOSCRCEN bit cleared is strongly recommended + * to ensure that the core will not execute undesired instructions + */ + for (i = 0; i < 500; i++) { + __NOP(); + } + while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN)); + +#if (!SAMG) + /* Restore Flash in idle mode */ + i = PMC->PMC_FSMR; + i &= ~PMC_FSMR_FLPM_Msk; + i |= PMC_WAIT_MODE_FLASH_IDLE; + PMC->PMC_FSMR = i; +#endif +} +#else +/** + * \brief Enable Wait Mode. Enter condition: WFE + (SLEEPDEEP bit = 0) + + * (LPM bit = 1) + */ +void pmc_enable_waitmode(void) +{ + uint32_t i; + + PMC->PMC_FSMR |= PMC_FSMR_LPM; /* Enter Wait mode */ + SCB->SCR &= (uint32_t) ~ SCB_SCR_SLEEPDEEP_Msk; /* Deep sleep */ + + __WFE(); + + /* Waiting for MOSCRCEN bit cleared is strongly recommended + * to ensure that the core will not execute undesired instructions + */ + for (i = 0; i < 500; i++) { + __NOP(); + } + while (!(PMC->CKGR_MOR & CKGR_MOR_MOSCRCEN)); + +} +#endif + +#if (!(SAMG51 || SAMG53 || SAMG54)) +/** + * \brief Enable Backup Mode. Enter condition: WFE/(VROFF bit = 1) + + * (SLEEPDEEP bit = 1) + */ +void pmc_enable_backupmode(void) +{ +#if (SAM4C || SAM4CM || SAM4CP) + uint32_t tmp = SUPC->SUPC_MR & ~(SUPC_MR_BUPPOREN | SUPC_MR_KEY_Msk); + SUPC->SUPC_MR = tmp | SUPC_MR_KEY_PASSWD; + while (SUPC->SUPC_SR & SUPC_SR_BUPPORS); +#endif + SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk; +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55) + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; + __WFE(); + __WFI(); +#else + __WFE(); +#endif +} +#endif + +/** + * \brief Enable Clock Failure Detector. + */ +void pmc_enable_clock_failure_detector(void) +{ + uint32_t ul_reg = PMC->CKGR_MOR; + + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_CFDEN | ul_reg; +} + +/** + * \brief Disable Clock Failure Detector. + */ +void pmc_disable_clock_failure_detector(void) +{ + uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_CFDEN); + + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg; +} + +#if (SAM4N || SAM4C || SAM4CM || SAM4CP) +/** + * \brief Enable Slow Crystal Oscillator Frequency Monitoring. + */ +void pmc_enable_sclk_osc_freq_monitor(void) +{ + uint32_t ul_reg = PMC->CKGR_MOR; + + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | CKGR_MOR_XT32KFME | ul_reg; +} + +/** + * \brief Disable Slow Crystal Oscillator Frequency Monitoring. + */ +void pmc_disable_sclk_osc_freq_monitor(void) +{ + uint32_t ul_reg = PMC->CKGR_MOR & (~CKGR_MOR_XT32KFME); + + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | ul_reg; +} +#endif + +/** + * \brief Enable or disable write protect of PMC registers. + * + * \param ul_enable 1 to enable, 0 to disable. + */ +void pmc_set_writeprotect(uint32_t ul_enable) +{ + if (ul_enable) { + PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD | PMC_WPMR_WPEN; + } else { + PMC->PMC_WPMR = PMC_WPMR_WPKEY_PASSWD; + } +} + +/** + * \brief Return write protect status. + * + * \return Return write protect status. + */ +uint32_t pmc_get_writeprotect_status(void) +{ + return PMC->PMC_WPSR; +} + +#if (SAMG53 || SAMG54 || SAMG55) +/** + * \brief Enable the specified peripheral clock. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Fail. + */ +uint32_t pmc_enable_sleepwalking(uint32_t ul_id) +{ + uint32_t temp; +#if SAMG55 + if ((7 <= ul_id) && (ul_id<= 29)) { +#else + if ((8 <= ul_id) && (ul_id<= 29)) { +#endif + temp = pmc_get_active_status(); + if (temp & (1 << ul_id)) { + return 1; + } + PMC->PMC_SLPWK_ER0 = 1 << ul_id; + temp = pmc_get_active_status(); + if (temp & (1 << ul_id)) { + pmc_disable_sleepwalking(ul_id); + return 1; + } + return 0; + } else { + return 1; + } +} + +/** + * \brief Disable the sleepwalking of specified peripheral. + * + * \note The ID must NOT be shifted (i.e., 1 << ID_xxx). + * + * \param ul_id Peripheral ID (ID_xxx). + * + * \retval 0 Success. + * \retval 1 Invalid parameter. + */ +uint32_t pmc_disable_sleepwalking(uint32_t ul_id) +{ +#if SAMG55 + if ((7 <= ul_id) && (ul_id<= 29)) { +#else + if ((8 <= ul_id) && (ul_id<= 29)) { +#endif + PMC->PMC_SLPWK_DR0 = 1 << ul_id; + return 0; + } else { + return 1; + } +} + +/** + * \brief Return peripheral sleepwalking enable status. + * + * \return the status register value. + */ +uint32_t pmc_get_sleepwalking_status(void) +{ + return PMC->PMC_SLPWK_SR0; +} + +/** + * \brief Return peripheral active status. + * + * \return the status register value. + */ +uint32_t pmc_get_active_status(void) +{ + return PMC->PMC_SLPWK_ASR0; +} + +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.h new file mode 100644 index 0000000..789d1b1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/pmc.h @@ -0,0 +1,540 @@ +/** + * \file + * + * \brief Power Management Controller (PMC) driver for SAM. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef PMC_H_INCLUDED +#define PMC_H_INCLUDED + +#include "compiler.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Bit mask for peripheral clocks (PCER0) */ +#define PMC_MASK_STATUS0 (0xFFFFFFFC) + +/** Bit mask for peripheral clocks (PCER1) */ +#define PMC_MASK_STATUS1 (0xFFFFFFFF) + +/** Loop counter timeout value */ +#define PMC_TIMEOUT (2048) + +/** Key to unlock CKGR_MOR register */ +#ifndef CKGR_MOR_KEY_PASSWD +#define CKGR_MOR_KEY_PASSWD CKGR_MOR_KEY(0x37U) +#endif + +/** Key used to write SUPC registers */ +#ifndef SUPC_CR_KEY_PASSWD +#define SUPC_CR_KEY_PASSWD SUPC_CR_KEY(0xA5U) +#endif + +#ifndef SUPC_MR_KEY_PASSWD +#define SUPC_MR_KEY_PASSWD SUPC_MR_KEY(0xA5U) +#endif + +/** Mask to access fast startup input */ +#define PMC_FAST_STARTUP_Msk (0x7FFFFu) + +/** PMC_WPMR Write Protect KEY, unlock it */ +#ifndef PMC_WPMR_WPKEY_PASSWD +#define PMC_WPMR_WPKEY_PASSWD PMC_WPMR_WPKEY((uint32_t) 0x504D43) +#endif + +/** Using external oscillator */ +#define PMC_OSC_XTAL 0 + +/** Oscillator in bypass mode */ +#define PMC_OSC_BYPASS 1 + +#define PMC_PCK_0 0 /* PCK0 ID */ +#define PMC_PCK_1 1 /* PCK1 ID */ +#define PMC_PCK_2 2 /* PCK2 ID */ +#if SAMG55 +#define PMC_PCK_3 3 /* PCK3 ID */ +#define PMC_PCK_4 4 /* PCK4 ID */ +#define PMC_PCK_5 5 /* PCK5 ID */ +#define PMC_PCK_6 6 /* PCK6 ID */ +#define PMC_PCK_7 7 /* PCK7 ID */ +#endif + +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP) +/** Flash state in Wait Mode */ +#define PMC_WAIT_MODE_FLASH_STANDBY PMC_FSMR_FLPM_FLASH_STANDBY +#define PMC_WAIT_MODE_FLASH_DEEP_POWERDOWN PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN +#define PMC_WAIT_MODE_FLASH_IDLE PMC_FSMR_FLPM_FLASH_IDLE +#endif + +/** Convert startup time from us to MOSCXTST */ +#define pmc_us_to_moscxtst(startup_us, slowck_freq) \ + ((startup_us * slowck_freq / 8 / 1000000) < 0x100 ? \ + (startup_us * slowck_freq / 8 / 1000000) : 0xFF) + +/** + * \name Master clock (MCK) Source and Prescaler configuration + * + * \note The following functions may be used to select the clock source and + * prescaler for the master clock. + */ +//@{ + +void pmc_mck_set_prescaler(uint32_t ul_pres); +void pmc_mck_set_source(uint32_t ul_source); +uint32_t pmc_switch_mck_to_sclk(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_mainck(uint32_t ul_pres); +uint32_t pmc_switch_mck_to_pllack(uint32_t ul_pres); +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +uint32_t pmc_switch_mck_to_pllbck(uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_mck_to_upllck(uint32_t ul_pres); +#endif +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAMG || SAM4CP) +void pmc_set_flash_in_wait_mode(uint32_t ul_flash_state); +#endif + + +//@} + +/** + * \name Slow clock (SLCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_sclk_to_32kxtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_32kxtal(void); + +//@} + +/** + * \name Main Clock (MAINCK) oscillator and configuration + * + */ +//@{ + +void pmc_switch_mainck_to_fastrc(uint32_t ul_moscrcf); +void pmc_osc_enable_fastrc(uint32_t ul_rc); +void pmc_osc_disable_fastrc(void); +uint32_t pmc_osc_is_ready_fastrc(void); +void pmc_osc_enable_main_xtal(uint32_t ul_xtal_startup_time); +void pmc_osc_bypass_main_xtal(void); +void pmc_osc_disable_main_xtal(void); +uint32_t pmc_osc_is_bypassed_main_xtal(void); +uint32_t pmc_osc_is_ready_main_xtal(void); +void pmc_switch_mainck_to_xtal(uint32_t ul_bypass, + uint32_t ul_xtal_startup_time); +void pmc_osc_disable_xtal(uint32_t ul_bypass); +uint32_t pmc_osc_is_ready_mainck(void); +void pmc_mainck_osc_select(uint32_t ul_xtal_rc); + +//@} + +/** + * \name PLL oscillator and configuration + * + */ +//@{ + +void pmc_enable_pllack(uint32_t mula, uint32_t pllacount, uint32_t diva); +void pmc_disable_pllack(void); +uint32_t pmc_is_locked_pllack(void); + +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +void pmc_enable_pllbck(uint32_t mulb, uint32_t pllbcount, uint32_t divb); +void pmc_disable_pllbck(void); +uint32_t pmc_is_locked_pllbck(void); +#endif + +#if (SAM3XA || SAM3U) +void pmc_enable_upll_clock(void); +void pmc_disable_upll_clock(void); +uint32_t pmc_is_locked_upll(void); +#endif + +//@} + +/** + * \name Peripherals clock configuration + * + */ +//@{ + +uint32_t pmc_enable_periph_clk(uint32_t ul_id); +uint32_t pmc_disable_periph_clk(uint32_t ul_id); +void pmc_enable_all_periph_clk(void); +void pmc_disable_all_periph_clk(void); +uint32_t pmc_is_periph_clk_enabled(uint32_t ul_id); + +//@} + +/** + * \name Programmable clock Source and Prescaler configuration + * + * The following functions may be used to select the clock source and + * prescaler for the specified programmable clock. + */ +//@{ + +void pmc_pck_set_prescaler(uint32_t ul_id, uint32_t ul_pres); +void pmc_pck_set_source(uint32_t ul_id, uint32_t ul_source); +uint32_t pmc_switch_pck_to_sclk(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_mainck(uint32_t ul_id, uint32_t ul_pres); +uint32_t pmc_switch_pck_to_pllack(uint32_t ul_id, uint32_t ul_pres); +#if (SAM4C || SAM4CM || SAM4CP) +void pmc_enable_cpck(void); +void pmc_disable_cpck(void); +bool pmc_is_cpck_enabled(void); +void pmc_enable_cpbmck(void); +void pmc_disable_cpbmck(void); +bool pmc_is_cpbmck_enabled(void); +void pmc_cpck_set_prescaler(uint32_t ul_pres); +void pmc_cpck_set_source(uint32_t ul_source); +#endif +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP || SAMG55) +uint32_t pmc_switch_pck_to_pllbck(uint32_t ul_id, uint32_t ul_pres); +#endif +#if (SAM3XA || SAM3U) +uint32_t pmc_switch_pck_to_upllck(uint32_t ul_id, uint32_t ul_pres); +#endif +uint32_t pmc_switch_pck_to_mck(uint32_t ul_id, uint32_t ul_pres); +void pmc_enable_pck(uint32_t ul_id); +void pmc_disable_pck(uint32_t ul_id); +void pmc_enable_all_pck(void); +void pmc_disable_all_pck(void); +uint32_t pmc_is_pck_enabled(uint32_t ul_id); + +//@} + +/** + * \name USB clock configuration + * + */ +//@{ + +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55) +void pmc_switch_udpck_to_pllack(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM4S || SAMG55) +void pmc_switch_udpck_to_pllbck(uint32_t ul_usbdiv); +#endif +#if (SAM3XA) +void pmc_switch_udpck_to_upllck(uint32_t ul_usbdiv); +#endif +#if (SAM3S || SAM3XA || SAM4S || SAM4E || SAMG55) +void pmc_enable_udpck(void); +void pmc_disable_udpck(void); +#endif +#if SAMG55 +void pmc_switch_uhpck_to_pllack(uint32_t ul_usbdiv); +void pmc_switch_uhpck_to_pllbck(uint32_t ul_usbdiv); +void pmc_enable_uhpck(void); +#endif + +//@} + +/** + * \name Interrupt and status management + * + */ +//@{ + +void pmc_enable_interrupt(uint32_t ul_sources); +void pmc_disable_interrupt(uint32_t ul_sources); +uint32_t pmc_get_interrupt_mask(void); +uint32_t pmc_get_status(void); + +//@} + +/** + * \name Power management + * + * The following functions are used to configure sleep mode and additional + * wake up inputs. + */ +//@{ + +void pmc_set_fast_startup_input(uint32_t ul_inputs); +void pmc_clr_fast_startup_input(uint32_t ul_inputs); +#if (SAM4C || SAM4CM || SAM4CP) +void pmc_cp_set_fast_startup_input(uint32_t ul_inputs); +void pmc_cp_clr_fast_startup_input(uint32_t ul_inputs); +#endif +#if (!(SAMG51 || SAMG53 || SAMG54)) +void pmc_enable_sleepmode(uint8_t uc_type); +#endif +void pmc_enable_waitmode(void); +#if (!(SAMG51 || SAMG53 || SAMG54)) +void pmc_enable_backupmode(void); +#endif +//@} + +/** + * \name Failure detector + * + */ +//@{ + +void pmc_enable_clock_failure_detector(void); +void pmc_disable_clock_failure_detector(void); + +//@} + +#if (SAM4N || SAM4C || SAM4CM || SAM4CP) +/** + * \name Slow Crystal Oscillator Frequency Monitoring + * + */ +//@{ + +void pmc_enable_sclk_osc_freq_monitor(void); +void pmc_disable_sclk_osc_freq_monitor(void); + +//@} +#endif + +/** + * \name Write protection + * + */ +//@{ + +void pmc_set_writeprotect(uint32_t ul_enable); +uint32_t pmc_get_writeprotect_status(void); + +//@} + +#if (SAMG53 || SAMG54 || SAMG55) +/** + * \name Sleepwalking configuration + * + */ +//@{ + +uint32_t pmc_enable_sleepwalking(uint32_t ul_id); +uint32_t pmc_disable_sleepwalking(uint32_t ul_id); +uint32_t pmc_get_sleepwalking_status(void); +uint32_t pmc_get_active_status(void); + +//@} +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +//! @} + +/** + * \page sam_pmc_quickstart Quick start guide for the SAM PMC module + * + * This is the quick start guide for the \ref sam_drivers_pmc_group "PMC module", + * with step-by-step instructions on how to configure and use the driver in a + * selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \section pmc_use_cases PMC use cases + * - \ref pmc_basic_use_case Basic use case - Switch Main Clock sources + * - \ref pmc_use_case_2 Advanced use case - Configure Programmable Clocks + * + * \section pmc_basic_use_case Basic use case - Switch Main Clock sources + * In this use case, the PMC module is configured for a variety of system clock + * sources and speeds. A LED is used to visually indicate the current clock + * speed as the source is switched. + * + * \section pmc_basic_use_case_setup Setup + * + * \subsection pmc_basic_use_case_setup_prereq Prerequisites + * -# \ref gpio_group "General Purpose I/O Management (gpio)" + * + * \subsection pmc_basic_use_case_setup_code Code + * The following function needs to be added to the user application, to flash a + * board LED a variable number of times at a rate given in CPU ticks. + * + * \code + #define FLASH_TICK_COUNT 0x00012345 + + void flash_led(uint32_t tick_count, uint8_t flash_count) + { + SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; + SysTick->LOAD = tick_count; + + while (flash_count--) + { + gpio_toggle_pin(LED0_GPIO); + while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + gpio_toggle_pin(LED0_GPIO); + while (!(SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk)); + } + } +\endcode + * + * \section pmc_basic_use_case_usage Use case + * + * \subsection pmc_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + for (;;) + { + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + flash_led(FLASH_TICK_COUNT, 5); + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + flash_led(FLASH_TICK_COUNT, 5); + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + flash_led(FLASH_TICK_COUNT, 5); + pmc_switch_mainck_to_xtal(0); + flash_led(FLASH_TICK_COUNT, 5); + } +\endcode + * + * \subsection pmc_basic_use_case_usage_flow Workflow + * -# Wrap the code in an infinite loop: + * \code + for (;;) +\endcode + * -# Switch the Master CPU frequency to the internal 12MHz RC oscillator, flash + * a LED on the board several times: + * \code + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_12_MHz); + flash_led(FLASH_TICK_COUNT, 5); +\endcode + * -# Switch the Master CPU frequency to the internal 8MHz RC oscillator, flash + * a LED on the board several times: + * \code + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_8_MHz); + flash_led(FLASH_TICK_COUNT, 5); +\endcode + * -# Switch the Master CPU frequency to the internal 4MHz RC oscillator, flash + * a LED on the board several times: + * \code + pmc_switch_mainck_to_fastrc(CKGR_MOR_MOSCRCF_4_MHz); + flash_led(FLASH_TICK_COUNT, 5); +\endcode + * -# Switch the Master CPU frequency to the external crystal oscillator, flash + * a LED on the board several times: + * \code + pmc_switch_mainck_to_xtal(0, BOARD_OSC_STARTUP_US); + flash_led(FLASH_TICK_COUNT, 5); +\endcode + * + * \section pmc_use_case_2 Use case #2 - Configure Programmable Clocks + * In this use case, the PMC module is configured to start the Slow Clock from + * an attached 32KHz crystal, and start one of the Programmable Clock modules + * sourced from the Slow Clock divided down with a prescale factor of 64. + * + * \section pmc_use_case_2_setup Setup + * + * \subsection pmc_use_case_2_setup_prereq Prerequisites + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * + * \subsection pmc_use_case_2_setup_code Code + * The following code must be added to the user application: + * \code + pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); +\endcode + * + * \subsection pmc_use_case_2_setup_code_workflow Workflow + * -# Configure the PCK1 pin to output on a specific port pin (in this case, + * PIOA pin 17) of the microcontroller. + * \code + pio_set_peripheral(PIOA, PIO_PERIPH_B, PIO_PA17); +\endcode + * \note The peripheral selection and pin will vary according to your selected + * SAM device model. Refer to the "Peripheral Signal Multiplexing on I/O + * Lines" of your device's datasheet. + * + * \section pmc_use_case_2_usage Use case + * The generated PCK1 clock output can be viewed on an oscilloscope attached to + * the correct pin of the microcontroller. + * + * \subsection pmc_use_case_2_usage_code Example code + * Add to application C-file: + * \code + pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); + pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); + pmc_enable_pck(PMC_PCK_1); + + for (;;) + { + // Do Nothing + } +\endcode + * + * \subsection pmc_use_case_2_usage_flow Workflow + * -# Switch the Slow Clock source input to an external 32KHz crystal: + * \code + pmc_switch_sclk_to_32kxtal(PMC_OSC_XTAL); +\endcode + * -# Switch the Programmable Clock module PCK1 source clock to the Slow Clock, + * with a prescaler of 64: + * \code + pmc_switch_pck_to_sclk(PMC_PCK_1, PMC_PCK_PRES_CLK_64); +\endcode + * -# Enable Programmable Clock module PCK1: + * \code + pmc_enable_pck(PMC_PCK_1); +\endcode + * -# Enter an infinite loop: + * \code + for (;;) + { + // Do Nothing + } +\endcode + */ + +#endif /* PMC_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.c new file mode 100644 index 0000000..65af01b --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.c @@ -0,0 +1,389 @@ +/** + * \file + * + * \brief Sleep mode access + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include +#include "sleep.h" + +/* SAM3 and SAM4 series */ +#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \ + SAM4CM || SAMG || SAM4CP) +# include "pmc.h" +# include "board.h" + +/* Checking board configuration of main clock xtal statup time */ +#if !defined(BOARD_OSC_STARTUP_US) +# warning The board main clock xtal statup time has not been defined. Using default settings. +# define BOARD_OSC_STARTUP_US (15625UL) +#endif + +#if !defined(EFC0) +# define EFC0 EFC +#endif + +/** + * Save clock settings and shutdown PLLs + */ +__always_inline static void pmc_save_clock_settings( + uint32_t *p_osc_setting, + uint32_t *p_pll0_setting, + uint32_t *p_pll1_setting, + uint32_t *p_mck_setting, + uint32_t *p_fmr_setting, +#if defined(EFC1) + uint32_t *p_fmr_setting1, +#endif + const bool disable_xtal) +{ + uint32_t mor = PMC->CKGR_MOR; + uint32_t mckr = PMC->PMC_MCKR; + uint32_t fmr = EFC0->EEFC_FMR; +# if defined(EFC1) + uint32_t fmr1 = EFC1->EEFC_FMR; +# endif + + if (p_osc_setting) { + *p_osc_setting = mor; + } + if (p_pll0_setting) { + *p_pll0_setting = PMC->CKGR_PLLAR; + } + if (p_pll1_setting) { +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) + *p_pll1_setting = PMC->CKGR_PLLBR; +#elif (SAM3U || SAM3XA) + *p_pll1_setting = PMC->CKGR_UCKR; +#else + *p_pll1_setting = 0; +#endif + } + if (p_mck_setting) { + *p_mck_setting = mckr; + } + if (p_fmr_setting) { + *p_fmr_setting = fmr; + } +#if defined(EFC1) + if (p_fmr_setting1) { + *p_fmr_setting1 = fmr1; + } +#endif + + /* Enable FAST RC */ + PMC->CKGR_MOR = CKGR_MOR_KEY_PASSWD | mor | CKGR_MOR_MOSCRCEN; + /* if MCK source is PLL, switch to mainck */ + if ((mckr & PMC_MCKR_CSS_Msk) > PMC_MCKR_CSS_MAIN_CLK) { + /* MCK -> MAINCK */ + mckr = (mckr & (~PMC_MCKR_CSS_Msk)) | PMC_MCKR_CSS_MAIN_CLK; + PMC->PMC_MCKR = mckr; + while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); + } + /* MCK prescale -> 1 */ + if (mckr & PMC_MCKR_PRES_Msk) { + mckr = (mckr & (~PMC_MCKR_PRES_Msk)); + PMC->PMC_MCKR = mckr; + while(!(PMC->PMC_SR & PMC_SR_MCKRDY)); + } + /* Disable PLLs */ + pmc_disable_pllack(); +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) + pmc_disable_pllbck(); +#elif (SAM3U || SAM3XA) + pmc_disable_upll_clock(); +#endif + + /* Prepare for entering WAIT mode */ + /* Wait fast RC ready */ + while (!(PMC->PMC_SR & PMC_SR_MOSCRCS)); + + /* Switch mainck to FAST RC */ +#if SAMG + /** + * For the sleepwalking feature, we need an accurate RC clock. Only 24M and + * 16M are trimmed in production. Here we select the 24M. + * And so wait state need to be 1. + */ + EFC0->EEFC_FMR = (fmr & (~EEFC_FMR_FWS_Msk)) | EEFC_FMR_FWS(1); + + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | CKGR_MOR_MOSCRCF_24_MHz | + CKGR_MOR_KEY_PASSWD; +#else + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCSEL) | + CKGR_MOR_KEY_PASSWD; +#endif + while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)); + +#if (!SAMG) + /* FWS update */ + EFC0->EEFC_FMR = fmr & (~EEFC_FMR_FWS_Msk); +#if defined(EFC1) + EFC1->EEFC_FMR = fmr1 & (~EEFC_FMR_FWS_Msk); +#endif +#endif + + /* Disable XTALs */ + if (disable_xtal) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + CKGR_MOR_KEY_PASSWD; + } +} + +/** + * Restore clock settings + */ +__always_inline static void pmc_restore_clock_setting( + const uint32_t osc_setting, + const uint32_t pll0_setting, + const uint32_t pll1_setting, + const uint32_t mck_setting, + const uint32_t fmr_setting +#if defined(EFC1) + , const uint32_t fmr_setting1 +#endif + ) +{ + uint32_t mckr; + uint32_t pll_sr = 0; + + /* Switch mainck to external xtal */ + if (CKGR_MOR_MOSCXTBY == (osc_setting & CKGR_MOR_MOSCXTBY)) { + /* Bypass mode */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTEN) | + CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTBY | + CKGR_MOR_MOSCSEL; + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & + ~CKGR_MOR_MOSCRCF_Msk) + | CKGR_MOR_KEY_PASSWD; + } else if (CKGR_MOR_MOSCXTEN == (osc_setting & CKGR_MOR_MOSCXTEN)) { + /* Enable External XTAL */ + if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCXTEN)) { + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCXTBY) | + CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCXTEN; + /* Wait the Xtal to stabilize */ + while (!(PMC->PMC_SR & PMC_SR_MOSCXTS)); + } + /* Select External XTAL */ + if (!(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL)) { + PMC->CKGR_MOR |= CKGR_MOR_KEY_PASSWD | CKGR_MOR_MOSCSEL; + while (!(PMC->PMC_SR & PMC_SR_MOSCSELS)); + } + /* Disable Fast RC */ + PMC->CKGR_MOR = (PMC->CKGR_MOR & ~CKGR_MOR_MOSCRCEN & + ~CKGR_MOR_MOSCRCF_Msk) + | CKGR_MOR_KEY_PASSWD; + } + + if (pll0_setting & CKGR_PLLAR_MULA_Msk) { +#if (SAM4C || SAM4CM || SAMG || SAM4CP) + PMC->CKGR_PLLAR = pll0_setting; +#else + PMC->CKGR_PLLAR = CKGR_PLLAR_ONE | pll0_setting; +#endif + pll_sr |= PMC_SR_LOCKA; + } +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) + if (pll1_setting & CKGR_PLLBR_MULB_Msk) { + PMC->CKGR_PLLBR = pll1_setting; + pll_sr |= PMC_SR_LOCKB; + } +#elif (SAM3U || SAM3XA) + if (pll1_setting & CKGR_UCKR_UPLLEN) { + PMC->CKGR_UCKR = pll1_setting; + pll_sr |= PMC_SR_LOCKU; + } +#else + UNUSED(pll1_setting); +#endif + /* Wait MCK source ready */ + switch(mck_setting & PMC_MCKR_CSS_Msk) { + case PMC_MCKR_CSS_PLLA_CLK: + while (!(PMC->PMC_SR & PMC_SR_LOCKA)); + break; +#if (SAM3S || SAM4S || SAM4C || SAM4CM || SAM4CP) + case PMC_MCKR_CSS_PLLB_CLK: + while (!(PMC->PMC_SR & PMC_SR_LOCKB)); + break; +#elif (SAM3U || SAM3XA) + case PMC_MCKR_CSS_UPLL_CLK: + while (!(PMC->PMC_SR & PMC_SR_LOCKU)); + break; +#endif + } + + /* Switch to faster clock */ + mckr = PMC->PMC_MCKR; + + /* Set PRES */ + PMC->PMC_MCKR = (mckr & ~PMC_MCKR_PRES_Msk) + | (mck_setting & PMC_MCKR_PRES_Msk); + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); + + /* Restore flash wait states */ + EFC0->EEFC_FMR = fmr_setting; +#if defined(EFC1) + EFC1->EEFC_FMR = fmr_setting1; +#endif + + /* Set CSS and others */ + PMC->PMC_MCKR = mck_setting; + while (!(PMC->PMC_SR & PMC_SR_MCKRDY)); + + /* Waiting all restored PLLs ready */ + while (!(PMC->PMC_SR & pll_sr)); +} + +/** If clocks are switched for some sleep mode */ +static volatile bool b_is_sleep_clock_used = false; +/** Callback invoked once when clocks are restored */ +static pmc_callback_wakeup_clocks_restored_t callback_clocks_restored = NULL; + +void pmc_sleep(int sleep_mode) +{ + switch (sleep_mode) { +#if (!(SAMG51 || SAMG53 || SAMG54)) + case SAM_PM_SMODE_SLEEP_WFI: + case SAM_PM_SMODE_SLEEP_WFE: +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55) + SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP; + cpu_irq_enable(); + __WFI(); + break; +#else + PMC->PMC_FSMR &= (uint32_t)~PMC_FSMR_LPM; + SCB->SCR &= (uint32_t)~SCR_SLEEPDEEP; + cpu_irq_enable(); + if (sleep_mode == SAM_PM_SMODE_SLEEP_WFI) + __WFI(); + else + __WFE(); + break; +#endif +#endif + + case SAM_PM_SMODE_WAIT_FAST: + case SAM_PM_SMODE_WAIT: { + uint32_t mor, pllr0, pllr1, mckr; + uint32_t fmr; +#if defined(EFC1) + uint32_t fmr1; +#endif +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55) + (sleep_mode == SAM_PM_SMODE_WAIT_FAST) ? + pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_STANDBY) : + pmc_set_flash_in_wait_mode(PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN); +#endif + cpu_irq_disable(); + b_is_sleep_clock_used = true; + +#if (SAM4C || SAM4CM || SAM4CP) + /* Backup the sub-system 1 status and stop sub-system 1 */ + uint32_t cpclk_backup = PMC->PMC_SCSR & + (PMC_SCSR_CPCK | PMC_SCSR_CPBMCK); + PMC->PMC_SCDR = cpclk_backup | PMC_SCDR_CPKEY_PASSWD; +#endif + pmc_save_clock_settings(&mor, &pllr0, &pllr1, &mckr, &fmr, +#if defined(EFC1) + &fmr1, +#endif + (sleep_mode == SAM_PM_SMODE_WAIT)); + + /* Enter wait mode */ + cpu_irq_enable(); + + pmc_enable_waitmode(); + + cpu_irq_disable(); + pmc_restore_clock_setting(mor, pllr0, pllr1, mckr, fmr +#if defined(EFC1) + , fmr1 +#endif + ); + +#if (SAM4C || SAM4CM || SAM4CP) + /* Restore the sub-system 1 */ + PMC->PMC_SCER = cpclk_backup | PMC_SCER_CPKEY_PASSWD; +#endif + b_is_sleep_clock_used = false; + if (callback_clocks_restored) { + callback_clocks_restored(); + callback_clocks_restored = NULL; + } + cpu_irq_enable(); + + break; + } +#if (!(SAMG51 || SAMG53 || SAMG54)) + case SAM_PM_SMODE_BACKUP: + SCB->SCR |= SCR_SLEEPDEEP; +#if (SAM4S || SAM4E || SAM4N || SAM4C || SAM4CM || SAM4CP || SAMG55) + SUPC->SUPC_CR = SUPC_CR_KEY_PASSWD | SUPC_CR_VROFF_STOP_VREG; + cpu_irq_enable(); + __WFI() ; +#else + cpu_irq_enable(); + __WFE() ; +#endif + break; +#endif + } +} + +bool pmc_is_wakeup_clocks_restored(void) +{ + return !b_is_sleep_clock_used; +} + +void pmc_wait_wakeup_clocks_restore( + pmc_callback_wakeup_clocks_restored_t callback) +{ + if (b_is_sleep_clock_used) { + cpu_irq_disable(); + callback_clocks_restored = callback; + } else if (callback) { + callback(); + } +} + +#endif diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.h new file mode 100644 index 0000000..56868f4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/pmc/sleep.h @@ -0,0 +1,133 @@ +/** + * \file + * + * \brief Sleep mode access + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef SLEEP_H +#define SLEEP_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +/** + * \defgroup sleep_group Power Manager (PM) + * + * This is a stub on the SAM Power Manager Control (PMC) for the sleepmgr + * service. + * + * \note To minimize the code overhead, these functions do not feature + * interrupt-protected access since they are likely to be called inside + * interrupt handlers or in applications where such protection is not + * necessary. If such protection is needed, it must be ensured by the calling + * code. + * + * @{ + */ + +#if defined(__DOXYGEN__) +/** + * \brief Sets the MCU in the specified sleep mode + * \param sleep_mode Sleep mode to set. + */ +#endif +/* SAM3 and SAM4 series */ +#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \ + SAM4CM || SAM4CP || SAMG) + +#if (SAM3S || SAM3N || SAM3XA || SAM3U || SAM4S || SAM4E || SAM4N || SAM4C || \ + SAM4CM || SAM4CP || SAMG55) +# define SAM_PM_SMODE_ACTIVE 0 /**< Active */ +# define SAM_PM_SMODE_SLEEP_WFE 1 /**< Wait for Events */ +# define SAM_PM_SMODE_SLEEP_WFI 2 /**< Wait for Interrupts */ +# define SAM_PM_SMODE_WAIT_FAST 3 /**< Wait Mode, startup fast (in 3ms) */ +# define SAM_PM_SMODE_WAIT 4 /**< Wait Mode */ +# define SAM_PM_SMODE_BACKUP 5 /**< Backup Mode */ +#else +# define SAM_PM_SMODE_ACTIVE 0 /**< Active */ +# define SAM_PM_SMODE_WAIT_FAST 1 /**< Wait Mode, startup fast (in 3ms) */ +# define SAM_PM_SMODE_WAIT 2 /**< Wait Mode */ +#endif + +/** (SCR) Sleep deep bit */ +#define SCR_SLEEPDEEP (0x1 << 2) + +/** + * Clocks restored callback function type. + * Registered by routine pmc_wait_wakeup_clocks_restore() + * Callback called when all clocks are restored. + */ +typedef void (*pmc_callback_wakeup_clocks_restored_t) (void); + +/** + * Enter sleep mode + * \param sleep_mode Sleep mode to enter + */ +void pmc_sleep(int sleep_mode); + +/** + * Check if clocks are restored after wakeup + * (For WAIT mode. In WAIT mode, clocks are switched to FASTRC. + * After wakeup clocks should be restored, before that some of the + * ISR should not be served, otherwise there may be timing or clock issue.) + */ +bool pmc_is_wakeup_clocks_restored(void); + +/** + * \return true if start waiting + */ +void pmc_wait_wakeup_clocks_restore( + pmc_callback_wakeup_clocks_restored_t callback); + +#endif + +//! @} + +#ifdef __cplusplus +} +#endif + +#endif /* SLEEP_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.c new file mode 100644 index 0000000..8f65ddd --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.c @@ -0,0 +1,558 @@ +/** + * \file + * + * \brief Universal Asynchronous Receiver Transceiver (UART) driver for SAM. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "uart.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_uart_group Universal Asynchronous Receiver Transceiver (UART) + * + * The Universal Asynchronous Receiver Transmitter features a two-pin UART that + * can be used for communication and trace purposes and offers an ideal medium + * for in-situ programming solutions. Moreover, the association with two + * peripheral DMA controller (PDC) channels permits packet handling for these + * tasks with processor time reduced to a minimum. + * + * \par Usage + * + * -# Enable the UART peripheral clock in the PMC. + * -# Enable the required UART PIOs (see pio.h). + * -# Configure the UART by calling uart_init. + * -# Send data through the UART using the uart_write. + * -# Receive data from the UART using the uart_read; the availability of data + * can be polled with uart_is_rx_ready. + * -# Disable the transmitter and/or the receiver of the UART with + * uart_disable_tx and uart_disable_rx. + * + * @{ + */ + +/** + * \brief Configure UART with the specified parameters. + * + * \note The PMC and PIOs must be configured first. + * + * \param p_uart Pointer to a UART instance. + * \param p_uart_opt Pointer to sam_uart_opt_t instance. + * + * \retval 0 Success. + * \retval 1 Bad baud rate generator value. + */ +uint32_t uart_init(Uart *p_uart, const sam_uart_opt_t *p_uart_opt) +{ + uint32_t cd = 0; + + /* Reset and disable receiver & transmitter */ + p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX + | UART_CR_RXDIS | UART_CR_TXDIS; + + /* Check and configure baudrate */ + /* Asynchronous, no oversampling */ + cd = (p_uart_opt->ul_mck / p_uart_opt->ul_baudrate) / UART_MCK_DIV; + if (cd < UART_MCK_DIV_MIN_FACTOR || cd > UART_MCK_DIV_MAX_FACTOR) + return 1; + + p_uart->UART_BRGR = cd; + /* Configure mode */ + p_uart->UART_MR = p_uart_opt->ul_mode; + + /* Disable PDC channel */ + p_uart->UART_PTCR = UART_PTCR_RXTDIS | UART_PTCR_TXTDIS; + + /* Enable receiver and transmitter */ + p_uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN; + + return 0; +} + +/** + * \brief Enable UART transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_enable_tx(Uart *p_uart) +{ + /* Enable transmitter */ + p_uart->UART_CR = UART_CR_TXEN; +} + +/** + * \brief Disable UART transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_disable_tx(Uart *p_uart) +{ + /* Disable transmitter */ + p_uart->UART_CR = UART_CR_TXDIS; +} + +/** + * \brief Reset UART transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_reset_tx(Uart *p_uart) +{ + /* Reset transmitter */ + p_uart->UART_CR = UART_CR_RSTTX | UART_CR_TXDIS; +} + +/** + * \brief Enable UART receiver. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_enable_rx(Uart *p_uart) +{ + /* Enable receiver */ + p_uart->UART_CR = UART_CR_RXEN; +} + +/** + * \brief Disable UART receiver. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_disable_rx(Uart *p_uart) +{ + /* Disable receiver */ + p_uart->UART_CR = UART_CR_RXDIS; +} + +/** + * \brief Reset UART receiver. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_reset_rx(Uart *p_uart) +{ + /* Reset receiver */ + p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RXDIS; +} + +/** + * \brief Enable UART receiver and transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_enable(Uart *p_uart) +{ + /* Enable receiver and transmitter */ + p_uart->UART_CR = UART_CR_RXEN | UART_CR_TXEN; +} + +/** + * \brief Disable UART receiver and transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_disable(Uart *p_uart) +{ + /* Disable receiver and transmitter */ + p_uart->UART_CR = UART_CR_RXDIS | UART_CR_TXDIS; +} + +/** + * \brief Reset UART receiver and transmitter. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_reset(Uart *p_uart) +{ + /* Reset and disable receiver & transmitter */ + p_uart->UART_CR = UART_CR_RSTRX | UART_CR_RSTTX + | UART_CR_RXDIS | UART_CR_TXDIS; +} + +/** \brief Enable UART interrupts. + * + * \param p_uart Pointer to a UART instance. + * \param ul_sources Interrupts to be enabled. + */ +void uart_enable_interrupt(Uart *p_uart, uint32_t ul_sources) +{ + p_uart->UART_IER = ul_sources; +} + +/** \brief Disable UART interrupts. + * + * \param p_uart Pointer to a UART instance. + * \param ul_sources Interrupts to be disabled. + */ +void uart_disable_interrupt(Uart *p_uart, uint32_t ul_sources) +{ + p_uart->UART_IDR = ul_sources; +} + +/** \brief Read UART interrupt mask. + * + * \param p_uart Pointer to a UART instance. + * + * \return The interrupt mask value. + */ +uint32_t uart_get_interrupt_mask(Uart *p_uart) +{ + return p_uart->UART_IMR; +} + +/** + * \brief Get current status. + * + * \param p_uart Pointer to a UART instance. + * + * \return The current UART status. + */ +uint32_t uart_get_status(Uart *p_uart) +{ + return p_uart->UART_SR; +} + +/** + * \brief Reset status bits. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_reset_status(Uart *p_uart) +{ + p_uart->UART_CR = UART_CR_RSTSTA; +} + +/** + * \brief Check if Transmit is Ready. + * Check if data has been loaded in UART_THR and is waiting to be loaded in the + * Transmit Shift Register (TSR). + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Data has been transmitted. + * \retval 0 Transmit is not ready, data pending. + */ +uint32_t uart_is_tx_ready(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_TXRDY) > 0; +} + +/** + * \brief Check if Transmit Hold Register is empty. + * Check if the last data written in UART_THR has been loaded in TSR and the + * last data loaded in TSR has been transmitted. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Transmitter is empty. + * \retval 0 Transmitter is not empty. + */ +uint32_t uart_is_tx_empty(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_TXEMPTY) > 0; +} + +/** + * \brief Check if Received data is ready. + * Check if data has been received and loaded in UART_RHR. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 One data has been received. + * \retval 0 No data has been received. + */ +uint32_t uart_is_rx_ready(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_RXRDY) > 0; +} + +/** + * \brief Check if one receive buffer is filled. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Receive is completed. + * \retval 0 Receive is still pending. + */ +uint32_t uart_is_rx_buf_end(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_ENDRX) > 0; +} + +/** + * \brief Check if one transmit buffer is sent out. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Transmit is completed. + * \retval 0 Transmit is still pending. + */ +uint32_t uart_is_tx_buf_end(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_ENDTX) > 0; +} + +/** + * \brief Check if both receive buffers are full. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Receive buffers are full. + * \retval 0 Receive buffers are not full. + */ +uint32_t uart_is_rx_buf_full(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_RXBUFF) > 0; +} + +/** + * \brief Check if both transmit buffers are sent out. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 1 Transmit buffer is empty. + * \retval 0 Transmit buffer is not empty. + */ +uint32_t uart_is_tx_buf_empty(Uart *p_uart) +{ + return (p_uart->UART_SR & UART_SR_TXEMPTY) > 0; +} + +/** + * \brief Set UART clock divisor value + * + * \param p_uart Pointer to a UART instance. + * \param us_divisor Value to be set. + * + */ +void uart_set_clock_divisor(Uart *p_uart, uint16_t us_divisor) +{ + p_uart->UART_BRGR = us_divisor; +} + +/** + * \brief Write to UART Transmit Holding Register + * Before writing user should check if tx is ready (or empty). + * + * \param p_uart Pointer to a UART instance. + * \param data Data to be sent. + * + * \retval 0 Success. + * \retval 1 I/O Failure, UART is not ready. + */ +uint32_t uart_write(Uart *p_uart, const uint8_t uc_data) +{ + /* Check if the transmitter is ready */ + if (!(p_uart->UART_SR & UART_SR_TXRDY)) + return 1; + + /* Send character */ + p_uart->UART_THR = uc_data; + return 0; +} + +/** + * \brief Read from UART Receive Holding Register. + * Before reading user should check if rx is ready. + * + * \param p_uart Pointer to a UART instance. + * + * \retval 0 Success. + * \retval 1 I/O Failure, UART is not ready. + */ +uint32_t uart_read(Uart *p_uart, uint8_t *puc_data) +{ + /* Check if the receiver is ready */ + if ((p_uart->UART_SR & UART_SR_RXRDY) == 0) + return 1; + + /* Read character */ + *puc_data = (uint8_t) p_uart->UART_RHR; + return 0; +} + +/** + * \brief Get UART PDC base address. + * + * \param p_uart Pointer to a UART instance. + * + * \return UART PDC registers base for PDC driver to access. + */ +Pdc *uart_get_pdc_base(Uart *p_uart) +{ + Pdc *p_pdc_base; + +#if (SAM3S || SAM3N || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM) + if (p_uart == UART0) + p_pdc_base = PDC_UART0; +#elif (SAM3XA || SAM3U) + if (p_uart == UART) + p_pdc_base = PDC_UART; +#else +#error "Unsupported device" +#endif + +#if (SAM3S || SAM4S || SAM4E || SAM4N || SAM4C || SAMG || SAM4CP || SAM4CM) + if (p_uart == UART1) + p_pdc_base = PDC_UART1; +#endif + +#if (SAM4N) + if (p_uart == UART2) + p_pdc_base = PDC_UART2; +#endif + + return p_pdc_base; +} + +#if (SAM4C || SAM4CP || SAM4CM) +/** + * \brief Enable UART optical interface. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_enable_optical_interface(Uart *p_uart) +{ + Assert(p_uart == UART1); + p_uart->UART_MR |= UART_MR_OPT_EN; +} + +/** + * \brief Disable UART optical interface. + * + * \param p_uart Pointer to a UART instance. + */ +void uart_disable_optical_interface(Uart *p_uart) +{ + Assert(p_uart == UART1); + p_uart->UART_MR &= ~UART_MR_OPT_EN; +} + +/** + * \brief Enable UART optical interface. + * + * \param p_uart Pointer to a UART instance. + * \param cfg Pointer to a UART optical interface configuration. + */ +void uart_config_optical_interface(Uart *p_uart, + struct uart_config_optical *cfg) +{ + Assert(p_uart == UART1); + uint32_t reg = p_uart->UART_MR; + + reg &= ~(UART_MR_OPT_RXINV | UART_MR_OPT_MDINV | UART_MR_FILTER + | UART_MR_OPT_CLKDIV_Msk | UART_MR_OPT_DUTY_Msk + | UART_MR_OPT_CMPTH_Msk); + reg |= (cfg->rx_inverted ? UART_MR_OPT_RXINV : 0) + | (cfg->tx_inverted ? UART_MR_OPT_MDINV : 0) + | (cfg->rx_filter ? UART_MR_FILTER : 0) + | UART_MR_OPT_CLKDIV(cfg->clk_div) + | cfg->duty | cfg->threshold; + + p_uart->UART_MR = reg; +} +#endif + +#if (SAMG53 || SAMG54) +/** + * \brief Set sleepwalking match mode. + * + * \param p_uart Pointer to a UART instance. + * \param ul_low_value First comparison value for received character. + * \param ul_high_value Second comparison value for received character. + * \param cmpmode ture for start condition, false for flag only. + * \param cmppar ture for parity check, false for no. + */ +void uart_set_sleepwalking(Uart *p_uart, uint8_t ul_low_value, + bool cmpmode, bool cmppar, uint8_t ul_high_value) +{ + Assert(ul_low_value <= ul_high_value); + + uint32_t temp = 0; + + if (cmpmode) { + temp |= UART_CMPR_CMPMODE_START_CONDITION; + } + + if (cmppar) { + temp |= UART_CMPR_CMPPAR; + } + + temp |= UART_CMPR_VAL1(ul_low_value); + + temp |= UART_CMPR_VAL2(ul_high_value); + + p_uart->UART_CMPR= temp; +} + +/** + * \brief Enables/Disables write protection mode. + * + * \param p_uart Pointer to a UART instance. + * \param flag ture for enable, false for disable. + */ +void uart_set_write_protection(Uart *p_uart, bool flag) +{ + if (flag) { + p_uart->UART_WPMR = UART_WPMR_WPKEY_PASSWD | UART_WPMR_WPEN; + } else { + p_uart->UART_WPMR = UART_WPMR_WPKEY_PASSWD; + } +} +#endif + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.h new file mode 100644 index 0000000..404f554 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/uart/uart.h @@ -0,0 +1,158 @@ +/** + * \file + * + * \brief Universal Asynchronous Receiver Transceiver (UART) driver for SAM. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef UART_H_INCLUDED +#define UART_H_INCLUDED + +#include "compiler.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/* UART internal div factor for sampling */ +#define UART_MCK_DIV 16 +/* Div factor to get the maximum baud rate */ +#define UART_MCK_DIV_MIN_FACTOR 1 +/* Div factor to get the minimum baud rate */ +#define UART_MCK_DIV_MAX_FACTOR 65535 + +/*! \brief Option list for UART peripheral initialization */ +typedef struct sam_uart_opt { + /** MCK for UART */ + uint32_t ul_mck; + /** Expected baud rate */ + uint32_t ul_baudrate; + /** Initialize value for UART mode register */ + uint32_t ul_mode; +} sam_uart_opt_t; + +uint32_t uart_init(Uart *p_uart, const sam_uart_opt_t *p_uart_opt); +void uart_enable_tx(Uart *p_uart); +void uart_disable_tx(Uart *p_uart); +void uart_reset_tx(Uart *p_uart); +void uart_enable_rx(Uart *p_uart); +void uart_disable_rx(Uart *p_uart); +void uart_reset_rx(Uart *p_uart); +void uart_enable(Uart *p_uart); +void uart_disable(Uart *p_uart); +void uart_reset(Uart *p_uart); +void uart_enable_interrupt(Uart *p_uart, uint32_t ul_sources); +void uart_disable_interrupt(Uart *p_uart, uint32_t ul_sources); +uint32_t uart_get_interrupt_mask(Uart *p_uart); +uint32_t uart_get_status(Uart *p_uart); +void uart_reset_status(Uart *p_uart); +uint32_t uart_is_tx_ready(Uart *p_uart); +uint32_t uart_is_tx_empty(Uart *p_uart); +uint32_t uart_is_rx_ready(Uart *p_uart); +uint32_t uart_is_rx_buf_end(Uart *p_uart); +uint32_t uart_is_tx_buf_end(Uart *p_uart); +uint32_t uart_is_rx_buf_full(Uart *p_uart); +uint32_t uart_is_tx_buf_empty(Uart *p_uart); +void uart_set_clock_divisor(Uart *p_uart, uint16_t us_divisor); +uint32_t uart_write(Uart *p_uart, const uint8_t uc_data); +uint32_t uart_read(Uart *p_uart, uint8_t *puc_data); +Pdc *uart_get_pdc_base(Uart *p_uart); +#if (SAMG53 || SAMG54) +void uart_set_sleepwalking(Uart *p_uart, uint8_t ul_low_value, + bool cmpmode, bool cmppar, uint8_t ul_high_value); +void uart_set_write_protection(Uart *p_uart, bool flag); +#endif + +#if (SAM4C || SAM4CP || SAM4CM) +enum uart_optical_duty_cycle { + UART_MOD_CLK_DUTY_50_00 = UART_MR_OPT_DUTY_DUTY_50, + UART_MOD_CLK_DUTY_43_75 = UART_MR_OPT_DUTY_DUTY_43P75, + UART_MOD_CLK_DUTY_37_50 = UART_MR_OPT_DUTY_DUTY_37P5, + UART_MOD_CLK_DUTY_31_25 = UART_MR_OPT_DUTY_DUTY_31P25, + UART_MOD_CLK_DUTY_25_00 = UART_MR_OPT_DUTY_DUTY_25, + UART_MOD_CLK_DUTY_18_75 = UART_MR_OPT_DUTY_DUTY_18P75, + UART_MOD_CLK_DUTY_12_50 = UART_MR_OPT_DUTY_DUTY_12P5, + UART_MOD_CLK_DUTY_06_25 = UART_MR_OPT_DUTY_DUTY_6P25, +}; + +enum uart_optical_cmp_threshold { + UART_RX_CMP_THRESHOLD_VDDIO_DIV_10_0 = UART_MR_OPT_CMPTH_VDDIO_DIV10, + UART_RX_CMP_THRESHOLD_VDDIO_DIV_5_0 = UART_MR_OPT_CMPTH_VDDIO_DIV5, + UART_RX_CMP_THRESHOLD_VDDIO_DIV_3_3 = UART_MR_OPT_CMPTH_VDDIO_DIV3P3, + UART_RX_CMP_THRESHOLD_VDDIO_DIV_2_5 = UART_MR_OPT_CMPTH_VDDIO_DIV2P5, + UART_RX_CMP_THRESHOLD_VDDIO_DIV_2_0 = UART_MR_OPT_CMPTH_VDDIO_DIV2, +}; + +struct uart_config_optical { + /* UART Receive Data Inverted */ + bool rx_inverted; + /* UART Modulated Data Inverted */ + bool tx_inverted; + /* UART Receiver Digital Filter */ + bool rx_filter; + /* Optical Link Clock Divider */ + uint8_t clk_div; + /* Optical Link Modulation Clock Duty Cycle */ + enum uart_optical_duty_cycle duty; + /* Receive Path Comparator Threshold */ + enum uart_optical_cmp_threshold threshold; +}; + +void uart_enable_optical_interface(Uart *p_uart); +void uart_disable_optical_interface(Uart *p_uart); +void uart_config_optical_interface(Uart *p_uart, + struct uart_config_optical *cfg); +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +#endif /* UART_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.c new file mode 100644 index 0000000..5db7fd2 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.c @@ -0,0 +1,1834 @@ +/** + * \file + * + * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver + * for SAM. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "usart.h" + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** + * \defgroup sam_drivers_usart_group Universal Synchronous Asynchronous + * Receiver Transmitter (USART) + * + * The Universal Synchronous Asynchronous Receiver Transceiver (USART) + * provides one full duplex universal synchronous asynchronous serial link. + * Data frame format is widely programmable (data length, parity, number of + * stop bits) to support a maximum of standards. The receiver implements + * parity error, framing error and overrun error detection. The receiver + * time-out enables handling variable-length frames and the transmitter + * timeguard facilitates communications with slow remote devices. Multidrop + * communications are also supported through address bit handling in reception + * and transmission. The driver supports the following modes: + * RS232, RS485, SPI, IrDA, ISO7816, MODEM, Hardware handshaking and LIN. + * + * @{ + */ + +/* The write protect key value. */ +#ifndef US_WPMR_WPKEY_PASSWD +#define US_WPMR_WPKEY_PASSWD US_WPMR_WPKEY(0x555341U) +#endif + +#ifndef US_WPMR_WPKEY_PASSWD +# define US_WPMR_WPKEY_PASSWD US_WPMR_WPKEY(US_WPKEY_VALUE) +#endif + +/* The CD value scope programmed in MR register. */ +#define MIN_CD_VALUE 0x01 +#define MIN_CD_VALUE_SPI 0x04 +#define MAX_CD_VALUE US_BRGR_CD_Msk + +/* The receiver sampling divide of baudrate clock. */ +#define HIGH_FRQ_SAMPLE_DIV 16 +#define LOW_FRQ_SAMPLE_DIV 8 + +/* Max transmitter timeguard. */ +#define MAX_TRAN_GUARD_TIME US_TTGR_TG_Msk + +/* The non-existent parity error number. */ +#define USART_PARITY_ERROR 5 + +/* ISO7816 protocol type. */ +#define ISO7816_T_0 0 +#define ISO7816_T_1 1 + +/** + * \brief Calculate a clock divider(CD) and a fractional part (FP) for the + * USART asynchronous modes to generate a baudrate as close as possible to + * the baudrate set point. + * + * \note Baud rate calculation: Baudrate = ul_mck/(Over * (CD + FP/8)) + * (Over being 16 or 8). The maximal oversampling is selected if it allows to + * generate a baudrate close to the set point. + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +uint32_t usart_set_async_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t over; + uint32_t cd_fp; + uint32_t cd; + uint32_t fp; + + /* Calculate the receiver sampling divide of baudrate clock. */ + if (ul_mck >= HIGH_FRQ_SAMPLE_DIV * baudrate) { + over = HIGH_FRQ_SAMPLE_DIV; + } else { + over = LOW_FRQ_SAMPLE_DIV; + } + + /* Calculate clock divider according to the fraction calculated formula. */ + cd_fp = (8 * ul_mck + (over * baudrate) / 2) / (over * baudrate); + cd = cd_fp >> 3; + fp = cd_fp & 0x07; + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + /* Configure the OVER bit in MR register. */ + if (over == 8) { + p_usart->US_MR |= US_MR_OVER; + } + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = (cd << US_BRGR_CD_Pos) | (fp << US_BRGR_FP_Pos); + + return 0; +} + +/** + * \brief Calculate a clock divider for the USART synchronous master modes + * to generate a baudrate as close as possible to the baudrate set point. + * + * \note Synchronous baudrate calculation: baudrate = ul_mck / cd + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_sync_master_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate clock divider according to the formula in synchronous mode. */ + cd = (ul_mck + baudrate / 2) / baudrate; + + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) | + US_MR_USCLKS_MCK | US_MR_SYNC; + return 0; +} + +/** + * \brief Select the SCK pin as the source of baud rate for the USART + * synchronous slave modes. + * + * \param p_usart Pointer to a USART instance. + */ +static void usart_set_sync_slave_baudrate(Usart *p_usart) +{ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USCLKS_Msk) | + US_MR_USCLKS_SCK | US_MR_SYNC; +} + + +/** + * \brief Calculate a clock divider (\e CD) for the USART ISO7816 mode to + * generate an ISO7816 clock as close as possible to the clock set point. + * + * \note ISO7816 clock calculation: Clock = ul_mck / cd + * + * \param p_usart Pointer to a USART instance. + * \param clock ISO7816 clock set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 ISO7816 clock is successfully initialized. + * \retval 1 ISO7816 clock set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_iso7816_clock(Usart *p_usart, + uint32_t clock, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate clock divider according to the formula in ISO7816 mode. */ + cd = (ul_mck + clock / 2) / clock; + + if (cd < MIN_CD_VALUE || cd > MAX_CD_VALUE) { + return 1; + } + + p_usart->US_MR = (p_usart->US_MR & ~(US_MR_USCLKS_Msk | US_MR_SYNC | + US_MR_OVER)) | US_MR_USCLKS_MCK | US_MR_CLKO; + + /* Configure the baudrate generate register. */ + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + return 0; +} + +/** + * \brief Calculate a clock divider (\e CD) for the USART SPI master mode to + * generate a baud rate as close as possible to the baud rate set point. + * + * \note Baud rate calculation: + * \f$ Baudrate = \frac{SelectedClock}{CD} \f$. + * + * \param p_usart Pointer to a USART instance. + * \param baudrate Baud rate set point. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 Baud rate is successfully initialized. + * \retval 1 Baud rate set point is out of range for the given input clock + * frequency. + */ +static uint32_t usart_set_spi_master_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck) +{ + uint32_t cd; + + /* Calculate the clock divider according to the formula in SPI mode. */ + cd = (ul_mck + baudrate / 2) / baudrate; + + if (cd < MIN_CD_VALUE_SPI || cd > MAX_CD_VALUE) { + return 1; + } + + p_usart->US_BRGR = cd << US_BRGR_CD_Pos; + + return 0; +} + +/** + * \brief Select the SCK pin as the source of baudrate for the USART SPI slave + * mode. + * + * \param p_usart Pointer to a USART instance. + */ +static void usart_set_spi_slave_baudrate(Usart *p_usart) +{ + p_usart->US_MR &= ~US_MR_USCLKS_Msk; + p_usart->US_MR |= US_MR_USCLKS_SCK; +} + +/** + * \brief Reset the USART and disable TX and RX. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset(Usart *p_usart) +{ + /* Disable the Write Protect. */ + usart_disable_writeprotect(p_usart); + + /* Reset registers that could cause unpredictable behavior after reset. */ + p_usart->US_MR = 0; + p_usart->US_RTOR = 0; + p_usart->US_TTGR = 0; + + /* Disable TX and RX. */ + usart_reset_tx(p_usart); + usart_reset_rx(p_usart); + /* Reset status bits. */ + usart_reset_status(p_usart); + /* Turn off RTS and DTR if exist. */ + usart_drive_RTS_pin_high(p_usart); +#if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E) + usart_drive_DTR_pin_high(p_usart); +#endif +} + +/** + * \brief Configure USART to work in RS232 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_rs232(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || usart_set_async_baudrate(p_usart, + p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Configure the USART option. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Configure the USART mode as normal mode. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL; + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in hardware handshaking mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_hw_handshaking(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set hardware handshaking mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_HW_HANDSHAKING; + + return 0; +} + +#if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E) + +/** + * \brief Configure USART to work in modem mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_modem(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* + * SAM3S, SAM4S and SAM4E series support MODEM mode only on USART1, + * SAM3U and SAM4L series support MODEM mode only on USART0. + */ +#if (SAM3S || SAM4S || SAM4E) +#ifdef USART1 + if (p_usart != USART1) { + return 1; + } +#endif +#elif (SAM3U || SAM4L) + if (p_usart != USART0) { + return 1; + } +#endif + + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set MODEM mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_MODEM; + + return 0; +} +#endif + +/** + * \brief Configure USART to work in SYNC mode and act as a master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_sync_master(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || usart_set_sync_master_baudrate(p_usart, + p_usart_opt->baudrate, ul_mck)) { + return 1; + } + + /* Configure the USART option. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Set normal mode and output clock as synchronous master. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL | US_MR_CLKO; + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SYNC mode and act as a slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_sync_slave(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + usart_set_sync_slave_baudrate(p_usart); + + /* Check whether the input values are legal. */ + if (!p_usart_opt) { + return 1; + } + + /* Configure the USART option. */ + ul_reg_val |= p_usart_opt->char_length | p_usart_opt->parity_type | + p_usart_opt->channel_mode | p_usart_opt->stop_bits; + + /* Set normal mode. */ + ul_reg_val |= US_MR_USART_MODE_NORMAL; + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in RS485 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_rs485(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set RS485 mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_RS485; + + return 0; +} + +#if (!SAMG55) +/** + * \brief Configure USART to work in IrDA mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_irda(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck) +{ + /* Initialize the USART as standard RS232. */ + if (usart_init_rs232(p_usart, p_usart_opt, ul_mck)) { + return 1; + } + + /* Set IrDA filter. */ + p_usart->US_IF = p_usart_opt->irda_filter; + + /* Set IrDA mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_IRDA; + + return 0; +} +#endif + +/** + * \brief Configure USART to work in ISO7816 mode. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_iso7816(Usart *p_usart, + const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + + /* Check whether the input values are legal. */ + if (!p_usart_opt || ((p_usart_opt->parity_type != US_MR_PAR_EVEN) && + (p_usart_opt->parity_type != US_MR_PAR_ODD))) { + return 1; + } + + if (p_usart_opt->protocol_type == ISO7816_T_0) { + ul_reg_val |= US_MR_USART_MODE_IS07816_T_0 | US_MR_NBSTOP_2_BIT | + (p_usart_opt->max_iterations << US_MR_MAX_ITERATION_Pos); + + if (p_usart_opt->bit_order) { + ul_reg_val |= US_MR_MSBF; + } + } else if (p_usart_opt->protocol_type == ISO7816_T_1) { + /* + * Only LSBF is used in the T=1 protocol, and max_iterations field + * is only used in T=0 mode. + */ + if (p_usart_opt->bit_order || p_usart_opt->max_iterations) { + return 1; + } + + /* Set USART mode to ISO7816, T=1, and always uses 1 stop bit. */ + ul_reg_val |= US_MR_USART_MODE_IS07816_T_1 | US_MR_NBSTOP_1_BIT; + } else { + return 1; + } + + /* Set up the baudrate. */ + if (usart_set_iso7816_clock(p_usart, p_usart_opt->iso7816_hz, ul_mck)) { + return 1; + } + + /* Set FIDI register: bit rate = iso7816_hz / fidi_ratio. */ + p_usart->US_FIDI = p_usart_opt->fidi_ratio; + + /* Set ISO7816 parity type in the MODE register. */ + ul_reg_val |= p_usart_opt->parity_type; + + if (p_usart_opt->inhibit_nack) { + ul_reg_val |= US_MR_INACK; + } + if (p_usart_opt->dis_suc_nack) { + ul_reg_val |= US_MR_DSNACK; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SPI mode and act as a master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_spi_master(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + /* Check whether the input values are legal. */ + if (!p_usart_opt || (p_usart_opt->spi_mode > SPI_MODE_3) || + usart_set_spi_master_baudrate(p_usart, p_usart_opt->baudrate, + ul_mck)) { + return 1; + } + + /* Configure the character length bit in MR register. */ + ul_reg_val |= p_usart_opt->char_length; + + /* Set SPI master mode and channel mode. */ + ul_reg_val |= US_MR_USART_MODE_SPI_MASTER | US_MR_CLKO | + p_usart_opt->channel_mode; + + switch (p_usart_opt->spi_mode) { + case SPI_MODE_0: + ul_reg_val |= US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + + case SPI_MODE_1: + ul_reg_val &= ~US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + + case SPI_MODE_2: + ul_reg_val |= US_MR_CPHA; + ul_reg_val |= US_MR_CPOL; + break; + + case SPI_MODE_3: + ul_reg_val &= ~US_MR_CPHA; + ul_reg_val |= US_MR_CPOL; + break; + + default: + break; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +/** + * \brief Configure USART to work in SPI mode and act as a slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param p_usart_opt Pointer to sam_usart_opt_t instance. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_spi_slave(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt) +{ + static uint32_t ul_reg_val; + + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + ul_reg_val = 0; + usart_set_spi_slave_baudrate(p_usart); + + /* Check whether the input values are legal. */ + if (!p_usart_opt || p_usart_opt->spi_mode > SPI_MODE_3) { + return 1; + } + + /* Configure the character length bit in MR register. */ + ul_reg_val |= p_usart_opt->char_length; + + /* Set SPI slave mode and channel mode. */ + ul_reg_val |= US_MR_USART_MODE_SPI_SLAVE | p_usart_opt->channel_mode; + + switch (p_usart_opt->spi_mode) { + case SPI_MODE_0: + ul_reg_val |= US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + + case SPI_MODE_1: + ul_reg_val &= ~US_MR_CPHA; + ul_reg_val &= ~US_MR_CPOL; + break; + + case SPI_MODE_2: + ul_reg_val |= US_MR_CPHA; + ul_reg_val |= US_MR_CPOL; + break; + + case SPI_MODE_3: + ul_reg_val |= US_MR_CPOL; + ul_reg_val &= ~US_MR_CPHA; + break; + + default: + break; + } + + p_usart->US_MR |= ul_reg_val; + + return 0; +} + +#if (SAM3XA || SAM4L || SAMG55) + +/** + * \brief Configure USART to work in LIN mode and act as a LIN master. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param ul_baudrate Baudrate to be used. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_lin_master(Usart *p_usart,uint32_t ul_baudrate, + uint32_t ul_mck) +{ + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + /* Set up the baudrate. */ + if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) { + return 1; + } + + /* Set LIN master mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_LIN_MASTER; + + usart_enable_rx(p_usart); + usart_enable_tx(p_usart); + + return 0; +} + +/** + * \brief Configure USART to work in LIN mode and act as a LIN slave. + * + * \note By default, the transmitter and receiver aren't enabled. + * + * \param p_usart Pointer to a USART instance. + * \param ul_baudrate Baudrate to be used. + * \param ul_mck USART module input clock frequency. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_init_lin_slave(Usart *p_usart, uint32_t ul_baudrate, + uint32_t ul_mck) +{ + /* Reset the USART and shut down TX and RX. */ + usart_reset(p_usart); + + usart_enable_rx(p_usart); + usart_enable_tx(p_usart); + + /* Set LIN slave mode. */ + p_usart->US_MR = (p_usart->US_MR & ~US_MR_USART_MODE_Msk) | + US_MR_USART_MODE_LIN_SLAVE; + + /* Set up the baudrate. */ + if (usart_set_async_baudrate(p_usart, ul_baudrate, ul_mck)) { + return 1; + } + + return 0; +} + +/** + * \brief Abort the current LIN transmission. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_abort_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_LINABT; +} + +/** + * \brief Send a wakeup signal on the LIN bus. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_send_wakeup_signal(Usart *p_usart) +{ + p_usart->US_CR = US_CR_LINWKUP; +} + +/** + * \brief Configure the LIN node action, which should be one of PUBLISH, + * SUBSCRIBE or IGNORE. + * + * \param p_usart Pointer to a USART instance. + * \param uc_action 0 for PUBLISH, 1 for SUBSCRIBE, 2 for IGNORE. + */ +void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_NACT_Msk) | + (uc_action << US_LINMR_NACT_Pos); +} + +/** + * \brief Disable the parity check during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_parity(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_PARDIS; +} + +/** + * \brief Enable the parity check during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_parity(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_PARDIS; +} + +/** + * \brief Disable the checksum during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_checksum(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_CHKDIS; +} + +/** + * \brief Enable the checksum during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_checksum(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_CHKDIS; +} + +/** + * \brief Configure the checksum type during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_type 0 for LIN 2.0 Enhanced checksum or 1 for LIN 1.3 Classic + * checksum. + */ +void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_CHKTYP) | + (uc_type << 4); +} + +/** + * \brief Configure the data length mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_mode Indicate the data length type: 0 if the data length is + * defined by the DLC of LIN mode register or 1 if the data length is defined + * by the bit 5 and 6 of the identifier. + */ +void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLM) | + (uc_mode << 5); +} + +/** + * \brief Disable the frame slot mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_frame_slot(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_FSDIS; +} + +/** + * \brief Enable the frame slot mode during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_frame_slot(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_FSDIS; +} + +/** + * \brief Configure the wakeup signal type during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_type Indicate the checksum type: 0 if the wakeup signal is a + * LIN 2.0 wakeup signal; 1 if the wakeup signal is a LIN 1.3 wakeup signal. + */ +void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_WKUPTYP) | + (uc_type << 7); +} + +/** + * \brief Configure the response data length if the data length is defined by + * the DLC field during the LIN communication. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len Indicate the response data length. + */ +void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_LINMR = (p_usart->US_LINMR & ~US_LINMR_DLC_Msk) | + ((uc_len - 1) << US_LINMR_DLC_Pos); +} + +/** + * \brief The LIN mode register is not written by the PDC. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_disable_pdc_mode(Usart *p_usart) +{ + p_usart->US_LINMR &= ~US_LINMR_PDCM; +} + +/** + * \brief The LIN mode register (except this flag) is written by the PDC. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_lin_enable_pdc_mode(Usart *p_usart) +{ + p_usart->US_LINMR |= US_LINMR_PDCM; +} + +/** + * \brief Configure the LIN identifier when USART works in LIN master mode. + * + * \param p_usart Pointer to a USART instance. + * \param uc_id The identifier to be transmitted. + */ +void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id) +{ + p_usart->US_LINIR = (p_usart->US_LINIR & ~US_LINIR_IDCHR_Msk) | + US_LINIR_IDCHR(uc_id); +} + +/** + * \brief Read the identifier when USART works in LIN mode. + * + * \param p_usart Pointer to a USART instance. + * + * \return The last identifier received in LIN slave mode or the last + * identifier transmitted in LIN master mode. + */ +uint8_t usart_lin_read_identifier(Usart *p_usart) +{ + return (p_usart->US_LINIR & US_LINIR_IDCHR_Msk); +} + +/** + * \brief Get data length. + * + * \param p_usart Pointer to a USART instance. + * + * \return Data length. + */ +uint8_t usart_lin_get_data_length(Usart *usart) +{ + if (usart->US_LINMR & US_LINMR_DLM) { + uint8_t data_length = 1 << ((usart->US_LINIR >> + (US_LINIR_IDCHR_Pos + 4)) & 0x03); + return data_length; + } else { + return ((usart->US_LINMR & US_LINMR_DLC_Msk) >> US_LINMR_DLC_Pos) + 1; + } +} + +#endif + +/** + * \brief Enable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_TXEN; +} + +/** + * \brief Disable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_tx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_TXDIS; +} + +/** + * \brief Immediately stop and disable USART transmitter. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_tx(Usart *p_usart) +{ + /* Reset transmitter */ + p_usart->US_CR = US_CR_RSTTX | US_CR_TXDIS; +} + +/** + * \brief Configure the transmit timeguard register. + * + * \param p_usart Pointer to a USART instance. + * \param timeguard The value of transmit timeguard. + */ +void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard) +{ + p_usart->US_TTGR = timeguard; +} + +/** + * \brief Enable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_rx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RXEN; +} + +/** + * \brief Disable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_rx(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RXDIS; +} + +/** + * \brief Immediately stop and disable USART receiver. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_rx(Usart *p_usart) +{ + /* Reset Receiver */ + p_usart->US_CR = US_CR_RSTRX | US_CR_RXDIS; +} + +/** + * \brief Configure the receive timeout register. + * + * \param p_usart Pointer to a USART instance. + * \param timeout The value of receive timeout. + */ +void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout) +{ + p_usart->US_RTOR = timeout; +} + +/** + * \brief Enable USART interrupts. + * + * \param p_usart Pointer to a USART peripheral. + * \param ul_sources Interrupt sources bit map. + */ +void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources) +{ + p_usart->US_IER = ul_sources; +} + +/** + * \brief Disable USART interrupts. + * + * \param p_usart Pointer to a USART peripheral. + * \param ul_sources Interrupt sources bit map. + */ +void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources) +{ + p_usart->US_IDR = ul_sources; +} + +/** + * \brief Read USART interrupt mask. + * + * \param p_usart Pointer to a USART peripheral. + * + * \return The interrupt mask value. + */ +uint32_t usart_get_interrupt_mask(Usart *p_usart) +{ + return p_usart->US_IMR; +} + +/** + * \brief Get current status. + * + * \param p_usart Pointer to a USART instance. + * + * \return The current USART status. + */ +uint32_t usart_get_status(Usart *p_usart) +{ + return p_usart->US_CSR; +} + +/** + * \brief Reset status bits (PARE, OVER, MANERR, UNRE and PXBRK in US_CSR). + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_status(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTSTA; +} + +/** + * \brief Start transmission of a break. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_start_tx_break(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STTBRK; +} + +/** + * \brief Stop transmission of a break. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_stop_tx_break(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STPBRK; +} + +/** + * \brief Start waiting for a character before clocking the timeout count. + * Reset the status bit TIMEOUT in US_CSR. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_start_rx_timeout(Usart *p_usart) +{ + p_usart->US_CR = US_CR_STTTO; +} + +/** + * \brief In Multidrop mode only, the next character written to the US_THR + * is sent with the address bit set. + * + * \param p_usart Pointer to a USART instance. + * \param ul_addr The address to be sent out. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr) +{ + if ((p_usart->US_MR & US_MR_PAR_MULTIDROP) != US_MR_PAR_MULTIDROP) { + return 1; + } + + p_usart->US_CR = US_CR_SENDA; + + if (usart_write(p_usart, ul_addr)) { + return 1; + } else { + return 0; + } +} + +/** + * \brief Reset the ITERATION in US_CSR when the ISO7816 mode is enabled. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_iterations(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTIT; +} + +/** + * \brief Reset NACK in US_CSR. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_reset_nack(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RSTNACK; +} + +/** + * \brief Restart the receive timeout. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_restart_rx_timeout(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RETTO; +} + +#if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E) + +/** + * \brief Drive the pin DTR to 0. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_DTR_pin_low(Usart *p_usart) +{ + p_usart->US_CR = US_CR_DTREN; +} + +/** + * \brief Drive the pin DTR to 1. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_DTR_pin_high(Usart *p_usart) +{ + p_usart->US_CR = US_CR_DTRDIS; +} + +#endif + +/** + * \brief Drive the pin RTS to 0. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_RTS_pin_low(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RTSEN; +} + +/** + * \brief Drive the pin RTS to 1. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_drive_RTS_pin_high(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RTSDIS; +} + +/** + * \brief Drive the slave select line NSS (RTS pin) to 0 in SPI master mode. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_spi_force_chip_select(Usart *p_usart) +{ + p_usart->US_CR = US_CR_FCS; +} + +/** + * \brief Drive the slave select line NSS (RTS pin) to 1 in SPI master mode. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_spi_release_chip_select(Usart *p_usart) +{ + p_usart->US_CR = US_CR_RCS; +} + +/** + * \brief Check if Transmit is Ready. + * Check if data have been loaded in USART_THR and are waiting to be loaded + * into the Transmit Shift Register (TSR). + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 No data is in the Transmit Holding Register. + * \retval 0 There is data in the Transmit Holding Register. + */ +uint32_t usart_is_tx_ready(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXRDY) > 0; +} + +/** + * \brief Check if Transmit Holding Register is empty. + * Check if the last data written in USART_THR have been loaded in TSR and the + * last data loaded in TSR have been transmitted. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmitter is empty. + * \retval 0 Transmitter is not empty. + */ +uint32_t usart_is_tx_empty(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXEMPTY) > 0; +} + +/** + * \brief Check if the received data are ready. + * Check if Data have been received and loaded into USART_RHR. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Some data has been received. + * \retval 0 No data has been received. + */ +uint32_t usart_is_rx_ready(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_RXRDY) > 0; +} + +/** + * \brief Check if one receive buffer is filled. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Receive is complete. + * \retval 0 Receive is still pending. + */ +uint32_t usart_is_rx_buf_end(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_ENDRX) > 0; +} + +/** + * \brief Check if one transmit buffer is empty. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmit is complete. + * \retval 0 Transmit is still pending. + */ +uint32_t usart_is_tx_buf_end(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_ENDTX) > 0; +} + +/** + * \brief Check if both receive buffers are full. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Receive buffers are full. + * \retval 0 Receive buffers are not full. + */ +uint32_t usart_is_rx_buf_full(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_RXBUFF) > 0; +} + +/** + * \brief Check if both transmit buffers are empty. + * + * \param p_usart Pointer to a USART instance. + * + * \retval 1 Transmit buffers are empty. + * \retval 0 Transmit buffers are not empty. + */ +uint32_t usart_is_tx_buf_empty(Usart *p_usart) +{ + return (p_usart->US_CSR & US_CSR_TXBUFE) > 0; +} + +/** + * \brief Write to USART Transmit Holding Register. + * + * \note Before writing user should check if tx is ready (or empty). + * + * \param p_usart Pointer to a USART instance. + * \param c Data to be sent. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_write(Usart *p_usart, uint32_t c) +{ + if (!(p_usart->US_CSR & US_CSR_TXRDY)) { + return 1; + } + + p_usart->US_THR = US_THR_TXCHR(c); + return 0; +} + +/** + * \brief Write to USART Transmit Holding Register. + * + * \note Before writing user should check if tx is ready (or empty). + * + * \param p_usart Pointer to a USART instance. + * \param c Data to be sent. + * + * \retval 0 on success. + * \retval 1 on failure. + */ +uint32_t usart_putchar(Usart *p_usart, uint32_t c) +{ + while (!(p_usart->US_CSR & US_CSR_TXRDY)) { + } + + p_usart->US_THR = US_THR_TXCHR(c); + + return 0; +} + +/** + * \brief Write one-line string through USART. + * + * \param p_usart Pointer to a USART instance. + * \param string Pointer to one-line string to be sent. + */ +void usart_write_line(Usart *p_usart, const char *string) +{ + while (*string != '\0') { + usart_putchar(p_usart, *string++); + } +} + +/** + * \brief Read from USART Receive Holding Register. + * + * \note Before reading user should check if rx is ready. + * + * \param p_usart Pointer to a USART instance. + * \param c Pointer where the one-byte received data will be stored. + * + * \retval 0 on success. + * \retval 1 if no data is available or errors. + */ +uint32_t usart_read(Usart *p_usart, uint32_t *c) +{ + if (!(p_usart->US_CSR & US_CSR_RXRDY)) { + return 1; + } + + /* Read character */ + *c = p_usart->US_RHR & US_RHR_RXCHR_Msk; + + return 0; +} + +/** + * \brief Read from USART Receive Holding Register. + * Before reading user should check if rx is ready. + * + * \param p_usart Pointer to a USART instance. + * \param c Pointer where the one-byte received data will be stored. + * + * \retval 0 Data has been received. + * \retval 1 on failure. + */ +uint32_t usart_getchar(Usart *p_usart, uint32_t *c) +{ + /* Wait until it's not empty or timeout has reached. */ + while (!(p_usart->US_CSR & US_CSR_RXRDY)) { + } + + /* Read character */ + *c = p_usart->US_RHR & US_RHR_RXCHR_Msk; + + return 0; +} + +#if (SAM3XA || SAM3U) +/** + * \brief Get Transmit address for DMA operation. + * + * \param p_usart Pointer to a USART instance. + * + * \return Transmit address for DMA access. + */ +uint32_t *usart_get_tx_access(Usart *p_usart) +{ + return (uint32_t *)&(p_usart->US_THR); +} + +/** + * \brief Get Receive address for DMA operation. + * + * \param p_usart Pointer to a USART instance. + * + * \return Receive address for DMA access. + */ +uint32_t *usart_get_rx_access(Usart *p_usart) +{ + return (uint32_t *)&(p_usart->US_RHR); +} +#endif + +#if (!SAM4L) +/** + * \brief Get USART PDC base address. + * + * \param p_usart Pointer to a UART instance. + * + * \return USART PDC registers base for PDC driver to access. + */ +Pdc *usart_get_pdc_base(Usart *p_usart) +{ + Pdc *p_pdc_base; + + p_pdc_base = (Pdc *)NULL; + +#ifdef PDC_USART + if (p_usart == USART) { + p_pdc_base = PDC_USART; + return p_pdc_base; + } +#endif +#ifdef PDC_USART0 + if (p_usart == USART0) { + p_pdc_base = PDC_USART0; + return p_pdc_base; + } +#endif +#ifdef PDC_USART1 + else if (p_usart == USART1) { + p_pdc_base = PDC_USART1; + return p_pdc_base; + } +#endif +#ifdef PDC_USART2 + else if (p_usart == USART2) { + p_pdc_base = PDC_USART2; + return p_pdc_base; + } +#endif +#ifdef PDC_USART3 + else if (p_usart == USART3) { + p_pdc_base = PDC_USART3; + return p_pdc_base; + } +#endif +#ifdef PDC_USART4 + else if (p_usart == USART4) { + p_pdc_base = PDC_USART4; + return p_pdc_base; + } +#endif +#ifdef PDC_USART5 + else if (p_usart == USART5) { + p_pdc_base = PDC_USART5; + return p_pdc_base; + } +#endif +#ifdef PDC_USART6 + else if (p_usart == USART6) { + p_pdc_base = PDC_USART6; + return p_pdc_base; + } +#endif +#ifdef PDC_USART7 + else if (p_usart == USART7) { + p_pdc_base = PDC_USART7; + return p_pdc_base; + } +#endif + + return p_pdc_base; +} +#endif + +/** + * \brief Enable write protect of USART registers. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_enable_writeprotect(Usart *p_usart) +{ + p_usart->US_WPMR = US_WPMR_WPEN | US_WPMR_WPKEY_PASSWD; +} + +/** + * \brief Disable write protect of USART registers. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_disable_writeprotect(Usart *p_usart) +{ + p_usart->US_WPMR = US_WPMR_WPKEY_PASSWD; +} + +/** + * \brief Get write protect status. + * + * \param p_usart Pointer to a USART instance. + * + * \return 0 if no write protect violation occurred, or 16-bit write protect + * violation source. + */ +uint32_t usart_get_writeprotect_status(Usart *p_usart) +{ + uint32_t reg_value; + + reg_value = p_usart->US_WPSR; + if (reg_value & US_WPSR_WPVS) { + return (reg_value & US_WPSR_WPVSRC_Msk) >> US_WPSR_WPVSRC_Pos; + } else { + return 0; + } +} + +/** + * \brief Get the total number of errors that occur during an ISO7816 transfer. + * + * \param p_usart Pointer to a USART instance. + * + * \return The number of errors that occurred. + */ +uint8_t usart_get_error_number(Usart *p_usart) +{ + return (p_usart->US_NER & US_NER_NB_ERRORS_Msk); +} + +#if (SAM3S || SAM4S || SAM3U || SAM3XA || SAM4L || SAM4E || SAM4C || SAM4CP || SAM4CM) + +/** + * \brief Configure the transmitter preamble length when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len The transmitter preamble length, which should be 0 ~ 15. + */ +void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PL_Msk) | + US_MAN_TX_PL(uc_len); +} + +/** + * \brief Configure the transmitter preamble pattern when the Manchester + * encode/decode is enabled, which should be 0 ~ 3. + * + * \param p_usart Pointer to a USART instance. + * \param uc_pattern 0 if the preamble is composed of '1's; + * 1 if the preamble is composed of '0's; + * 2 if the preamble is composed of '01's; + * 3 if the preamble is composed of '10's. + */ +void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_PP_Msk) | + (uc_pattern << US_MAN_TX_PP_Pos); +} + +/** + * \brief Configure the transmitter Manchester polarity when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_polarity Indicate the transmitter Manchester polarity, which + * should be 0 or 1. + */ +void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_TX_MPOL) | + (uc_polarity << 12); +} + +/** + * \brief Configure the detected receiver preamble length when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_len The detected receiver preamble length, which should be 0 ~ 15. + */ +void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PL_Msk) | + US_MAN_RX_PL(uc_len); +} + +/** + * \brief Configure the detected receiver preamble pattern when the Manchester + * encode/decode is enabled, which should be 0 ~ 3. + * + * \param p_usart Pointer to a USART instance. + * \param uc_pattern 0 if the preamble is composed of '1's; + * 1 if the preamble is composed of '0's; + * 2 if the preamble is composed of '01's; + * 3 if the preamble is composed of '10's. + */ +void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_PP_Msk) | + (uc_pattern << US_MAN_RX_PP_Pos); +} + +/** + * \brief Configure the receiver Manchester polarity when the Manchester + * encode/decode is enabled. + * + * \param p_usart Pointer to a USART instance. + * \param uc_polarity Indicate the receiver Manchester polarity, which should + * be 0 or 1. + */ +void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity) +{ + p_usart->US_MAN = (p_usart->US_MAN & ~US_MAN_RX_MPOL) | + (uc_polarity << 28); +} + +/** + * \brief Enable drift compensation. + * + * \note The 16X clock mode must be enabled. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_man_enable_drift_compensation(Usart *p_usart) +{ + p_usart->US_MAN |= US_MAN_DRIFT; +} + +/** + * \brief Disable drift compensation. + * + * \param p_usart Pointer to a USART instance. + */ +void usart_man_disable_drift_compensation(Usart *p_usart) +{ + p_usart->US_MAN &= ~US_MAN_DRIFT; +} + +#endif + +#if SAM4L + +uint32_t usart_get_version(Usart *p_usart) +{ + return p_usart->US_VERSION; +} + +#endif + +#if SAMG55 +/** + * \brief Set sleepwalking match mode. + * + * \param p_uart Pointer to a USART instance. + * \param ul_low_value First comparison value for received character. + * \param ul_high_value Second comparison value for received character. + * \param cmpmode ture for start condition, false for flag only. + * \param cmppar ture for parity check, false for no. + */ +void usart_set_sleepwalking(Usart *p_uart, uint8_t ul_low_value, + bool cmpmode, bool cmppar, uint8_t ul_high_value) +{ + Assert(ul_low_value <= ul_high_value); + + uint32_t temp = 0; + + if (cmpmode) { + temp |= US_CMPR_CMPMODE_START_CONDITION; + } + + if (cmppar) { + temp |= US_CMPR_CMPPAR; + } + + temp |= US_CMPR_VAL1(ul_low_value); + + temp |= US_CMPR_VAL2(ul_high_value); + + p_uart->US_CMPR= temp; +} +#endif + +//@} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.h new file mode 100644 index 0000000..a11a74d --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/drivers/usart/usart.h @@ -0,0 +1,723 @@ +/** + * \file + * + * \brief Universal Synchronous Asynchronous Receiver Transmitter (USART) driver + * for SAM. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef USART_H_INCLUDED +#define USART_H_INCLUDED + +#include "compiler.h" + +/** + * \defgroup group_sam_drivers_usart Universal Synchronous Asynchronous Receiver + * Transmitter (USART). + * + * See \ref sam_usart_quickstart. + * + * This is a low-level driver implementation for the SAM Universal + * Synchronous/Asynchronous Receiver/Transmitter. + * + * @{ + */ + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +/** Clock phase. */ +#define SPI_CPHA (1 << 0) + +/** Clock polarity. */ +#define SPI_CPOL (1 << 1) + +/** SPI mode definition. */ +#define SPI_MODE_0 0 +#define SPI_MODE_1 (SPI_CPHA) +#define SPI_MODE_2 (SPI_CPOL) +#define SPI_MODE_3 (SPI_CPOL | SPI_CPHA) + +/* Input parameters when initializing RS232 and similar modes. */ +typedef struct { + /* Set baud rate of the USART (unused in slave modes). */ + uint32_t baudrate; + + /* + * Number of bits, which should be one of the following: US_MR_CHRL_5_BIT, + * US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or + * US_MR_MODE9. + */ + uint32_t char_length; + + /* + * Parity type, which should be one of the following: US_MR_PAR_EVEN, + * US_MR_PAR_ODD, US_MR_PAR_SPACE, US_MR_PAR_MARK, US_MR_PAR_NO + * or US_MR_PAR_MULTIDROP. + */ + uint32_t parity_type; + + /* + * Number of stop bits between two characters: US_MR_NBSTOP_1_BIT, + * US_MR_NBSTOP_1_5_BIT, US_MR_NBSTOP_2_BIT. + * \note US_MR_NBSTOP_1_5_BIT is supported in asynchronous modes only. + */ + uint32_t stop_bits; + + /* + * Run the channel in test mode, which should be one of following: + * US_MR_CHMODE_NORMAL, US_MR_CHMODE_AUTOMATIC, + * US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK. + */ + uint32_t channel_mode; + + /* Filter of IrDA mode, useless in other modes. */ + uint32_t irda_filter; +} sam_usart_opt_t; + +/* Input parameters when initializing ISO7816 mode. */ +typedef struct { + /* Set the frequency of the ISO7816 clock. */ + uint32_t iso7816_hz; + + /* + * The number of ISO7816 clock ticks in every bit period (1 to 2047, + * 0 = disable clock). Baudrate rate = iso7816_hz / fidi_ratio. + */ + uint32_t fidi_ratio; + + /* + * How to calculate the parity bit: US_MR_PAR_EVEN for normal mode or + * US_MR_PAR_ODD for inverse mode. + */ + uint32_t parity_type; + + /* + * Inhibit Non Acknowledge: + * - 0: the NACK is generated; + * - 1: the NACK is not generated. + * + * \note This bit will be used only in ISO7816 mode, protocol T = 0 + * receiver. + */ + uint32_t inhibit_nack; + + /* + * Disable successive NACKs. + * - 0: NACK is sent on the ISO line as soon as a parity error occurs + * in the received character. Successive parity errors are counted up to + * the value in the max_iterations field. These parity errors generate + * a NACK on the ISO line. As soon as this value is reached, no additional + * NACK is sent on the ISO line. The ITERATION flag is asserted. + */ + uint32_t dis_suc_nack; + + /* Max number of repetitions (0 to 7). */ + uint32_t max_iterations; + + /* + * Bit order in transmitted characters: + * - 0: LSB first; + * - 1: MSB first. + */ + uint32_t bit_order; + + /* + * Which protocol is used: + * - 0: T = 0; + * - 1: T = 1. + */ + uint32_t protocol_type; +} usart_iso7816_opt_t; + +/* Input parameters when initializing SPI mode. */ +typedef struct { + /* Set the frequency of the SPI clock (unused in slave mode). */ + uint32_t baudrate; + + /* + * Number of bits, which should be one of the following: US_MR_CHRL_5_BIT, + * US_MR_CHRL_6_BIT, US_MR_CHRL_7_BIT, US_MR_CHRL_8_BIT or + * US_MR_MODE9. + */ + uint32_t char_length; + + /* + * Which SPI mode to use, which should be one of the following: + * SPI_MODE_0, SPI_MODE_1, SPI_MODE_2, SPI_MODE_3. + */ + uint32_t spi_mode; + + /* + * Run the channel in test mode, which should be one of following: + * US_MR_CHMODE_NORMAL, US_MR_CHMODE_AUTOMATIC, + * US_MR_CHMODE_LOCAL_LOOPBACK, US_MR_CHMODE_REMOTE_LOOPBACK. + */ + uint32_t channel_mode; +} usart_spi_opt_t; + +void usart_reset(Usart *p_usart); +uint32_t usart_set_async_baudrate(Usart *p_usart, + uint32_t baudrate, uint32_t ul_mck); +uint32_t usart_init_rs232(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_hw_handshaking(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E) +uint32_t usart_init_modem(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#endif +uint32_t usart_init_sync_master(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_sync_slave(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt); +uint32_t usart_init_rs485(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#if (!SAMG55) +uint32_t usart_init_irda(Usart *p_usart, + const sam_usart_opt_t *p_usart_opt, uint32_t ul_mck); +#endif +uint32_t usart_init_iso7816(Usart *p_usart, + const usart_iso7816_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_spi_master(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt, uint32_t ul_mck); +uint32_t usart_init_spi_slave(Usart *p_usart, + const usart_spi_opt_t *p_usart_opt); +#if (SAM3XA || SAM4L || SAMG55) +uint32_t usart_init_lin_master(Usart *p_usart, uint32_t ul_baudrate, + uint32_t ul_mck); +uint32_t usart_init_lin_slave(Usart *p_usart, uint32_t ul_baudrate, + uint32_t ul_mck); +void usart_lin_abort_tx(Usart *p_usart); +void usart_lin_send_wakeup_signal(Usart *p_usart); +void usart_lin_set_node_action(Usart *p_usart, uint8_t uc_action); +void usart_lin_disable_parity(Usart *p_usart); +void usart_lin_enable_parity(Usart *p_usart); +void usart_lin_disable_checksum(Usart *p_usart); +void usart_lin_enable_checksum(Usart *p_usart); +void usart_lin_set_checksum_type(Usart *p_usart, uint8_t uc_type); +void usart_lin_set_data_len_mode(Usart *p_usart, uint8_t uc_mode); +void usart_lin_disable_frame_slot(Usart *p_usart); +void usart_lin_enable_frame_slot(Usart *p_usart); +void usart_lin_set_wakeup_signal_type(Usart *p_usart, uint8_t uc_type); +void usart_lin_set_response_data_len(Usart *p_usart, uint8_t uc_len); +void usart_lin_disable_pdc_mode(Usart *p_usart); +void usart_lin_enable_pdc_mode(Usart *p_usart); +void usart_lin_set_tx_identifier(Usart *p_usart, uint8_t uc_id); +uint8_t usart_lin_read_identifier(Usart *p_usart); +uint8_t usart_lin_get_data_length(Usart *usart); +#endif +void usart_enable_tx(Usart *p_usart); +void usart_disable_tx(Usart *p_usart); +void usart_reset_tx(Usart *p_usart); +void usart_set_tx_timeguard(Usart *p_usart, uint32_t timeguard); +void usart_enable_rx(Usart *p_usart); +void usart_disable_rx(Usart *p_usart); +void usart_reset_rx(Usart *p_usart); +void usart_set_rx_timeout(Usart *p_usart, uint32_t timeout); +void usart_enable_interrupt(Usart *p_usart, uint32_t ul_sources); +void usart_disable_interrupt(Usart *p_usart, uint32_t ul_sources); +uint32_t usart_get_interrupt_mask(Usart *p_usart); +uint32_t usart_get_status(Usart *p_usart); +void usart_reset_status(Usart *p_usart); +void usart_start_tx_break(Usart *p_usart); +void usart_stop_tx_break(Usart *p_usart); +void usart_start_rx_timeout(Usart *p_usart); +uint32_t usart_send_address(Usart *p_usart, uint32_t ul_addr); +void usart_reset_iterations(Usart *p_usart); +void usart_reset_nack(Usart *p_usart); +void usart_restart_rx_timeout(Usart *p_usart); +#if (SAM3S || SAM4S || SAM3U || SAM4L || SAM4E) +void usart_drive_DTR_pin_low(Usart *p_usart); +void usart_drive_DTR_pin_high(Usart *p_usart); +#endif +void usart_drive_RTS_pin_low(Usart *p_usart); +void usart_drive_RTS_pin_high(Usart *p_usart); +void usart_spi_force_chip_select(Usart *p_usart); +void usart_spi_release_chip_select(Usart *p_usart); +uint32_t usart_is_tx_ready(Usart *p_usart); +uint32_t usart_is_tx_empty(Usart *p_usart); +uint32_t usart_is_rx_ready(Usart *p_usart); +uint32_t usart_is_rx_buf_end(Usart *p_usart); +uint32_t usart_is_tx_buf_end(Usart *p_usart); +uint32_t usart_is_rx_buf_full(Usart *p_usart); +uint32_t usart_is_tx_buf_empty(Usart *p_usart); +uint32_t usart_write(Usart *p_usart, uint32_t c); +uint32_t usart_putchar(Usart *p_usart, uint32_t c); +void usart_write_line(Usart *p_usart, const char *string); +uint32_t usart_read(Usart *p_usart, uint32_t *c); +uint32_t usart_getchar(Usart *p_usart, uint32_t *c); +#if (SAM3XA || SAM3U) +uint32_t *usart_get_tx_access(Usart *p_usart); +uint32_t *usart_get_rx_access(Usart *p_usart); +#endif +#if (!SAM4L) +Pdc *usart_get_pdc_base(Usart *p_usart); +#endif +void usart_enable_writeprotect(Usart *p_usart); +void usart_disable_writeprotect(Usart *p_usart); +uint32_t usart_get_writeprotect_status(Usart *p_usart); +uint8_t usart_get_error_number(Usart *p_usart); +#if (SAM3S || SAM4S || SAM3U || SAM3XA || SAM4L || SAM4E || SAM4C || SAM4CP || SAM4CM) +void usart_man_set_tx_pre_len(Usart *p_usart, uint8_t uc_len); +void usart_man_set_tx_pre_pattern(Usart *p_usart, uint8_t uc_pattern); +void usart_man_set_tx_polarity(Usart *p_usart, uint8_t uc_polarity); +void usart_man_set_rx_pre_len(Usart *p_usart, uint8_t uc_len); +void usart_man_set_rx_pre_pattern(Usart *p_usart, uint8_t uc_pattern); +void usart_man_set_rx_polarity(Usart *p_usart, uint8_t uc_polarity); +void usart_man_enable_drift_compensation(Usart *p_usart); +void usart_man_disable_drift_compensation(Usart *p_usart); +#endif + +#if SAM4L +uint32_t usart_get_version(Usart *p_usart); +#endif + +#if SAMG55 +void usart_set_sleepwalking(Usart *p_uart, uint8_t ul_low_value, + bool cmpmode, bool cmppar, uint8_t ul_high_value); +#endif + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond + +//! @} + +/** + * \page sam_usart_quickstart Quick start guide for the SAM USART module + * + * This is the quick start guide for the \ref group_sam_drivers_usart + * "USART module", with step-by-step instructions on how to configure and + * use the driver in a selection of use cases. + * + * The use cases contain several code fragments. The code fragments in the + * steps for setup can be copied into a custom initialization function, while + * the steps for usage can be copied into, e.g., the main application function. + * + * \note Some SAM devices contain both USART and UART modules, with the latter + * being a subset in functionality of the former but physically separate + * peripherals. UART modules are compatible with the USART driver, but + * only for the functions and modes supported by the base UART driver. + * + * \section usart_use_cases USART use cases + * - \ref usart_basic_use_case + * - \subpage usart_use_case_1 + * - \subpage usart_use_case_2 + * + * \note The USART pins configuration are not included here. Please refer + * the related code in board_init() function. + * + * \section usart_basic_use_case Basic use case - transmit a character + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * \section usart_basic_use_case_setup Setup steps + * + * \subsection usart_basic_use_case_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref ioport_group "Common IOPORT API (ioport)" + * + * \subsection usart_basic_use_case_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.) + * \code + #define USART_SERIAL USART0 + #define USART_SERIAL_ID ID_USART0 //USART0 for sam4l + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + #define USART_SERIAL_PARITY US_MR_PAR_NO + #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + board_init(); + + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); +\endcode + * + * \subsection usart_basic_use_case_setup_flow Workflow + * -# Initialize system clock: + * \code + sysclk_init(); +\endcode + * -# Configure the USART Tx and Rx pins by call the board init function: + * \code + board_init(); +\endcode + * \note Set the define in conf_board.h file. + * -# Create USART options struct: + * \code + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; +\endcode + * -# Enable the clock to the USART module: + * \code + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif +\endcode + * -# Initialize the USART module in RS232 mode: + * \code + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); +\endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); +\endcode + * + * \section usart_basic_use_case_usage Usage steps + * + * \subsection usart_basic_use_case_usage_code Example code + * Add to application C-file: + * \code + usart_putchar(USART_SERIAL, 'a'); +\endcode + * + * \subsection usart_basic_use_case_usage_flow Workflow + * -# Send an 'a' character via USART + * \code usart_putchar(USART_SERIAL, 'a'); \endcode + */ + +/** + * \page usart_use_case_1 USART receive character and echo back + * + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. + * + * \section usart_use_case_1_setup Setup steps + * + * \subsection usart_use_case_1_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref ioport_group "Common IOPORT API (ioport)" + * + * \subsection usart_use_case_1_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL USART0 + #define USART_SERIAL_ID ID_USART0 //USART0 for sam4l + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + #define USART_SERIAL_PARITY US_MR_PAR_NO + #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT +\endcode + * + * A variable for the received byte must be added: + * \code + uint32_t received_byte; +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + board_init(); + + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; + + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif + + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); +\endcode + * + * \subsection usart_use_case_1_setup_flow Workflow + * -# Initialize system clock: + * \code + sysclk_init(); +\endcode + * -# Configure the USART Tx and Rx pins by call the board init function: + * \code + board_init(); +\endcode + * \note Set the define in conf_board.h file. + * -# Create USART options struct: + * \code + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; +\endcode + * -# Enable the clock to the USART module: + * \code + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif +\endcode + * -# Initialize the USART module in RS232 mode: + * \code + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); +\endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); +\endcode + * + * \section usart_use_case_1_usage Usage steps + * + * \subsection usart_use_case_1_usage_code Example code + * Add to, e.g., main loop in application C-file: + * \code + received_byte = usart_getchar(USART_SERIAL); + usart_putchar(USART_SERIAL, received_byte); +\endcode + * + * \subsection usart_use_case_1_usage_flow Workflow + * -# Wait for reception of a character: + * \code usart_getchar(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * \code usart_putchar(USART_SERIAL, received_byte); \endcode + */ + +/** + * \page usart_use_case_2 USART receive character and echo back via interrupts + * + * In this use case, the USART module is configured for: + * - Using USART0 + * - Baudrate: 9600 + * - Character length: 8 bit + * - Parity mode: Disabled + * - Stop bit: None + * - RS232 mode + * + * The use case waits for a received character on the configured USART and + * echoes the character back to the same USART. The character reception is + * performed via an interrupt handler, rather than the polling method used + * in \ref usart_use_case_1. + * + * \section usart_use_case_2_setup Setup steps + * + * \subsection usart_use_case_2_setup_prereq Prerequisites + * -# \ref sysclk_group "System Clock Management (sysclock)" + * -# \ref pio_group "Parallel Input/Output Controller (pio)" + * -# \ref pmc_group "Power Management Controller (pmc)" + * + * \subsection usart_use_case_2_setup_code Example code + * The following configuration must be added to the project (typically to a + * conf_usart.h file, but it can also be added to your main application file.): + * \code + #define USART_SERIAL USART0 + #define USART_SERIAL_ID ID_USART0 //USART0 for sam4l + #define USART_SERIAL_ISR_HANDLER USART0_Handler + #define USART_SERIAL_BAUDRATE 9600 + #define USART_SERIAL_CHAR_LENGTH US_MR_CHRL_8_BIT + #define USART_SERIAL_PARITY US_MR_PAR_NO + #define USART_SERIAL_STOP_BIT US_MR_NBSTOP_1_BIT +\endcode + * + * A variable for the received byte must be added: + * \code + uint32_t received_byte; +\endcode + * + * Add to application initialization: + * \code + sysclk_init(); + + board_init(); + + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; + + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif + + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); + + usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY); + NVIC_EnableIRQ(USART_SERIAL_IRQ); +\endcode + * + * \subsection usart_use_case_2_setup_flow Workflow + * -# Initialize system clock: + * \code + sysclk_init(); +\endcode + * -# Configure the USART Tx and Rx pins by call the board init function: + * \code + board_init(); +\endcode + * \note Set the define in conf_board.h file. + * -# Create USART options struct: + * \code + const sam_usart_opt_t usart_console_settings = { + USART_SERIAL_BAUDRATE, + USART_SERIAL_CHAR_LENGTH, + USART_SERIAL_PARITY, + USART_SERIAL_STOP_BIT, + US_MR_CHMODE_NORMAL + }; +\endcode + * -# Enable the clock to the USART module: + * \code + #if SAM4L + sysclk_enable_peripheral_clock(USART_SERIAL); + #else + sysclk_enable_peripheral_clock(USART_SERIAL_ID); + #endif +\endcode + * -# Initialize the USART module in RS232 mode: + * \code + usart_init_rs232(USART_SERIAL, &usart_console_settings, + sysclk_get_main_hz()); +\endcode + * -# Enable the Rx and Tx modes of the USART module: + * \code + usart_enable_tx(USART_SERIAL); + usart_enable_rx(USART_SERIAL); +\endcode + * -# Enable the USART character reception interrupt, and general interrupts + * for the USART module. + * \code + usart_enable_interrupt(USART_SERIAL, US_IER_RXRDY); + NVIC_EnableIRQ(USART_SERIAL_IRQ); +\endcode + * \section usart_use_case_2_usage Usage steps + * + * \subsection usart_use_case_2_usage_code Example code + * Add to your main application C-file the USART interrupt handler: + * \code + void USART_SERIAL_ISR_HANDLER(void) + { + uint32_t dw_status = usart_get_status(USART_SERIAL); + + if (dw_status & US_CSR_RXRDY) { + uint32_t received_byte; + + usart_read(USART_SERIAL, &received_byte); + usart_write(USART_SERIAL, received_byte); + } + } +\endcode + * + * \subsection usart_use_case_2_usage_flow Workflow + * -# When the USART ISR fires, retrieve the USART module interrupt flags: + * \code uint32_t dw_status = usart_get_status(USART_SERIAL); \endcode + * -# Check if the USART Receive Character interrupt has fired: + * \code if (dw_status & US_CSR_RXRDY) \endcode + * -# If a character has been received, fetch it into a temporary variable: + * \code usart_read(USART_SERIAL, &received_byte); \endcode + * -# Echo the character back: + * \code usart_write(USART_SERIAL, received_byte); \endcode + */ + +#endif /* USART_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/acc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/acc.h new file mode 100644 index 0000000..c74222b --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/acc.h @@ -0,0 +1,139 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_ACC_COMPONENT_ +#define _SAM4E_ACC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Analog Comparator Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_ACC Analog Comparator Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Acc hardware registers */ +typedef struct { + __O uint32_t ACC_CR; /**< \brief (Acc Offset: 0x00) Control Register */ + __IO uint32_t ACC_MR; /**< \brief (Acc Offset: 0x04) Mode Register */ + __I uint32_t Reserved1[7]; + __O uint32_t ACC_IER; /**< \brief (Acc Offset: 0x24) Interrupt Enable Register */ + __O uint32_t ACC_IDR; /**< \brief (Acc Offset: 0x28) Interrupt Disable Register */ + __I uint32_t ACC_IMR; /**< \brief (Acc Offset: 0x2C) Interrupt Mask Register */ + __I uint32_t ACC_ISR; /**< \brief (Acc Offset: 0x30) Interrupt Status Register */ + __I uint32_t Reserved2[24]; + __IO uint32_t ACC_ACR; /**< \brief (Acc Offset: 0x94) Analog Control Register */ + __I uint32_t Reserved3[19]; + __IO uint32_t ACC_WPMR; /**< \brief (Acc Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t ACC_WPSR; /**< \brief (Acc Offset: 0xE8) Write Protection Status Register */ +} Acc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- ACC_CR : (ACC Offset: 0x00) Control Register -------- */ +#define ACC_CR_SWRST (0x1u << 0) /**< \brief (ACC_CR) Software Reset */ +/* -------- ACC_MR : (ACC Offset: 0x04) Mode Register -------- */ +#define ACC_MR_SELMINUS_Pos 0 +#define ACC_MR_SELMINUS_Msk (0x7u << ACC_MR_SELMINUS_Pos) /**< \brief (ACC_MR) Selection for Minus Comparator Input */ +#define ACC_MR_SELMINUS_TS (0x0u << 0) /**< \brief (ACC_MR) Select TS */ +#define ACC_MR_SELMINUS_ADVREF (0x1u << 0) /**< \brief (ACC_MR) Select ADVREF */ +#define ACC_MR_SELMINUS_DAC0 (0x2u << 0) /**< \brief (ACC_MR) Select DAC0 */ +#define ACC_MR_SELMINUS_DAC1 (0x3u << 0) /**< \brief (ACC_MR) Select DAC1 */ +#define ACC_MR_SELMINUS_AD0 (0x4u << 0) /**< \brief (ACC_MR) Select AD0 */ +#define ACC_MR_SELMINUS_AD1 (0x5u << 0) /**< \brief (ACC_MR) Select AD1 */ +#define ACC_MR_SELMINUS_AD2 (0x6u << 0) /**< \brief (ACC_MR) Select AD2 */ +#define ACC_MR_SELMINUS_AD3 (0x7u << 0) /**< \brief (ACC_MR) Select AD3 */ +#define ACC_MR_SELPLUS_Pos 4 +#define ACC_MR_SELPLUS_Msk (0x7u << ACC_MR_SELPLUS_Pos) /**< \brief (ACC_MR) Selection For Plus Comparator Input */ +#define ACC_MR_SELPLUS_AD0 (0x0u << 4) /**< \brief (ACC_MR) Select AD0 */ +#define ACC_MR_SELPLUS_AD1 (0x1u << 4) /**< \brief (ACC_MR) Select AD1 */ +#define ACC_MR_SELPLUS_AD2 (0x2u << 4) /**< \brief (ACC_MR) Select AD2 */ +#define ACC_MR_SELPLUS_AD3 (0x3u << 4) /**< \brief (ACC_MR) Select AD3 */ +#define ACC_MR_SELPLUS_AD4 (0x4u << 4) /**< \brief (ACC_MR) Select AD4 */ +#define ACC_MR_SELPLUS_AD5 (0x5u << 4) /**< \brief (ACC_MR) Select AD5 */ +#define ACC_MR_SELPLUS_AD6 (0x6u << 4) /**< \brief (ACC_MR) Select AD6 */ +#define ACC_MR_SELPLUS_AD7 (0x7u << 4) /**< \brief (ACC_MR) Select AD7 */ +#define ACC_MR_ACEN (0x1u << 8) /**< \brief (ACC_MR) Analog Comparator Enable */ +#define ACC_MR_ACEN_DIS (0x0u << 8) /**< \brief (ACC_MR) Analog comparator disabled. */ +#define ACC_MR_ACEN_EN (0x1u << 8) /**< \brief (ACC_MR) Analog comparator enabled. */ +#define ACC_MR_EDGETYP_Pos 9 +#define ACC_MR_EDGETYP_Msk (0x3u << ACC_MR_EDGETYP_Pos) /**< \brief (ACC_MR) Edge Type */ +#define ACC_MR_EDGETYP_RISING (0x0u << 9) /**< \brief (ACC_MR) Only rising edge of comparator output */ +#define ACC_MR_EDGETYP_FALLING (0x1u << 9) /**< \brief (ACC_MR) Falling edge of comparator output */ +#define ACC_MR_EDGETYP_ANY (0x2u << 9) /**< \brief (ACC_MR) Any edge of comparator output */ +#define ACC_MR_INV (0x1u << 12) /**< \brief (ACC_MR) Invert Comparator Output */ +#define ACC_MR_INV_DIS (0x0u << 12) /**< \brief (ACC_MR) Analog comparator output is directly processed. */ +#define ACC_MR_INV_EN (0x1u << 12) /**< \brief (ACC_MR) Analog comparator output is inverted prior to being processed. */ +#define ACC_MR_SELFS (0x1u << 13) /**< \brief (ACC_MR) Selection Of Fault Source */ +#define ACC_MR_SELFS_CF (0x0u << 13) /**< \brief (ACC_MR) The CF flag is used to drive the FAULT output. */ +#define ACC_MR_SELFS_OUTPUT (0x1u << 13) /**< \brief (ACC_MR) The output of the analog comparator flag is used to drive the FAULT output. */ +#define ACC_MR_FE (0x1u << 14) /**< \brief (ACC_MR) Fault Enable */ +#define ACC_MR_FE_DIS (0x0u << 14) /**< \brief (ACC_MR) The FAULT output is tied to 0. */ +#define ACC_MR_FE_EN (0x1u << 14) /**< \brief (ACC_MR) The FAULT output is driven by the signal defined by SELFS. */ +/* -------- ACC_IER : (ACC Offset: 0x24) Interrupt Enable Register -------- */ +#define ACC_IER_CE (0x1u << 0) /**< \brief (ACC_IER) Comparison Edge */ +/* -------- ACC_IDR : (ACC Offset: 0x28) Interrupt Disable Register -------- */ +#define ACC_IDR_CE (0x1u << 0) /**< \brief (ACC_IDR) Comparison Edge */ +/* -------- ACC_IMR : (ACC Offset: 0x2C) Interrupt Mask Register -------- */ +#define ACC_IMR_CE (0x1u << 0) /**< \brief (ACC_IMR) Comparison Edge */ +/* -------- ACC_ISR : (ACC Offset: 0x30) Interrupt Status Register -------- */ +#define ACC_ISR_CE (0x1u << 0) /**< \brief (ACC_ISR) Comparison Edge */ +#define ACC_ISR_SCO (0x1u << 1) /**< \brief (ACC_ISR) Synchronized Comparator Output */ +#define ACC_ISR_MASK (0x1u << 31) /**< \brief (ACC_ISR) Flag Mask */ +/* -------- ACC_ACR : (ACC Offset: 0x94) Analog Control Register -------- */ +#define ACC_ACR_ISEL (0x1u << 0) /**< \brief (ACC_ACR) Current Selection */ +#define ACC_ACR_ISEL_LOPW (0x0u << 0) /**< \brief (ACC_ACR) Low-power option. */ +#define ACC_ACR_ISEL_HISP (0x1u << 0) /**< \brief (ACC_ACR) High-speed option. */ +#define ACC_ACR_HYST_Pos 1 +#define ACC_ACR_HYST_Msk (0x3u << ACC_ACR_HYST_Pos) /**< \brief (ACC_ACR) Hysteresis Selection */ +#define ACC_ACR_HYST(value) ((ACC_ACR_HYST_Msk & ((value) << ACC_ACR_HYST_Pos))) +/* -------- ACC_WPMR : (ACC Offset: 0xE4) Write Protection Mode Register -------- */ +#define ACC_WPMR_WPEN (0x1u << 0) /**< \brief (ACC_WPMR) Write Protection Enable */ +#define ACC_WPMR_WPKEY_Pos 8 +#define ACC_WPMR_WPKEY_Msk (0xffffffu << ACC_WPMR_WPKEY_Pos) /**< \brief (ACC_WPMR) Write Protection Key */ +#define ACC_WPMR_WPKEY_PASSWD (0x414343u << 8) /**< \brief (ACC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- ACC_WPSR : (ACC Offset: 0xE8) Write Protection Status Register -------- */ +#define ACC_WPSR_WPROTERR (0x1u << 0) /**< \brief (ACC_WPSR) Write Protection Violation Status */ + +/*@}*/ + + +#endif /* _SAM4E_ACC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/aes.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/aes.h new file mode 100644 index 0000000..b634499 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/aes.h @@ -0,0 +1,148 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_AES_COMPONENT_ +#define _SAM4E_AES_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Advanced Encryption Standard */ +/* ============================================================================= */ +/** \addtogroup SAM4E_AES Advanced Encryption Standard */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Aes hardware registers */ +typedef struct { + __O uint32_t AES_CR; /**< \brief (Aes Offset: 0x00) Control Register */ + __IO uint32_t AES_MR; /**< \brief (Aes Offset: 0x04) Mode Register */ + __I uint32_t Reserved1[2]; + __O uint32_t AES_IER; /**< \brief (Aes Offset: 0x10) Interrupt Enable Register */ + __O uint32_t AES_IDR; /**< \brief (Aes Offset: 0x14) Interrupt Disable Register */ + __I uint32_t AES_IMR; /**< \brief (Aes Offset: 0x18) Interrupt Mask Register */ + __I uint32_t AES_ISR; /**< \brief (Aes Offset: 0x1C) Interrupt Status Register */ + __O uint32_t AES_KEYWR[8]; /**< \brief (Aes Offset: 0x20) Key Word Register */ + __O uint32_t AES_IDATAR[4]; /**< \brief (Aes Offset: 0x40) Input Data Register */ + __I uint32_t AES_ODATAR[4]; /**< \brief (Aes Offset: 0x50) Output Data Register */ + __O uint32_t AES_IVR[4]; /**< \brief (Aes Offset: 0x60) Initialization Vector Register */ +} Aes; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- AES_CR : (AES Offset: 0x00) Control Register -------- */ +#define AES_CR_START (0x1u << 0) /**< \brief (AES_CR) Start Processing */ +#define AES_CR_SWRST (0x1u << 8) /**< \brief (AES_CR) Software Reset */ +/* -------- AES_MR : (AES Offset: 0x04) Mode Register -------- */ +#define AES_MR_CIPHER (0x1u << 0) /**< \brief (AES_MR) Processing Mode */ +#define AES_MR_DUALBUFF (0x1u << 3) /**< \brief (AES_MR) Dual Input Buffer */ +#define AES_MR_DUALBUFF_INACTIVE (0x0u << 3) /**< \brief (AES_MR) AES_IDATARx cannot be written during processing of previous block. */ +#define AES_MR_DUALBUFF_ACTIVE (0x1u << 3) /**< \brief (AES_MR) AES_IDATARx can be written during processing of previous block when SMOD = 0x2. It speeds up the overall runtime of large files. */ +#define AES_MR_PROCDLY_Pos 4 +#define AES_MR_PROCDLY_Msk (0xfu << AES_MR_PROCDLY_Pos) /**< \brief (AES_MR) Processing Delay */ +#define AES_MR_PROCDLY(value) ((AES_MR_PROCDLY_Msk & ((value) << AES_MR_PROCDLY_Pos))) +#define AES_MR_SMOD_Pos 8 +#define AES_MR_SMOD_Msk (0x3u << AES_MR_SMOD_Pos) /**< \brief (AES_MR) Start Mode */ +#define AES_MR_SMOD_MANUAL_START (0x0u << 8) /**< \brief (AES_MR) Manual Mode */ +#define AES_MR_SMOD_AUTO_START (0x1u << 8) /**< \brief (AES_MR) Auto Mode */ +#define AES_MR_SMOD_IDATAR0_START (0x2u << 8) /**< \brief (AES_MR) AES_IDATAR0 access only Auto Mode */ +#define AES_MR_KEYSIZE_Pos 10 +#define AES_MR_KEYSIZE_Msk (0x3u << AES_MR_KEYSIZE_Pos) /**< \brief (AES_MR) Key Size */ +#define AES_MR_KEYSIZE_AES128 (0x0u << 10) /**< \brief (AES_MR) AES Key Size is 128 bits */ +#define AES_MR_KEYSIZE_AES192 (0x1u << 10) /**< \brief (AES_MR) AES Key Size is 192 bits */ +#define AES_MR_KEYSIZE_AES256 (0x2u << 10) /**< \brief (AES_MR) AES Key Size is 256 bits */ +#define AES_MR_OPMOD_Pos 12 +#define AES_MR_OPMOD_Msk (0x7u << AES_MR_OPMOD_Pos) /**< \brief (AES_MR) Operation Mode */ +#define AES_MR_OPMOD_ECB (0x0u << 12) /**< \brief (AES_MR) ECB: Electronic Code Book mode */ +#define AES_MR_OPMOD_CBC (0x1u << 12) /**< \brief (AES_MR) CBC: Cipher Block Chaining mode */ +#define AES_MR_OPMOD_OFB (0x2u << 12) /**< \brief (AES_MR) OFB: Output Feedback mode */ +#define AES_MR_OPMOD_CFB (0x3u << 12) /**< \brief (AES_MR) CFB: Cipher Feedback mode */ +#define AES_MR_OPMOD_CTR (0x4u << 12) /**< \brief (AES_MR) CTR: Counter mode (16-bit internal counter) */ +#define AES_MR_LOD (0x1u << 15) /**< \brief (AES_MR) Last Output Data Mode */ +#define AES_MR_CFBS_Pos 16 +#define AES_MR_CFBS_Msk (0x7u << AES_MR_CFBS_Pos) /**< \brief (AES_MR) Cipher Feedback Data Size */ +#define AES_MR_CFBS_SIZE_128BIT (0x0u << 16) /**< \brief (AES_MR) 128-bit */ +#define AES_MR_CFBS_SIZE_64BIT (0x1u << 16) /**< \brief (AES_MR) 64-bit */ +#define AES_MR_CFBS_SIZE_32BIT (0x2u << 16) /**< \brief (AES_MR) 32-bit */ +#define AES_MR_CFBS_SIZE_16BIT (0x3u << 16) /**< \brief (AES_MR) 16-bit */ +#define AES_MR_CFBS_SIZE_8BIT (0x4u << 16) /**< \brief (AES_MR) 8-bit */ +#define AES_MR_CKEY_Pos 20 +#define AES_MR_CKEY_Msk (0xfu << AES_MR_CKEY_Pos) /**< \brief (AES_MR) Key */ +#define AES_MR_CKEY_PASSWD (0xEu << 20) /**< \brief (AES_MR) This field must be written with 0xE the first time that AES_MR is programmed. For subsequent programming of the AES_MR, any value can be written, including that of 0xE.Always reads as 0. */ +/* -------- AES_IER : (AES Offset: 0x10) Interrupt Enable Register -------- */ +#define AES_IER_DATRDY (0x1u << 0) /**< \brief (AES_IER) Data Ready Interrupt Enable */ +#define AES_IER_URAD (0x1u << 8) /**< \brief (AES_IER) Unspecified Register Access Detection Interrupt Enable */ +/* -------- AES_IDR : (AES Offset: 0x14) Interrupt Disable Register -------- */ +#define AES_IDR_DATRDY (0x1u << 0) /**< \brief (AES_IDR) Data Ready Interrupt Disable */ +#define AES_IDR_URAD (0x1u << 8) /**< \brief (AES_IDR) Unspecified Register Access Detection Interrupt Disable */ +/* -------- AES_IMR : (AES Offset: 0x18) Interrupt Mask Register -------- */ +#define AES_IMR_DATRDY (0x1u << 0) /**< \brief (AES_IMR) Data Ready Interrupt Mask */ +#define AES_IMR_URAD (0x1u << 8) /**< \brief (AES_IMR) Unspecified Register Access Detection Interrupt Mask */ +/* -------- AES_ISR : (AES Offset: 0x1C) Interrupt Status Register -------- */ +#define AES_ISR_DATRDY (0x1u << 0) /**< \brief (AES_ISR) Data Ready */ +#define AES_ISR_URAD (0x1u << 8) /**< \brief (AES_ISR) Unspecified Register Access Detection Status */ +#define AES_ISR_URAT_Pos 12 +#define AES_ISR_URAT_Msk (0xfu << AES_ISR_URAT_Pos) /**< \brief (AES_ISR) Unspecified Register Access */ +#define AES_ISR_URAT_IDR_WR_PROCESSING (0x0u << 12) /**< \brief (AES_ISR) Input Data Register written during the data processing when SMOD = 0x2 mode. */ +#define AES_ISR_URAT_ODR_RD_PROCESSING (0x1u << 12) /**< \brief (AES_ISR) Output Data Register read during the data processing. */ +#define AES_ISR_URAT_MR_WR_PROCESSING (0x2u << 12) /**< \brief (AES_ISR) Mode Register written during the data processing. */ +#define AES_ISR_URAT_ODR_RD_SUBKGEN (0x3u << 12) /**< \brief (AES_ISR) Output Data Register read during the sub-keys generation. */ +#define AES_ISR_URAT_MR_WR_SUBKGEN (0x4u << 12) /**< \brief (AES_ISR) Mode Register written during the sub-keys generation. */ +#define AES_ISR_URAT_WOR_RD_ACCESS (0x5u << 12) /**< \brief (AES_ISR) Write-only register read access. */ +/* -------- AES_KEYWR[8] : (AES Offset: 0x20) Key Word Register -------- */ +#define AES_KEYWR_KEYW_Pos 0 +#define AES_KEYWR_KEYW_Msk (0xffffffffu << AES_KEYWR_KEYW_Pos) /**< \brief (AES_KEYWR[8]) Key Word */ +#define AES_KEYWR_KEYW(value) ((AES_KEYWR_KEYW_Msk & ((value) << AES_KEYWR_KEYW_Pos))) +/* -------- AES_IDATAR[4] : (AES Offset: 0x40) Input Data Register -------- */ +#define AES_IDATAR_IDATA_Pos 0 +#define AES_IDATAR_IDATA_Msk (0xffffffffu << AES_IDATAR_IDATA_Pos) /**< \brief (AES_IDATAR[4]) Input Data Word */ +#define AES_IDATAR_IDATA(value) ((AES_IDATAR_IDATA_Msk & ((value) << AES_IDATAR_IDATA_Pos))) +/* -------- AES_ODATAR[4] : (AES Offset: 0x50) Output Data Register -------- */ +#define AES_ODATAR_ODATA_Pos 0 +#define AES_ODATAR_ODATA_Msk (0xffffffffu << AES_ODATAR_ODATA_Pos) /**< \brief (AES_ODATAR[4]) Output Data */ +/* -------- AES_IVR[4] : (AES Offset: 0x60) Initialization Vector Register -------- */ +#define AES_IVR_IV_Pos 0 +#define AES_IVR_IV_Msk (0xffffffffu << AES_IVR_IV_Pos) /**< \brief (AES_IVR[4]) Initialization Vector */ +#define AES_IVR_IV(value) ((AES_IVR_IV_Msk & ((value) << AES_IVR_IV_Pos))) + +/*@}*/ + + +#endif /* _SAM4E_AES_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/afec.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/afec.h new file mode 100644 index 0000000..9187b00 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/afec.h @@ -0,0 +1,574 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_AFEC_COMPONENT_ +#define _SAM4E_AFEC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Analog-Front-End Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_AFEC Analog-Front-End Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Afec hardware registers */ +typedef struct { + __O uint32_t AFEC_CR; /**< \brief (Afec Offset: 0x00) AFEC Control Register */ + __IO uint32_t AFEC_MR; /**< \brief (Afec Offset: 0x04) AFEC Mode Register */ + __IO uint32_t AFEC_EMR; /**< \brief (Afec Offset: 0x08) AFEC Extended Mode Register */ + __IO uint32_t AFEC_SEQ1R; /**< \brief (Afec Offset: 0x0C) AFEC Channel Sequence 1 Register */ + __IO uint32_t AFEC_SEQ2R; /**< \brief (Afec Offset: 0x10) AFEC Channel Sequence 2 Register */ + __O uint32_t AFEC_CHER; /**< \brief (Afec Offset: 0x14) AFEC Channel Enable Register */ + __O uint32_t AFEC_CHDR; /**< \brief (Afec Offset: 0x18) AFEC Channel Disable Register */ + __I uint32_t AFEC_CHSR; /**< \brief (Afec Offset: 0x1C) AFEC Channel Status Register */ + __I uint32_t AFEC_LCDR; /**< \brief (Afec Offset: 0x20) AFEC Last Converted Data Register */ + __O uint32_t AFEC_IER; /**< \brief (Afec Offset: 0x24) AFEC Interrupt Enable Register */ + __O uint32_t AFEC_IDR; /**< \brief (Afec Offset: 0x28) AFEC Interrupt Disable Register */ + __I uint32_t AFEC_IMR; /**< \brief (Afec Offset: 0x2C) AFEC Interrupt Mask Register */ + __I uint32_t AFEC_ISR; /**< \brief (Afec Offset: 0x30) AFEC Interrupt Status Register */ + __I uint32_t Reserved1[6]; + __I uint32_t AFEC_OVER; /**< \brief (Afec Offset: 0x4C) AFEC Overrun Status Register */ + __IO uint32_t AFEC_CWR; /**< \brief (Afec Offset: 0x50) AFEC Compare Window Register */ + __IO uint32_t AFEC_CGR; /**< \brief (Afec Offset: 0x54) AFEC Channel Gain Register */ + __I uint32_t Reserved2[1]; + __IO uint32_t AFEC_CDOR; /**< \brief (Afec Offset: 0x5C) AFEC Channel Calibration DC Offset Register */ + __IO uint32_t AFEC_DIFFR; /**< \brief (Afec Offset: 0x60) AFEC Channel Differential Register */ + __IO uint32_t AFEC_CSELR; /**< \brief (Afec Offset: 0x64) AFEC Channel Register Selection */ + __I uint32_t AFEC_CDR; /**< \brief (Afec Offset: 0x68) AFEC Channel Data Register */ + __IO uint32_t AFEC_COCR; /**< \brief (Afec Offset: 0x6C) AFEC Channel Offset Compensation Register */ + __IO uint32_t AFEC_TEMPMR; /**< \brief (Afec Offset: 0x70) AFEC Temperature Sensor Mode Register */ + __IO uint32_t AFEC_TEMPCWR; /**< \brief (Afec Offset: 0x74) AFEC Temperature Compare Window Register */ + __I uint32_t Reserved3[7]; + __IO uint32_t AFEC_ACR; /**< \brief (Afec Offset: 0x94) AFEC Analog Control Register */ + __I uint32_t Reserved4[19]; + __IO uint32_t AFEC_WPMR; /**< \brief (Afec Offset: 0xE4) AFEC Write Protection Mode Register */ + __I uint32_t AFEC_WPSR; /**< \brief (Afec Offset: 0xE8) AFEC Write Protection Status Register */ + __I uint32_t Reserved6[5]; + __IO uint32_t AFEC_RPR; /**< \brief (Afec Offset: 0x100) Receive Pointer Register */ + __IO uint32_t AFEC_RCR; /**< \brief (Afec Offset: 0x104) Receive Counter Register */ + __I uint32_t Reserved7[2]; + __IO uint32_t AFEC_RNPR; /**< \brief (Afec Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t AFEC_RNCR; /**< \brief (Afec Offset: 0x114) Receive Next Counter Register */ + __I uint32_t Reserved8[2]; + __O uint32_t AFEC_PTCR; /**< \brief (Afec Offset: 0x120) Transfer Control Register */ + __I uint32_t AFEC_PTSR; /**< \brief (Afec Offset: 0x124) Transfer Status Register */ +} Afec; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- AFEC_CR : (AFEC Offset: 0x00) AFEC Control Register -------- */ +#define AFEC_CR_SWRST (0x1u << 0) /**< \brief (AFEC_CR) Software Reset */ +#define AFEC_CR_START (0x1u << 1) /**< \brief (AFEC_CR) Start Conversion */ +#define AFEC_CR_AUTOCAL (0x1u << 3) /**< \brief (AFEC_CR) Automatic Calibration of AFEC */ +/* -------- AFEC_MR : (AFEC Offset: 0x04) AFEC Mode Register -------- */ +#define AFEC_MR_TRGEN (0x1u << 0) /**< \brief (AFEC_MR) Trigger Enable */ +#define AFEC_MR_TRGEN_DIS (0x0u << 0) /**< \brief (AFEC_MR) Hardware triggers are disabled. Starting a conversion is only possible by software. */ +#define AFEC_MR_TRGEN_EN (0x1u << 0) /**< \brief (AFEC_MR) Hardware trigger selected by TRGSEL field is enabled. */ +#define AFEC_MR_TRGSEL_Pos 1 +#define AFEC_MR_TRGSEL_Msk (0x7u << AFEC_MR_TRGSEL_Pos) /**< \brief (AFEC_MR) Trigger Selection */ +#define AFEC_MR_TRGSEL_AFEC_TRIG0 (0x0u << 1) /**< \brief (AFEC_MR) ADTRG pin */ +#define AFEC_MR_TRGSEL_AFEC_TRIG1 (0x1u << 1) /**< \brief (AFEC_MR) TIO Output of the Timer Counter Channel 0 */ +#define AFEC_MR_TRGSEL_AFEC_TRIG2 (0x2u << 1) /**< \brief (AFEC_MR) TIO Output of the Timer Counter Channel 1 */ +#define AFEC_MR_TRGSEL_AFEC_TRIG3 (0x3u << 1) /**< \brief (AFEC_MR) TIO Output of the Timer Counter Channel 2 */ +#define AFEC_MR_TRGSEL_AFEC_TRIG4 (0x4u << 1) /**< \brief (AFEC_MR) PWM Event Line 0 */ +#define AFEC_MR_TRGSEL_AFEC_TRIG5 (0x5u << 1) /**< \brief (AFEC_MR) PWM Event Line 1 */ +#define AFEC_MR_SLEEP (0x1u << 5) /**< \brief (AFEC_MR) Sleep Mode */ +#define AFEC_MR_SLEEP_NORMAL (0x0u << 5) /**< \brief (AFEC_MR) Normal Mode: The AFEC Core and reference voltage circuitry are kept ON between conversions */ +#define AFEC_MR_SLEEP_SLEEP (0x1u << 5) /**< \brief (AFEC_MR) Sleep Mode: The AFEC Core and reference voltage circuitry are OFF between conversions */ +#define AFEC_MR_FWUP (0x1u << 6) /**< \brief (AFEC_MR) Fast Wake-up */ +#define AFEC_MR_FWUP_OFF (0x0u << 6) /**< \brief (AFEC_MR) Normal Sleep Mode: The sleep mode is defined by the SLEEP bit */ +#define AFEC_MR_FWUP_ON (0x1u << 6) /**< \brief (AFEC_MR) Fast Wake Up Sleep Mode: The Voltage reference is ON between conversions and AFEC Core is OFF */ +#define AFEC_MR_FREERUN (0x1u << 7) /**< \brief (AFEC_MR) Free Run Mode */ +#define AFEC_MR_FREERUN_OFF (0x0u << 7) /**< \brief (AFEC_MR) Normal Mode */ +#define AFEC_MR_FREERUN_ON (0x1u << 7) /**< \brief (AFEC_MR) Free Run Mode: Never wait for any trigger. */ +#define AFEC_MR_PRESCAL_Pos 8 +#define AFEC_MR_PRESCAL_Msk (0xffu << AFEC_MR_PRESCAL_Pos) /**< \brief (AFEC_MR) Prescaler Rate Selection */ +#define AFEC_MR_PRESCAL(value) ((AFEC_MR_PRESCAL_Msk & ((value) << AFEC_MR_PRESCAL_Pos))) +#define AFEC_MR_STARTUP_Pos 16 +#define AFEC_MR_STARTUP_Msk (0xfu << AFEC_MR_STARTUP_Pos) /**< \brief (AFEC_MR) Start-up Time */ +#define AFEC_MR_STARTUP_SUT0 (0x0u << 16) /**< \brief (AFEC_MR) 0 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT8 (0x1u << 16) /**< \brief (AFEC_MR) 8 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT16 (0x2u << 16) /**< \brief (AFEC_MR) 16 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT24 (0x3u << 16) /**< \brief (AFEC_MR) 24 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT64 (0x4u << 16) /**< \brief (AFEC_MR) 64 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT80 (0x5u << 16) /**< \brief (AFEC_MR) 80 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT96 (0x6u << 16) /**< \brief (AFEC_MR) 96 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT112 (0x7u << 16) /**< \brief (AFEC_MR) 112 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT512 (0x8u << 16) /**< \brief (AFEC_MR) 512 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT576 (0x9u << 16) /**< \brief (AFEC_MR) 576 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT640 (0xAu << 16) /**< \brief (AFEC_MR) 640 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT704 (0xBu << 16) /**< \brief (AFEC_MR) 704 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT768 (0xCu << 16) /**< \brief (AFEC_MR) 768 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT832 (0xDu << 16) /**< \brief (AFEC_MR) 832 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT896 (0xEu << 16) /**< \brief (AFEC_MR) 896 periods of AFEClock */ +#define AFEC_MR_STARTUP_SUT960 (0xFu << 16) /**< \brief (AFEC_MR) 960 periods of AFEClock */ +#define AFEC_MR_SETTLING_Pos 20 +#define AFEC_MR_SETTLING_Msk (0x3u << AFEC_MR_SETTLING_Pos) /**< \brief (AFEC_MR) Analog Settling Time */ +#define AFEC_MR_SETTLING_AST3 (0x0u << 20) /**< \brief (AFEC_MR) 3 periods of AFEClock */ +#define AFEC_MR_SETTLING_AST5 (0x1u << 20) /**< \brief (AFEC_MR) 5 periods of AFEClock */ +#define AFEC_MR_SETTLING_AST9 (0x2u << 20) /**< \brief (AFEC_MR) 9 periods of AFEClock */ +#define AFEC_MR_SETTLING_AST17 (0x3u << 20) /**< \brief (AFEC_MR) 17 periods of AFEClock */ +#define AFEC_MR_ANACH (0x1u << 23) /**< \brief (AFEC_MR) Analog Change */ +#define AFEC_MR_ANACH_NONE (0x0u << 23) /**< \brief (AFEC_MR) No analog change on channel switching: DIFF0, GAIN0 are used for all channels */ +#define AFEC_MR_ANACH_ALLOWED (0x1u << 23) /**< \brief (AFEC_MR) Allows different analog settings for each channel. See AFEC_CGR. */ +#define AFEC_MR_TRACKTIM_Pos 24 +#define AFEC_MR_TRACKTIM_Msk (0xfu << AFEC_MR_TRACKTIM_Pos) /**< \brief (AFEC_MR) Tracking Time */ +#define AFEC_MR_TRACKTIM(value) ((AFEC_MR_TRACKTIM_Msk & ((value) << AFEC_MR_TRACKTIM_Pos))) +#define AFEC_MR_TRANSFER_Pos 28 +#define AFEC_MR_TRANSFER_Msk (0x3u << AFEC_MR_TRANSFER_Pos) /**< \brief (AFEC_MR) Transfer Period */ +#define AFEC_MR_TRANSFER(value) ((AFEC_MR_TRANSFER_Msk & ((value) << AFEC_MR_TRANSFER_Pos))) +#define AFEC_MR_USEQ (0x1u << 31) /**< \brief (AFEC_MR) Use Sequence Enable */ +#define AFEC_MR_USEQ_NUM_ORDER (0x0u << 31) /**< \brief (AFEC_MR) Normal Mode: The controller converts channels in a simple numeric order. */ +#define AFEC_MR_USEQ_REG_ORDER (0x1u << 31) /**< \brief (AFEC_MR) User Sequence Mode: The sequence respects what is defined in AFEC_SEQR1 and AFEC_SEQR2. */ +/* -------- AFEC_EMR : (AFEC Offset: 0x08) AFEC Extended Mode Register -------- */ +#define AFEC_EMR_CMPMODE_Pos 0 +#define AFEC_EMR_CMPMODE_Msk (0x3u << AFEC_EMR_CMPMODE_Pos) /**< \brief (AFEC_EMR) Comparison Mode */ +#define AFEC_EMR_CMPMODE_LOW (0x0u << 0) /**< \brief (AFEC_EMR) Generates an event when the converted data is lower than the low threshold of the window. */ +#define AFEC_EMR_CMPMODE_HIGH (0x1u << 0) /**< \brief (AFEC_EMR) Generates an event when the converted data is higher than the high threshold of the window. */ +#define AFEC_EMR_CMPMODE_IN (0x2u << 0) /**< \brief (AFEC_EMR) Generates an event when the converted data is in the comparison window. */ +#define AFEC_EMR_CMPMODE_OUT (0x3u << 0) /**< \brief (AFEC_EMR) Generates an event when the converted data is out of the comparison window. */ +#define AFEC_EMR_CMPSEL_Pos 3 +#define AFEC_EMR_CMPSEL_Msk (0x1fu << AFEC_EMR_CMPSEL_Pos) /**< \brief (AFEC_EMR) Comparison Selected Channel */ +#define AFEC_EMR_CMPSEL(value) ((AFEC_EMR_CMPSEL_Msk & ((value) << AFEC_EMR_CMPSEL_Pos))) +#define AFEC_EMR_CMPALL (0x1u << 9) /**< \brief (AFEC_EMR) Compare All Channels */ +#define AFEC_EMR_CMPFILTER_Pos 12 +#define AFEC_EMR_CMPFILTER_Msk (0x3u << AFEC_EMR_CMPFILTER_Pos) /**< \brief (AFEC_EMR) Compare Event Filtering */ +#define AFEC_EMR_CMPFILTER(value) ((AFEC_EMR_CMPFILTER_Msk & ((value) << AFEC_EMR_CMPFILTER_Pos))) +#define AFEC_EMR_RES_Pos 16 +#define AFEC_EMR_RES_Msk (0x7u << AFEC_EMR_RES_Pos) /**< \brief (AFEC_EMR) Resolution */ +#define AFEC_EMR_RES_NO_AVERAGE (0x0u << 16) /**< \brief (AFEC_EMR) 12-bit resolution, AFEC sample rate is maximum (no averaging). */ +#define AFEC_EMR_RES_LOW_RES (0x1u << 16) /**< \brief (AFEC_EMR) 10-bit resolution, AFEC sample rate is maximum (no averaging). */ +#define AFEC_EMR_RES_OSR4 (0x2u << 16) /**< \brief (AFEC_EMR) 13-bit resolution, AFEC sample rate divided by 4 (averaging). */ +#define AFEC_EMR_RES_OSR16 (0x3u << 16) /**< \brief (AFEC_EMR) 14-bit resolution, AFEC sample rate divided by 16 (averaging). */ +#define AFEC_EMR_RES_OSR64 (0x4u << 16) /**< \brief (AFEC_EMR) 15-bit resolution, AFEC sample rate divided by 64 (averaging). */ +#define AFEC_EMR_RES_OSR256 (0x5u << 16) /**< \brief (AFEC_EMR) 16-bit resolution, AFEC sample rate divided by 256 (averaging). */ +#define AFEC_EMR_AFEMODE_Pos 20 +#define AFEC_EMR_AFEMODE_Msk (0x3u << AFEC_EMR_AFEMODE_Pos) /**< \brief (AFEC_EMR) AFE Running Mode */ +#define AFEC_EMR_AFEMODE_NORMAL (0x0u << 20) /**< \brief (AFEC_EMR) Normal mode of operation. */ +#define AFEC_EMR_AFEMODE_OFFSET_ERROR (0x1u << 20) /**< \brief (AFEC_EMR) Offset Error mode to measure the offset error. */ +#define AFEC_EMR_AFEMODE_GAIN_ERROR_HIGH (0x2u << 20) /**< \brief (AFEC_EMR) Gain Error mode to measure the gain error. */ +#define AFEC_EMR_AFEMODE_GAIN_ERROR_LOW (0x3u << 20) /**< \brief (AFEC_EMR) */ +#define AFEC_EMR_TAG (0x1u << 24) /**< \brief (AFEC_EMR) TAG of the AFEC_LDCR */ +#define AFEC_EMR_STM (0x1u << 25) /**< \brief (AFEC_EMR) Single Trigger Mode */ +#define AFEC_EMR_SIGNMODE_Pos 28 +#define AFEC_EMR_SIGNMODE_Msk (0x3u << AFEC_EMR_SIGNMODE_Pos) /**< \brief (AFEC_EMR) Sign Mode */ +#define AFEC_EMR_SIGNMODE_SE_UNSG_DF_SIGN (0x0u << 28) /**< \brief (AFEC_EMR) Single-Ended Channels: Unsigned conversions.Differential Channels: Signed conversions. */ +#define AFEC_EMR_SIGNMODE_SE_SIGN_DF_UNSG (0x1u << 28) /**< \brief (AFEC_EMR) Single-Ended Channels: Signed conversions.Differential Channels: Unsigned conversions. */ +#define AFEC_EMR_SIGNMODE_ALL_UNSIGNED (0x2u << 28) /**< \brief (AFEC_EMR) All Channels: Unsigned conversions. */ +#define AFEC_EMR_SIGNMODE_ALL_SIGNED (0x3u << 28) /**< \brief (AFEC_EMR) All Channels: Signed conversions. */ +/* -------- AFEC_SEQ1R : (AFEC Offset: 0x0C) AFEC Channel Sequence 1 Register -------- */ +#define AFEC_SEQ1R_USCH0_Pos 0 +#define AFEC_SEQ1R_USCH0_Msk (0xfu << AFEC_SEQ1R_USCH0_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 0 */ +#define AFEC_SEQ1R_USCH0(value) ((AFEC_SEQ1R_USCH0_Msk & ((value) << AFEC_SEQ1R_USCH0_Pos))) +#define AFEC_SEQ1R_USCH1_Pos 4 +#define AFEC_SEQ1R_USCH1_Msk (0xfu << AFEC_SEQ1R_USCH1_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 1 */ +#define AFEC_SEQ1R_USCH1(value) ((AFEC_SEQ1R_USCH1_Msk & ((value) << AFEC_SEQ1R_USCH1_Pos))) +#define AFEC_SEQ1R_USCH2_Pos 8 +#define AFEC_SEQ1R_USCH2_Msk (0xfu << AFEC_SEQ1R_USCH2_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 2 */ +#define AFEC_SEQ1R_USCH2(value) ((AFEC_SEQ1R_USCH2_Msk & ((value) << AFEC_SEQ1R_USCH2_Pos))) +#define AFEC_SEQ1R_USCH3_Pos 12 +#define AFEC_SEQ1R_USCH3_Msk (0xfu << AFEC_SEQ1R_USCH3_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 3 */ +#define AFEC_SEQ1R_USCH3(value) ((AFEC_SEQ1R_USCH3_Msk & ((value) << AFEC_SEQ1R_USCH3_Pos))) +#define AFEC_SEQ1R_USCH4_Pos 16 +#define AFEC_SEQ1R_USCH4_Msk (0xfu << AFEC_SEQ1R_USCH4_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 4 */ +#define AFEC_SEQ1R_USCH4(value) ((AFEC_SEQ1R_USCH4_Msk & ((value) << AFEC_SEQ1R_USCH4_Pos))) +#define AFEC_SEQ1R_USCH5_Pos 20 +#define AFEC_SEQ1R_USCH5_Msk (0xfu << AFEC_SEQ1R_USCH5_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 5 */ +#define AFEC_SEQ1R_USCH5(value) ((AFEC_SEQ1R_USCH5_Msk & ((value) << AFEC_SEQ1R_USCH5_Pos))) +#define AFEC_SEQ1R_USCH6_Pos 24 +#define AFEC_SEQ1R_USCH6_Msk (0xfu << AFEC_SEQ1R_USCH6_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 6 */ +#define AFEC_SEQ1R_USCH6(value) ((AFEC_SEQ1R_USCH6_Msk & ((value) << AFEC_SEQ1R_USCH6_Pos))) +#define AFEC_SEQ1R_USCH7_Pos 28 +#define AFEC_SEQ1R_USCH7_Msk (0xfu << AFEC_SEQ1R_USCH7_Pos) /**< \brief (AFEC_SEQ1R) User Sequence Number 7 */ +#define AFEC_SEQ1R_USCH7(value) ((AFEC_SEQ1R_USCH7_Msk & ((value) << AFEC_SEQ1R_USCH7_Pos))) +/* -------- AFEC_SEQ2R : (AFEC Offset: 0x10) AFEC Channel Sequence 2 Register -------- */ +#define AFEC_SEQ2R_USCH8_Pos 0 +#define AFEC_SEQ2R_USCH8_Msk (0xfu << AFEC_SEQ2R_USCH8_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 8 */ +#define AFEC_SEQ2R_USCH8(value) ((AFEC_SEQ2R_USCH8_Msk & ((value) << AFEC_SEQ2R_USCH8_Pos))) +#define AFEC_SEQ2R_USCH9_Pos 4 +#define AFEC_SEQ2R_USCH9_Msk (0xfu << AFEC_SEQ2R_USCH9_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 9 */ +#define AFEC_SEQ2R_USCH9(value) ((AFEC_SEQ2R_USCH9_Msk & ((value) << AFEC_SEQ2R_USCH9_Pos))) +#define AFEC_SEQ2R_USCH10_Pos 8 +#define AFEC_SEQ2R_USCH10_Msk (0xfu << AFEC_SEQ2R_USCH10_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 10 */ +#define AFEC_SEQ2R_USCH10(value) ((AFEC_SEQ2R_USCH10_Msk & ((value) << AFEC_SEQ2R_USCH10_Pos))) +#define AFEC_SEQ2R_USCH11_Pos 12 +#define AFEC_SEQ2R_USCH11_Msk (0xfu << AFEC_SEQ2R_USCH11_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 11 */ +#define AFEC_SEQ2R_USCH11(value) ((AFEC_SEQ2R_USCH11_Msk & ((value) << AFEC_SEQ2R_USCH11_Pos))) +#define AFEC_SEQ2R_USCH12_Pos 16 +#define AFEC_SEQ2R_USCH12_Msk (0xfu << AFEC_SEQ2R_USCH12_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 12 */ +#define AFEC_SEQ2R_USCH12(value) ((AFEC_SEQ2R_USCH12_Msk & ((value) << AFEC_SEQ2R_USCH12_Pos))) +#define AFEC_SEQ2R_USCH13_Pos 20 +#define AFEC_SEQ2R_USCH13_Msk (0xfu << AFEC_SEQ2R_USCH13_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 13 */ +#define AFEC_SEQ2R_USCH13(value) ((AFEC_SEQ2R_USCH13_Msk & ((value) << AFEC_SEQ2R_USCH13_Pos))) +#define AFEC_SEQ2R_USCH14_Pos 24 +#define AFEC_SEQ2R_USCH14_Msk (0xfu << AFEC_SEQ2R_USCH14_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 14 */ +#define AFEC_SEQ2R_USCH14(value) ((AFEC_SEQ2R_USCH14_Msk & ((value) << AFEC_SEQ2R_USCH14_Pos))) +#define AFEC_SEQ2R_USCH15_Pos 28 +#define AFEC_SEQ2R_USCH15_Msk (0xfu << AFEC_SEQ2R_USCH15_Pos) /**< \brief (AFEC_SEQ2R) User Sequence Number 15 */ +#define AFEC_SEQ2R_USCH15(value) ((AFEC_SEQ2R_USCH15_Msk & ((value) << AFEC_SEQ2R_USCH15_Pos))) +/* -------- AFEC_CHER : (AFEC Offset: 0x14) AFEC Channel Enable Register -------- */ +#define AFEC_CHER_CH0 (0x1u << 0) /**< \brief (AFEC_CHER) Channel 0 Enable */ +#define AFEC_CHER_CH1 (0x1u << 1) /**< \brief (AFEC_CHER) Channel 1 Enable */ +#define AFEC_CHER_CH2 (0x1u << 2) /**< \brief (AFEC_CHER) Channel 2 Enable */ +#define AFEC_CHER_CH3 (0x1u << 3) /**< \brief (AFEC_CHER) Channel 3 Enable */ +#define AFEC_CHER_CH4 (0x1u << 4) /**< \brief (AFEC_CHER) Channel 4 Enable */ +#define AFEC_CHER_CH5 (0x1u << 5) /**< \brief (AFEC_CHER) Channel 5 Enable */ +#define AFEC_CHER_CH6 (0x1u << 6) /**< \brief (AFEC_CHER) Channel 6 Enable */ +#define AFEC_CHER_CH7 (0x1u << 7) /**< \brief (AFEC_CHER) Channel 7 Enable */ +#define AFEC_CHER_CH8 (0x1u << 8) /**< \brief (AFEC_CHER) Channel 8 Enable */ +#define AFEC_CHER_CH9 (0x1u << 9) /**< \brief (AFEC_CHER) Channel 9 Enable */ +#define AFEC_CHER_CH10 (0x1u << 10) /**< \brief (AFEC_CHER) Channel 10 Enable */ +#define AFEC_CHER_CH11 (0x1u << 11) /**< \brief (AFEC_CHER) Channel 11 Enable */ +#define AFEC_CHER_CH12 (0x1u << 12) /**< \brief (AFEC_CHER) Channel 12 Enable */ +#define AFEC_CHER_CH13 (0x1u << 13) /**< \brief (AFEC_CHER) Channel 13 Enable */ +#define AFEC_CHER_CH14 (0x1u << 14) /**< \brief (AFEC_CHER) Channel 14 Enable */ +#define AFEC_CHER_CH15 (0x1u << 15) /**< \brief (AFEC_CHER) Channel 15 Enable */ +/* -------- AFEC_CHDR : (AFEC Offset: 0x18) AFEC Channel Disable Register -------- */ +#define AFEC_CHDR_CH0 (0x1u << 0) /**< \brief (AFEC_CHDR) Channel 0 Disable */ +#define AFEC_CHDR_CH1 (0x1u << 1) /**< \brief (AFEC_CHDR) Channel 1 Disable */ +#define AFEC_CHDR_CH2 (0x1u << 2) /**< \brief (AFEC_CHDR) Channel 2 Disable */ +#define AFEC_CHDR_CH3 (0x1u << 3) /**< \brief (AFEC_CHDR) Channel 3 Disable */ +#define AFEC_CHDR_CH4 (0x1u << 4) /**< \brief (AFEC_CHDR) Channel 4 Disable */ +#define AFEC_CHDR_CH5 (0x1u << 5) /**< \brief (AFEC_CHDR) Channel 5 Disable */ +#define AFEC_CHDR_CH6 (0x1u << 6) /**< \brief (AFEC_CHDR) Channel 6 Disable */ +#define AFEC_CHDR_CH7 (0x1u << 7) /**< \brief (AFEC_CHDR) Channel 7 Disable */ +#define AFEC_CHDR_CH8 (0x1u << 8) /**< \brief (AFEC_CHDR) Channel 8 Disable */ +#define AFEC_CHDR_CH9 (0x1u << 9) /**< \brief (AFEC_CHDR) Channel 9 Disable */ +#define AFEC_CHDR_CH10 (0x1u << 10) /**< \brief (AFEC_CHDR) Channel 10 Disable */ +#define AFEC_CHDR_CH11 (0x1u << 11) /**< \brief (AFEC_CHDR) Channel 11 Disable */ +#define AFEC_CHDR_CH12 (0x1u << 12) /**< \brief (AFEC_CHDR) Channel 12 Disable */ +#define AFEC_CHDR_CH13 (0x1u << 13) /**< \brief (AFEC_CHDR) Channel 13 Disable */ +#define AFEC_CHDR_CH14 (0x1u << 14) /**< \brief (AFEC_CHDR) Channel 14 Disable */ +#define AFEC_CHDR_CH15 (0x1u << 15) /**< \brief (AFEC_CHDR) Channel 15 Disable */ +/* -------- AFEC_CHSR : (AFEC Offset: 0x1C) AFEC Channel Status Register -------- */ +#define AFEC_CHSR_CH0 (0x1u << 0) /**< \brief (AFEC_CHSR) Channel 0 Status */ +#define AFEC_CHSR_CH1 (0x1u << 1) /**< \brief (AFEC_CHSR) Channel 1 Status */ +#define AFEC_CHSR_CH2 (0x1u << 2) /**< \brief (AFEC_CHSR) Channel 2 Status */ +#define AFEC_CHSR_CH3 (0x1u << 3) /**< \brief (AFEC_CHSR) Channel 3 Status */ +#define AFEC_CHSR_CH4 (0x1u << 4) /**< \brief (AFEC_CHSR) Channel 4 Status */ +#define AFEC_CHSR_CH5 (0x1u << 5) /**< \brief (AFEC_CHSR) Channel 5 Status */ +#define AFEC_CHSR_CH6 (0x1u << 6) /**< \brief (AFEC_CHSR) Channel 6 Status */ +#define AFEC_CHSR_CH7 (0x1u << 7) /**< \brief (AFEC_CHSR) Channel 7 Status */ +#define AFEC_CHSR_CH8 (0x1u << 8) /**< \brief (AFEC_CHSR) Channel 8 Status */ +#define AFEC_CHSR_CH9 (0x1u << 9) /**< \brief (AFEC_CHSR) Channel 9 Status */ +#define AFEC_CHSR_CH10 (0x1u << 10) /**< \brief (AFEC_CHSR) Channel 10 Status */ +#define AFEC_CHSR_CH11 (0x1u << 11) /**< \brief (AFEC_CHSR) Channel 11 Status */ +#define AFEC_CHSR_CH12 (0x1u << 12) /**< \brief (AFEC_CHSR) Channel 12 Status */ +#define AFEC_CHSR_CH13 (0x1u << 13) /**< \brief (AFEC_CHSR) Channel 13 Status */ +#define AFEC_CHSR_CH14 (0x1u << 14) /**< \brief (AFEC_CHSR) Channel 14 Status */ +#define AFEC_CHSR_CH15 (0x1u << 15) /**< \brief (AFEC_CHSR) Channel 15 Status */ +/* -------- AFEC_LCDR : (AFEC Offset: 0x20) AFEC Last Converted Data Register -------- */ +#define AFEC_LCDR_LDATA_Pos 0 +#define AFEC_LCDR_LDATA_Msk (0xffffu << AFEC_LCDR_LDATA_Pos) /**< \brief (AFEC_LCDR) Last Data Converted */ +#define AFEC_LCDR_CHNB_Pos 24 +#define AFEC_LCDR_CHNB_Msk (0xfu << AFEC_LCDR_CHNB_Pos) /**< \brief (AFEC_LCDR) Channel Number */ +/* -------- AFEC_IER : (AFEC Offset: 0x24) AFEC Interrupt Enable Register -------- */ +#define AFEC_IER_EOC0 (0x1u << 0) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 0 */ +#define AFEC_IER_EOC1 (0x1u << 1) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 1 */ +#define AFEC_IER_EOC2 (0x1u << 2) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 2 */ +#define AFEC_IER_EOC3 (0x1u << 3) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 3 */ +#define AFEC_IER_EOC4 (0x1u << 4) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 4 */ +#define AFEC_IER_EOC5 (0x1u << 5) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 5 */ +#define AFEC_IER_EOC6 (0x1u << 6) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 6 */ +#define AFEC_IER_EOC7 (0x1u << 7) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 7 */ +#define AFEC_IER_EOC8 (0x1u << 8) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 8 */ +#define AFEC_IER_EOC9 (0x1u << 9) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 9 */ +#define AFEC_IER_EOC10 (0x1u << 10) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 10 */ +#define AFEC_IER_EOC11 (0x1u << 11) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 11 */ +#define AFEC_IER_EOC12 (0x1u << 12) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 12 */ +#define AFEC_IER_EOC13 (0x1u << 13) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 13 */ +#define AFEC_IER_EOC14 (0x1u << 14) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 14 */ +#define AFEC_IER_EOC15 (0x1u << 15) /**< \brief (AFEC_IER) End of Conversion Interrupt Enable 15 */ +#define AFEC_IER_DRDY (0x1u << 24) /**< \brief (AFEC_IER) Data Ready Interrupt Enable */ +#define AFEC_IER_GOVRE (0x1u << 25) /**< \brief (AFEC_IER) General Overrun Error Interrupt Enable */ +#define AFEC_IER_COMPE (0x1u << 26) /**< \brief (AFEC_IER) Comparison Event Interrupt Enable */ +#define AFEC_IER_ENDRX (0x1u << 27) /**< \brief (AFEC_IER) End of Receive Buffer Interrupt Enable */ +#define AFEC_IER_RXBUFF (0x1u << 28) /**< \brief (AFEC_IER) Receive Buffer Full Interrupt Enable */ +#define AFEC_IER_TEMPCHG (0x1u << 30) /**< \brief (AFEC_IER) Temperature Change Interrupt Enable */ +#define AFEC_IER_EOCAL (0x1u << 31) /**< \brief (AFEC_IER) End of Calibration Sequence Interrupt Enable */ +/* -------- AFEC_IDR : (AFEC Offset: 0x28) AFEC Interrupt Disable Register -------- */ +#define AFEC_IDR_EOC0 (0x1u << 0) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 0 */ +#define AFEC_IDR_EOC1 (0x1u << 1) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 1 */ +#define AFEC_IDR_EOC2 (0x1u << 2) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 2 */ +#define AFEC_IDR_EOC3 (0x1u << 3) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 3 */ +#define AFEC_IDR_EOC4 (0x1u << 4) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 4 */ +#define AFEC_IDR_EOC5 (0x1u << 5) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 5 */ +#define AFEC_IDR_EOC6 (0x1u << 6) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 6 */ +#define AFEC_IDR_EOC7 (0x1u << 7) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 7 */ +#define AFEC_IDR_EOC8 (0x1u << 8) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 8 */ +#define AFEC_IDR_EOC9 (0x1u << 9) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 9 */ +#define AFEC_IDR_EOC10 (0x1u << 10) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 10 */ +#define AFEC_IDR_EOC11 (0x1u << 11) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 11 */ +#define AFEC_IDR_EOC12 (0x1u << 12) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 12 */ +#define AFEC_IDR_EOC13 (0x1u << 13) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 13 */ +#define AFEC_IDR_EOC14 (0x1u << 14) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 14 */ +#define AFEC_IDR_EOC15 (0x1u << 15) /**< \brief (AFEC_IDR) End of Conversion Interrupt Disable 15 */ +#define AFEC_IDR_DRDY (0x1u << 24) /**< \brief (AFEC_IDR) Data Ready Interrupt Disable */ +#define AFEC_IDR_GOVRE (0x1u << 25) /**< \brief (AFEC_IDR) General Overrun Error Interrupt Disable */ +#define AFEC_IDR_COMPE (0x1u << 26) /**< \brief (AFEC_IDR) Comparison Event Interrupt Disable */ +#define AFEC_IDR_ENDRX (0x1u << 27) /**< \brief (AFEC_IDR) End of Receive Buffer Interrupt Disable */ +#define AFEC_IDR_RXBUFF (0x1u << 28) /**< \brief (AFEC_IDR) Receive Buffer Full Interrupt Disable */ +#define AFEC_IDR_TEMPCHG (0x1u << 30) /**< \brief (AFEC_IDR) Temperature Change Interrupt Disable */ +#define AFEC_IDR_EOCAL (0x1u << 31) /**< \brief (AFEC_IDR) End of Calibration Sequence Interrupt Disable */ +/* -------- AFEC_IMR : (AFEC Offset: 0x2C) AFEC Interrupt Mask Register -------- */ +#define AFEC_IMR_EOC0 (0x1u << 0) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 0 */ +#define AFEC_IMR_EOC1 (0x1u << 1) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 1 */ +#define AFEC_IMR_EOC2 (0x1u << 2) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 2 */ +#define AFEC_IMR_EOC3 (0x1u << 3) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 3 */ +#define AFEC_IMR_EOC4 (0x1u << 4) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 4 */ +#define AFEC_IMR_EOC5 (0x1u << 5) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 5 */ +#define AFEC_IMR_EOC6 (0x1u << 6) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 6 */ +#define AFEC_IMR_EOC7 (0x1u << 7) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 7 */ +#define AFEC_IMR_EOC8 (0x1u << 8) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 8 */ +#define AFEC_IMR_EOC9 (0x1u << 9) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 9 */ +#define AFEC_IMR_EOC10 (0x1u << 10) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 10 */ +#define AFEC_IMR_EOC11 (0x1u << 11) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 11 */ +#define AFEC_IMR_EOC12 (0x1u << 12) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 12 */ +#define AFEC_IMR_EOC13 (0x1u << 13) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 13 */ +#define AFEC_IMR_EOC14 (0x1u << 14) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 14 */ +#define AFEC_IMR_EOC15 (0x1u << 15) /**< \brief (AFEC_IMR) End of Conversion Interrupt Mask 15 */ +#define AFEC_IMR_DRDY (0x1u << 24) /**< \brief (AFEC_IMR) Data Ready Interrupt Mask */ +#define AFEC_IMR_GOVRE (0x1u << 25) /**< \brief (AFEC_IMR) General Overrun Error Interrupt Mask */ +#define AFEC_IMR_COMPE (0x1u << 26) /**< \brief (AFEC_IMR) Comparison Event Interrupt Mask */ +#define AFEC_IMR_ENDRX (0x1u << 27) /**< \brief (AFEC_IMR) End of Receive Buffer Interrupt Mask */ +#define AFEC_IMR_RXBUFF (0x1u << 28) /**< \brief (AFEC_IMR) Receive Buffer Full Interrupt Mask */ +#define AFEC_IMR_TEMPCHG (0x1u << 30) /**< \brief (AFEC_IMR) Temperature Change Interrupt Mask */ +#define AFEC_IMR_EOCAL (0x1u << 31) /**< \brief (AFEC_IMR) End of Calibration Sequence Interrupt Mask */ +/* -------- AFEC_ISR : (AFEC Offset: 0x30) AFEC Interrupt Status Register -------- */ +#define AFEC_ISR_EOC0 (0x1u << 0) /**< \brief (AFEC_ISR) End of Conversion 0 */ +#define AFEC_ISR_EOC1 (0x1u << 1) /**< \brief (AFEC_ISR) End of Conversion 1 */ +#define AFEC_ISR_EOC2 (0x1u << 2) /**< \brief (AFEC_ISR) End of Conversion 2 */ +#define AFEC_ISR_EOC3 (0x1u << 3) /**< \brief (AFEC_ISR) End of Conversion 3 */ +#define AFEC_ISR_EOC4 (0x1u << 4) /**< \brief (AFEC_ISR) End of Conversion 4 */ +#define AFEC_ISR_EOC5 (0x1u << 5) /**< \brief (AFEC_ISR) End of Conversion 5 */ +#define AFEC_ISR_EOC6 (0x1u << 6) /**< \brief (AFEC_ISR) End of Conversion 6 */ +#define AFEC_ISR_EOC7 (0x1u << 7) /**< \brief (AFEC_ISR) End of Conversion 7 */ +#define AFEC_ISR_EOC8 (0x1u << 8) /**< \brief (AFEC_ISR) End of Conversion 8 */ +#define AFEC_ISR_EOC9 (0x1u << 9) /**< \brief (AFEC_ISR) End of Conversion 9 */ +#define AFEC_ISR_EOC10 (0x1u << 10) /**< \brief (AFEC_ISR) End of Conversion 10 */ +#define AFEC_ISR_EOC11 (0x1u << 11) /**< \brief (AFEC_ISR) End of Conversion 11 */ +#define AFEC_ISR_EOC12 (0x1u << 12) /**< \brief (AFEC_ISR) End of Conversion 12 */ +#define AFEC_ISR_EOC13 (0x1u << 13) /**< \brief (AFEC_ISR) End of Conversion 13 */ +#define AFEC_ISR_EOC14 (0x1u << 14) /**< \brief (AFEC_ISR) End of Conversion 14 */ +#define AFEC_ISR_EOC15 (0x1u << 15) /**< \brief (AFEC_ISR) End of Conversion 15 */ +#define AFEC_ISR_DRDY (0x1u << 24) /**< \brief (AFEC_ISR) Data Ready */ +#define AFEC_ISR_GOVRE (0x1u << 25) /**< \brief (AFEC_ISR) General Overrun Error */ +#define AFEC_ISR_COMPE (0x1u << 26) /**< \brief (AFEC_ISR) Comparison Error */ +#define AFEC_ISR_ENDRX (0x1u << 27) /**< \brief (AFEC_ISR) End of RX Buffer */ +#define AFEC_ISR_RXBUFF (0x1u << 28) /**< \brief (AFEC_ISR) RX Buffer Full */ +#define AFEC_ISR_TEMPCHG (0x1u << 30) /**< \brief (AFEC_ISR) Temperature Change */ +#define AFEC_ISR_EOCAL (0x1u << 31) /**< \brief (AFEC_ISR) End of Calibration Sequence */ +/* -------- AFEC_OVER : (AFEC Offset: 0x4C) AFEC Overrun Status Register -------- */ +#define AFEC_OVER_OVRE0 (0x1u << 0) /**< \brief (AFEC_OVER) Overrun Error 0 */ +#define AFEC_OVER_OVRE1 (0x1u << 1) /**< \brief (AFEC_OVER) Overrun Error 1 */ +#define AFEC_OVER_OVRE2 (0x1u << 2) /**< \brief (AFEC_OVER) Overrun Error 2 */ +#define AFEC_OVER_OVRE3 (0x1u << 3) /**< \brief (AFEC_OVER) Overrun Error 3 */ +#define AFEC_OVER_OVRE4 (0x1u << 4) /**< \brief (AFEC_OVER) Overrun Error 4 */ +#define AFEC_OVER_OVRE5 (0x1u << 5) /**< \brief (AFEC_OVER) Overrun Error 5 */ +#define AFEC_OVER_OVRE6 (0x1u << 6) /**< \brief (AFEC_OVER) Overrun Error 6 */ +#define AFEC_OVER_OVRE7 (0x1u << 7) /**< \brief (AFEC_OVER) Overrun Error 7 */ +#define AFEC_OVER_OVRE8 (0x1u << 8) /**< \brief (AFEC_OVER) Overrun Error 8 */ +#define AFEC_OVER_OVRE9 (0x1u << 9) /**< \brief (AFEC_OVER) Overrun Error 9 */ +#define AFEC_OVER_OVRE10 (0x1u << 10) /**< \brief (AFEC_OVER) Overrun Error 10 */ +#define AFEC_OVER_OVRE11 (0x1u << 11) /**< \brief (AFEC_OVER) Overrun Error 11 */ +#define AFEC_OVER_OVRE12 (0x1u << 12) /**< \brief (AFEC_OVER) Overrun Error 12 */ +#define AFEC_OVER_OVRE13 (0x1u << 13) /**< \brief (AFEC_OVER) Overrun Error 13 */ +#define AFEC_OVER_OVRE14 (0x1u << 14) /**< \brief (AFEC_OVER) Overrun Error 14 */ +#define AFEC_OVER_OVRE15 (0x1u << 15) /**< \brief (AFEC_OVER) Overrun Error 15 */ +/* -------- AFEC_CWR : (AFEC Offset: 0x50) AFEC Compare Window Register -------- */ +#define AFEC_CWR_LOWTHRES_Pos 0 +#define AFEC_CWR_LOWTHRES_Msk (0xffffu << AFEC_CWR_LOWTHRES_Pos) /**< \brief (AFEC_CWR) Low Threshold */ +#define AFEC_CWR_LOWTHRES(value) ((AFEC_CWR_LOWTHRES_Msk & ((value) << AFEC_CWR_LOWTHRES_Pos))) +#define AFEC_CWR_HIGHTHRES_Pos 16 +#define AFEC_CWR_HIGHTHRES_Msk (0xffffu << AFEC_CWR_HIGHTHRES_Pos) /**< \brief (AFEC_CWR) High Threshold */ +#define AFEC_CWR_HIGHTHRES(value) ((AFEC_CWR_HIGHTHRES_Msk & ((value) << AFEC_CWR_HIGHTHRES_Pos))) +/* -------- AFEC_CGR : (AFEC Offset: 0x54) AFEC Channel Gain Register -------- */ +#define AFEC_CGR_GAIN0_Pos 0 +#define AFEC_CGR_GAIN0_Msk (0x3u << AFEC_CGR_GAIN0_Pos) /**< \brief (AFEC_CGR) Gain for channel 0 */ +#define AFEC_CGR_GAIN0(value) ((AFEC_CGR_GAIN0_Msk & ((value) << AFEC_CGR_GAIN0_Pos))) +#define AFEC_CGR_GAIN1_Pos 2 +#define AFEC_CGR_GAIN1_Msk (0x3u << AFEC_CGR_GAIN1_Pos) /**< \brief (AFEC_CGR) Gain for channel 1 */ +#define AFEC_CGR_GAIN1(value) ((AFEC_CGR_GAIN1_Msk & ((value) << AFEC_CGR_GAIN1_Pos))) +#define AFEC_CGR_GAIN2_Pos 4 +#define AFEC_CGR_GAIN2_Msk (0x3u << AFEC_CGR_GAIN2_Pos) /**< \brief (AFEC_CGR) Gain for channel 2 */ +#define AFEC_CGR_GAIN2(value) ((AFEC_CGR_GAIN2_Msk & ((value) << AFEC_CGR_GAIN2_Pos))) +#define AFEC_CGR_GAIN3_Pos 6 +#define AFEC_CGR_GAIN3_Msk (0x3u << AFEC_CGR_GAIN3_Pos) /**< \brief (AFEC_CGR) Gain for channel 3 */ +#define AFEC_CGR_GAIN3(value) ((AFEC_CGR_GAIN3_Msk & ((value) << AFEC_CGR_GAIN3_Pos))) +#define AFEC_CGR_GAIN4_Pos 8 +#define AFEC_CGR_GAIN4_Msk (0x3u << AFEC_CGR_GAIN4_Pos) /**< \brief (AFEC_CGR) Gain for channel 4 */ +#define AFEC_CGR_GAIN4(value) ((AFEC_CGR_GAIN4_Msk & ((value) << AFEC_CGR_GAIN4_Pos))) +#define AFEC_CGR_GAIN5_Pos 10 +#define AFEC_CGR_GAIN5_Msk (0x3u << AFEC_CGR_GAIN5_Pos) /**< \brief (AFEC_CGR) Gain for channel 5 */ +#define AFEC_CGR_GAIN5(value) ((AFEC_CGR_GAIN5_Msk & ((value) << AFEC_CGR_GAIN5_Pos))) +#define AFEC_CGR_GAIN6_Pos 12 +#define AFEC_CGR_GAIN6_Msk (0x3u << AFEC_CGR_GAIN6_Pos) /**< \brief (AFEC_CGR) Gain for channel 6 */ +#define AFEC_CGR_GAIN6(value) ((AFEC_CGR_GAIN6_Msk & ((value) << AFEC_CGR_GAIN6_Pos))) +#define AFEC_CGR_GAIN7_Pos 14 +#define AFEC_CGR_GAIN7_Msk (0x3u << AFEC_CGR_GAIN7_Pos) /**< \brief (AFEC_CGR) Gain for channel 7 */ +#define AFEC_CGR_GAIN7(value) ((AFEC_CGR_GAIN7_Msk & ((value) << AFEC_CGR_GAIN7_Pos))) +#define AFEC_CGR_GAIN8_Pos 16 +#define AFEC_CGR_GAIN8_Msk (0x3u << AFEC_CGR_GAIN8_Pos) /**< \brief (AFEC_CGR) Gain for channel 8 */ +#define AFEC_CGR_GAIN8(value) ((AFEC_CGR_GAIN8_Msk & ((value) << AFEC_CGR_GAIN8_Pos))) +#define AFEC_CGR_GAIN9_Pos 18 +#define AFEC_CGR_GAIN9_Msk (0x3u << AFEC_CGR_GAIN9_Pos) /**< \brief (AFEC_CGR) Gain for channel 9 */ +#define AFEC_CGR_GAIN9(value) ((AFEC_CGR_GAIN9_Msk & ((value) << AFEC_CGR_GAIN9_Pos))) +#define AFEC_CGR_GAIN10_Pos 20 +#define AFEC_CGR_GAIN10_Msk (0x3u << AFEC_CGR_GAIN10_Pos) /**< \brief (AFEC_CGR) Gain for channel 10 */ +#define AFEC_CGR_GAIN10(value) ((AFEC_CGR_GAIN10_Msk & ((value) << AFEC_CGR_GAIN10_Pos))) +#define AFEC_CGR_GAIN11_Pos 22 +#define AFEC_CGR_GAIN11_Msk (0x3u << AFEC_CGR_GAIN11_Pos) /**< \brief (AFEC_CGR) Gain for channel 11 */ +#define AFEC_CGR_GAIN11(value) ((AFEC_CGR_GAIN11_Msk & ((value) << AFEC_CGR_GAIN11_Pos))) +#define AFEC_CGR_GAIN12_Pos 24 +#define AFEC_CGR_GAIN12_Msk (0x3u << AFEC_CGR_GAIN12_Pos) /**< \brief (AFEC_CGR) Gain for channel 12 */ +#define AFEC_CGR_GAIN12(value) ((AFEC_CGR_GAIN12_Msk & ((value) << AFEC_CGR_GAIN12_Pos))) +#define AFEC_CGR_GAIN13_Pos 26 +#define AFEC_CGR_GAIN13_Msk (0x3u << AFEC_CGR_GAIN13_Pos) /**< \brief (AFEC_CGR) Gain for channel 13 */ +#define AFEC_CGR_GAIN13(value) ((AFEC_CGR_GAIN13_Msk & ((value) << AFEC_CGR_GAIN13_Pos))) +#define AFEC_CGR_GAIN14_Pos 28 +#define AFEC_CGR_GAIN14_Msk (0x3u << AFEC_CGR_GAIN14_Pos) /**< \brief (AFEC_CGR) Gain for channel 14 */ +#define AFEC_CGR_GAIN14(value) ((AFEC_CGR_GAIN14_Msk & ((value) << AFEC_CGR_GAIN14_Pos))) +#define AFEC_CGR_GAIN15_Pos 30 +#define AFEC_CGR_GAIN15_Msk (0x3u << AFEC_CGR_GAIN15_Pos) /**< \brief (AFEC_CGR) Gain for channel 15 */ +#define AFEC_CGR_GAIN15(value) ((AFEC_CGR_GAIN15_Msk & ((value) << AFEC_CGR_GAIN15_Pos))) +/* -------- AFEC_CDOR : (AFEC Offset: 0x5C) AFEC Channel Calibration DC Offset Register -------- */ +#define AFEC_CDOR_OFF0 (0x1u << 0) /**< \brief (AFEC_CDOR) Offset for Channel 0, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF1 (0x1u << 1) /**< \brief (AFEC_CDOR) Offset for Channel 1, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF2 (0x1u << 2) /**< \brief (AFEC_CDOR) Offset for Channel 2, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF3 (0x1u << 3) /**< \brief (AFEC_CDOR) Offset for Channel 3, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF4 (0x1u << 4) /**< \brief (AFEC_CDOR) Offset for Channel 4, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF5 (0x1u << 5) /**< \brief (AFEC_CDOR) Offset for Channel 5, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF6 (0x1u << 6) /**< \brief (AFEC_CDOR) Offset for Channel 6, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF7 (0x1u << 7) /**< \brief (AFEC_CDOR) Offset for Channel 7, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF8 (0x1u << 8) /**< \brief (AFEC_CDOR) Offset for Channel 8, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF9 (0x1u << 9) /**< \brief (AFEC_CDOR) Offset for Channel 9, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF10 (0x1u << 10) /**< \brief (AFEC_CDOR) Offset for Channel 10, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF11 (0x1u << 11) /**< \brief (AFEC_CDOR) Offset for Channel 11, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF12 (0x1u << 12) /**< \brief (AFEC_CDOR) Offset for Channel 12, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF13 (0x1u << 13) /**< \brief (AFEC_CDOR) Offset for Channel 13, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF14 (0x1u << 14) /**< \brief (AFEC_CDOR) Offset for Channel 14, used in Automatic Calibration Procedure */ +#define AFEC_CDOR_OFF15 (0x1u << 15) /**< \brief (AFEC_CDOR) Offset for Channel 15, used in Automatic Calibration Procedure */ +/* -------- AFEC_DIFFR : (AFEC Offset: 0x60) AFEC Channel Differential Register -------- */ +#define AFEC_DIFFR_DIFF0 (0x1u << 0) /**< \brief (AFEC_DIFFR) Differential inputs for channel 0 */ +#define AFEC_DIFFR_DIFF1 (0x1u << 1) /**< \brief (AFEC_DIFFR) Differential inputs for channel 1 */ +#define AFEC_DIFFR_DIFF2 (0x1u << 2) /**< \brief (AFEC_DIFFR) Differential inputs for channel 2 */ +#define AFEC_DIFFR_DIFF3 (0x1u << 3) /**< \brief (AFEC_DIFFR) Differential inputs for channel 3 */ +#define AFEC_DIFFR_DIFF4 (0x1u << 4) /**< \brief (AFEC_DIFFR) Differential inputs for channel 4 */ +#define AFEC_DIFFR_DIFF5 (0x1u << 5) /**< \brief (AFEC_DIFFR) Differential inputs for channel 5 */ +#define AFEC_DIFFR_DIFF6 (0x1u << 6) /**< \brief (AFEC_DIFFR) Differential inputs for channel 6 */ +#define AFEC_DIFFR_DIFF7 (0x1u << 7) /**< \brief (AFEC_DIFFR) Differential inputs for channel 7 */ +#define AFEC_DIFFR_DIFF8 (0x1u << 8) /**< \brief (AFEC_DIFFR) Differential inputs for channel 8 */ +#define AFEC_DIFFR_DIFF9 (0x1u << 9) /**< \brief (AFEC_DIFFR) Differential inputs for channel 9 */ +#define AFEC_DIFFR_DIFF10 (0x1u << 10) /**< \brief (AFEC_DIFFR) Differential inputs for channel 10 */ +#define AFEC_DIFFR_DIFF11 (0x1u << 11) /**< \brief (AFEC_DIFFR) Differential inputs for channel 11 */ +#define AFEC_DIFFR_DIFF12 (0x1u << 12) /**< \brief (AFEC_DIFFR) Differential inputs for channel 12 */ +#define AFEC_DIFFR_DIFF13 (0x1u << 13) /**< \brief (AFEC_DIFFR) Differential inputs for channel 13 */ +#define AFEC_DIFFR_DIFF14 (0x1u << 14) /**< \brief (AFEC_DIFFR) Differential inputs for channel 14 */ +#define AFEC_DIFFR_DIFF15 (0x1u << 15) /**< \brief (AFEC_DIFFR) Differential inputs for channel 15 */ +/* -------- AFEC_CSELR : (AFEC Offset: 0x64) AFEC Channel Register Selection -------- */ +#define AFEC_CSELR_CSEL_Pos 0 +#define AFEC_CSELR_CSEL_Msk (0xfu << AFEC_CSELR_CSEL_Pos) /**< \brief (AFEC_CSELR) Channel Selection */ +#define AFEC_CSELR_CSEL(value) ((AFEC_CSELR_CSEL_Msk & ((value) << AFEC_CSELR_CSEL_Pos))) +/* -------- AFEC_CDR : (AFEC Offset: 0x68) AFEC Channel Data Register -------- */ +#define AFEC_CDR_DATA_Pos 0 +#define AFEC_CDR_DATA_Msk (0xfffu << AFEC_CDR_DATA_Pos) /**< \brief (AFEC_CDR) Converted Data */ +/* -------- AFEC_COCR : (AFEC Offset: 0x6C) AFEC Channel Offset Compensation Register -------- */ +#define AFEC_COCR_AOFF_Pos 0 +#define AFEC_COCR_AOFF_Msk (0xfffu << AFEC_COCR_AOFF_Pos) /**< \brief (AFEC_COCR) Analog Offset */ +#define AFEC_COCR_AOFF(value) ((AFEC_COCR_AOFF_Msk & ((value) << AFEC_COCR_AOFF_Pos))) +/* -------- AFEC_TEMPMR : (AFEC Offset: 0x70) AFEC Temperature Sensor Mode Register -------- */ +#define AFEC_TEMPMR_RTCT (0x1u << 0) /**< \brief (AFEC_TEMPMR) Temperature Sensor RTC Trigger mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_Pos 4 +#define AFEC_TEMPMR_TEMPCMPMOD_Msk (0x3u << AFEC_TEMPMR_TEMPCMPMOD_Pos) /**< \brief (AFEC_TEMPMR) Temperature Comparison Mode */ +#define AFEC_TEMPMR_TEMPCMPMOD_LOW (0x0u << 4) /**< \brief (AFEC_TEMPMR) Generates an event when the converted data is lower than the low threshold of the window. */ +#define AFEC_TEMPMR_TEMPCMPMOD_HIGH (0x1u << 4) /**< \brief (AFEC_TEMPMR) Generates an event when the converted data is higher than the high threshold of the window. */ +#define AFEC_TEMPMR_TEMPCMPMOD_IN (0x2u << 4) /**< \brief (AFEC_TEMPMR) Generates an event when the converted data is in the comparison window. */ +#define AFEC_TEMPMR_TEMPCMPMOD_OUT (0x3u << 4) /**< \brief (AFEC_TEMPMR) Generates an event when the converted data is out of the comparison window. */ +/* -------- AFEC_TEMPCWR : (AFEC Offset: 0x74) AFEC Temperature Compare Window Register -------- */ +#define AFEC_TEMPCWR_TLOWTHRES_Pos 0 +#define AFEC_TEMPCWR_TLOWTHRES_Msk (0xffffu << AFEC_TEMPCWR_TLOWTHRES_Pos) /**< \brief (AFEC_TEMPCWR) Temperature Low Threshold */ +#define AFEC_TEMPCWR_TLOWTHRES(value) ((AFEC_TEMPCWR_TLOWTHRES_Msk & ((value) << AFEC_TEMPCWR_TLOWTHRES_Pos))) +#define AFEC_TEMPCWR_THIGHTHRES_Pos 16 +#define AFEC_TEMPCWR_THIGHTHRES_Msk (0xffffu << AFEC_TEMPCWR_THIGHTHRES_Pos) /**< \brief (AFEC_TEMPCWR) Temperature High Threshold */ +#define AFEC_TEMPCWR_THIGHTHRES(value) ((AFEC_TEMPCWR_THIGHTHRES_Msk & ((value) << AFEC_TEMPCWR_THIGHTHRES_Pos))) +/* -------- AFEC_ACR : (AFEC Offset: 0x94) AFEC Analog Control Register -------- */ +#define AFEC_ACR_IBCTL_Pos 8 +#define AFEC_ACR_IBCTL_Msk (0x3u << AFEC_ACR_IBCTL_Pos) /**< \brief (AFEC_ACR) AFEC Bias Current Control */ +#define AFEC_ACR_IBCTL(value) ((AFEC_ACR_IBCTL_Msk & ((value) << AFEC_ACR_IBCTL_Pos))) +/* -------- AFEC_WPMR : (AFEC Offset: 0xE4) AFEC Write Protection Mode Register -------- */ +#define AFEC_WPMR_WPEN (0x1u << 0) /**< \brief (AFEC_WPMR) Write Protection Enable */ +#define AFEC_WPMR_WPKEY_Pos 8 +#define AFEC_WPMR_WPKEY_Msk (0xffffffu << AFEC_WPMR_WPKEY_Pos) /**< \brief (AFEC_WPMR) Write Protect KEY */ +#define AFEC_WPMR_WPKEY_PASSWD (0x414443u << 8) /**< \brief (AFEC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit. Always reads as 0. */ +/* -------- AFEC_WPSR : (AFEC Offset: 0xE8) AFEC Write Protection Status Register -------- */ +#define AFEC_WPSR_WPVS (0x1u << 0) /**< \brief (AFEC_WPSR) Write Protect Violation Status */ +#define AFEC_WPSR_WPVSRC_Pos 8 +#define AFEC_WPSR_WPVSRC_Msk (0xffffu << AFEC_WPSR_WPVSRC_Pos) /**< \brief (AFEC_WPSR) Write Protect Violation Source */ +/* -------- AFEC_RPR : (AFEC Offset: 0x100) Receive Pointer Register -------- */ +#define AFEC_RPR_RXPTR_Pos 0 +#define AFEC_RPR_RXPTR_Msk (0xffffffffu << AFEC_RPR_RXPTR_Pos) /**< \brief (AFEC_RPR) Receive Pointer Register */ +#define AFEC_RPR_RXPTR(value) ((AFEC_RPR_RXPTR_Msk & ((value) << AFEC_RPR_RXPTR_Pos))) +/* -------- AFEC_RCR : (AFEC Offset: 0x104) Receive Counter Register -------- */ +#define AFEC_RCR_RXCTR_Pos 0 +#define AFEC_RCR_RXCTR_Msk (0xffffu << AFEC_RCR_RXCTR_Pos) /**< \brief (AFEC_RCR) Receive Counter Register */ +#define AFEC_RCR_RXCTR(value) ((AFEC_RCR_RXCTR_Msk & ((value) << AFEC_RCR_RXCTR_Pos))) +/* -------- AFEC_RNPR : (AFEC Offset: 0x110) Receive Next Pointer Register -------- */ +#define AFEC_RNPR_RXNPTR_Pos 0 +#define AFEC_RNPR_RXNPTR_Msk (0xffffffffu << AFEC_RNPR_RXNPTR_Pos) /**< \brief (AFEC_RNPR) Receive Next Pointer */ +#define AFEC_RNPR_RXNPTR(value) ((AFEC_RNPR_RXNPTR_Msk & ((value) << AFEC_RNPR_RXNPTR_Pos))) +/* -------- AFEC_RNCR : (AFEC Offset: 0x114) Receive Next Counter Register -------- */ +#define AFEC_RNCR_RXNCTR_Pos 0 +#define AFEC_RNCR_RXNCTR_Msk (0xffffu << AFEC_RNCR_RXNCTR_Pos) /**< \brief (AFEC_RNCR) Receive Next Counter */ +#define AFEC_RNCR_RXNCTR(value) ((AFEC_RNCR_RXNCTR_Msk & ((value) << AFEC_RNCR_RXNCTR_Pos))) +/* -------- AFEC_PTCR : (AFEC Offset: 0x120) Transfer Control Register -------- */ +#define AFEC_PTCR_RXTEN (0x1u << 0) /**< \brief (AFEC_PTCR) Receiver Transfer Enable */ +#define AFEC_PTCR_RXTDIS (0x1u << 1) /**< \brief (AFEC_PTCR) Receiver Transfer Disable */ +#define AFEC_PTCR_TXTEN (0x1u << 8) /**< \brief (AFEC_PTCR) Transmitter Transfer Enable */ +#define AFEC_PTCR_TXTDIS (0x1u << 9) /**< \brief (AFEC_PTCR) Transmitter Transfer Disable */ +/* -------- AFEC_PTSR : (AFEC Offset: 0x124) Transfer Status Register -------- */ +#define AFEC_PTSR_RXTEN (0x1u << 0) /**< \brief (AFEC_PTSR) Receiver Transfer Enable */ +#define AFEC_PTSR_TXTEN (0x1u << 8) /**< \brief (AFEC_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_AFEC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/can.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/can.h new file mode 100644 index 0000000..c4ad122 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/can.h @@ -0,0 +1,307 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CAN_COMPONENT_ +#define _SAM4E_CAN_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Controller Area Network */ +/* ============================================================================= */ +/** \addtogroup SAM4E_CAN Controller Area Network */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief CanMb hardware registers */ +typedef struct { + __IO uint32_t CAN_MMR; /**< \brief (CanMb Offset: 0x0) Mailbox Mode Register */ + __IO uint32_t CAN_MAM; /**< \brief (CanMb Offset: 0x4) Mailbox Acceptance Mask Register */ + __IO uint32_t CAN_MID; /**< \brief (CanMb Offset: 0x8) Mailbox ID Register */ + __I uint32_t CAN_MFID; /**< \brief (CanMb Offset: 0xC) Mailbox Family ID Register */ + __I uint32_t CAN_MSR; /**< \brief (CanMb Offset: 0x10) Mailbox Status Register */ + __IO uint32_t CAN_MDL; /**< \brief (CanMb Offset: 0x14) Mailbox Data Low Register */ + __IO uint32_t CAN_MDH; /**< \brief (CanMb Offset: 0x18) Mailbox Data High Register */ + __O uint32_t CAN_MCR; /**< \brief (CanMb Offset: 0x1C) Mailbox Control Register */ +} CanMb; +/** \brief Can hardware registers */ +#define CANMB_NUMBER 8 +typedef struct { + __IO uint32_t CAN_MR; /**< \brief (Can Offset: 0x0000) Mode Register */ + __O uint32_t CAN_IER; /**< \brief (Can Offset: 0x0004) Interrupt Enable Register */ + __O uint32_t CAN_IDR; /**< \brief (Can Offset: 0x0008) Interrupt Disable Register */ + __I uint32_t CAN_IMR; /**< \brief (Can Offset: 0x000C) Interrupt Mask Register */ + __I uint32_t CAN_SR; /**< \brief (Can Offset: 0x0010) Status Register */ + __IO uint32_t CAN_BR; /**< \brief (Can Offset: 0x0014) Baudrate Register */ + __I uint32_t CAN_TIM; /**< \brief (Can Offset: 0x0018) Timer Register */ + __I uint32_t CAN_TIMESTP; /**< \brief (Can Offset: 0x001C) Timestamp Register */ + __I uint32_t CAN_ECR; /**< \brief (Can Offset: 0x0020) Error Counter Register */ + __O uint32_t CAN_TCR; /**< \brief (Can Offset: 0x0024) Transfer Command Register */ + __O uint32_t CAN_ACR; /**< \brief (Can Offset: 0x0028) Abort Command Register */ + __I uint32_t Reserved1[46]; + __IO uint32_t CAN_WPMR; /**< \brief (Can Offset: 0x00E4) Write Protect Mode Register */ + __I uint32_t CAN_WPSR; /**< \brief (Can Offset: 0x00E8) Write Protect Status Register */ + __I uint32_t Reserved2[69]; + CanMb CAN_MB[CANMB_NUMBER]; /**< \brief (Can Offset: 0x200) MB = 0 .. 7 */ +} Can; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- CAN_MR : (CAN Offset: 0x0000) Mode Register -------- */ +#define CAN_MR_CANEN (0x1u << 0) /**< \brief (CAN_MR) CAN Controller Enable */ +#define CAN_MR_LPM (0x1u << 1) /**< \brief (CAN_MR) Disable/Enable Low Power Mode */ +#define CAN_MR_ABM (0x1u << 2) /**< \brief (CAN_MR) Disable/Enable Autobaud/Listen mode */ +#define CAN_MR_OVL (0x1u << 3) /**< \brief (CAN_MR) Disable/Enable Overload Frame */ +#define CAN_MR_TEOF (0x1u << 4) /**< \brief (CAN_MR) Timestamp messages at each end of Frame */ +#define CAN_MR_TTM (0x1u << 5) /**< \brief (CAN_MR) Disable/Enable Time Triggered Mode */ +#define CAN_MR_TIMFRZ (0x1u << 6) /**< \brief (CAN_MR) Enable Timer Freeze */ +#define CAN_MR_DRPT (0x1u << 7) /**< \brief (CAN_MR) Disable Repeat */ +/* -------- CAN_IER : (CAN Offset: 0x0004) Interrupt Enable Register -------- */ +#define CAN_IER_MB0 (0x1u << 0) /**< \brief (CAN_IER) Mailbox 0 Interrupt Enable */ +#define CAN_IER_MB1 (0x1u << 1) /**< \brief (CAN_IER) Mailbox 1 Interrupt Enable */ +#define CAN_IER_MB2 (0x1u << 2) /**< \brief (CAN_IER) Mailbox 2 Interrupt Enable */ +#define CAN_IER_MB3 (0x1u << 3) /**< \brief (CAN_IER) Mailbox 3 Interrupt Enable */ +#define CAN_IER_MB4 (0x1u << 4) /**< \brief (CAN_IER) Mailbox 4 Interrupt Enable */ +#define CAN_IER_MB5 (0x1u << 5) /**< \brief (CAN_IER) Mailbox 5 Interrupt Enable */ +#define CAN_IER_MB6 (0x1u << 6) /**< \brief (CAN_IER) Mailbox 6 Interrupt Enable */ +#define CAN_IER_MB7 (0x1u << 7) /**< \brief (CAN_IER) Mailbox 7 Interrupt Enable */ +#define CAN_IER_ERRA (0x1u << 16) /**< \brief (CAN_IER) Error Active Mode Interrupt Enable */ +#define CAN_IER_WARN (0x1u << 17) /**< \brief (CAN_IER) Warning Limit Interrupt Enable */ +#define CAN_IER_ERRP (0x1u << 18) /**< \brief (CAN_IER) Error Passive Mode Interrupt Enable */ +#define CAN_IER_BOFF (0x1u << 19) /**< \brief (CAN_IER) Bus Off Mode Interrupt Enable */ +#define CAN_IER_SLEEP (0x1u << 20) /**< \brief (CAN_IER) Sleep Interrupt Enable */ +#define CAN_IER_WAKEUP (0x1u << 21) /**< \brief (CAN_IER) Wakeup Interrupt Enable */ +#define CAN_IER_TOVF (0x1u << 22) /**< \brief (CAN_IER) Timer Overflow Interrupt Enable */ +#define CAN_IER_TSTP (0x1u << 23) /**< \brief (CAN_IER) TimeStamp Interrupt Enable */ +#define CAN_IER_CERR (0x1u << 24) /**< \brief (CAN_IER) CRC Error Interrupt Enable */ +#define CAN_IER_SERR (0x1u << 25) /**< \brief (CAN_IER) Stuffing Error Interrupt Enable */ +#define CAN_IER_AERR (0x1u << 26) /**< \brief (CAN_IER) Acknowledgment Error Interrupt Enable */ +#define CAN_IER_FERR (0x1u << 27) /**< \brief (CAN_IER) Form Error Interrupt Enable */ +#define CAN_IER_BERR (0x1u << 28) /**< \brief (CAN_IER) Bit Error Interrupt Enable */ +/* -------- CAN_IDR : (CAN Offset: 0x0008) Interrupt Disable Register -------- */ +#define CAN_IDR_MB0 (0x1u << 0) /**< \brief (CAN_IDR) Mailbox 0 Interrupt Disable */ +#define CAN_IDR_MB1 (0x1u << 1) /**< \brief (CAN_IDR) Mailbox 1 Interrupt Disable */ +#define CAN_IDR_MB2 (0x1u << 2) /**< \brief (CAN_IDR) Mailbox 2 Interrupt Disable */ +#define CAN_IDR_MB3 (0x1u << 3) /**< \brief (CAN_IDR) Mailbox 3 Interrupt Disable */ +#define CAN_IDR_MB4 (0x1u << 4) /**< \brief (CAN_IDR) Mailbox 4 Interrupt Disable */ +#define CAN_IDR_MB5 (0x1u << 5) /**< \brief (CAN_IDR) Mailbox 5 Interrupt Disable */ +#define CAN_IDR_MB6 (0x1u << 6) /**< \brief (CAN_IDR) Mailbox 6 Interrupt Disable */ +#define CAN_IDR_MB7 (0x1u << 7) /**< \brief (CAN_IDR) Mailbox 7 Interrupt Disable */ +#define CAN_IDR_ERRA (0x1u << 16) /**< \brief (CAN_IDR) Error Active Mode Interrupt Disable */ +#define CAN_IDR_WARN (0x1u << 17) /**< \brief (CAN_IDR) Warning Limit Interrupt Disable */ +#define CAN_IDR_ERRP (0x1u << 18) /**< \brief (CAN_IDR) Error Passive Mode Interrupt Disable */ +#define CAN_IDR_BOFF (0x1u << 19) /**< \brief (CAN_IDR) Bus Off Mode Interrupt Disable */ +#define CAN_IDR_SLEEP (0x1u << 20) /**< \brief (CAN_IDR) Sleep Interrupt Disable */ +#define CAN_IDR_WAKEUP (0x1u << 21) /**< \brief (CAN_IDR) Wakeup Interrupt Disable */ +#define CAN_IDR_TOVF (0x1u << 22) /**< \brief (CAN_IDR) Timer Overflow Interrupt */ +#define CAN_IDR_TSTP (0x1u << 23) /**< \brief (CAN_IDR) TimeStamp Interrupt Disable */ +#define CAN_IDR_CERR (0x1u << 24) /**< \brief (CAN_IDR) CRC Error Interrupt Disable */ +#define CAN_IDR_SERR (0x1u << 25) /**< \brief (CAN_IDR) Stuffing Error Interrupt Disable */ +#define CAN_IDR_AERR (0x1u << 26) /**< \brief (CAN_IDR) Acknowledgment Error Interrupt Disable */ +#define CAN_IDR_FERR (0x1u << 27) /**< \brief (CAN_IDR) Form Error Interrupt Disable */ +#define CAN_IDR_BERR (0x1u << 28) /**< \brief (CAN_IDR) Bit Error Interrupt Disable */ +/* -------- CAN_IMR : (CAN Offset: 0x000C) Interrupt Mask Register -------- */ +#define CAN_IMR_MB0 (0x1u << 0) /**< \brief (CAN_IMR) Mailbox 0 Interrupt Mask */ +#define CAN_IMR_MB1 (0x1u << 1) /**< \brief (CAN_IMR) Mailbox 1 Interrupt Mask */ +#define CAN_IMR_MB2 (0x1u << 2) /**< \brief (CAN_IMR) Mailbox 2 Interrupt Mask */ +#define CAN_IMR_MB3 (0x1u << 3) /**< \brief (CAN_IMR) Mailbox 3 Interrupt Mask */ +#define CAN_IMR_MB4 (0x1u << 4) /**< \brief (CAN_IMR) Mailbox 4 Interrupt Mask */ +#define CAN_IMR_MB5 (0x1u << 5) /**< \brief (CAN_IMR) Mailbox 5 Interrupt Mask */ +#define CAN_IMR_MB6 (0x1u << 6) /**< \brief (CAN_IMR) Mailbox 6 Interrupt Mask */ +#define CAN_IMR_MB7 (0x1u << 7) /**< \brief (CAN_IMR) Mailbox 7 Interrupt Mask */ +#define CAN_IMR_ERRA (0x1u << 16) /**< \brief (CAN_IMR) Error Active Mode Interrupt Mask */ +#define CAN_IMR_WARN (0x1u << 17) /**< \brief (CAN_IMR) Warning Limit Interrupt Mask */ +#define CAN_IMR_ERRP (0x1u << 18) /**< \brief (CAN_IMR) Error Passive Mode Interrupt Mask */ +#define CAN_IMR_BOFF (0x1u << 19) /**< \brief (CAN_IMR) Bus Off Mode Interrupt Mask */ +#define CAN_IMR_SLEEP (0x1u << 20) /**< \brief (CAN_IMR) Sleep Interrupt Mask */ +#define CAN_IMR_WAKEUP (0x1u << 21) /**< \brief (CAN_IMR) Wakeup Interrupt Mask */ +#define CAN_IMR_TOVF (0x1u << 22) /**< \brief (CAN_IMR) Timer Overflow Interrupt Mask */ +#define CAN_IMR_TSTP (0x1u << 23) /**< \brief (CAN_IMR) Timestamp Interrupt Mask */ +#define CAN_IMR_CERR (0x1u << 24) /**< \brief (CAN_IMR) CRC Error Interrupt Mask */ +#define CAN_IMR_SERR (0x1u << 25) /**< \brief (CAN_IMR) Stuffing Error Interrupt Mask */ +#define CAN_IMR_AERR (0x1u << 26) /**< \brief (CAN_IMR) Acknowledgment Error Interrupt Mask */ +#define CAN_IMR_FERR (0x1u << 27) /**< \brief (CAN_IMR) Form Error Interrupt Mask */ +#define CAN_IMR_BERR (0x1u << 28) /**< \brief (CAN_IMR) Bit Error Interrupt Mask */ +/* -------- CAN_SR : (CAN Offset: 0x0010) Status Register -------- */ +#define CAN_SR_MB0 (0x1u << 0) /**< \brief (CAN_SR) Mailbox 0 Event */ +#define CAN_SR_MB1 (0x1u << 1) /**< \brief (CAN_SR) Mailbox 1 Event */ +#define CAN_SR_MB2 (0x1u << 2) /**< \brief (CAN_SR) Mailbox 2 Event */ +#define CAN_SR_MB3 (0x1u << 3) /**< \brief (CAN_SR) Mailbox 3 Event */ +#define CAN_SR_MB4 (0x1u << 4) /**< \brief (CAN_SR) Mailbox 4 Event */ +#define CAN_SR_MB5 (0x1u << 5) /**< \brief (CAN_SR) Mailbox 5 Event */ +#define CAN_SR_MB6 (0x1u << 6) /**< \brief (CAN_SR) Mailbox 6 Event */ +#define CAN_SR_MB7 (0x1u << 7) /**< \brief (CAN_SR) Mailbox 7 Event */ +#define CAN_SR_ERRA (0x1u << 16) /**< \brief (CAN_SR) Error Active Mode */ +#define CAN_SR_WARN (0x1u << 17) /**< \brief (CAN_SR) Warning Limit */ +#define CAN_SR_ERRP (0x1u << 18) /**< \brief (CAN_SR) Error Passive Mode */ +#define CAN_SR_BOFF (0x1u << 19) /**< \brief (CAN_SR) Bus Off Mode */ +#define CAN_SR_SLEEP (0x1u << 20) /**< \brief (CAN_SR) CAN controller in Low power Mode */ +#define CAN_SR_WAKEUP (0x1u << 21) /**< \brief (CAN_SR) CAN controller is not in Low power Mode */ +#define CAN_SR_TOVF (0x1u << 22) /**< \brief (CAN_SR) Timer Overflow */ +#define CAN_SR_TSTP (0x1u << 23) /**< \brief (CAN_SR) Timestamp */ +#define CAN_SR_CERR (0x1u << 24) /**< \brief (CAN_SR) Mailbox CRC Error */ +#define CAN_SR_SERR (0x1u << 25) /**< \brief (CAN_SR) Mailbox Stuffing Error */ +#define CAN_SR_AERR (0x1u << 26) /**< \brief (CAN_SR) Acknowledgment Error */ +#define CAN_SR_FERR (0x1u << 27) /**< \brief (CAN_SR) Form Error */ +#define CAN_SR_BERR (0x1u << 28) /**< \brief (CAN_SR) Bit Error */ +#define CAN_SR_RBSY (0x1u << 29) /**< \brief (CAN_SR) Receiver busy */ +#define CAN_SR_TBSY (0x1u << 30) /**< \brief (CAN_SR) Transmitter busy */ +#define CAN_SR_OVLSY (0x1u << 31) /**< \brief (CAN_SR) Overload busy */ +/* -------- CAN_BR : (CAN Offset: 0x0014) Baudrate Register -------- */ +#define CAN_BR_PHASE2_Pos 0 +#define CAN_BR_PHASE2_Msk (0x7u << CAN_BR_PHASE2_Pos) /**< \brief (CAN_BR) Phase 2 segment */ +#define CAN_BR_PHASE2(value) ((CAN_BR_PHASE2_Msk & ((value) << CAN_BR_PHASE2_Pos))) +#define CAN_BR_PHASE1_Pos 4 +#define CAN_BR_PHASE1_Msk (0x7u << CAN_BR_PHASE1_Pos) /**< \brief (CAN_BR) Phase 1 segment */ +#define CAN_BR_PHASE1(value) ((CAN_BR_PHASE1_Msk & ((value) << CAN_BR_PHASE1_Pos))) +#define CAN_BR_PROPAG_Pos 8 +#define CAN_BR_PROPAG_Msk (0x7u << CAN_BR_PROPAG_Pos) /**< \brief (CAN_BR) Programming time segment */ +#define CAN_BR_PROPAG(value) ((CAN_BR_PROPAG_Msk & ((value) << CAN_BR_PROPAG_Pos))) +#define CAN_BR_SJW_Pos 12 +#define CAN_BR_SJW_Msk (0x3u << CAN_BR_SJW_Pos) /**< \brief (CAN_BR) Re-synchronization jump width */ +#define CAN_BR_SJW(value) ((CAN_BR_SJW_Msk & ((value) << CAN_BR_SJW_Pos))) +#define CAN_BR_BRP_Pos 16 +#define CAN_BR_BRP_Msk (0x7fu << CAN_BR_BRP_Pos) /**< \brief (CAN_BR) Baudrate Prescaler. */ +#define CAN_BR_BRP(value) ((CAN_BR_BRP_Msk & ((value) << CAN_BR_BRP_Pos))) +#define CAN_BR_SMP (0x1u << 24) /**< \brief (CAN_BR) Sampling Mode */ +#define CAN_BR_SMP_ONCE (0x0u << 24) /**< \brief (CAN_BR) The incoming bit stream is sampled once at sample point. */ +#define CAN_BR_SMP_THREE (0x1u << 24) /**< \brief (CAN_BR) The incoming bit stream is sampled three times with a period of a peripheral clock, centered on sample point. */ +/* -------- CAN_TIM : (CAN Offset: 0x0018) Timer Register -------- */ +#define CAN_TIM_TIMER_Pos 0 +#define CAN_TIM_TIMER_Msk (0xffffu << CAN_TIM_TIMER_Pos) /**< \brief (CAN_TIM) Timer */ +/* -------- CAN_TIMESTP : (CAN Offset: 0x001C) Timestamp Register -------- */ +#define CAN_TIMESTP_MTIMESTAMP_Pos 0 +#define CAN_TIMESTP_MTIMESTAMP_Msk (0xffffu << CAN_TIMESTP_MTIMESTAMP_Pos) /**< \brief (CAN_TIMESTP) Timestamp */ +/* -------- CAN_ECR : (CAN Offset: 0x0020) Error Counter Register -------- */ +#define CAN_ECR_REC_Pos 0 +#define CAN_ECR_REC_Msk (0xffu << CAN_ECR_REC_Pos) /**< \brief (CAN_ECR) Receive Error Counter */ +#define CAN_ECR_TEC_Pos 16 +#define CAN_ECR_TEC_Msk (0x1ffu << CAN_ECR_TEC_Pos) /**< \brief (CAN_ECR) Transmit Error Counter */ +/* -------- CAN_TCR : (CAN Offset: 0x0024) Transfer Command Register -------- */ +#define CAN_TCR_MB0 (0x1u << 0) /**< \brief (CAN_TCR) Transfer Request for Mailbox 0 */ +#define CAN_TCR_MB1 (0x1u << 1) /**< \brief (CAN_TCR) Transfer Request for Mailbox 1 */ +#define CAN_TCR_MB2 (0x1u << 2) /**< \brief (CAN_TCR) Transfer Request for Mailbox 2 */ +#define CAN_TCR_MB3 (0x1u << 3) /**< \brief (CAN_TCR) Transfer Request for Mailbox 3 */ +#define CAN_TCR_MB4 (0x1u << 4) /**< \brief (CAN_TCR) Transfer Request for Mailbox 4 */ +#define CAN_TCR_MB5 (0x1u << 5) /**< \brief (CAN_TCR) Transfer Request for Mailbox 5 */ +#define CAN_TCR_MB6 (0x1u << 6) /**< \brief (CAN_TCR) Transfer Request for Mailbox 6 */ +#define CAN_TCR_MB7 (0x1u << 7) /**< \brief (CAN_TCR) Transfer Request for Mailbox 7 */ +#define CAN_TCR_TIMRST (0x1u << 31) /**< \brief (CAN_TCR) Timer Reset */ +/* -------- CAN_ACR : (CAN Offset: 0x0028) Abort Command Register -------- */ +#define CAN_ACR_MB0 (0x1u << 0) /**< \brief (CAN_ACR) Abort Request for Mailbox 0 */ +#define CAN_ACR_MB1 (0x1u << 1) /**< \brief (CAN_ACR) Abort Request for Mailbox 1 */ +#define CAN_ACR_MB2 (0x1u << 2) /**< \brief (CAN_ACR) Abort Request for Mailbox 2 */ +#define CAN_ACR_MB3 (0x1u << 3) /**< \brief (CAN_ACR) Abort Request for Mailbox 3 */ +#define CAN_ACR_MB4 (0x1u << 4) /**< \brief (CAN_ACR) Abort Request for Mailbox 4 */ +#define CAN_ACR_MB5 (0x1u << 5) /**< \brief (CAN_ACR) Abort Request for Mailbox 5 */ +#define CAN_ACR_MB6 (0x1u << 6) /**< \brief (CAN_ACR) Abort Request for Mailbox 6 */ +#define CAN_ACR_MB7 (0x1u << 7) /**< \brief (CAN_ACR) Abort Request for Mailbox 7 */ +/* -------- CAN_WPMR : (CAN Offset: 0x00E4) Write Protect Mode Register -------- */ +#define CAN_WPMR_WPEN (0x1u << 0) /**< \brief (CAN_WPMR) Write Protection Enable */ +#define CAN_WPMR_WPKEY_Pos 8 +#define CAN_WPMR_WPKEY_Msk (0xffffffu << CAN_WPMR_WPKEY_Pos) /**< \brief (CAN_WPMR) SPI Write Protection Key Password. */ +#define CAN_WPMR_WPKEY_PASSWD (0x43414Eu << 8) /**< \brief (CAN_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0 */ +/* -------- CAN_WPSR : (CAN Offset: 0x00E8) Write Protect Status Register -------- */ +#define CAN_WPSR_WPVS (0x1u << 0) /**< \brief (CAN_WPSR) Write Protection Violation Status */ +#define CAN_WPSR_WPVSRC_Pos 8 +#define CAN_WPSR_WPVSRC_Msk (0xffu << CAN_WPSR_WPVSRC_Pos) /**< \brief (CAN_WPSR) Write Protection Violation Source */ +/* -------- CAN_MMR : (CAN Offset: N/A) Mailbox Mode Register -------- */ +#define CAN_MMR_MTIMEMARK_Pos 0 +#define CAN_MMR_MTIMEMARK_Msk (0xffffu << CAN_MMR_MTIMEMARK_Pos) /**< \brief (CAN_MMR) Mailbox Timemark */ +#define CAN_MMR_MTIMEMARK(value) ((CAN_MMR_MTIMEMARK_Msk & ((value) << CAN_MMR_MTIMEMARK_Pos))) +#define CAN_MMR_PRIOR_Pos 16 +#define CAN_MMR_PRIOR_Msk (0xfu << CAN_MMR_PRIOR_Pos) /**< \brief (CAN_MMR) Mailbox Priority */ +#define CAN_MMR_PRIOR(value) ((CAN_MMR_PRIOR_Msk & ((value) << CAN_MMR_PRIOR_Pos))) +#define CAN_MMR_MOT_Pos 24 +#define CAN_MMR_MOT_Msk (0x7u << CAN_MMR_MOT_Pos) /**< \brief (CAN_MMR) Mailbox Object Type */ +#define CAN_MMR_MOT_MB_DISABLED (0x0u << 24) /**< \brief (CAN_MMR) Mailbox is disabled. This prevents receiving or transmitting any messages with this mailbox. */ +#define CAN_MMR_MOT_MB_RX (0x1u << 24) /**< \brief (CAN_MMR) Reception Mailbox. Mailbox is configured for reception. If a message is received while the mailbox data register is full, it is discarded. */ +#define CAN_MMR_MOT_MB_RX_OVERWRITE (0x2u << 24) /**< \brief (CAN_MMR) Reception mailbox with overwrite. Mailbox is configured for reception. If a message is received while the mailbox is full, it overwrites the previous message. */ +#define CAN_MMR_MOT_MB_TX (0x3u << 24) /**< \brief (CAN_MMR) Transmit mailbox. Mailbox is configured for transmission. */ +#define CAN_MMR_MOT_MB_CONSUMER (0x4u << 24) /**< \brief (CAN_MMR) Consumer Mailbox. Mailbox is configured in reception but behaves as a Transmit Mailbox, i.e., it sends a remote frame and waits for an answer. */ +#define CAN_MMR_MOT_MB_PRODUCER (0x5u << 24) /**< \brief (CAN_MMR) Producer Mailbox. Mailbox is configured in transmission but also behaves like a reception mailbox, i.e., it waits to receive a Remote Frame before sending its contents. */ +/* -------- CAN_MAM : (CAN Offset: N/A) Mailbox Acceptance Mask Register -------- */ +#define CAN_MAM_MIDvB_Pos 0 +#define CAN_MAM_MIDvB_Msk (0x3ffffu << CAN_MAM_MIDvB_Pos) /**< \brief (CAN_MAM) Complementary bits for identifier in extended frame mode */ +#define CAN_MAM_MIDvB(value) ((CAN_MAM_MIDvB_Msk & ((value) << CAN_MAM_MIDvB_Pos))) +#define CAN_MAM_MIDvA_Pos 18 +#define CAN_MAM_MIDvA_Msk (0x7ffu << CAN_MAM_MIDvA_Pos) /**< \brief (CAN_MAM) Identifier for standard frame mode */ +#define CAN_MAM_MIDvA(value) ((CAN_MAM_MIDvA_Msk & ((value) << CAN_MAM_MIDvA_Pos))) +#define CAN_MAM_MIDE (0x1u << 29) /**< \brief (CAN_MAM) Identifier Version */ +/* -------- CAN_MID : (CAN Offset: N/A) Mailbox ID Register -------- */ +#define CAN_MID_MIDvB_Pos 0 +#define CAN_MID_MIDvB_Msk (0x3ffffu << CAN_MID_MIDvB_Pos) /**< \brief (CAN_MID) Complementary bits for identifier in extended frame mode */ +#define CAN_MID_MIDvB(value) ((CAN_MID_MIDvB_Msk & ((value) << CAN_MID_MIDvB_Pos))) +#define CAN_MID_MIDvA_Pos 18 +#define CAN_MID_MIDvA_Msk (0x7ffu << CAN_MID_MIDvA_Pos) /**< \brief (CAN_MID) Identifier for standard frame mode */ +#define CAN_MID_MIDvA(value) ((CAN_MID_MIDvA_Msk & ((value) << CAN_MID_MIDvA_Pos))) +#define CAN_MID_MIDE (0x1u << 29) /**< \brief (CAN_MID) Identifier Version */ +/* -------- CAN_MFID : (CAN Offset: N/A) Mailbox Family ID Register -------- */ +#define CAN_MFID_MFID_Pos 0 +#define CAN_MFID_MFID_Msk (0x1fffffffu << CAN_MFID_MFID_Pos) /**< \brief (CAN_MFID) Family ID */ +/* -------- CAN_MSR : (CAN Offset: N/A) Mailbox Status Register -------- */ +#define CAN_MSR_MTIMESTAMP_Pos 0 +#define CAN_MSR_MTIMESTAMP_Msk (0xffffu << CAN_MSR_MTIMESTAMP_Pos) /**< \brief (CAN_MSR) Timer value */ +#define CAN_MSR_MDLC_Pos 16 +#define CAN_MSR_MDLC_Msk (0xfu << CAN_MSR_MDLC_Pos) /**< \brief (CAN_MSR) Mailbox Data Length Code */ +#define CAN_MSR_MRTR (0x1u << 20) /**< \brief (CAN_MSR) Mailbox Remote Transmission Request */ +#define CAN_MSR_MABT (0x1u << 22) /**< \brief (CAN_MSR) Mailbox Message Abort */ +#define CAN_MSR_MRDY (0x1u << 23) /**< \brief (CAN_MSR) Mailbox Ready */ +#define CAN_MSR_MMI (0x1u << 24) /**< \brief (CAN_MSR) Mailbox Message Ignored */ +/* -------- CAN_MDL : (CAN Offset: N/A) Mailbox Data Low Register -------- */ +#define CAN_MDL_MDL_Pos 0 +#define CAN_MDL_MDL_Msk (0xffffffffu << CAN_MDL_MDL_Pos) /**< \brief (CAN_MDL) Message Data Low Value */ +#define CAN_MDL_MDL(value) ((CAN_MDL_MDL_Msk & ((value) << CAN_MDL_MDL_Pos))) +/* -------- CAN_MDH : (CAN Offset: N/A) Mailbox Data High Register -------- */ +#define CAN_MDH_MDH_Pos 0 +#define CAN_MDH_MDH_Msk (0xffffffffu << CAN_MDH_MDH_Pos) /**< \brief (CAN_MDH) Message Data High Value */ +#define CAN_MDH_MDH(value) ((CAN_MDH_MDH_Msk & ((value) << CAN_MDH_MDH_Pos))) +/* -------- CAN_MCR : (CAN Offset: N/A) Mailbox Control Register -------- */ +#define CAN_MCR_MDLC_Pos 16 +#define CAN_MCR_MDLC_Msk (0xfu << CAN_MCR_MDLC_Pos) /**< \brief (CAN_MCR) Mailbox Data Length Code */ +#define CAN_MCR_MDLC(value) ((CAN_MCR_MDLC_Msk & ((value) << CAN_MCR_MDLC_Pos))) +#define CAN_MCR_MRTR (0x1u << 20) /**< \brief (CAN_MCR) Mailbox Remote Transmission Request */ +#define CAN_MCR_MACR (0x1u << 22) /**< \brief (CAN_MCR) Abort Request for Mailbox x */ +#define CAN_MCR_MTCR (0x1u << 23) /**< \brief (CAN_MCR) Mailbox Transfer Command */ + +/*@}*/ + + +#endif /* _SAM4E_CAN_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/chipid.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/chipid.h new file mode 100644 index 0000000..507a5d7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/chipid.h @@ -0,0 +1,133 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CHIPID_COMPONENT_ +#define _SAM4E_CHIPID_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Chip Identifier */ +/* ============================================================================= */ +/** \addtogroup SAM4E_CHIPID Chip Identifier */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Chipid hardware registers */ +typedef struct { + __I uint32_t CHIPID_CIDR; /**< \brief (Chipid Offset: 0x0) Chip ID Register */ + __I uint32_t CHIPID_EXID; /**< \brief (Chipid Offset: 0x4) Chip ID Extension Register */ +} Chipid; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- CHIPID_CIDR : (CHIPID Offset: 0x0) Chip ID Register -------- */ +#define CHIPID_CIDR_VERSION_Pos 0 +#define CHIPID_CIDR_VERSION_Msk (0x1fu << CHIPID_CIDR_VERSION_Pos) /**< \brief (CHIPID_CIDR) Version of the Device */ +#define CHIPID_CIDR_EPROC_Pos 5 +#define CHIPID_CIDR_EPROC_Msk (0x7u << CHIPID_CIDR_EPROC_Pos) /**< \brief (CHIPID_CIDR) Embedded Processor */ +#define CHIPID_CIDR_EPROC_ARM946ES (0x1u << 5) /**< \brief (CHIPID_CIDR) ARM946ES */ +#define CHIPID_CIDR_EPROC_ARM7TDMI (0x2u << 5) /**< \brief (CHIPID_CIDR) ARM7TDMI */ +#define CHIPID_CIDR_EPROC_CM3 (0x3u << 5) /**< \brief (CHIPID_CIDR) Cortex-M3 */ +#define CHIPID_CIDR_EPROC_ARM920T (0x4u << 5) /**< \brief (CHIPID_CIDR) ARM920T */ +#define CHIPID_CIDR_EPROC_ARM926EJS (0x5u << 5) /**< \brief (CHIPID_CIDR) ARM926EJS */ +#define CHIPID_CIDR_EPROC_CA5 (0x6u << 5) /**< \brief (CHIPID_CIDR) Cortex-A5 */ +#define CHIPID_CIDR_EPROC_CM4 (0x7u << 5) /**< \brief (CHIPID_CIDR) Cortex-M4 */ +#define CHIPID_CIDR_NVPSIZ_Pos 8 +#define CHIPID_CIDR_NVPSIZ_Msk (0xfu << CHIPID_CIDR_NVPSIZ_Pos) /**< \brief (CHIPID_CIDR) Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ_NONE (0x0u << 8) /**< \brief (CHIPID_CIDR) None */ +#define CHIPID_CIDR_NVPSIZ_8K (0x1u << 8) /**< \brief (CHIPID_CIDR) 8 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_16K (0x2u << 8) /**< \brief (CHIPID_CIDR) 16 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_32K (0x3u << 8) /**< \brief (CHIPID_CIDR) 32 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_64K (0x5u << 8) /**< \brief (CHIPID_CIDR) 64 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_128K (0x7u << 8) /**< \brief (CHIPID_CIDR) 128 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_256K (0x9u << 8) /**< \brief (CHIPID_CIDR) 256 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_512K (0xAu << 8) /**< \brief (CHIPID_CIDR) 512 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_1024K (0xCu << 8) /**< \brief (CHIPID_CIDR) 1024 Kbytes */ +#define CHIPID_CIDR_NVPSIZ_2048K (0xEu << 8) /**< \brief (CHIPID_CIDR) 2048 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_Pos 12 +#define CHIPID_CIDR_NVPSIZ2_Msk (0xfu << CHIPID_CIDR_NVPSIZ2_Pos) /**< \brief (CHIPID_CIDR) Second Nonvolatile Program Memory Size */ +#define CHIPID_CIDR_NVPSIZ2_NONE (0x0u << 12) /**< \brief (CHIPID_CIDR) None */ +#define CHIPID_CIDR_NVPSIZ2_8K (0x1u << 12) /**< \brief (CHIPID_CIDR) 8 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_16K (0x2u << 12) /**< \brief (CHIPID_CIDR) 16 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_32K (0x3u << 12) /**< \brief (CHIPID_CIDR) 32 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_64K (0x5u << 12) /**< \brief (CHIPID_CIDR) 64 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_128K (0x7u << 12) /**< \brief (CHIPID_CIDR) 128 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_256K (0x9u << 12) /**< \brief (CHIPID_CIDR) 256 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_512K (0xAu << 12) /**< \brief (CHIPID_CIDR) 512 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_1024K (0xCu << 12) /**< \brief (CHIPID_CIDR) 1024 Kbytes */ +#define CHIPID_CIDR_NVPSIZ2_2048K (0xEu << 12) /**< \brief (CHIPID_CIDR) 2048 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_Pos 16 +#define CHIPID_CIDR_SRAMSIZ_Msk (0xfu << CHIPID_CIDR_SRAMSIZ_Pos) /**< \brief (CHIPID_CIDR) Internal SRAM Size */ +#define CHIPID_CIDR_SRAMSIZ_48K (0x0u << 16) /**< \brief (CHIPID_CIDR) 48 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_192K (0x1u << 16) /**< \brief (CHIPID_CIDR) 192 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_2K (0x2u << 16) /**< \brief (CHIPID_CIDR) 2 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_6K (0x3u << 16) /**< \brief (CHIPID_CIDR) 6 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_24K (0x4u << 16) /**< \brief (CHIPID_CIDR) 24 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_4K (0x5u << 16) /**< \brief (CHIPID_CIDR) 4 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_80K (0x6u << 16) /**< \brief (CHIPID_CIDR) 80 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_160K (0x7u << 16) /**< \brief (CHIPID_CIDR) 160 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_8K (0x8u << 16) /**< \brief (CHIPID_CIDR) 8 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_16K (0x9u << 16) /**< \brief (CHIPID_CIDR) 16 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_32K (0xAu << 16) /**< \brief (CHIPID_CIDR) 32 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_64K (0xBu << 16) /**< \brief (CHIPID_CIDR) 64 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_128K (0xCu << 16) /**< \brief (CHIPID_CIDR) 128 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_256K (0xDu << 16) /**< \brief (CHIPID_CIDR) 256 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_96K (0xEu << 16) /**< \brief (CHIPID_CIDR) 96 Kbytes */ +#define CHIPID_CIDR_SRAMSIZ_512K (0xFu << 16) /**< \brief (CHIPID_CIDR) 512 Kbytes */ +#define CHIPID_CIDR_ARCH_Pos 20 +#define CHIPID_CIDR_ARCH_Msk (0xffu << CHIPID_CIDR_ARCH_Pos) /**< \brief (CHIPID_CIDR) Architecture Identifier */ +#define CHIPID_CIDR_ARCH_SAM4E (0x3Cu << 20) /**< \brief (CHIPID_CIDR) SAM4E Series */ +#define CHIPID_CIDR_NVPTYP_Pos 28 +#define CHIPID_CIDR_NVPTYP_Msk (0x7u << CHIPID_CIDR_NVPTYP_Pos) /**< \brief (CHIPID_CIDR) Nonvolatile Program Memory Type */ +#define CHIPID_CIDR_NVPTYP_ROM (0x0u << 28) /**< \brief (CHIPID_CIDR) ROM */ +#define CHIPID_CIDR_NVPTYP_ROMLESS (0x1u << 28) /**< \brief (CHIPID_CIDR) ROMless or on-chip Flash */ +#define CHIPID_CIDR_NVPTYP_FLASH (0x2u << 28) /**< \brief (CHIPID_CIDR) Embedded Flash Memory */ +#define CHIPID_CIDR_NVPTYP_ROM_FLASH (0x3u << 28) /**< \brief (CHIPID_CIDR) ROM and Embedded Flash Memory- NVPSIZ is ROM size- NVPSIZ2 is Flash size */ +#define CHIPID_CIDR_NVPTYP_SRAM (0x4u << 28) /**< \brief (CHIPID_CIDR) SRAM emulating ROM */ +#define CHIPID_CIDR_EXT (0x1u << 31) /**< \brief (CHIPID_CIDR) Extension Flag */ +/* -------- CHIPID_EXID : (CHIPID Offset: 0x4) Chip ID Extension Register -------- */ +#define CHIPID_EXID_EXID_Pos 0 +#define CHIPID_EXID_EXID_Msk (0xffffffffu << CHIPID_EXID_EXID_Pos) /**< \brief (CHIPID_EXID) Chip ID Extension */ + +/*@}*/ + + +#endif /* _SAM4E_CHIPID_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/cmcc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/cmcc.h new file mode 100644 index 0000000..5a2e674 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/cmcc.h @@ -0,0 +1,130 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CMCC_COMPONENT_ +#define _SAM4E_CMCC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Cortex M Cache Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_CMCC Cortex M Cache Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Cmcc hardware registers */ +typedef struct { + __I uint32_t CMCC_TYPE; /**< \brief (Cmcc Offset: 0x00) Cache Type Register */ + __IO uint32_t CMCC_CFG; /**< \brief (Cmcc Offset: 0x04) Cache Configuration Register */ + __O uint32_t CMCC_CTRL; /**< \brief (Cmcc Offset: 0x08) Cache Control Register */ + __I uint32_t CMCC_SR; /**< \brief (Cmcc Offset: 0x0C) Cache Status Register */ + __I uint32_t Reserved1[4]; + __O uint32_t CMCC_MAINT0; /**< \brief (Cmcc Offset: 0x20) Cache Maintenance Register 0 */ + __O uint32_t CMCC_MAINT1; /**< \brief (Cmcc Offset: 0x24) Cache Maintenance Register 1 */ + __IO uint32_t CMCC_MCFG; /**< \brief (Cmcc Offset: 0x28) Cache Monitor Configuration Register */ + __IO uint32_t CMCC_MEN; /**< \brief (Cmcc Offset: 0x2C) Cache Monitor Enable Register */ + __O uint32_t CMCC_MCTRL; /**< \brief (Cmcc Offset: 0x30) Cache Monitor Control Register */ + __I uint32_t CMCC_MSR; /**< \brief (Cmcc Offset: 0x34) Cache Monitor Status Register */ +} Cmcc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- CMCC_TYPE : (CMCC Offset: 0x00) Cache Type Register -------- */ +#define CMCC_TYPE_AP (0x1u << 0) /**< \brief (CMCC_TYPE) Access Port Access Allowed */ +#define CMCC_TYPE_GCLK (0x1u << 1) /**< \brief (CMCC_TYPE) Dynamic Clock Gating Supported */ +#define CMCC_TYPE_RANDP (0x1u << 2) /**< \brief (CMCC_TYPE) Random Selection Policy Supported */ +#define CMCC_TYPE_LRUP (0x1u << 3) /**< \brief (CMCC_TYPE) Least Recently Used Policy Supported */ +#define CMCC_TYPE_RRP (0x1u << 4) /**< \brief (CMCC_TYPE) Random Selection Policy Supported */ +#define CMCC_TYPE_WAYNUM_Pos 5 +#define CMCC_TYPE_WAYNUM_Msk (0x3u << CMCC_TYPE_WAYNUM_Pos) /**< \brief (CMCC_TYPE) Number of Way */ +#define CMCC_TYPE_WAYNUM_DMAPPED (0x0u << 5) /**< \brief (CMCC_TYPE) Direct Mapped Cache */ +#define CMCC_TYPE_WAYNUM_ARCH2WAY (0x1u << 5) /**< \brief (CMCC_TYPE) 2-WAY set associative */ +#define CMCC_TYPE_WAYNUM_ARCH4WAY (0x2u << 5) /**< \brief (CMCC_TYPE) 4-WAY set associative */ +#define CMCC_TYPE_WAYNUM_ARCH8WAY (0x3u << 5) /**< \brief (CMCC_TYPE) 8-WAY set associative */ +#define CMCC_TYPE_LCKDOWN (0x1u << 7) /**< \brief (CMCC_TYPE) Lock Down Supported */ +#define CMCC_TYPE_CSIZE_Pos 8 +#define CMCC_TYPE_CSIZE_Msk (0x7u << CMCC_TYPE_CSIZE_Pos) /**< \brief (CMCC_TYPE) Cache Size */ +#define CMCC_TYPE_CSIZE_CSIZE_1KB (0x0u << 8) /**< \brief (CMCC_TYPE) Cache Size 1 Kbytes */ +#define CMCC_TYPE_CSIZE_CSIZE_2KB (0x1u << 8) /**< \brief (CMCC_TYPE) Cache Size 2 Kbytes */ +#define CMCC_TYPE_CSIZE_CSIZE_4KB (0x2u << 8) /**< \brief (CMCC_TYPE) Cache Size 4 Kbytes */ +#define CMCC_TYPE_CSIZE_CSIZE_8KB (0x3u << 8) /**< \brief (CMCC_TYPE) Cache Size 8 Kbytes */ +#define CMCC_TYPE_CLSIZE_Pos 11 +#define CMCC_TYPE_CLSIZE_Msk (0x7u << CMCC_TYPE_CLSIZE_Pos) /**< \brief (CMCC_TYPE) Cache Size */ +#define CMCC_TYPE_CLSIZE_CLSIZE_1KB (0x0u << 11) /**< \brief (CMCC_TYPE) 4 Bytes */ +#define CMCC_TYPE_CLSIZE_CLSIZE_2KB (0x1u << 11) /**< \brief (CMCC_TYPE) 8 Bytes */ +#define CMCC_TYPE_CLSIZE_CLSIZE_4KB (0x2u << 11) /**< \brief (CMCC_TYPE) 16 Bytes */ +#define CMCC_TYPE_CLSIZE_CLSIZE_8KB (0x3u << 11) /**< \brief (CMCC_TYPE) 32 Bytes */ +/* -------- CMCC_CFG : (CMCC Offset: 0x04) Cache Configuration Register -------- */ +#define CMCC_CFG_GCLKDIS (0x1u << 0) /**< \brief (CMCC_CFG) Disable Clock Gating */ +/* -------- CMCC_CTRL : (CMCC Offset: 0x08) Cache Control Register -------- */ +#define CMCC_CTRL_CEN (0x1u << 0) /**< \brief (CMCC_CTRL) Cache Controller Enable */ +/* -------- CMCC_SR : (CMCC Offset: 0x0C) Cache Status Register -------- */ +#define CMCC_SR_CSTS (0x1u << 0) /**< \brief (CMCC_SR) Cache Controller Status */ +/* -------- CMCC_MAINT0 : (CMCC Offset: 0x20) Cache Maintenance Register 0 -------- */ +#define CMCC_MAINT0_INVALL (0x1u << 0) /**< \brief (CMCC_MAINT0) Cache Controller Invalidate All */ +/* -------- CMCC_MAINT1 : (CMCC Offset: 0x24) Cache Maintenance Register 1 -------- */ +#define CMCC_MAINT1_INDEX_Pos 4 +#define CMCC_MAINT1_INDEX_Msk (0x1fu << CMCC_MAINT1_INDEX_Pos) /**< \brief (CMCC_MAINT1) Invalidate Index */ +#define CMCC_MAINT1_INDEX(value) ((CMCC_MAINT1_INDEX_Msk & ((value) << CMCC_MAINT1_INDEX_Pos))) +#define CMCC_MAINT1_WAY_Pos 30 +#define CMCC_MAINT1_WAY_Msk (0x3u << CMCC_MAINT1_WAY_Pos) /**< \brief (CMCC_MAINT1) Invalidate Way */ +#define CMCC_MAINT1_WAY_WAY0 (0x0u << 30) /**< \brief (CMCC_MAINT1) Way 0 is selection for index invalidation */ +#define CMCC_MAINT1_WAY_WAY1 (0x1u << 30) /**< \brief (CMCC_MAINT1) Way 1 is selection for index invalidation */ +#define CMCC_MAINT1_WAY_WAY2 (0x2u << 30) /**< \brief (CMCC_MAINT1) Way 2 is selection for index invalidation */ +#define CMCC_MAINT1_WAY_WAY3 (0x3u << 30) /**< \brief (CMCC_MAINT1) Way 3 is selection for index invalidation */ +/* -------- CMCC_MCFG : (CMCC Offset: 0x28) Cache Monitor Configuration Register -------- */ +#define CMCC_MCFG_MODE_Pos 0 +#define CMCC_MCFG_MODE_Msk (0x3u << CMCC_MCFG_MODE_Pos) /**< \brief (CMCC_MCFG) Cache Controller Monitor Counter Mode */ +#define CMCC_MCFG_MODE_CYCLE_COUNT (0x0u << 0) /**< \brief (CMCC_MCFG) Cycle counter */ +#define CMCC_MCFG_MODE_IHIT_COUNT (0x1u << 0) /**< \brief (CMCC_MCFG) Instruction hit counter */ +#define CMCC_MCFG_MODE_DHIT_COUNT (0x2u << 0) /**< \brief (CMCC_MCFG) Data hit counter */ +/* -------- CMCC_MEN : (CMCC Offset: 0x2C) Cache Monitor Enable Register -------- */ +#define CMCC_MEN_MENABLE (0x1u << 0) /**< \brief (CMCC_MEN) Cache Controller Monitor Enable */ +/* -------- CMCC_MCTRL : (CMCC Offset: 0x30) Cache Monitor Control Register -------- */ +#define CMCC_MCTRL_SWRST (0x1u << 0) /**< \brief (CMCC_MCTRL) Monitor */ +/* -------- CMCC_MSR : (CMCC Offset: 0x34) Cache Monitor Status Register -------- */ +#define CMCC_MSR_EVENT_CNT_Pos 0 +#define CMCC_MSR_EVENT_CNT_Msk (0xffffffffu << CMCC_MSR_EVENT_CNT_Pos) /**< \brief (CMCC_MSR) Monitor Event Counter */ + +/*@}*/ + + +#endif /* _SAM4E_CMCC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dacc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dacc.h new file mode 100644 index 0000000..1d7e025 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dacc.h @@ -0,0 +1,264 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_DACC_COMPONENT_ +#define _SAM4E_DACC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Digital-to-Analog Converter Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_DACC Digital-to-Analog Converter Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Dacc hardware registers */ +typedef struct { + __O uint32_t DACC_CR; /**< \brief (Dacc Offset: 0x00) Control Register */ + __IO uint32_t DACC_MR; /**< \brief (Dacc Offset: 0x04) Mode Register */ + __I uint32_t Reserved1[2]; + __O uint32_t DACC_CHER; /**< \brief (Dacc Offset: 0x10) Channel Enable Register */ + __O uint32_t DACC_CHDR; /**< \brief (Dacc Offset: 0x14) Channel Disable Register */ + __I uint32_t DACC_CHSR; /**< \brief (Dacc Offset: 0x18) Channel Status Register */ + __I uint32_t Reserved2[1]; + __O uint32_t DACC_CDR; /**< \brief (Dacc Offset: 0x20) Conversion Data Register */ + __O uint32_t DACC_IER; /**< \brief (Dacc Offset: 0x24) Interrupt Enable Register */ + __O uint32_t DACC_IDR; /**< \brief (Dacc Offset: 0x28) Interrupt Disable Register */ + __I uint32_t DACC_IMR; /**< \brief (Dacc Offset: 0x2C) Interrupt Mask Register */ + __I uint32_t DACC_ISR; /**< \brief (Dacc Offset: 0x30) Interrupt Status Register */ + __I uint32_t Reserved3[24]; + __IO uint32_t DACC_ACR; /**< \brief (Dacc Offset: 0x94) Analog Current Register */ + __I uint32_t Reserved4[19]; + __IO uint32_t DACC_WPMR; /**< \brief (Dacc Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t DACC_WPSR; /**< \brief (Dacc Offset: 0xE8) Write Protection Status Register */ + __I uint32_t Reserved5[7]; + __IO uint32_t DACC_TPR; /**< \brief (Dacc Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t DACC_TCR; /**< \brief (Dacc Offset: 0x10C) Transmit Counter Register */ + __I uint32_t Reserved6[2]; + __IO uint32_t DACC_TNPR; /**< \brief (Dacc Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t DACC_TNCR; /**< \brief (Dacc Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t DACC_PTCR; /**< \brief (Dacc Offset: 0x120) Transfer Control Register */ + __I uint32_t DACC_PTSR; /**< \brief (Dacc Offset: 0x124) Transfer Status Register */ +} Dacc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- DACC_CR : (DACC Offset: 0x00) Control Register -------- */ +#define DACC_CR_SWRST (0x1u << 0) /**< \brief (DACC_CR) Software Reset */ +/* -------- DACC_MR : (DACC Offset: 0x04) Mode Register -------- */ +#define DACC_MR_TRGEN (0x1u << 0) /**< \brief (DACC_MR) Trigger Enable */ +#define DACC_MR_TRGEN_DIS (0x0u << 0) /**< \brief (DACC_MR) External trigger mode disabled. DACC in free-running mode. */ +#define DACC_MR_TRGEN_EN (0x1u << 0) /**< \brief (DACC_MR) External trigger mode enabled. */ +#define DACC_MR_TRGSEL_Pos 1 +#define DACC_MR_TRGSEL_Msk (0x7u << DACC_MR_TRGSEL_Pos) /**< \brief (DACC_MR) Trigger Selection */ +#define DACC_MR_TRGSEL(value) ((DACC_MR_TRGSEL_Msk & ((value) << DACC_MR_TRGSEL_Pos))) +#define DACC_MR_WORD (0x1u << 4) /**< \brief (DACC_MR) Word Transfer */ +#define DACC_MR_WORD_HALF (0x0u << 4) /**< \brief (DACC_MR) Half-word transfer */ +#define DACC_MR_WORD_WORD (0x1u << 4) /**< \brief (DACC_MR) Word transfer */ +#define DACC_MR_SLEEP (0x1u << 5) /**< \brief (DACC_MR) Sleep Mode */ +#define DACC_MR_SLEEP_DISABLED (0x0u << 5) /**< \brief (DACC_MR) Normal mode: the DAC core and reference voltage circuitry are kept ON between conversions. */ +#define DACC_MR_SLEEP_ENABLED (0x1u << 5) /**< \brief (DACC_MR) Sleep mode: the DAC core and/or reference voltage circuitry are OFF between conversions. */ +#define DACC_MR_FASTWKUP (0x1u << 6) /**< \brief (DACC_MR) Fast Wake-up Mode */ +#define DACC_MR_FASTWKUP_STAMODE (0x0u << 6) /**< \brief (DACC_MR) Normal sleep mode: the sleep mode is defined by the SLEEP bit. Voltage reference is OFF between conversions. */ +#define DACC_MR_FASTWKUP_FASTWAKEUP (0x1u << 6) /**< \brief (DACC_MR) Fast wake-up after sleep mode: voltage reference is kept ON between conversions; DAC core is OFF */ +#define DACC_MR_REFRESH_Pos 8 +#define DACC_MR_REFRESH_Msk (0xffu << DACC_MR_REFRESH_Pos) /**< \brief (DACC_MR) Automatic Refresh Period */ +#define DACC_MR_REFRESH(value) ((DACC_MR_REFRESH_Msk & ((value) << DACC_MR_REFRESH_Pos))) +#define DACC_MR_USER_SEL_Pos 16 +#define DACC_MR_USER_SEL_Msk (0x3u << DACC_MR_USER_SEL_Pos) /**< \brief (DACC_MR) User Channel Selection */ +#define DACC_MR_USER_SEL_CHANNEL0 (0x0u << 16) /**< \brief (DACC_MR) Channel 0 */ +#define DACC_MR_USER_SEL_CHANNEL1 (0x1u << 16) /**< \brief (DACC_MR) Channel 1 */ +#define DACC_MR_TAG (0x1u << 20) /**< \brief (DACC_MR) Tag Selection Mode */ +#define DACC_MR_TAG_DIS (0x0u << 20) /**< \brief (DACC_MR) Tag selection mode disabled. Using USER_SEL to select the channel for the conversion. */ +#define DACC_MR_TAG_EN (0x1u << 20) /**< \brief (DACC_MR) Tag selection mode enabled */ +#define DACC_MR_MAXS (0x1u << 21) /**< \brief (DACC_MR) Max Speed Mode */ +#define DACC_MR_MAXS_NORMAL (0x0u << 21) /**< \brief (DACC_MR) Normal mode */ +#define DACC_MR_MAXS_MAXIMUM (0x1u << 21) /**< \brief (DACC_MR) Maximum speed mode enabled */ +#define DACC_MR_CLKDIV (0x1u << 22) /**< \brief (DACC_MR) Clock Divider */ +#define DACC_MR_CLKDIV_DIV_2 (0x0u << 22) /**< \brief (DACC_MR) The DAC clock is peripheral clock divided by 2 */ +#define DACC_MR_CLKDIV_DIV_4 (0x1u << 22) /**< \brief (DACC_MR) The DAC clock is peripheral clock divided by 4 (to be used when peripheral clock frequency is above 100 MHz) */ +#define DACC_MR_STARTUP_Pos 24 +#define DACC_MR_STARTUP_Msk (0x3fu << DACC_MR_STARTUP_Pos) /**< \brief (DACC_MR) Startup Time Selection */ +#define DACC_MR_STARTUP_0 (0x0u << 24) /**< \brief (DACC_MR) 0 periods of DACClock */ +#define DACC_MR_STARTUP_8 (0x1u << 24) /**< \brief (DACC_MR) 8 periods of DACClock */ +#define DACC_MR_STARTUP_16 (0x2u << 24) /**< \brief (DACC_MR) 16 periods of DACClock */ +#define DACC_MR_STARTUP_24 (0x3u << 24) /**< \brief (DACC_MR) 24 periods of DACClock */ +#define DACC_MR_STARTUP_64 (0x4u << 24) /**< \brief (DACC_MR) 64 periods of DACClock */ +#define DACC_MR_STARTUP_80 (0x5u << 24) /**< \brief (DACC_MR) 80 periods of DACClock */ +#define DACC_MR_STARTUP_96 (0x6u << 24) /**< \brief (DACC_MR) 96 periods of DACClock */ +#define DACC_MR_STARTUP_112 (0x7u << 24) /**< \brief (DACC_MR) 112 periods of DACClock */ +#define DACC_MR_STARTUP_512 (0x8u << 24) /**< \brief (DACC_MR) 512 periods of DACClock */ +#define DACC_MR_STARTUP_576 (0x9u << 24) /**< \brief (DACC_MR) 576 periods of DACClock */ +#define DACC_MR_STARTUP_640 (0xAu << 24) /**< \brief (DACC_MR) 640 periods of DACClock */ +#define DACC_MR_STARTUP_704 (0xBu << 24) /**< \brief (DACC_MR) 704 periods of DACClock */ +#define DACC_MR_STARTUP_768 (0xCu << 24) /**< \brief (DACC_MR) 768 periods of DACClock */ +#define DACC_MR_STARTUP_832 (0xDu << 24) /**< \brief (DACC_MR) 832 periods of DACClock */ +#define DACC_MR_STARTUP_896 (0xEu << 24) /**< \brief (DACC_MR) 896 periods of DACClock */ +#define DACC_MR_STARTUP_960 (0xFu << 24) /**< \brief (DACC_MR) 960 periods of DACClock */ +#define DACC_MR_STARTUP_1024 (0x10u << 24) /**< \brief (DACC_MR) 1024 periods of DACClock */ +#define DACC_MR_STARTUP_1088 (0x11u << 24) /**< \brief (DACC_MR) 1088 periods of DACClock */ +#define DACC_MR_STARTUP_1152 (0x12u << 24) /**< \brief (DACC_MR) 1152 periods of DACClock */ +#define DACC_MR_STARTUP_1216 (0x13u << 24) /**< \brief (DACC_MR) 1216 periods of DACClock */ +#define DACC_MR_STARTUP_1280 (0x14u << 24) /**< \brief (DACC_MR) 1280 periods of DACClock */ +#define DACC_MR_STARTUP_1344 (0x15u << 24) /**< \brief (DACC_MR) 1344 periods of DACClock */ +#define DACC_MR_STARTUP_1408 (0x16u << 24) /**< \brief (DACC_MR) 1408 periods of DACClock */ +#define DACC_MR_STARTUP_1472 (0x17u << 24) /**< \brief (DACC_MR) 1472 periods of DACClock */ +#define DACC_MR_STARTUP_1536 (0x18u << 24) /**< \brief (DACC_MR) 1536 periods of DACClock */ +#define DACC_MR_STARTUP_1600 (0x19u << 24) /**< \brief (DACC_MR) 1600 periods of DACClock */ +#define DACC_MR_STARTUP_1664 (0x1Au << 24) /**< \brief (DACC_MR) 1664 periods of DACClock */ +#define DACC_MR_STARTUP_1728 (0x1Bu << 24) /**< \brief (DACC_MR) 1728 periods of DACClock */ +#define DACC_MR_STARTUP_1792 (0x1Cu << 24) /**< \brief (DACC_MR) 1792 periods of DACClock */ +#define DACC_MR_STARTUP_1856 (0x1Du << 24) /**< \brief (DACC_MR) 1856 periods of DACClock */ +#define DACC_MR_STARTUP_1920 (0x1Eu << 24) /**< \brief (DACC_MR) 1920 periods of DACClock */ +#define DACC_MR_STARTUP_1984 (0x1Fu << 24) /**< \brief (DACC_MR) 1984 periods of DACClock */ +#define DACC_MR_STARTUP_2048 (0x20u << 24) /**< \brief (DACC_MR) 2048 periods of DACClock */ +#define DACC_MR_STARTUP_2112 (0x21u << 24) /**< \brief (DACC_MR) 2112 periods of DACClock */ +#define DACC_MR_STARTUP_2176 (0x22u << 24) /**< \brief (DACC_MR) 2176 periods of DACClock */ +#define DACC_MR_STARTUP_2240 (0x23u << 24) /**< \brief (DACC_MR) 2240 periods of DACClock */ +#define DACC_MR_STARTUP_2304 (0x24u << 24) /**< \brief (DACC_MR) 2304 periods of DACClock */ +#define DACC_MR_STARTUP_2368 (0x25u << 24) /**< \brief (DACC_MR) 2368 periods of DACClock */ +#define DACC_MR_STARTUP_2432 (0x26u << 24) /**< \brief (DACC_MR) 2432 periods of DACClock */ +#define DACC_MR_STARTUP_2496 (0x27u << 24) /**< \brief (DACC_MR) 2496 periods of DACClock */ +#define DACC_MR_STARTUP_2560 (0x28u << 24) /**< \brief (DACC_MR) 2560 periods of DACClock */ +#define DACC_MR_STARTUP_2624 (0x29u << 24) /**< \brief (DACC_MR) 2624 periods of DACClock */ +#define DACC_MR_STARTUP_2688 (0x2Au << 24) /**< \brief (DACC_MR) 2688 periods of DACClock */ +#define DACC_MR_STARTUP_2752 (0x2Bu << 24) /**< \brief (DACC_MR) 2752 periods of DACClock */ +#define DACC_MR_STARTUP_2816 (0x2Cu << 24) /**< \brief (DACC_MR) 2816 periods of DACClock */ +#define DACC_MR_STARTUP_2880 (0x2Du << 24) /**< \brief (DACC_MR) 2880 periods of DACClock */ +#define DACC_MR_STARTUP_2944 (0x2Eu << 24) /**< \brief (DACC_MR) 2944 periods of DACClock */ +#define DACC_MR_STARTUP_3008 (0x2Fu << 24) /**< \brief (DACC_MR) 3008 periods of DACClock */ +#define DACC_MR_STARTUP_3072 (0x30u << 24) /**< \brief (DACC_MR) 3072 periods of DACClock */ +#define DACC_MR_STARTUP_3136 (0x31u << 24) /**< \brief (DACC_MR) 3136 periods of DACClock */ +#define DACC_MR_STARTUP_3200 (0x32u << 24) /**< \brief (DACC_MR) 3200 periods of DACClock */ +#define DACC_MR_STARTUP_3264 (0x33u << 24) /**< \brief (DACC_MR) 3264 periods of DACClock */ +#define DACC_MR_STARTUP_3328 (0x34u << 24) /**< \brief (DACC_MR) 3328 periods of DACClock */ +#define DACC_MR_STARTUP_3392 (0x35u << 24) /**< \brief (DACC_MR) 3392 periods of DACClock */ +#define DACC_MR_STARTUP_3456 (0x36u << 24) /**< \brief (DACC_MR) 3456 periods of DACClock */ +#define DACC_MR_STARTUP_3520 (0x37u << 24) /**< \brief (DACC_MR) 3520 periods of DACClock */ +#define DACC_MR_STARTUP_3584 (0x38u << 24) /**< \brief (DACC_MR) 3584 periods of DACClock */ +#define DACC_MR_STARTUP_3648 (0x39u << 24) /**< \brief (DACC_MR) 3648 periods of DACClock */ +#define DACC_MR_STARTUP_3712 (0x3Au << 24) /**< \brief (DACC_MR) 3712 periods of DACClock */ +#define DACC_MR_STARTUP_3776 (0x3Bu << 24) /**< \brief (DACC_MR) 3776 periods of DACClock */ +#define DACC_MR_STARTUP_3840 (0x3Cu << 24) /**< \brief (DACC_MR) 3840 periods of DACClock */ +#define DACC_MR_STARTUP_3904 (0x3Du << 24) /**< \brief (DACC_MR) 3904 periods of DACClock */ +#define DACC_MR_STARTUP_3968 (0x3Eu << 24) /**< \brief (DACC_MR) 3968 periods of DACClock */ +#define DACC_MR_STARTUP_4032 (0x3Fu << 24) /**< \brief (DACC_MR) 4032 periods of DACClock */ +/* -------- DACC_CHER : (DACC Offset: 0x10) Channel Enable Register -------- */ +#define DACC_CHER_CH0 (0x1u << 0) /**< \brief (DACC_CHER) Channel 0 Enable */ +#define DACC_CHER_CH1 (0x1u << 1) /**< \brief (DACC_CHER) Channel 1 Enable */ +/* -------- DACC_CHDR : (DACC Offset: 0x14) Channel Disable Register -------- */ +#define DACC_CHDR_CH0 (0x1u << 0) /**< \brief (DACC_CHDR) Channel 0 Disable */ +#define DACC_CHDR_CH1 (0x1u << 1) /**< \brief (DACC_CHDR) Channel 1 Disable */ +/* -------- DACC_CHSR : (DACC Offset: 0x18) Channel Status Register -------- */ +#define DACC_CHSR_CH0 (0x1u << 0) /**< \brief (DACC_CHSR) Channel 0 Status */ +#define DACC_CHSR_CH1 (0x1u << 1) /**< \brief (DACC_CHSR) Channel 1 Status */ +/* -------- DACC_CDR : (DACC Offset: 0x20) Conversion Data Register -------- */ +#define DACC_CDR_DATA_Pos 0 +#define DACC_CDR_DATA_Msk (0xffffffffu << DACC_CDR_DATA_Pos) /**< \brief (DACC_CDR) Data to Convert */ +#define DACC_CDR_DATA(value) ((DACC_CDR_DATA_Msk & ((value) << DACC_CDR_DATA_Pos))) +/* -------- DACC_IER : (DACC Offset: 0x24) Interrupt Enable Register -------- */ +#define DACC_IER_TXRDY (0x1u << 0) /**< \brief (DACC_IER) Transmit Ready Interrupt Enable */ +#define DACC_IER_EOC (0x1u << 1) /**< \brief (DACC_IER) End of Conversion Interrupt Enable */ +#define DACC_IER_ENDTX (0x1u << 2) /**< \brief (DACC_IER) End of Transmit Buffer Interrupt Enable */ +#define DACC_IER_TXBUFE (0x1u << 3) /**< \brief (DACC_IER) Transmit Buffer Empty Interrupt Enable */ +/* -------- DACC_IDR : (DACC Offset: 0x28) Interrupt Disable Register -------- */ +#define DACC_IDR_TXRDY (0x1u << 0) /**< \brief (DACC_IDR) Transmit Ready Interrupt Disable. */ +#define DACC_IDR_EOC (0x1u << 1) /**< \brief (DACC_IDR) End of Conversion Interrupt Disable */ +#define DACC_IDR_ENDTX (0x1u << 2) /**< \brief (DACC_IDR) End of Transmit Buffer Interrupt Disable */ +#define DACC_IDR_TXBUFE (0x1u << 3) /**< \brief (DACC_IDR) Transmit Buffer Empty Interrupt Disable */ +/* -------- DACC_IMR : (DACC Offset: 0x2C) Interrupt Mask Register -------- */ +#define DACC_IMR_TXRDY (0x1u << 0) /**< \brief (DACC_IMR) Transmit Ready Interrupt Mask */ +#define DACC_IMR_EOC (0x1u << 1) /**< \brief (DACC_IMR) End of Conversion Interrupt Mask */ +#define DACC_IMR_ENDTX (0x1u << 2) /**< \brief (DACC_IMR) End of Transmit Buffer Interrupt Mask */ +#define DACC_IMR_TXBUFE (0x1u << 3) /**< \brief (DACC_IMR) Transmit Buffer Empty Interrupt Mask */ +/* -------- DACC_ISR : (DACC Offset: 0x30) Interrupt Status Register -------- */ +#define DACC_ISR_TXRDY (0x1u << 0) /**< \brief (DACC_ISR) Transmit Ready Interrupt Flag */ +#define DACC_ISR_EOC (0x1u << 1) /**< \brief (DACC_ISR) End of Conversion Interrupt Flag */ +#define DACC_ISR_ENDTX (0x1u << 2) /**< \brief (DACC_ISR) End of DMA Interrupt Flag */ +#define DACC_ISR_TXBUFE (0x1u << 3) /**< \brief (DACC_ISR) Transmit Buffer Empty */ +/* -------- DACC_ACR : (DACC Offset: 0x94) Analog Current Register -------- */ +#define DACC_ACR_IBCTLCH0_Pos 0 +#define DACC_ACR_IBCTLCH0_Msk (0x3u << DACC_ACR_IBCTLCH0_Pos) /**< \brief (DACC_ACR) Analog Output Current Control */ +#define DACC_ACR_IBCTLCH0(value) ((DACC_ACR_IBCTLCH0_Msk & ((value) << DACC_ACR_IBCTLCH0_Pos))) +#define DACC_ACR_IBCTLCH1_Pos 2 +#define DACC_ACR_IBCTLCH1_Msk (0x3u << DACC_ACR_IBCTLCH1_Pos) /**< \brief (DACC_ACR) Analog Output Current Control */ +#define DACC_ACR_IBCTLCH1(value) ((DACC_ACR_IBCTLCH1_Msk & ((value) << DACC_ACR_IBCTLCH1_Pos))) +#define DACC_ACR_IBCTLDACCORE_Pos 8 +#define DACC_ACR_IBCTLDACCORE_Msk (0x3u << DACC_ACR_IBCTLDACCORE_Pos) /**< \brief (DACC_ACR) Bias Current Control for DAC Core */ +#define DACC_ACR_IBCTLDACCORE(value) ((DACC_ACR_IBCTLDACCORE_Msk & ((value) << DACC_ACR_IBCTLDACCORE_Pos))) +/* -------- DACC_WPMR : (DACC Offset: 0xE4) Write Protection Mode Register -------- */ +#define DACC_WPMR_WPEN (0x1u << 0) /**< \brief (DACC_WPMR) Write Protection Enable */ +#define DACC_WPMR_WPKEY_Pos 8 +#define DACC_WPMR_WPKEY_Msk (0xffffffu << DACC_WPMR_WPKEY_Pos) /**< \brief (DACC_WPMR) Write Protection KEY */ +#define DACC_WPMR_WPKEY_PASSWD (0x444143u << 8) /**< \brief (DACC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- DACC_WPSR : (DACC Offset: 0xE8) Write Protection Status Register -------- */ +#define DACC_WPSR_WPVS (0x1u << 0) /**< \brief (DACC_WPSR) Write Protection Violation Status */ +#define DACC_WPSR_WPVSRC_Pos 8 +#define DACC_WPSR_WPVSRC_Msk (0xffu << DACC_WPSR_WPVSRC_Pos) /**< \brief (DACC_WPSR) Write Protection Violation Source */ +/* -------- DACC_TPR : (DACC Offset: 0x108) Transmit Pointer Register -------- */ +#define DACC_TPR_TXPTR_Pos 0 +#define DACC_TPR_TXPTR_Msk (0xffffffffu << DACC_TPR_TXPTR_Pos) /**< \brief (DACC_TPR) Transmit Counter Register */ +#define DACC_TPR_TXPTR(value) ((DACC_TPR_TXPTR_Msk & ((value) << DACC_TPR_TXPTR_Pos))) +/* -------- DACC_TCR : (DACC Offset: 0x10C) Transmit Counter Register -------- */ +#define DACC_TCR_TXCTR_Pos 0 +#define DACC_TCR_TXCTR_Msk (0xffffu << DACC_TCR_TXCTR_Pos) /**< \brief (DACC_TCR) Transmit Counter Register */ +#define DACC_TCR_TXCTR(value) ((DACC_TCR_TXCTR_Msk & ((value) << DACC_TCR_TXCTR_Pos))) +/* -------- DACC_TNPR : (DACC Offset: 0x118) Transmit Next Pointer Register -------- */ +#define DACC_TNPR_TXNPTR_Pos 0 +#define DACC_TNPR_TXNPTR_Msk (0xffffffffu << DACC_TNPR_TXNPTR_Pos) /**< \brief (DACC_TNPR) Transmit Next Pointer */ +#define DACC_TNPR_TXNPTR(value) ((DACC_TNPR_TXNPTR_Msk & ((value) << DACC_TNPR_TXNPTR_Pos))) +/* -------- DACC_TNCR : (DACC Offset: 0x11C) Transmit Next Counter Register -------- */ +#define DACC_TNCR_TXNCTR_Pos 0 +#define DACC_TNCR_TXNCTR_Msk (0xffffu << DACC_TNCR_TXNCTR_Pos) /**< \brief (DACC_TNCR) Transmit Counter Next */ +#define DACC_TNCR_TXNCTR(value) ((DACC_TNCR_TXNCTR_Msk & ((value) << DACC_TNCR_TXNCTR_Pos))) +/* -------- DACC_PTCR : (DACC Offset: 0x120) Transfer Control Register -------- */ +#define DACC_PTCR_RXTEN (0x1u << 0) /**< \brief (DACC_PTCR) Receiver Transfer Enable */ +#define DACC_PTCR_RXTDIS (0x1u << 1) /**< \brief (DACC_PTCR) Receiver Transfer Disable */ +#define DACC_PTCR_TXTEN (0x1u << 8) /**< \brief (DACC_PTCR) Transmitter Transfer Enable */ +#define DACC_PTCR_TXTDIS (0x1u << 9) /**< \brief (DACC_PTCR) Transmitter Transfer Disable */ +/* -------- DACC_PTSR : (DACC Offset: 0x124) Transfer Status Register -------- */ +#define DACC_PTSR_RXTEN (0x1u << 0) /**< \brief (DACC_PTSR) Receiver Transfer Enable */ +#define DACC_PTSR_TXTEN (0x1u << 8) /**< \brief (DACC_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_DACC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dmac.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dmac.h new file mode 100644 index 0000000..b951da7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/dmac.h @@ -0,0 +1,308 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_DMAC_COMPONENT_ +#define _SAM4E_DMAC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR DMA Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_DMAC DMA Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief DmacCh_num hardware registers */ +typedef struct { + __IO uint32_t DMAC_SADDR; /**< \brief (DmacCh_num Offset: 0x0) DMAC Channel Source Address Register */ + __IO uint32_t DMAC_DADDR; /**< \brief (DmacCh_num Offset: 0x4) DMAC Channel Destination Address Register */ + __IO uint32_t DMAC_DSCR; /**< \brief (DmacCh_num Offset: 0x8) DMAC Channel Descriptor Address Register */ + __IO uint32_t DMAC_CTRLA; /**< \brief (DmacCh_num Offset: 0xC) DMAC Channel Control A Register */ + __IO uint32_t DMAC_CTRLB; /**< \brief (DmacCh_num Offset: 0x10) DMAC Channel Control B Register */ + __IO uint32_t DMAC_CFG; /**< \brief (DmacCh_num Offset: 0x14) DMAC Channel Configuration Register */ + __I uint32_t Reserved1[4]; +} DmacCh_num; +/** \brief Dmac hardware registers */ +#define DMACCH_NUM_NUMBER 4 +typedef struct { + __IO uint32_t DMAC_GCFG; /**< \brief (Dmac Offset: 0x000) DMAC Global Configuration Register */ + __IO uint32_t DMAC_EN; /**< \brief (Dmac Offset: 0x004) DMAC Enable Register */ + __IO uint32_t DMAC_SREQ; /**< \brief (Dmac Offset: 0x008) DMAC Software Single Request Register */ + __IO uint32_t DMAC_CREQ; /**< \brief (Dmac Offset: 0x00C) DMAC Software Chunk Transfer Request Register */ + __IO uint32_t DMAC_LAST; /**< \brief (Dmac Offset: 0x010) DMAC Software Last Transfer Flag Register */ + __I uint32_t Reserved1[1]; + __O uint32_t DMAC_EBCIER; /**< \brief (Dmac Offset: 0x018) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. */ + __O uint32_t DMAC_EBCIDR; /**< \brief (Dmac Offset: 0x01C) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. */ + __I uint32_t DMAC_EBCIMR; /**< \brief (Dmac Offset: 0x020) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. */ + __I uint32_t DMAC_EBCISR; /**< \brief (Dmac Offset: 0x024) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. */ + __O uint32_t DMAC_CHER; /**< \brief (Dmac Offset: 0x028) DMAC Channel Handler Enable Register */ + __O uint32_t DMAC_CHDR; /**< \brief (Dmac Offset: 0x02C) DMAC Channel Handler Disable Register */ + __I uint32_t DMAC_CHSR; /**< \brief (Dmac Offset: 0x030) DMAC Channel Handler Status Register */ + __I uint32_t Reserved2[2]; + DmacCh_num DMAC_CH_NUM[DMACCH_NUM_NUMBER]; /**< \brief (Dmac Offset: 0x3C) ch_num = 0 .. 3 */ + __I uint32_t Reserved3[66]; + __IO uint32_t DMAC_WPMR; /**< \brief (Dmac Offset: 0x1E4) DMAC Write Protect Mode Register */ + __I uint32_t DMAC_WPSR; /**< \brief (Dmac Offset: 0x1E8) DMAC Write Protect Status Register */ +} Dmac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- DMAC_GCFG : (DMAC Offset: 0x000) DMAC Global Configuration Register -------- */ +#define DMAC_GCFG_ARB_CFG (0x1u << 4) /**< \brief (DMAC_GCFG) Arbiter Configuration */ +#define DMAC_GCFG_ARB_CFG_FIXED (0x0u << 4) /**< \brief (DMAC_GCFG) Fixed priority arbiter (see "Basic Definitions" ) */ +#define DMAC_GCFG_ARB_CFG_ROUND_ROBIN (0x1u << 4) /**< \brief (DMAC_GCFG) Modified round robin arbiter. */ +/* -------- DMAC_EN : (DMAC Offset: 0x004) DMAC Enable Register -------- */ +#define DMAC_EN_ENABLE (0x1u << 0) /**< \brief (DMAC_EN) General Enable of DMA */ +/* -------- DMAC_SREQ : (DMAC Offset: 0x008) DMAC Software Single Request Register -------- */ +#define DMAC_SREQ_SSREQ0 (0x1u << 0) /**< \brief (DMAC_SREQ) Source Request */ +#define DMAC_SREQ_DSREQ0 (0x1u << 1) /**< \brief (DMAC_SREQ) Destination Request */ +#define DMAC_SREQ_SSREQ1 (0x1u << 2) /**< \brief (DMAC_SREQ) Source Request */ +#define DMAC_SREQ_DSREQ1 (0x1u << 3) /**< \brief (DMAC_SREQ) Destination Request */ +#define DMAC_SREQ_SSREQ2 (0x1u << 4) /**< \brief (DMAC_SREQ) Source Request */ +#define DMAC_SREQ_DSREQ2 (0x1u << 5) /**< \brief (DMAC_SREQ) Destination Request */ +#define DMAC_SREQ_SSREQ3 (0x1u << 6) /**< \brief (DMAC_SREQ) Source Request */ +#define DMAC_SREQ_DSREQ3 (0x1u << 7) /**< \brief (DMAC_SREQ) Destination Request */ +/* -------- DMAC_CREQ : (DMAC Offset: 0x00C) DMAC Software Chunk Transfer Request Register -------- */ +#define DMAC_CREQ_SCREQ0 (0x1u << 0) /**< \brief (DMAC_CREQ) Source Chunk Request */ +#define DMAC_CREQ_DCREQ0 (0x1u << 1) /**< \brief (DMAC_CREQ) Destination Chunk Request */ +#define DMAC_CREQ_SCREQ1 (0x1u << 2) /**< \brief (DMAC_CREQ) Source Chunk Request */ +#define DMAC_CREQ_DCREQ1 (0x1u << 3) /**< \brief (DMAC_CREQ) Destination Chunk Request */ +#define DMAC_CREQ_SCREQ2 (0x1u << 4) /**< \brief (DMAC_CREQ) Source Chunk Request */ +#define DMAC_CREQ_DCREQ2 (0x1u << 5) /**< \brief (DMAC_CREQ) Destination Chunk Request */ +#define DMAC_CREQ_SCREQ3 (0x1u << 6) /**< \brief (DMAC_CREQ) Source Chunk Request */ +#define DMAC_CREQ_DCREQ3 (0x1u << 7) /**< \brief (DMAC_CREQ) Destination Chunk Request */ +/* -------- DMAC_LAST : (DMAC Offset: 0x010) DMAC Software Last Transfer Flag Register -------- */ +#define DMAC_LAST_SLAST0 (0x1u << 0) /**< \brief (DMAC_LAST) Source Last */ +#define DMAC_LAST_DLAST0 (0x1u << 1) /**< \brief (DMAC_LAST) Destination Last */ +#define DMAC_LAST_SLAST1 (0x1u << 2) /**< \brief (DMAC_LAST) Source Last */ +#define DMAC_LAST_DLAST1 (0x1u << 3) /**< \brief (DMAC_LAST) Destination Last */ +#define DMAC_LAST_SLAST2 (0x1u << 4) /**< \brief (DMAC_LAST) Source Last */ +#define DMAC_LAST_DLAST2 (0x1u << 5) /**< \brief (DMAC_LAST) Destination Last */ +#define DMAC_LAST_SLAST3 (0x1u << 6) /**< \brief (DMAC_LAST) Source Last */ +#define DMAC_LAST_DLAST3 (0x1u << 7) /**< \brief (DMAC_LAST) Destination Last */ +/* -------- DMAC_EBCIER : (DMAC Offset: 0x018) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. -------- */ +#define DMAC_EBCIER_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIER) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIER) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIER_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIER) Access Error [3:0] */ +#define DMAC_EBCIER_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIER) Access Error [3:0] */ +#define DMAC_EBCIER_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIER) Access Error [3:0] */ +#define DMAC_EBCIER_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIER) Access Error [3:0] */ +/* -------- DMAC_EBCIDR : (DMAC Offset: 0x01C) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. -------- */ +#define DMAC_EBCIDR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIDR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIDR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIDR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIDR) Access Error [3:0] */ +#define DMAC_EBCIDR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIDR) Access Error [3:0] */ +#define DMAC_EBCIDR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIDR) Access Error [3:0] */ +#define DMAC_EBCIDR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIDR) Access Error [3:0] */ +/* -------- DMAC_EBCIMR : (DMAC Offset: 0x020) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. -------- */ +#define DMAC_EBCIMR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCIMR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCIMR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCIMR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCIMR) Access Error [3:0] */ +#define DMAC_EBCIMR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCIMR) Access Error [3:0] */ +#define DMAC_EBCIMR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCIMR) Access Error [3:0] */ +#define DMAC_EBCIMR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCIMR) Access Error [3:0] */ +/* -------- DMAC_EBCISR : (DMAC Offset: 0x024) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. -------- */ +#define DMAC_EBCISR_BTC0 (0x1u << 0) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_BTC1 (0x1u << 1) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_BTC2 (0x1u << 2) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_BTC3 (0x1u << 3) /**< \brief (DMAC_EBCISR) Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_CBTC0 (0x1u << 8) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_CBTC1 (0x1u << 9) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_CBTC2 (0x1u << 10) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_CBTC3 (0x1u << 11) /**< \brief (DMAC_EBCISR) Chained Buffer Transfer Completed [3:0] */ +#define DMAC_EBCISR_ERR0 (0x1u << 16) /**< \brief (DMAC_EBCISR) Access Error [3:0] */ +#define DMAC_EBCISR_ERR1 (0x1u << 17) /**< \brief (DMAC_EBCISR) Access Error [3:0] */ +#define DMAC_EBCISR_ERR2 (0x1u << 18) /**< \brief (DMAC_EBCISR) Access Error [3:0] */ +#define DMAC_EBCISR_ERR3 (0x1u << 19) /**< \brief (DMAC_EBCISR) Access Error [3:0] */ +/* -------- DMAC_CHER : (DMAC Offset: 0x028) DMAC Channel Handler Enable Register -------- */ +#define DMAC_CHER_ENA0 (0x1u << 0) /**< \brief (DMAC_CHER) Enable [3:0] */ +#define DMAC_CHER_ENA1 (0x1u << 1) /**< \brief (DMAC_CHER) Enable [3:0] */ +#define DMAC_CHER_ENA2 (0x1u << 2) /**< \brief (DMAC_CHER) Enable [3:0] */ +#define DMAC_CHER_ENA3 (0x1u << 3) /**< \brief (DMAC_CHER) Enable [3:0] */ +#define DMAC_CHER_SUSP0 (0x1u << 8) /**< \brief (DMAC_CHER) Suspend [3:0] */ +#define DMAC_CHER_SUSP1 (0x1u << 9) /**< \brief (DMAC_CHER) Suspend [3:0] */ +#define DMAC_CHER_SUSP2 (0x1u << 10) /**< \brief (DMAC_CHER) Suspend [3:0] */ +#define DMAC_CHER_SUSP3 (0x1u << 11) /**< \brief (DMAC_CHER) Suspend [3:0] */ +#define DMAC_CHER_KEEP0 (0x1u << 24) /**< \brief (DMAC_CHER) Keep on [3:0] */ +#define DMAC_CHER_KEEP1 (0x1u << 25) /**< \brief (DMAC_CHER) Keep on [3:0] */ +#define DMAC_CHER_KEEP2 (0x1u << 26) /**< \brief (DMAC_CHER) Keep on [3:0] */ +#define DMAC_CHER_KEEP3 (0x1u << 27) /**< \brief (DMAC_CHER) Keep on [3:0] */ +/* -------- DMAC_CHDR : (DMAC Offset: 0x02C) DMAC Channel Handler Disable Register -------- */ +#define DMAC_CHDR_DIS0 (0x1u << 0) /**< \brief (DMAC_CHDR) Disable [3:0] */ +#define DMAC_CHDR_DIS1 (0x1u << 1) /**< \brief (DMAC_CHDR) Disable [3:0] */ +#define DMAC_CHDR_DIS2 (0x1u << 2) /**< \brief (DMAC_CHDR) Disable [3:0] */ +#define DMAC_CHDR_DIS3 (0x1u << 3) /**< \brief (DMAC_CHDR) Disable [3:0] */ +#define DMAC_CHDR_RES0 (0x1u << 8) /**< \brief (DMAC_CHDR) Resume [3:0] */ +#define DMAC_CHDR_RES1 (0x1u << 9) /**< \brief (DMAC_CHDR) Resume [3:0] */ +#define DMAC_CHDR_RES2 (0x1u << 10) /**< \brief (DMAC_CHDR) Resume [3:0] */ +#define DMAC_CHDR_RES3 (0x1u << 11) /**< \brief (DMAC_CHDR) Resume [3:0] */ +/* -------- DMAC_CHSR : (DMAC Offset: 0x030) DMAC Channel Handler Status Register -------- */ +#define DMAC_CHSR_ENA0 (0x1u << 0) /**< \brief (DMAC_CHSR) Enable [3:0] */ +#define DMAC_CHSR_ENA1 (0x1u << 1) /**< \brief (DMAC_CHSR) Enable [3:0] */ +#define DMAC_CHSR_ENA2 (0x1u << 2) /**< \brief (DMAC_CHSR) Enable [3:0] */ +#define DMAC_CHSR_ENA3 (0x1u << 3) /**< \brief (DMAC_CHSR) Enable [3:0] */ +#define DMAC_CHSR_SUSP0 (0x1u << 8) /**< \brief (DMAC_CHSR) Suspend [3:0] */ +#define DMAC_CHSR_SUSP1 (0x1u << 9) /**< \brief (DMAC_CHSR) Suspend [3:0] */ +#define DMAC_CHSR_SUSP2 (0x1u << 10) /**< \brief (DMAC_CHSR) Suspend [3:0] */ +#define DMAC_CHSR_SUSP3 (0x1u << 11) /**< \brief (DMAC_CHSR) Suspend [3:0] */ +#define DMAC_CHSR_EMPT0 (0x1u << 16) /**< \brief (DMAC_CHSR) Empty [3:0] */ +#define DMAC_CHSR_EMPT1 (0x1u << 17) /**< \brief (DMAC_CHSR) Empty [3:0] */ +#define DMAC_CHSR_EMPT2 (0x1u << 18) /**< \brief (DMAC_CHSR) Empty [3:0] */ +#define DMAC_CHSR_EMPT3 (0x1u << 19) /**< \brief (DMAC_CHSR) Empty [3:0] */ +#define DMAC_CHSR_STAL0 (0x1u << 24) /**< \brief (DMAC_CHSR) Stalled [3:0] */ +#define DMAC_CHSR_STAL1 (0x1u << 25) /**< \brief (DMAC_CHSR) Stalled [3:0] */ +#define DMAC_CHSR_STAL2 (0x1u << 26) /**< \brief (DMAC_CHSR) Stalled [3:0] */ +#define DMAC_CHSR_STAL3 (0x1u << 27) /**< \brief (DMAC_CHSR) Stalled [3:0] */ +/* -------- DMAC_SADDR : (DMAC Offset: N/A) DMAC Channel Source Address Register -------- */ +#define DMAC_SADDR_SADDR_Pos 0 +#define DMAC_SADDR_SADDR_Msk (0xffffffffu << DMAC_SADDR_SADDR_Pos) /**< \brief (DMAC_SADDR) Channel x Source Address */ +#define DMAC_SADDR_SADDR(value) ((DMAC_SADDR_SADDR_Msk & ((value) << DMAC_SADDR_SADDR_Pos))) +/* -------- DMAC_DADDR : (DMAC Offset: N/A) DMAC Channel Destination Address Register -------- */ +#define DMAC_DADDR_DADDR_Pos 0 +#define DMAC_DADDR_DADDR_Msk (0xffffffffu << DMAC_DADDR_DADDR_Pos) /**< \brief (DMAC_DADDR) Channel x Destination Address */ +#define DMAC_DADDR_DADDR(value) ((DMAC_DADDR_DADDR_Msk & ((value) << DMAC_DADDR_DADDR_Pos))) +/* -------- DMAC_DSCR : (DMAC Offset: N/A) DMAC Channel Descriptor Address Register -------- */ +#define DMAC_DSCR_DSCR_Pos 2 +#define DMAC_DSCR_DSCR_Msk (0x3fffffffu << DMAC_DSCR_DSCR_Pos) /**< \brief (DMAC_DSCR) Buffer Transfer Descriptor Address */ +#define DMAC_DSCR_DSCR(value) ((DMAC_DSCR_DSCR_Msk & ((value) << DMAC_DSCR_DSCR_Pos))) +/* -------- DMAC_CTRLA : (DMAC Offset: N/A) DMAC Channel Control A Register -------- */ +#define DMAC_CTRLA_BTSIZE_Pos 0 +#define DMAC_CTRLA_BTSIZE_Msk (0xffffu << DMAC_CTRLA_BTSIZE_Pos) /**< \brief (DMAC_CTRLA) Buffer Transfer Size */ +#define DMAC_CTRLA_BTSIZE(value) ((DMAC_CTRLA_BTSIZE_Msk & ((value) << DMAC_CTRLA_BTSIZE_Pos))) +#define DMAC_CTRLA_SRC_WIDTH_Pos 24 +#define DMAC_CTRLA_SRC_WIDTH_Msk (0x3u << DMAC_CTRLA_SRC_WIDTH_Pos) /**< \brief (DMAC_CTRLA) Transfer Width for the Source */ +#define DMAC_CTRLA_SRC_WIDTH_BYTE (0x0u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 8-bit width */ +#define DMAC_CTRLA_SRC_WIDTH_HALF_WORD (0x1u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 16-bit width */ +#define DMAC_CTRLA_SRC_WIDTH_WORD (0x2u << 24) /**< \brief (DMAC_CTRLA) the transfer size is set to 32-bit width */ +#define DMAC_CTRLA_DST_WIDTH_Pos 28 +#define DMAC_CTRLA_DST_WIDTH_Msk (0x3u << DMAC_CTRLA_DST_WIDTH_Pos) /**< \brief (DMAC_CTRLA) Transfer Width for the Destination */ +#define DMAC_CTRLA_DST_WIDTH_BYTE (0x0u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 8-bit width */ +#define DMAC_CTRLA_DST_WIDTH_HALF_WORD (0x1u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 16-bit width */ +#define DMAC_CTRLA_DST_WIDTH_WORD (0x2u << 28) /**< \brief (DMAC_CTRLA) the transfer size is set to 32-bit width */ +#define DMAC_CTRLA_DONE (0x1u << 31) /**< \brief (DMAC_CTRLA) Current Descriptor Stop Command and Transfer Completed Memory Indicator */ +/* -------- DMAC_CTRLB : (DMAC Offset: N/A) DMAC Channel Control B Register -------- */ +#define DMAC_CTRLB_SRC_DSCR (0x1u << 16) /**< \brief (DMAC_CTRLB) Source Address Descriptor */ +#define DMAC_CTRLB_SRC_DSCR_FETCH_FROM_MEM (0x0u << 16) /**< \brief (DMAC_CTRLB) Source address is updated when the descriptor is fetched from the memory. */ +#define DMAC_CTRLB_SRC_DSCR_FETCH_DISABLE (0x1u << 16) /**< \brief (DMAC_CTRLB) Buffer Descriptor Fetch operation is disabled for the source. */ +#define DMAC_CTRLB_DST_DSCR (0x1u << 20) /**< \brief (DMAC_CTRLB) Destination Address Descriptor */ +#define DMAC_CTRLB_DST_DSCR_FETCH_FROM_MEM (0x0u << 20) /**< \brief (DMAC_CTRLB) Destination address is updated when the descriptor is fetched from the memory. */ +#define DMAC_CTRLB_DST_DSCR_FETCH_DISABLE (0x1u << 20) /**< \brief (DMAC_CTRLB) Buffer Descriptor Fetch operation is disabled for the destination. */ +#define DMAC_CTRLB_FC_Pos 21 +#define DMAC_CTRLB_FC_Msk (0x3u << DMAC_CTRLB_FC_Pos) /**< \brief (DMAC_CTRLB) Flow Control */ +#define DMAC_CTRLB_FC_MEM2MEM_DMA_FC (0x0u << 21) /**< \brief (DMAC_CTRLB) Memory-to-Memory Transfer DMAC is flow controller */ +#define DMAC_CTRLB_FC_MEM2PER_DMA_FC (0x1u << 21) /**< \brief (DMAC_CTRLB) Memory-to-Peripheral Transfer DMAC is flow controller */ +#define DMAC_CTRLB_FC_PER2MEM_DMA_FC (0x2u << 21) /**< \brief (DMAC_CTRLB) Peripheral-to-Memory Transfer DMAC is flow controller */ +#define DMAC_CTRLB_FC_PER2PER_DMA_FC (0x3u << 21) /**< \brief (DMAC_CTRLB) Peripheral-to-Peripheral Transfer DMAC is flow controller */ +#define DMAC_CTRLB_SRC_INCR_Pos 24 +#define DMAC_CTRLB_SRC_INCR_Msk (0x3u << DMAC_CTRLB_SRC_INCR_Pos) /**< \brief (DMAC_CTRLB) Incrementing, Decrementing or Fixed Address for the Source */ +#define DMAC_CTRLB_SRC_INCR_INCREMENTING (0x0u << 24) /**< \brief (DMAC_CTRLB) The source address is incremented */ +#define DMAC_CTRLB_SRC_INCR_DECREMENTING (0x1u << 24) /**< \brief (DMAC_CTRLB) The source address is decremented */ +#define DMAC_CTRLB_SRC_INCR_FIXED (0x2u << 24) /**< \brief (DMAC_CTRLB) The source address remains unchanged */ +#define DMAC_CTRLB_DST_INCR_Pos 28 +#define DMAC_CTRLB_DST_INCR_Msk (0x3u << DMAC_CTRLB_DST_INCR_Pos) /**< \brief (DMAC_CTRLB) Incrementing, Decrementing or Fixed Address for the Destination */ +#define DMAC_CTRLB_DST_INCR_INCREMENTING (0x0u << 28) /**< \brief (DMAC_CTRLB) The destination address is incremented */ +#define DMAC_CTRLB_DST_INCR_DECREMENTING (0x1u << 28) /**< \brief (DMAC_CTRLB) The destination address is decremented */ +#define DMAC_CTRLB_DST_INCR_FIXED (0x2u << 28) /**< \brief (DMAC_CTRLB) The destination address remains unchanged */ +#define DMAC_CTRLB_IEN (0x1u << 30) /**< \brief (DMAC_CTRLB) Interrupt Enable Not */ +/* -------- DMAC_CFG : (DMAC Offset: N/A) DMAC Channel Configuration Register -------- */ +#define DMAC_CFG_SRC_PER_Pos 0 +#define DMAC_CFG_SRC_PER_Msk (0xfu << DMAC_CFG_SRC_PER_Pos) /**< \brief (DMAC_CFG) Source with Peripheral identifier */ +#define DMAC_CFG_SRC_PER(value) ((DMAC_CFG_SRC_PER_Msk & ((value) << DMAC_CFG_SRC_PER_Pos))) +#define DMAC_CFG_DST_PER_Pos 4 +#define DMAC_CFG_DST_PER_Msk (0xfu << DMAC_CFG_DST_PER_Pos) /**< \brief (DMAC_CFG) Destination with Peripheral identifier */ +#define DMAC_CFG_DST_PER(value) ((DMAC_CFG_DST_PER_Msk & ((value) << DMAC_CFG_DST_PER_Pos))) +#define DMAC_CFG_SRC_H2SEL (0x1u << 9) /**< \brief (DMAC_CFG) Software or Hardware Selection for the Source */ +#define DMAC_CFG_SRC_H2SEL_SW (0x0u << 9) /**< \brief (DMAC_CFG) Software handshaking interface is used to trigger a transfer request. */ +#define DMAC_CFG_SRC_H2SEL_HW (0x1u << 9) /**< \brief (DMAC_CFG) Hardware handshaking interface is used to trigger a transfer request. */ +#define DMAC_CFG_DST_H2SEL (0x1u << 13) /**< \brief (DMAC_CFG) Software or Hardware Selection for the Destination */ +#define DMAC_CFG_DST_H2SEL_SW (0x0u << 13) /**< \brief (DMAC_CFG) Software handshaking interface is used to trigger a transfer request. */ +#define DMAC_CFG_DST_H2SEL_HW (0x1u << 13) /**< \brief (DMAC_CFG) Hardware handshaking interface is used to trigger a transfer request. */ +#define DMAC_CFG_SOD (0x1u << 16) /**< \brief (DMAC_CFG) Stop On Done */ +#define DMAC_CFG_SOD_DISABLE (0x0u << 16) /**< \brief (DMAC_CFG) STOP ON DONE disabled, the descriptor fetch operation ignores DONE Field of CTRLA register. */ +#define DMAC_CFG_SOD_ENABLE (0x1u << 16) /**< \brief (DMAC_CFG) STOP ON DONE activated, the DMAC module is automatically disabled if DONE FIELD is set to 1. */ +#define DMAC_CFG_LOCK_IF (0x1u << 20) /**< \brief (DMAC_CFG) Interface Lock */ +#define DMAC_CFG_LOCK_IF_DISABLE (0x0u << 20) /**< \brief (DMAC_CFG) Interface Lock capability is disabled */ +#define DMAC_CFG_LOCK_IF_ENABLE (0x1u << 20) /**< \brief (DMAC_CFG) Interface Lock capability is enabled */ +#define DMAC_CFG_LOCK_B (0x1u << 21) /**< \brief (DMAC_CFG) Bus Lock */ +#define DMAC_CFG_LOCK_B_DISABLE (0x0u << 21) /**< \brief (DMAC_CFG) AHB Bus Locking capability is disabled. */ +#define DMAC_CFG_LOCK_IF_L (0x1u << 22) /**< \brief (DMAC_CFG) Master Interface Arbiter Lock */ +#define DMAC_CFG_LOCK_IF_L_CHUNK (0x0u << 22) /**< \brief (DMAC_CFG) The Master Interface Arbiter is locked by the channel x for a chunk transfer. */ +#define DMAC_CFG_LOCK_IF_L_BUFFER (0x1u << 22) /**< \brief (DMAC_CFG) The Master Interface Arbiter is locked by the channel x for a buffer transfer. */ +#define DMAC_CFG_AHB_PROT_Pos 24 +#define DMAC_CFG_AHB_PROT_Msk (0x7u << DMAC_CFG_AHB_PROT_Pos) /**< \brief (DMAC_CFG) AHB Protection */ +#define DMAC_CFG_AHB_PROT(value) ((DMAC_CFG_AHB_PROT_Msk & ((value) << DMAC_CFG_AHB_PROT_Pos))) +#define DMAC_CFG_FIFOCFG_Pos 28 +#define DMAC_CFG_FIFOCFG_Msk (0x3u << DMAC_CFG_FIFOCFG_Pos) /**< \brief (DMAC_CFG) FIFO Configuration */ +#define DMAC_CFG_FIFOCFG_ALAP_CFG (0x0u << 28) /**< \brief (DMAC_CFG) The largest defined length AHB burst is performed on the destination AHB interface. */ +#define DMAC_CFG_FIFOCFG_HALF_CFG (0x1u << 28) /**< \brief (DMAC_CFG) When half FIFO size is available/filled, a source/destination request is serviced. */ +#define DMAC_CFG_FIFOCFG_ASAP_CFG (0x2u << 28) /**< \brief (DMAC_CFG) When there is enough space/data available to perform a single AHB access, then the request is serviced. */ +/* -------- DMAC_WPMR : (DMAC Offset: 0x1E4) DMAC Write Protect Mode Register -------- */ +#define DMAC_WPMR_WPEN (0x1u << 0) /**< \brief (DMAC_WPMR) Write Protect Enable */ +#define DMAC_WPMR_WPKEY_Pos 8 +#define DMAC_WPMR_WPKEY_Msk (0xffffffu << DMAC_WPMR_WPKEY_Pos) /**< \brief (DMAC_WPMR) Write Protect KEY */ +#define DMAC_WPMR_WPKEY_PASSWD (0x444D41u << 8) /**< \brief (DMAC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- DMAC_WPSR : (DMAC Offset: 0x1E8) DMAC Write Protect Status Register -------- */ +#define DMAC_WPSR_WPVS (0x1u << 0) /**< \brief (DMAC_WPSR) Write Protect Violation Status */ +#define DMAC_WPSR_WPVSRC_Pos 8 +#define DMAC_WPSR_WPVSRC_Msk (0xffffu << DMAC_WPSR_WPVSRC_Pos) /**< \brief (DMAC_WPSR) Write Protect Violation Source */ + +/*@}*/ + + +#endif /* _SAM4E_DMAC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/efc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/efc.h new file mode 100644 index 0000000..ae4d8a6 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/efc.h @@ -0,0 +1,113 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_EFC_COMPONENT_ +#define _SAM4E_EFC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Embedded Flash Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_EFC Embedded Flash Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Efc hardware registers */ +typedef struct { + __IO uint32_t EEFC_FMR; /**< \brief (Efc Offset: 0x00) EEFC Flash Mode Register */ + __O uint32_t EEFC_FCR; /**< \brief (Efc Offset: 0x04) EEFC Flash Command Register */ + __I uint32_t EEFC_FSR; /**< \brief (Efc Offset: 0x08) EEFC Flash Status Register */ + __I uint32_t EEFC_FRR; /**< \brief (Efc Offset: 0x0C) EEFC Flash Result Register */ +} Efc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- EEFC_FMR : (EFC Offset: 0x00) EEFC Flash Mode Register -------- */ +#define EEFC_FMR_FRDY (0x1u << 0) /**< \brief (EEFC_FMR) Ready Interrupt Enable */ +#define EEFC_FMR_FWS_Pos 8 +#define EEFC_FMR_FWS_Msk (0xfu << EEFC_FMR_FWS_Pos) /**< \brief (EEFC_FMR) Flash Wait State */ +#define EEFC_FMR_FWS(value) ((EEFC_FMR_FWS_Msk & ((value) << EEFC_FMR_FWS_Pos))) +#define EEFC_FMR_SCOD (0x1u << 16) /**< \brief (EEFC_FMR) Sequential Code Optimization Disable */ +#define EEFC_FMR_FAM (0x1u << 24) /**< \brief (EEFC_FMR) Flash Access Mode */ +#define EEFC_FMR_CLOE (0x1u << 26) /**< \brief (EEFC_FMR) Code Loop Optimization Enable */ +/* -------- EEFC_FCR : (EFC Offset: 0x04) EEFC Flash Command Register -------- */ +#define EEFC_FCR_FCMD_Pos 0 +#define EEFC_FCR_FCMD_Msk (0xffu << EEFC_FCR_FCMD_Pos) /**< \brief (EEFC_FCR) Flash Command */ +#define EEFC_FCR_FCMD_GETD (0x0u << 0) /**< \brief (EEFC_FCR) Get Flash descriptor */ +#define EEFC_FCR_FCMD_WP (0x1u << 0) /**< \brief (EEFC_FCR) Write page */ +#define EEFC_FCR_FCMD_WPL (0x2u << 0) /**< \brief (EEFC_FCR) Write page and lock */ +#define EEFC_FCR_FCMD_EWP (0x3u << 0) /**< \brief (EEFC_FCR) Erase page and write page */ +#define EEFC_FCR_FCMD_EWPL (0x4u << 0) /**< \brief (EEFC_FCR) Erase page and write page then lock */ +#define EEFC_FCR_FCMD_EA (0x5u << 0) /**< \brief (EEFC_FCR) Erase all */ +#define EEFC_FCR_FCMD_EPA (0x7u << 0) /**< \brief (EEFC_FCR) Erase pages */ +#define EEFC_FCR_FCMD_SLB (0x8u << 0) /**< \brief (EEFC_FCR) Set lock bit */ +#define EEFC_FCR_FCMD_CLB (0x9u << 0) /**< \brief (EEFC_FCR) Clear lock bit */ +#define EEFC_FCR_FCMD_GLB (0xAu << 0) /**< \brief (EEFC_FCR) Get lock bit */ +#define EEFC_FCR_FCMD_SGPB (0xBu << 0) /**< \brief (EEFC_FCR) Set GPNVM bit */ +#define EEFC_FCR_FCMD_CGPB (0xCu << 0) /**< \brief (EEFC_FCR) Clear GPNVM bit */ +#define EEFC_FCR_FCMD_GGPB (0xDu << 0) /**< \brief (EEFC_FCR) Get GPNVM bit */ +#define EEFC_FCR_FCMD_STUI (0xEu << 0) /**< \brief (EEFC_FCR) Start read unique identifier */ +#define EEFC_FCR_FCMD_SPUI (0xFu << 0) /**< \brief (EEFC_FCR) Stop read unique identifier */ +#define EEFC_FCR_FCMD_GCALB (0x10u << 0) /**< \brief (EEFC_FCR) Get CALIB bit */ +#define EEFC_FCR_FCMD_ES (0x11u << 0) /**< \brief (EEFC_FCR) Erase sector */ +#define EEFC_FCR_FCMD_WUS (0x12u << 0) /**< \brief (EEFC_FCR) Write user signature */ +#define EEFC_FCR_FCMD_EUS (0x13u << 0) /**< \brief (EEFC_FCR) Erase user signature */ +#define EEFC_FCR_FCMD_STUS (0x14u << 0) /**< \brief (EEFC_FCR) Start read user signature */ +#define EEFC_FCR_FCMD_SPUS (0x15u << 0) /**< \brief (EEFC_FCR) Stop read user signature */ +#define EEFC_FCR_FARG_Pos 8 +#define EEFC_FCR_FARG_Msk (0xffffu << EEFC_FCR_FARG_Pos) /**< \brief (EEFC_FCR) Flash Command Argument */ +#define EEFC_FCR_FARG(value) ((EEFC_FCR_FARG_Msk & ((value) << EEFC_FCR_FARG_Pos))) +#define EEFC_FCR_FKEY_Pos 24 +#define EEFC_FCR_FKEY_Msk (0xffu << EEFC_FCR_FKEY_Pos) /**< \brief (EEFC_FCR) Flash Writing Protection Key */ +#define EEFC_FCR_FKEY_PASSWD (0x5Au << 24) /**< \brief (EEFC_FCR) The 0x5A value enables the command defined by the bits of the register. If the field is written with a different value, the write is not performed and no action is started. */ +/* -------- EEFC_FSR : (EFC Offset: 0x08) EEFC Flash Status Register -------- */ +#define EEFC_FSR_FRDY (0x1u << 0) /**< \brief (EEFC_FSR) Flash Ready Status */ +#define EEFC_FSR_FCMDE (0x1u << 1) /**< \brief (EEFC_FSR) Flash Command Error Status */ +#define EEFC_FSR_FLOCKE (0x1u << 2) /**< \brief (EEFC_FSR) Flash Lock Error Status */ +#define EEFC_FSR_FLERR (0x1u << 3) /**< \brief (EEFC_FSR) Flash Error Status */ +/* -------- EEFC_FRR : (EFC Offset: 0x0C) EEFC Flash Result Register -------- */ +#define EEFC_FRR_FVALUE_Pos 0 +#define EEFC_FRR_FVALUE_Msk (0xffffffffu << EEFC_FRR_FVALUE_Pos) /**< \brief (EEFC_FRR) Flash Result Value */ + +/*@}*/ + + +#endif /* _SAM4E_EFC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gmac.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gmac.h new file mode 100644 index 0000000..ed19c10 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gmac.h @@ -0,0 +1,628 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_GMAC_COMPONENT_ +#define _SAM4E_GMAC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Gigabit Ethernet MAC */ +/* ============================================================================= */ +/** \addtogroup SAM4E_GMAC Gigabit Ethernet MAC */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief GmacSa hardware registers */ +typedef struct { + __IO uint32_t GMAC_SAB; /**< \brief (GmacSa Offset: 0x0) Specific Address 1 Bottom [31:0] Register */ + __IO uint32_t GMAC_SAT; /**< \brief (GmacSa Offset: 0x4) Specific Address 1 Top [47:32] Register */ +} GmacSa; +/** \brief Gmac hardware registers */ +#define GMACSA_NUMBER 4 +typedef struct { + __IO uint32_t GMAC_NCR; /**< \brief (Gmac Offset: 0x000) Network Control Register */ + __IO uint32_t GMAC_NCFGR; /**< \brief (Gmac Offset: 0x004) Network Configuration Register */ + __I uint32_t GMAC_NSR; /**< \brief (Gmac Offset: 0x008) Network Status Register */ + __IO uint32_t GMAC_UR; /**< \brief (Gmac Offset: 0x00C) User Register */ + __IO uint32_t GMAC_DCFGR; /**< \brief (Gmac Offset: 0x010) DMA Configuration Register */ + __IO uint32_t GMAC_TSR; /**< \brief (Gmac Offset: 0x014) Transmit Status Register */ + __IO uint32_t GMAC_RBQB; /**< \brief (Gmac Offset: 0x018) Receive Buffer Queue Base Address */ + __IO uint32_t GMAC_TBQB; /**< \brief (Gmac Offset: 0x01C) Transmit Buffer Queue Base Address */ + __IO uint32_t GMAC_RSR; /**< \brief (Gmac Offset: 0x020) Receive Status Register */ + __I uint32_t GMAC_ISR; /**< \brief (Gmac Offset: 0x024) Interrupt Status Register */ + __O uint32_t GMAC_IER; /**< \brief (Gmac Offset: 0x028) Interrupt Enable Register */ + __O uint32_t GMAC_IDR; /**< \brief (Gmac Offset: 0x02C) Interrupt Disable Register */ + __I uint32_t GMAC_IMR; /**< \brief (Gmac Offset: 0x030) Interrupt Mask Register */ + __IO uint32_t GMAC_MAN; /**< \brief (Gmac Offset: 0x034) PHY Maintenance Register */ + __I uint32_t GMAC_RPQ; /**< \brief (Gmac Offset: 0x038) Received Pause Quantum Register */ + __IO uint32_t GMAC_TPQ; /**< \brief (Gmac Offset: 0x03C) Transmit Pause Quantum Register */ + __I uint32_t Reserved1[16]; + __IO uint32_t GMAC_HRB; /**< \brief (Gmac Offset: 0x080) Hash Register Bottom [31:0] */ + __IO uint32_t GMAC_HRT; /**< \brief (Gmac Offset: 0x084) Hash Register Top [63:32] */ + GmacSa GMAC_SA[GMACSA_NUMBER]; /**< \brief (Gmac Offset: 0x088) 1 .. 4 */ + __IO uint32_t GMAC_TIDM[4]; /**< \brief (Gmac Offset: 0x0A8) Type ID Match 1 Register */ + __I uint32_t Reserved2[1]; + __IO uint32_t GMAC_IPGS; /**< \brief (Gmac Offset: 0x0BC) IPG Stretch Register */ + __IO uint32_t GMAC_SVLAN; /**< \brief (Gmac Offset: 0x0C0) Stacked VLAN Register */ + __IO uint32_t GMAC_TPFCP; /**< \brief (Gmac Offset: 0x0C4) Transmit PFC Pause Register */ + __IO uint32_t GMAC_SAMB1; /**< \brief (Gmac Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register */ + __IO uint32_t GMAC_SAMT1; /**< \brief (Gmac Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register */ + __I uint32_t Reserved3[12]; + __I uint32_t GMAC_OTLO; /**< \brief (Gmac Offset: 0x100) Octets Transmitted [31:0] Register */ + __I uint32_t GMAC_OTHI; /**< \brief (Gmac Offset: 0x104) Octets Transmitted [47:32] Register */ + __I uint32_t GMAC_FT; /**< \brief (Gmac Offset: 0x108) Frames Transmitted Register */ + __I uint32_t GMAC_BCFT; /**< \brief (Gmac Offset: 0x10C) Broadcast Frames Transmitted Register */ + __I uint32_t GMAC_MFT; /**< \brief (Gmac Offset: 0x110) Multicast Frames Transmitted Register */ + __I uint32_t GMAC_PFT; /**< \brief (Gmac Offset: 0x114) Pause Frames Transmitted Register */ + __I uint32_t GMAC_BFT64; /**< \brief (Gmac Offset: 0x118) 64 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TBFT127; /**< \brief (Gmac Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TBFT255; /**< \brief (Gmac Offset: 0x120) 128 to 255 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TBFT511; /**< \brief (Gmac Offset: 0x124) 256 to 511 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TBFT1023; /**< \brief (Gmac Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TBFT1518; /**< \brief (Gmac Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register */ + __I uint32_t GMAC_GTBFT1518; /**< \brief (Gmac Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register */ + __I uint32_t GMAC_TUR; /**< \brief (Gmac Offset: 0x134) Transmit Underruns Register */ + __I uint32_t GMAC_SCF; /**< \brief (Gmac Offset: 0x138) Single Collision Frames Register */ + __I uint32_t GMAC_MCF; /**< \brief (Gmac Offset: 0x13C) Multiple Collision Frames Register */ + __I uint32_t GMAC_EC; /**< \brief (Gmac Offset: 0x140) Excessive Collisions Register */ + __I uint32_t GMAC_LC; /**< \brief (Gmac Offset: 0x144) Late Collisions Register */ + __I uint32_t GMAC_DTF; /**< \brief (Gmac Offset: 0x148) Deferred Transmission Frames Register */ + __I uint32_t GMAC_CSE; /**< \brief (Gmac Offset: 0x14C) Carrier Sense Errors Register */ + __I uint32_t GMAC_ORLO; /**< \brief (Gmac Offset: 0x150) Octets Received [31:0] Received */ + __I uint32_t GMAC_ORHI; /**< \brief (Gmac Offset: 0x154) Octets Received [47:32] Received */ + __I uint32_t GMAC_FR; /**< \brief (Gmac Offset: 0x158) Frames Received Register */ + __I uint32_t GMAC_BCFR; /**< \brief (Gmac Offset: 0x15C) Broadcast Frames Received Register */ + __I uint32_t GMAC_MFR; /**< \brief (Gmac Offset: 0x160) Multicast Frames Received Register */ + __I uint32_t GMAC_PFR; /**< \brief (Gmac Offset: 0x164) Pause Frames Received Register */ + __I uint32_t GMAC_BFR64; /**< \brief (Gmac Offset: 0x168) 64 Byte Frames Received Register */ + __I uint32_t GMAC_TBFR127; /**< \brief (Gmac Offset: 0x16C) 65 to 127 Byte Frames Received Register */ + __I uint32_t GMAC_TBFR255; /**< \brief (Gmac Offset: 0x170) 128 to 255 Byte Frames Received Register */ + __I uint32_t GMAC_TBFR511; /**< \brief (Gmac Offset: 0x174) 256 to 511Byte Frames Received Register */ + __I uint32_t GMAC_TBFR1023; /**< \brief (Gmac Offset: 0x178) 512 to 1023 Byte Frames Received Register */ + __I uint32_t GMAC_TBFR1518; /**< \brief (Gmac Offset: 0x17C) 1024 to 1518 Byte Frames Received Register */ + __I uint32_t GMAC_TMXBFR; /**< \brief (Gmac Offset: 0x180) 1519 to Maximum Byte Frames Received Register */ + __I uint32_t GMAC_UFR; /**< \brief (Gmac Offset: 0x184) Undersize Frames Received Register */ + __I uint32_t GMAC_OFR; /**< \brief (Gmac Offset: 0x188) Oversize Frames Received Register */ + __I uint32_t GMAC_JR; /**< \brief (Gmac Offset: 0x18C) Jabbers Received Register */ + __I uint32_t GMAC_FCSE; /**< \brief (Gmac Offset: 0x190) Frame Check Sequence Errors Register */ + __I uint32_t GMAC_LFFE; /**< \brief (Gmac Offset: 0x194) Length Field Frame Errors Register */ + __I uint32_t GMAC_RSE; /**< \brief (Gmac Offset: 0x198) Receive Symbol Errors Register */ + __I uint32_t GMAC_AE; /**< \brief (Gmac Offset: 0x19C) Alignment Errors Register */ + __I uint32_t GMAC_RRE; /**< \brief (Gmac Offset: 0x1A0) Receive Resource Errors Register */ + __I uint32_t GMAC_ROE; /**< \brief (Gmac Offset: 0x1A4) Receive Overrun Register */ + __I uint32_t GMAC_IHCE; /**< \brief (Gmac Offset: 0x1A8) IP Header Checksum Errors Register */ + __I uint32_t GMAC_TCE; /**< \brief (Gmac Offset: 0x1AC) TCP Checksum Errors Register */ + __I uint32_t GMAC_UCE; /**< \brief (Gmac Offset: 0x1B0) UDP Checksum Errors Register */ + __I uint32_t Reserved4[5]; + __IO uint32_t GMAC_TSSSL; /**< \brief (Gmac Offset: 0x1C8) 1588 Timer Sync Strobe Seconds [31:0] Register */ + __IO uint32_t GMAC_TSSN; /**< \brief (Gmac Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register */ + __IO uint32_t GMAC_TSL; /**< \brief (Gmac Offset: 0x1D0) 1588 Timer Seconds [31:0] Register */ + __IO uint32_t GMAC_TN; /**< \brief (Gmac Offset: 0x1D4) 1588 Timer Nanoseconds Register */ + __O uint32_t GMAC_TA; /**< \brief (Gmac Offset: 0x1D8) 1588 Timer Adjust Register */ + __IO uint32_t GMAC_TI; /**< \brief (Gmac Offset: 0x1DC) 1588 Timer Increment Register */ + __I uint32_t GMAC_EFTS; /**< \brief (Gmac Offset: 0x1E0) PTP Event Frame Transmitted Seconds */ + __I uint32_t GMAC_EFTN; /**< \brief (Gmac Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds */ + __I uint32_t GMAC_EFRS; /**< \brief (Gmac Offset: 0x1E8) PTP Event Frame Received Seconds */ + __I uint32_t GMAC_EFRN; /**< \brief (Gmac Offset: 0x1EC) PTP Event Frame Received Nanoseconds */ + __I uint32_t GMAC_PEFTS; /**< \brief (Gmac Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds */ + __I uint32_t GMAC_PEFTN; /**< \brief (Gmac Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds */ + __I uint32_t GMAC_PEFRS; /**< \brief (Gmac Offset: 0x1F8) PTP Peer Event Frame Received Seconds */ + __I uint32_t GMAC_PEFRN; /**< \brief (Gmac Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds */ +} Gmac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- GMAC_NCR : (GMAC Offset: 0x000) Network Control Register -------- */ +#define GMAC_NCR_LBL (0x1u << 1) /**< \brief (GMAC_NCR) Loop Back Local */ +#define GMAC_NCR_RXEN (0x1u << 2) /**< \brief (GMAC_NCR) Receive Enable */ +#define GMAC_NCR_TXEN (0x1u << 3) /**< \brief (GMAC_NCR) Transmit Enable */ +#define GMAC_NCR_MPE (0x1u << 4) /**< \brief (GMAC_NCR) Management Port Enable */ +#define GMAC_NCR_CLRSTAT (0x1u << 5) /**< \brief (GMAC_NCR) Clear Statistics Registers */ +#define GMAC_NCR_INCSTAT (0x1u << 6) /**< \brief (GMAC_NCR) Increment Statistics Registers */ +#define GMAC_NCR_WESTAT (0x1u << 7) /**< \brief (GMAC_NCR) Write Enable for Statistics Registers */ +#define GMAC_NCR_BP (0x1u << 8) /**< \brief (GMAC_NCR) Back pressure */ +#define GMAC_NCR_TSTART (0x1u << 9) /**< \brief (GMAC_NCR) Start Transmission */ +#define GMAC_NCR_THALT (0x1u << 10) /**< \brief (GMAC_NCR) Transmit Halt */ +#define GMAC_NCR_TXPF (0x1u << 11) /**< \brief (GMAC_NCR) Transmit Pause Frame */ +#define GMAC_NCR_TXZQPF (0x1u << 12) /**< \brief (GMAC_NCR) Transmit Zero Quantum Pause Frame */ +#define GMAC_NCR_SRTSM (0x1u << 15) /**< \brief (GMAC_NCR) Store Receive Time Stamp to Memory */ +#define GMAC_NCR_ENPBPR (0x1u << 16) /**< \brief (GMAC_NCR) Enable PFC Priority-based Pause Reception */ +#define GMAC_NCR_TXPBPF (0x1u << 17) /**< \brief (GMAC_NCR) Transmit PFC Priority-based Pause Frame */ +#define GMAC_NCR_FNP (0x1u << 18) /**< \brief (GMAC_NCR) Flush Next Packet */ +/* -------- GMAC_NCFGR : (GMAC Offset: 0x004) Network Configuration Register -------- */ +#define GMAC_NCFGR_SPD (0x1u << 0) /**< \brief (GMAC_NCFGR) Speed */ +#define GMAC_NCFGR_FD (0x1u << 1) /**< \brief (GMAC_NCFGR) Full Duplex */ +#define GMAC_NCFGR_DNVLAN (0x1u << 2) /**< \brief (GMAC_NCFGR) Discard Non-VLAN FRAMES */ +#define GMAC_NCFGR_JFRAME (0x1u << 3) /**< \brief (GMAC_NCFGR) Jumbo Frame Size */ +#define GMAC_NCFGR_CAF (0x1u << 4) /**< \brief (GMAC_NCFGR) Copy All Frames */ +#define GMAC_NCFGR_NBC (0x1u << 5) /**< \brief (GMAC_NCFGR) No Broadcast */ +#define GMAC_NCFGR_MTIHEN (0x1u << 6) /**< \brief (GMAC_NCFGR) Multicast Hash Enable */ +#define GMAC_NCFGR_UNIHEN (0x1u << 7) /**< \brief (GMAC_NCFGR) Unicast Hash Enable */ +#define GMAC_NCFGR_MAXFS (0x1u << 8) /**< \brief (GMAC_NCFGR) 1536 Maximum Frame Size */ +#define GMAC_NCFGR_RTY (0x1u << 12) /**< \brief (GMAC_NCFGR) Retry Test */ +#define GMAC_NCFGR_PEN (0x1u << 13) /**< \brief (GMAC_NCFGR) Pause Enable */ +#define GMAC_NCFGR_RXBUFO_Pos 14 +#define GMAC_NCFGR_RXBUFO_Msk (0x3u << GMAC_NCFGR_RXBUFO_Pos) /**< \brief (GMAC_NCFGR) Receive Buffer Offset */ +#define GMAC_NCFGR_RXBUFO(value) ((GMAC_NCFGR_RXBUFO_Msk & ((value) << GMAC_NCFGR_RXBUFO_Pos))) +#define GMAC_NCFGR_LFERD (0x1u << 16) /**< \brief (GMAC_NCFGR) Length Field Error Frame Discard */ +#define GMAC_NCFGR_RFCS (0x1u << 17) /**< \brief (GMAC_NCFGR) Remove FCS */ +#define GMAC_NCFGR_CLK_Pos 18 +#define GMAC_NCFGR_CLK_Msk (0x7u << GMAC_NCFGR_CLK_Pos) /**< \brief (GMAC_NCFGR) MDC CLock Division */ +#define GMAC_NCFGR_CLK_MCK_8 (0x0u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 8 (MCK up to 20 MHz) */ +#define GMAC_NCFGR_CLK_MCK_16 (0x1u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 16 (MCK up to 40 MHz) */ +#define GMAC_NCFGR_CLK_MCK_32 (0x2u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 32 (MCK up to 80 MHz) */ +#define GMAC_NCFGR_CLK_MCK_48 (0x3u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 48 (MCK up to 120 MHz) */ +#define GMAC_NCFGR_CLK_MCK_64 (0x4u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 64 (MCK up to 160 MHz) */ +#define GMAC_NCFGR_CLK_MCK_96 (0x5u << 18) /**< \brief (GMAC_NCFGR) MCK divided by 96 (MCK up to 240 MHz) */ +#define GMAC_NCFGR_DBW_Pos 21 +#define GMAC_NCFGR_DBW_Msk (0x3u << GMAC_NCFGR_DBW_Pos) /**< \brief (GMAC_NCFGR) Data Bus Width */ +#define GMAC_NCFGR_DBW(value) ((GMAC_NCFGR_DBW_Msk & ((value) << GMAC_NCFGR_DBW_Pos))) +#define GMAC_NCFGR_DCPF (0x1u << 23) /**< \brief (GMAC_NCFGR) Disable Copy of Pause Frames */ +#define GMAC_NCFGR_RXCOEN (0x1u << 24) /**< \brief (GMAC_NCFGR) Receive Checksum Offload Enable */ +#define GMAC_NCFGR_EFRHD (0x1u << 25) /**< \brief (GMAC_NCFGR) Enable Frames Received in Half Duplex */ +#define GMAC_NCFGR_IRXFCS (0x1u << 26) /**< \brief (GMAC_NCFGR) Ignore RX FCS */ +#define GMAC_NCFGR_IPGSEN (0x1u << 28) /**< \brief (GMAC_NCFGR) IP Stretch Enable */ +#define GMAC_NCFGR_RXBP (0x1u << 29) /**< \brief (GMAC_NCFGR) Receive Bad Preamble */ +#define GMAC_NCFGR_IRXER (0x1u << 30) /**< \brief (GMAC_NCFGR) Ignore IPG GRXER */ +/* -------- GMAC_NSR : (GMAC Offset: 0x008) Network Status Register -------- */ +#define GMAC_NSR_MDIO (0x1u << 1) /**< \brief (GMAC_NSR) MDIO Input Status */ +#define GMAC_NSR_IDLE (0x1u << 2) /**< \brief (GMAC_NSR) PHY Management Logic Idle */ +/* -------- GMAC_UR : (GMAC Offset: 0x00C) User Register -------- */ +#define GMAC_UR_MII (0x1u << 0) /**< \brief (GMAC_UR) MII Mode */ +/* -------- GMAC_DCFGR : (GMAC Offset: 0x010) DMA Configuration Register -------- */ +#define GMAC_DCFGR_FBLDO_Pos 0 +#define GMAC_DCFGR_FBLDO_Msk (0x1fu << GMAC_DCFGR_FBLDO_Pos) /**< \brief (GMAC_DCFGR) Fixed Burst Length for DMA Data Operations: */ +#define GMAC_DCFGR_FBLDO_SINGLE (0x1u << 0) /**< \brief (GMAC_DCFGR) 00001: Always use SINGLE AHB bursts */ +#define GMAC_DCFGR_FBLDO_INCR4 (0x4u << 0) /**< \brief (GMAC_DCFGR) 001xx: Attempt to use INCR4 AHB bursts (Default) */ +#define GMAC_DCFGR_FBLDO_INCR8 (0x8u << 0) /**< \brief (GMAC_DCFGR) 01xxx: Attempt to use INCR8 AHB bursts */ +#define GMAC_DCFGR_FBLDO_INCR16 (0x10u << 0) /**< \brief (GMAC_DCFGR) 1xxxx: Attempt to use INCR16 AHB bursts */ +#define GMAC_DCFGR_ESMA (0x1u << 6) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Management Descriptor Accesses */ +#define GMAC_DCFGR_ESPA (0x1u << 7) /**< \brief (GMAC_DCFGR) Endian Swap Mode Enable for Packet Data Accesses */ +#define GMAC_DCFGR_DRBS_Pos 16 +#define GMAC_DCFGR_DRBS_Msk (0xffu << GMAC_DCFGR_DRBS_Pos) /**< \brief (GMAC_DCFGR) DMA Receive Buffer Size */ +#define GMAC_DCFGR_DRBS(value) ((GMAC_DCFGR_DRBS_Msk & ((value) << GMAC_DCFGR_DRBS_Pos))) +/* -------- GMAC_TSR : (GMAC Offset: 0x014) Transmit Status Register -------- */ +#define GMAC_TSR_UBR (0x1u << 0) /**< \brief (GMAC_TSR) Used Bit Read */ +#define GMAC_TSR_COL (0x1u << 1) /**< \brief (GMAC_TSR) Collision Occurred */ +#define GMAC_TSR_RLE (0x1u << 2) /**< \brief (GMAC_TSR) Retry Limit Exceeded */ +#define GMAC_TSR_TXGO (0x1u << 3) /**< \brief (GMAC_TSR) Transmit Go */ +#define GMAC_TSR_TFC (0x1u << 4) /**< \brief (GMAC_TSR) Transmit Frame Corruption Due to AHB Error */ +#define GMAC_TSR_TXCOMP (0x1u << 5) /**< \brief (GMAC_TSR) Transmit Complete */ +#define GMAC_TSR_UND (0x1u << 6) /**< \brief (GMAC_TSR) Transmit Underrun */ +#define GMAC_TSR_HRESP (0x1u << 8) /**< \brief (GMAC_TSR) HRESP Not OK */ +/* -------- GMAC_RBQB : (GMAC Offset: 0x018) Receive Buffer Queue Base Address -------- */ +#define GMAC_RBQB_ADDR_Pos 2 +#define GMAC_RBQB_ADDR_Msk (0x3fffffffu << GMAC_RBQB_ADDR_Pos) /**< \brief (GMAC_RBQB) Receive Buffer Queue Base Address */ +#define GMAC_RBQB_ADDR(value) ((GMAC_RBQB_ADDR_Msk & ((value) << GMAC_RBQB_ADDR_Pos))) +/* -------- GMAC_TBQB : (GMAC Offset: 0x01C) Transmit Buffer Queue Base Address -------- */ +#define GMAC_TBQB_ADDR_Pos 2 +#define GMAC_TBQB_ADDR_Msk (0x3fffffffu << GMAC_TBQB_ADDR_Pos) /**< \brief (GMAC_TBQB) Transmit Buffer Queue Base Address */ +#define GMAC_TBQB_ADDR(value) ((GMAC_TBQB_ADDR_Msk & ((value) << GMAC_TBQB_ADDR_Pos))) +/* -------- GMAC_RSR : (GMAC Offset: 0x020) Receive Status Register -------- */ +#define GMAC_RSR_BNA (0x1u << 0) /**< \brief (GMAC_RSR) Buffer Not Available */ +#define GMAC_RSR_REC (0x1u << 1) /**< \brief (GMAC_RSR) Frame Received */ +#define GMAC_RSR_RXOVR (0x1u << 2) /**< \brief (GMAC_RSR) Receive Overrun */ +#define GMAC_RSR_HNO (0x1u << 3) /**< \brief (GMAC_RSR) HRESP Not OK */ +/* -------- GMAC_ISR : (GMAC Offset: 0x024) Interrupt Status Register -------- */ +#define GMAC_ISR_MFS (0x1u << 0) /**< \brief (GMAC_ISR) Management Frame Sent */ +#define GMAC_ISR_RCOMP (0x1u << 1) /**< \brief (GMAC_ISR) Receive Complete */ +#define GMAC_ISR_RXUBR (0x1u << 2) /**< \brief (GMAC_ISR) RX Used Bit Read */ +#define GMAC_ISR_TXUBR (0x1u << 3) /**< \brief (GMAC_ISR) TX Used Bit Read */ +#define GMAC_ISR_TUR (0x1u << 4) /**< \brief (GMAC_ISR) Transmit Underrun */ +#define GMAC_ISR_RLEX (0x1u << 5) /**< \brief (GMAC_ISR) Retry Limit Exceeded */ +#define GMAC_ISR_TFC (0x1u << 6) /**< \brief (GMAC_ISR) Transmit Frame Corruption Due to AHB Error */ +#define GMAC_ISR_TCOMP (0x1u << 7) /**< \brief (GMAC_ISR) Transmit Complete */ +#define GMAC_ISR_ROVR (0x1u << 10) /**< \brief (GMAC_ISR) Receive Overrun */ +#define GMAC_ISR_HRESP (0x1u << 11) /**< \brief (GMAC_ISR) HRESP Not OK */ +#define GMAC_ISR_PFNZ (0x1u << 12) /**< \brief (GMAC_ISR) Pause Frame with Non-zero Pause Quantum Received */ +#define GMAC_ISR_PTZ (0x1u << 13) /**< \brief (GMAC_ISR) Pause Time Zero */ +#define GMAC_ISR_PFTR (0x1u << 14) /**< \brief (GMAC_ISR) Pause Frame Transmitted */ +#define GMAC_ISR_DRQFR (0x1u << 18) /**< \brief (GMAC_ISR) PTP Delay Request Frame Received */ +#define GMAC_ISR_SFR (0x1u << 19) /**< \brief (GMAC_ISR) PTP Sync Frame Received */ +#define GMAC_ISR_DRQFT (0x1u << 20) /**< \brief (GMAC_ISR) PTP Delay Request Frame Transmitted */ +#define GMAC_ISR_SFT (0x1u << 21) /**< \brief (GMAC_ISR) PTP Sync Frame Transmitted */ +#define GMAC_ISR_PDRQFR (0x1u << 22) /**< \brief (GMAC_ISR) PDelay Request Frame Received */ +#define GMAC_ISR_PDRSFR (0x1u << 23) /**< \brief (GMAC_ISR) PDelay Response Frame Received */ +#define GMAC_ISR_PDRQFT (0x1u << 24) /**< \brief (GMAC_ISR) PDelay Request Frame Transmitted */ +#define GMAC_ISR_PDRSFT (0x1u << 25) /**< \brief (GMAC_ISR) PDelay Response Frame Transmitted */ +#define GMAC_ISR_SRI (0x1u << 26) /**< \brief (GMAC_ISR) TSU Seconds Register Increment */ +#define GMAC_ISR_WOL (0x1u << 28) /**< \brief (GMAC_ISR) Wake On LAN */ +/* -------- GMAC_IER : (GMAC Offset: 0x028) Interrupt Enable Register -------- */ +#define GMAC_IER_MFS (0x1u << 0) /**< \brief (GMAC_IER) Management Frame Sent */ +#define GMAC_IER_RCOMP (0x1u << 1) /**< \brief (GMAC_IER) Receive Complete */ +#define GMAC_IER_RXUBR (0x1u << 2) /**< \brief (GMAC_IER) RX Used Bit Read */ +#define GMAC_IER_TXUBR (0x1u << 3) /**< \brief (GMAC_IER) TX Used Bit Read */ +#define GMAC_IER_TUR (0x1u << 4) /**< \brief (GMAC_IER) Transmit Underrun */ +#define GMAC_IER_RLEX (0x1u << 5) /**< \brief (GMAC_IER) Retry Limit Exceeded or Late Collision */ +#define GMAC_IER_TFC (0x1u << 6) /**< \brief (GMAC_IER) Transmit Frame Corruption Due to AHB Error */ +#define GMAC_IER_TCOMP (0x1u << 7) /**< \brief (GMAC_IER) Transmit Complete */ +#define GMAC_IER_ROVR (0x1u << 10) /**< \brief (GMAC_IER) Receive Overrun */ +#define GMAC_IER_HRESP (0x1u << 11) /**< \brief (GMAC_IER) HRESP Not OK */ +#define GMAC_IER_PFNZ (0x1u << 12) /**< \brief (GMAC_IER) Pause Frame with Non-zero Pause Quantum Received */ +#define GMAC_IER_PTZ (0x1u << 13) /**< \brief (GMAC_IER) Pause Time Zero */ +#define GMAC_IER_PFTR (0x1u << 14) /**< \brief (GMAC_IER) Pause Frame Transmitted */ +#define GMAC_IER_EXINT (0x1u << 15) /**< \brief (GMAC_IER) External Interrupt */ +#define GMAC_IER_DRQFR (0x1u << 18) /**< \brief (GMAC_IER) PTP Delay Request Frame Received */ +#define GMAC_IER_SFR (0x1u << 19) /**< \brief (GMAC_IER) PTP Sync Frame Received */ +#define GMAC_IER_DRQFT (0x1u << 20) /**< \brief (GMAC_IER) PTP Delay Request Frame Transmitted */ +#define GMAC_IER_SFT (0x1u << 21) /**< \brief (GMAC_IER) PTP Sync Frame Transmitted */ +#define GMAC_IER_PDRQFR (0x1u << 22) /**< \brief (GMAC_IER) PDelay Request Frame Received */ +#define GMAC_IER_PDRSFR (0x1u << 23) /**< \brief (GMAC_IER) PDelay Response Frame Received */ +#define GMAC_IER_PDRQFT (0x1u << 24) /**< \brief (GMAC_IER) PDelay Request Frame Transmitted */ +#define GMAC_IER_PDRSFT (0x1u << 25) /**< \brief (GMAC_IER) PDelay Response Frame Transmitted */ +#define GMAC_IER_SRI (0x1u << 26) /**< \brief (GMAC_IER) TSU Seconds Register Increment */ +#define GMAC_IER_WOL (0x1u << 28) /**< \brief (GMAC_IER) Wake On LAN */ +/* -------- GMAC_IDR : (GMAC Offset: 0x02C) Interrupt Disable Register -------- */ +#define GMAC_IDR_MFS (0x1u << 0) /**< \brief (GMAC_IDR) Management Frame Sent */ +#define GMAC_IDR_RCOMP (0x1u << 1) /**< \brief (GMAC_IDR) Receive Complete */ +#define GMAC_IDR_RXUBR (0x1u << 2) /**< \brief (GMAC_IDR) RX Used Bit Read */ +#define GMAC_IDR_TXUBR (0x1u << 3) /**< \brief (GMAC_IDR) TX Used Bit Read */ +#define GMAC_IDR_TUR (0x1u << 4) /**< \brief (GMAC_IDR) Transmit Underrun */ +#define GMAC_IDR_RLEX (0x1u << 5) /**< \brief (GMAC_IDR) Retry Limit Exceeded or Late Collision */ +#define GMAC_IDR_TFC (0x1u << 6) /**< \brief (GMAC_IDR) Transmit Frame Corruption Due to AHB Error */ +#define GMAC_IDR_TCOMP (0x1u << 7) /**< \brief (GMAC_IDR) Transmit Complete */ +#define GMAC_IDR_ROVR (0x1u << 10) /**< \brief (GMAC_IDR) Receive Overrun */ +#define GMAC_IDR_HRESP (0x1u << 11) /**< \brief (GMAC_IDR) HRESP Not OK */ +#define GMAC_IDR_PFNZ (0x1u << 12) /**< \brief (GMAC_IDR) Pause Frame with Non-zero Pause Quantum Received */ +#define GMAC_IDR_PTZ (0x1u << 13) /**< \brief (GMAC_IDR) Pause Time Zero */ +#define GMAC_IDR_PFTR (0x1u << 14) /**< \brief (GMAC_IDR) Pause Frame Transmitted */ +#define GMAC_IDR_EXINT (0x1u << 15) /**< \brief (GMAC_IDR) External Interrupt */ +#define GMAC_IDR_DRQFR (0x1u << 18) /**< \brief (GMAC_IDR) PTP Delay Request Frame Received */ +#define GMAC_IDR_SFR (0x1u << 19) /**< \brief (GMAC_IDR) PTP Sync Frame Received */ +#define GMAC_IDR_DRQFT (0x1u << 20) /**< \brief (GMAC_IDR) PTP Delay Request Frame Transmitted */ +#define GMAC_IDR_SFT (0x1u << 21) /**< \brief (GMAC_IDR) PTP Sync Frame Transmitted */ +#define GMAC_IDR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IDR) PDelay Request Frame Received */ +#define GMAC_IDR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IDR) PDelay Response Frame Received */ +#define GMAC_IDR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IDR) PDelay Request Frame Transmitted */ +#define GMAC_IDR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IDR) PDelay Response Frame Transmitted */ +#define GMAC_IDR_SRI (0x1u << 26) /**< \brief (GMAC_IDR) TSU Seconds Register Increment */ +#define GMAC_IDR_WOL (0x1u << 28) /**< \brief (GMAC_IDR) Wake On LAN */ +/* -------- GMAC_IMR : (GMAC Offset: 0x030) Interrupt Mask Register -------- */ +#define GMAC_IMR_MFS (0x1u << 0) /**< \brief (GMAC_IMR) Management Frame Sent */ +#define GMAC_IMR_RCOMP (0x1u << 1) /**< \brief (GMAC_IMR) Receive Complete */ +#define GMAC_IMR_RXUBR (0x1u << 2) /**< \brief (GMAC_IMR) RX Used Bit Read */ +#define GMAC_IMR_TXUBR (0x1u << 3) /**< \brief (GMAC_IMR) TX Used Bit Read */ +#define GMAC_IMR_TUR (0x1u << 4) /**< \brief (GMAC_IMR) Transmit Underrun */ +#define GMAC_IMR_RLEX (0x1u << 5) /**< \brief (GMAC_IMR) Retry Limit Exceeded */ +#define GMAC_IMR_TFC (0x1u << 6) /**< \brief (GMAC_IMR) Transmit Frame Corruption Due to AHB Error */ +#define GMAC_IMR_TCOMP (0x1u << 7) /**< \brief (GMAC_IMR) Transmit Complete */ +#define GMAC_IMR_ROVR (0x1u << 10) /**< \brief (GMAC_IMR) Receive Overrun */ +#define GMAC_IMR_HRESP (0x1u << 11) /**< \brief (GMAC_IMR) HRESP Not OK */ +#define GMAC_IMR_PFNZ (0x1u << 12) /**< \brief (GMAC_IMR) Pause Frame with Non-zero Pause Quantum Received */ +#define GMAC_IMR_PTZ (0x1u << 13) /**< \brief (GMAC_IMR) Pause Time Zero */ +#define GMAC_IMR_PFTR (0x1u << 14) /**< \brief (GMAC_IMR) Pause Frame Transmitted */ +#define GMAC_IMR_EXINT (0x1u << 15) /**< \brief (GMAC_IMR) External Interrupt */ +#define GMAC_IMR_DRQFR (0x1u << 18) /**< \brief (GMAC_IMR) PTP Delay Request Frame Received */ +#define GMAC_IMR_SFR (0x1u << 19) /**< \brief (GMAC_IMR) PTP Sync Frame Received */ +#define GMAC_IMR_DRQFT (0x1u << 20) /**< \brief (GMAC_IMR) PTP Delay Request Frame Transmitted */ +#define GMAC_IMR_SFT (0x1u << 21) /**< \brief (GMAC_IMR) PTP Sync Frame Transmitted */ +#define GMAC_IMR_PDRQFR (0x1u << 22) /**< \brief (GMAC_IMR) PDelay Request Frame Received */ +#define GMAC_IMR_PDRSFR (0x1u << 23) /**< \brief (GMAC_IMR) PDelay Response Frame Received */ +#define GMAC_IMR_PDRQFT (0x1u << 24) /**< \brief (GMAC_IMR) PDelay Request Frame Transmitted */ +#define GMAC_IMR_PDRSFT (0x1u << 25) /**< \brief (GMAC_IMR) PDelay Response Frame Transmitted */ +/* -------- GMAC_MAN : (GMAC Offset: 0x034) PHY Maintenance Register -------- */ +#define GMAC_MAN_DATA_Pos 0 +#define GMAC_MAN_DATA_Msk (0xffffu << GMAC_MAN_DATA_Pos) /**< \brief (GMAC_MAN) PHY Data */ +#define GMAC_MAN_DATA(value) ((GMAC_MAN_DATA_Msk & ((value) << GMAC_MAN_DATA_Pos))) +#define GMAC_MAN_WTN_Pos 16 +#define GMAC_MAN_WTN_Msk (0x3u << GMAC_MAN_WTN_Pos) /**< \brief (GMAC_MAN) Write Ten */ +#define GMAC_MAN_WTN(value) ((GMAC_MAN_WTN_Msk & ((value) << GMAC_MAN_WTN_Pos))) +#define GMAC_MAN_REGA_Pos 18 +#define GMAC_MAN_REGA_Msk (0x1fu << GMAC_MAN_REGA_Pos) /**< \brief (GMAC_MAN) Register Address */ +#define GMAC_MAN_REGA(value) ((GMAC_MAN_REGA_Msk & ((value) << GMAC_MAN_REGA_Pos))) +#define GMAC_MAN_PHYA_Pos 23 +#define GMAC_MAN_PHYA_Msk (0x1fu << GMAC_MAN_PHYA_Pos) /**< \brief (GMAC_MAN) PHY Address */ +#define GMAC_MAN_PHYA(value) ((GMAC_MAN_PHYA_Msk & ((value) << GMAC_MAN_PHYA_Pos))) +#define GMAC_MAN_OP_Pos 28 +#define GMAC_MAN_OP_Msk (0x3u << GMAC_MAN_OP_Pos) /**< \brief (GMAC_MAN) Operation */ +#define GMAC_MAN_OP(value) ((GMAC_MAN_OP_Msk & ((value) << GMAC_MAN_OP_Pos))) +#define GMAC_MAN_CLTTO (0x1u << 30) /**< \brief (GMAC_MAN) Clause 22 Operation */ +#define GMAC_MAN_WZO (0x1u << 31) /**< \brief (GMAC_MAN) Write ZERO */ +/* -------- GMAC_RPQ : (GMAC Offset: 0x038) Received Pause Quantum Register -------- */ +#define GMAC_RPQ_RPQ_Pos 0 +#define GMAC_RPQ_RPQ_Msk (0xffffu << GMAC_RPQ_RPQ_Pos) /**< \brief (GMAC_RPQ) Received Pause Quantum */ +/* -------- GMAC_TPQ : (GMAC Offset: 0x03C) Transmit Pause Quantum Register -------- */ +#define GMAC_TPQ_TPQ_Pos 0 +#define GMAC_TPQ_TPQ_Msk (0xffffu << GMAC_TPQ_TPQ_Pos) /**< \brief (GMAC_TPQ) Transmit Pause Quantum */ +#define GMAC_TPQ_TPQ(value) ((GMAC_TPQ_TPQ_Msk & ((value) << GMAC_TPQ_TPQ_Pos))) +/* -------- GMAC_HRB : (GMAC Offset: 0x080) Hash Register Bottom [31:0] -------- */ +#define GMAC_HRB_ADDR_Pos 0 +#define GMAC_HRB_ADDR_Msk (0xffffffffu << GMAC_HRB_ADDR_Pos) /**< \brief (GMAC_HRB) Hash Address */ +#define GMAC_HRB_ADDR(value) ((GMAC_HRB_ADDR_Msk & ((value) << GMAC_HRB_ADDR_Pos))) +/* -------- GMAC_HRT : (GMAC Offset: 0x084) Hash Register Top [63:32] -------- */ +#define GMAC_HRT_ADDR_Pos 0 +#define GMAC_HRT_ADDR_Msk (0xffffffffu << GMAC_HRT_ADDR_Pos) /**< \brief (GMAC_HRT) Hash Address */ +#define GMAC_HRT_ADDR(value) ((GMAC_HRT_ADDR_Msk & ((value) << GMAC_HRT_ADDR_Pos))) +/* -------- GMAC_SAB1 : (GMAC Offset: 0x088) Specific Address 1 Bottom [31:0] Register -------- */ +#define GMAC_SAB1_ADDR_Pos 0 +#define GMAC_SAB1_ADDR_Msk (0xffffffffu << GMAC_SAB1_ADDR_Pos) /**< \brief (GMAC_SAB1) Specific Address 1 */ +#define GMAC_SAB1_ADDR(value) ((GMAC_SAB1_ADDR_Msk & ((value) << GMAC_SAB1_ADDR_Pos))) +/* -------- GMAC_SAT1 : (GMAC Offset: 0x08C) Specific Address 1 Top [47:32] Register -------- */ +#define GMAC_SAT1_ADDR_Pos 0 +#define GMAC_SAT1_ADDR_Msk (0xffffu << GMAC_SAT1_ADDR_Pos) /**< \brief (GMAC_SAT1) Specific Address 1 */ +#define GMAC_SAT1_ADDR(value) ((GMAC_SAT1_ADDR_Msk & ((value) << GMAC_SAT1_ADDR_Pos))) +/* -------- GMAC_SAB2 : (GMAC Offset: 0x090) Specific Address 2 Bottom [31:0] Register -------- */ +#define GMAC_SAB2_ADDR_Pos 0 +#define GMAC_SAB2_ADDR_Msk (0xffffffffu << GMAC_SAB2_ADDR_Pos) /**< \brief (GMAC_SAB2) Specific Address 2 */ +#define GMAC_SAB2_ADDR(value) ((GMAC_SAB2_ADDR_Msk & ((value) << GMAC_SAB2_ADDR_Pos))) +/* -------- GMAC_SAT2 : (GMAC Offset: 0x094) Specific Address 2 Top [47:32] Register -------- */ +#define GMAC_SAT2_ADDR_Pos 0 +#define GMAC_SAT2_ADDR_Msk (0xffffu << GMAC_SAT2_ADDR_Pos) /**< \brief (GMAC_SAT2) Specific Address 2 */ +#define GMAC_SAT2_ADDR(value) ((GMAC_SAT2_ADDR_Msk & ((value) << GMAC_SAT2_ADDR_Pos))) +/* -------- GMAC_SAB3 : (GMAC Offset: 0x098) Specific Address 3 Bottom [31:0] Register -------- */ +#define GMAC_SAB3_ADDR_Pos 0 +#define GMAC_SAB3_ADDR_Msk (0xffffffffu << GMAC_SAB3_ADDR_Pos) /**< \brief (GMAC_SAB3) Specific Address 3 */ +#define GMAC_SAB3_ADDR(value) ((GMAC_SAB3_ADDR_Msk & ((value) << GMAC_SAB3_ADDR_Pos))) +/* -------- GMAC_SAT3 : (GMAC Offset: 0x09C) Specific Address 3 Top [47:32] Register -------- */ +#define GMAC_SAT3_ADDR_Pos 0 +#define GMAC_SAT3_ADDR_Msk (0xffffu << GMAC_SAT3_ADDR_Pos) /**< \brief (GMAC_SAT3) Specific Address 3 */ +#define GMAC_SAT3_ADDR(value) ((GMAC_SAT3_ADDR_Msk & ((value) << GMAC_SAT3_ADDR_Pos))) +/* -------- GMAC_SAB4 : (GMAC Offset: 0x0A0) Specific Address 4 Bottom [31:0] Register -------- */ +#define GMAC_SAB4_ADDR_Pos 0 +#define GMAC_SAB4_ADDR_Msk (0xffffffffu << GMAC_SAB4_ADDR_Pos) /**< \brief (GMAC_SAB4) Specific Address 4 */ +#define GMAC_SAB4_ADDR(value) ((GMAC_SAB4_ADDR_Msk & ((value) << GMAC_SAB4_ADDR_Pos))) +/* -------- GMAC_SAT4 : (GMAC Offset: 0x0A4) Specific Address 4 Top [47:32] Register -------- */ +#define GMAC_SAT4_ADDR_Pos 0 +#define GMAC_SAT4_ADDR_Msk (0xffffu << GMAC_SAT4_ADDR_Pos) /**< \brief (GMAC_SAT4) Specific Address 4 */ +#define GMAC_SAT4_ADDR(value) ((GMAC_SAT4_ADDR_Msk & ((value) << GMAC_SAT4_ADDR_Pos))) +/* -------- GMAC_TIDM[4] : (GMAC Offset: 0x0A8) Type ID Match 1 Register -------- */ +#define GMAC_TIDM_TID_Pos 0 +#define GMAC_TIDM_TID_Msk (0xffffu << GMAC_TIDM_TID_Pos) /**< \brief (GMAC_TIDM[4]) Type ID Match 1 */ +#define GMAC_TIDM_TID(value) ((GMAC_TIDM_TID_Msk & ((value) << GMAC_TIDM_TID_Pos))) +/* -------- GMAC_IPGS : (GMAC Offset: 0x0BC) IPG Stretch Register -------- */ +#define GMAC_IPGS_FL_Pos 0 +#define GMAC_IPGS_FL_Msk (0xffffu << GMAC_IPGS_FL_Pos) /**< \brief (GMAC_IPGS) Frame Length */ +#define GMAC_IPGS_FL(value) ((GMAC_IPGS_FL_Msk & ((value) << GMAC_IPGS_FL_Pos))) +/* -------- GMAC_SVLAN : (GMAC Offset: 0x0C0) Stacked VLAN Register -------- */ +#define GMAC_SVLAN_VLAN_TYPE_Pos 0 +#define GMAC_SVLAN_VLAN_TYPE_Msk (0xffffu << GMAC_SVLAN_VLAN_TYPE_Pos) /**< \brief (GMAC_SVLAN) User Defined VLAN_TYPE Field */ +#define GMAC_SVLAN_VLAN_TYPE(value) ((GMAC_SVLAN_VLAN_TYPE_Msk & ((value) << GMAC_SVLAN_VLAN_TYPE_Pos))) +#define GMAC_SVLAN_ESVLAN (0x1u << 31) /**< \brief (GMAC_SVLAN) Enable Stacked VLAN Processing Mode */ +/* -------- GMAC_TPFCP : (GMAC Offset: 0x0C4) Transmit PFC Pause Register -------- */ +#define GMAC_TPFCP_PEV_Pos 0 +#define GMAC_TPFCP_PEV_Msk (0xffu << GMAC_TPFCP_PEV_Pos) /**< \brief (GMAC_TPFCP) Priority Enable Vector */ +#define GMAC_TPFCP_PEV(value) ((GMAC_TPFCP_PEV_Msk & ((value) << GMAC_TPFCP_PEV_Pos))) +#define GMAC_TPFCP_PQ_Pos 8 +#define GMAC_TPFCP_PQ_Msk (0xffu << GMAC_TPFCP_PQ_Pos) /**< \brief (GMAC_TPFCP) Pause Quantum */ +#define GMAC_TPFCP_PQ(value) ((GMAC_TPFCP_PQ_Msk & ((value) << GMAC_TPFCP_PQ_Pos))) +/* -------- GMAC_SAMB1 : (GMAC Offset: 0x0C8) Specific Address 1 Mask Bottom [31:0] Register -------- */ +#define GMAC_SAMB1_ADDR_Pos 0 +#define GMAC_SAMB1_ADDR_Msk (0xffffffffu << GMAC_SAMB1_ADDR_Pos) /**< \brief (GMAC_SAMB1) Specific Address 1 Mask */ +#define GMAC_SAMB1_ADDR(value) ((GMAC_SAMB1_ADDR_Msk & ((value) << GMAC_SAMB1_ADDR_Pos))) +/* -------- GMAC_SAMT1 : (GMAC Offset: 0x0CC) Specific Address 1 Mask Top [47:32] Register -------- */ +#define GMAC_SAMT1_ADDR_Pos 0 +#define GMAC_SAMT1_ADDR_Msk (0xffffu << GMAC_SAMT1_ADDR_Pos) /**< \brief (GMAC_SAMT1) Specific Address 1 Mask */ +#define GMAC_SAMT1_ADDR(value) ((GMAC_SAMT1_ADDR_Msk & ((value) << GMAC_SAMT1_ADDR_Pos))) +/* -------- GMAC_OTLO : (GMAC Offset: 0x100) Octets Transmitted [31:0] Register -------- */ +#define GMAC_OTLO_TXO_Pos 0 +#define GMAC_OTLO_TXO_Msk (0xffffffffu << GMAC_OTLO_TXO_Pos) /**< \brief (GMAC_OTLO) Transmitted Octets */ +/* -------- GMAC_OTHI : (GMAC Offset: 0x104) Octets Transmitted [47:32] Register -------- */ +#define GMAC_OTHI_TXO_Pos 0 +#define GMAC_OTHI_TXO_Msk (0xffffu << GMAC_OTHI_TXO_Pos) /**< \brief (GMAC_OTHI) Transmitted Octets */ +/* -------- GMAC_FT : (GMAC Offset: 0x108) Frames Transmitted Register -------- */ +#define GMAC_FT_FTX_Pos 0 +#define GMAC_FT_FTX_Msk (0xffffffffu << GMAC_FT_FTX_Pos) /**< \brief (GMAC_FT) Frames Transmitted without Error */ +/* -------- GMAC_BCFT : (GMAC Offset: 0x10C) Broadcast Frames Transmitted Register -------- */ +#define GMAC_BCFT_BFTX_Pos 0 +#define GMAC_BCFT_BFTX_Msk (0xffffffffu << GMAC_BCFT_BFTX_Pos) /**< \brief (GMAC_BCFT) Broadcast Frames Transmitted without Error */ +/* -------- GMAC_MFT : (GMAC Offset: 0x110) Multicast Frames Transmitted Register -------- */ +#define GMAC_MFT_MFTX_Pos 0 +#define GMAC_MFT_MFTX_Msk (0xffffffffu << GMAC_MFT_MFTX_Pos) /**< \brief (GMAC_MFT) Multicast Frames Transmitted without Error */ +/* -------- GMAC_PFT : (GMAC Offset: 0x114) Pause Frames Transmitted Register -------- */ +#define GMAC_PFT_PFTX_Pos 0 +#define GMAC_PFT_PFTX_Msk (0xffffu << GMAC_PFT_PFTX_Pos) /**< \brief (GMAC_PFT) Pause Frames Transmitted Register */ +/* -------- GMAC_BFT64 : (GMAC Offset: 0x118) 64 Byte Frames Transmitted Register -------- */ +#define GMAC_BFT64_NFTX_Pos 0 +#define GMAC_BFT64_NFTX_Msk (0xffffffffu << GMAC_BFT64_NFTX_Pos) /**< \brief (GMAC_BFT64) 64 Byte Frames Transmitted without Error */ +/* -------- GMAC_TBFT127 : (GMAC Offset: 0x11C) 65 to 127 Byte Frames Transmitted Register -------- */ +#define GMAC_TBFT127_NFTX_Pos 0 +#define GMAC_TBFT127_NFTX_Msk (0xffffffffu << GMAC_TBFT127_NFTX_Pos) /**< \brief (GMAC_TBFT127) 65 to 127 Byte Frames Transmitted without Error */ +/* -------- GMAC_TBFT255 : (GMAC Offset: 0x120) 128 to 255 Byte Frames Transmitted Register -------- */ +#define GMAC_TBFT255_NFTX_Pos 0 +#define GMAC_TBFT255_NFTX_Msk (0xffffffffu << GMAC_TBFT255_NFTX_Pos) /**< \brief (GMAC_TBFT255) 128 to 255 Byte Frames Transmitted without Error */ +/* -------- GMAC_TBFT511 : (GMAC Offset: 0x124) 256 to 511 Byte Frames Transmitted Register -------- */ +#define GMAC_TBFT511_NFTX_Pos 0 +#define GMAC_TBFT511_NFTX_Msk (0xffffffffu << GMAC_TBFT511_NFTX_Pos) /**< \brief (GMAC_TBFT511) 256 to 511 Byte Frames Transmitted without Error */ +/* -------- GMAC_TBFT1023 : (GMAC Offset: 0x128) 512 to 1023 Byte Frames Transmitted Register -------- */ +#define GMAC_TBFT1023_NFTX_Pos 0 +#define GMAC_TBFT1023_NFTX_Msk (0xffffffffu << GMAC_TBFT1023_NFTX_Pos) /**< \brief (GMAC_TBFT1023) 512 to 1023 Byte Frames Transmitted without Error */ +/* -------- GMAC_TBFT1518 : (GMAC Offset: 0x12C) 1024 to 1518 Byte Frames Transmitted Register -------- */ +#define GMAC_TBFT1518_NFTX_Pos 0 +#define GMAC_TBFT1518_NFTX_Msk (0xffffffffu << GMAC_TBFT1518_NFTX_Pos) /**< \brief (GMAC_TBFT1518) 1024 to 1518 Byte Frames Transmitted without Error */ +/* -------- GMAC_GTBFT1518 : (GMAC Offset: 0x130) Greater Than 1518 Byte Frames Transmitted Register -------- */ +#define GMAC_GTBFT1518_NFTX_Pos 0 +#define GMAC_GTBFT1518_NFTX_Msk (0xffffffffu << GMAC_GTBFT1518_NFTX_Pos) /**< \brief (GMAC_GTBFT1518) Greater than 1518 Byte Frames Transmitted without Error */ +/* -------- GMAC_TUR : (GMAC Offset: 0x134) Transmit Underruns Register -------- */ +#define GMAC_TUR_TXUNR_Pos 0 +#define GMAC_TUR_TXUNR_Msk (0x3ffu << GMAC_TUR_TXUNR_Pos) /**< \brief (GMAC_TUR) Transmit Underruns */ +/* -------- GMAC_SCF : (GMAC Offset: 0x138) Single Collision Frames Register -------- */ +#define GMAC_SCF_SCOL_Pos 0 +#define GMAC_SCF_SCOL_Msk (0x3ffffu << GMAC_SCF_SCOL_Pos) /**< \brief (GMAC_SCF) Single Collision */ +/* -------- GMAC_MCF : (GMAC Offset: 0x13C) Multiple Collision Frames Register -------- */ +#define GMAC_MCF_MCOL_Pos 0 +#define GMAC_MCF_MCOL_Msk (0x3ffffu << GMAC_MCF_MCOL_Pos) /**< \brief (GMAC_MCF) Multiple Collision */ +/* -------- GMAC_EC : (GMAC Offset: 0x140) Excessive Collisions Register -------- */ +#define GMAC_EC_XCOL_Pos 0 +#define GMAC_EC_XCOL_Msk (0x3ffu << GMAC_EC_XCOL_Pos) /**< \brief (GMAC_EC) Excessive Collisions */ +/* -------- GMAC_LC : (GMAC Offset: 0x144) Late Collisions Register -------- */ +#define GMAC_LC_LCOL_Pos 0 +#define GMAC_LC_LCOL_Msk (0x3ffu << GMAC_LC_LCOL_Pos) /**< \brief (GMAC_LC) Late Collisions */ +/* -------- GMAC_DTF : (GMAC Offset: 0x148) Deferred Transmission Frames Register -------- */ +#define GMAC_DTF_DEFT_Pos 0 +#define GMAC_DTF_DEFT_Msk (0x3ffffu << GMAC_DTF_DEFT_Pos) /**< \brief (GMAC_DTF) Deferred Transmission */ +/* -------- GMAC_CSE : (GMAC Offset: 0x14C) Carrier Sense Errors Register -------- */ +#define GMAC_CSE_CSR_Pos 0 +#define GMAC_CSE_CSR_Msk (0x3ffu << GMAC_CSE_CSR_Pos) /**< \brief (GMAC_CSE) Carrier Sense Error */ +/* -------- GMAC_ORLO : (GMAC Offset: 0x150) Octets Received [31:0] Received -------- */ +#define GMAC_ORLO_RXO_Pos 0 +#define GMAC_ORLO_RXO_Msk (0xffffffffu << GMAC_ORLO_RXO_Pos) /**< \brief (GMAC_ORLO) Received Octets */ +/* -------- GMAC_ORHI : (GMAC Offset: 0x154) Octets Received [47:32] Received -------- */ +#define GMAC_ORHI_RXO_Pos 0 +#define GMAC_ORHI_RXO_Msk (0xffffu << GMAC_ORHI_RXO_Pos) /**< \brief (GMAC_ORHI) Received Octets */ +/* -------- GMAC_FR : (GMAC Offset: 0x158) Frames Received Register -------- */ +#define GMAC_FR_FRX_Pos 0 +#define GMAC_FR_FRX_Msk (0xffffffffu << GMAC_FR_FRX_Pos) /**< \brief (GMAC_FR) Frames Received without Error */ +/* -------- GMAC_BCFR : (GMAC Offset: 0x15C) Broadcast Frames Received Register -------- */ +#define GMAC_BCFR_BFRX_Pos 0 +#define GMAC_BCFR_BFRX_Msk (0xffffffffu << GMAC_BCFR_BFRX_Pos) /**< \brief (GMAC_BCFR) Broadcast Frames Received without Error */ +/* -------- GMAC_MFR : (GMAC Offset: 0x160) Multicast Frames Received Register -------- */ +#define GMAC_MFR_MFRX_Pos 0 +#define GMAC_MFR_MFRX_Msk (0xffffffffu << GMAC_MFR_MFRX_Pos) /**< \brief (GMAC_MFR) Multicast Frames Received without Error */ +/* -------- GMAC_PFR : (GMAC Offset: 0x164) Pause Frames Received Register -------- */ +#define GMAC_PFR_PFRX_Pos 0 +#define GMAC_PFR_PFRX_Msk (0xffffu << GMAC_PFR_PFRX_Pos) /**< \brief (GMAC_PFR) Pause Frames Received Register */ +/* -------- GMAC_BFR64 : (GMAC Offset: 0x168) 64 Byte Frames Received Register -------- */ +#define GMAC_BFR64_NFRX_Pos 0 +#define GMAC_BFR64_NFRX_Msk (0xffffffffu << GMAC_BFR64_NFRX_Pos) /**< \brief (GMAC_BFR64) 64 Byte Frames Received without Error */ +/* -------- GMAC_TBFR127 : (GMAC Offset: 0x16C) 65 to 127 Byte Frames Received Register -------- */ +#define GMAC_TBFR127_NFRX_Pos 0 +#define GMAC_TBFR127_NFRX_Msk (0xffffffffu << GMAC_TBFR127_NFRX_Pos) /**< \brief (GMAC_TBFR127) 65 to 127 Byte Frames Received without Error */ +/* -------- GMAC_TBFR255 : (GMAC Offset: 0x170) 128 to 255 Byte Frames Received Register -------- */ +#define GMAC_TBFR255_NFRX_Pos 0 +#define GMAC_TBFR255_NFRX_Msk (0xffffffffu << GMAC_TBFR255_NFRX_Pos) /**< \brief (GMAC_TBFR255) 128 to 255 Byte Frames Received without Error */ +/* -------- GMAC_TBFR511 : (GMAC Offset: 0x174) 256 to 511Byte Frames Received Register -------- */ +#define GMAC_TBFR511_NFRX_Pos 0 +#define GMAC_TBFR511_NFRX_Msk (0xffffffffu << GMAC_TBFR511_NFRX_Pos) /**< \brief (GMAC_TBFR511) 256 to 511 Byte Frames Received without Error */ +/* -------- GMAC_TBFR1023 : (GMAC Offset: 0x178) 512 to 1023 Byte Frames Received Register -------- */ +#define GMAC_TBFR1023_NFRX_Pos 0 +#define GMAC_TBFR1023_NFRX_Msk (0xffffffffu << GMAC_TBFR1023_NFRX_Pos) /**< \brief (GMAC_TBFR1023) 512 to 1023 Byte Frames Received without Error */ +/* -------- GMAC_TBFR1518 : (GMAC Offset: 0x17C) 1024 to 1518 Byte Frames Received Register -------- */ +#define GMAC_TBFR1518_NFRX_Pos 0 +#define GMAC_TBFR1518_NFRX_Msk (0xffffffffu << GMAC_TBFR1518_NFRX_Pos) /**< \brief (GMAC_TBFR1518) 1024 to 1518 Byte Frames Received without Error */ +/* -------- GMAC_TMXBFR : (GMAC Offset: 0x180) 1519 to Maximum Byte Frames Received Register -------- */ +#define GMAC_TMXBFR_NFRX_Pos 0 +#define GMAC_TMXBFR_NFRX_Msk (0xffffffffu << GMAC_TMXBFR_NFRX_Pos) /**< \brief (GMAC_TMXBFR) 1519 to Maximum Byte Frames Received without Error */ +/* -------- GMAC_UFR : (GMAC Offset: 0x184) Undersize Frames Received Register -------- */ +#define GMAC_UFR_UFRX_Pos 0 +#define GMAC_UFR_UFRX_Msk (0x3ffu << GMAC_UFR_UFRX_Pos) /**< \brief (GMAC_UFR) Undersize Frames Received */ +/* -------- GMAC_OFR : (GMAC Offset: 0x188) Oversize Frames Received Register -------- */ +#define GMAC_OFR_OFRX_Pos 0 +#define GMAC_OFR_OFRX_Msk (0x3ffu << GMAC_OFR_OFRX_Pos) /**< \brief (GMAC_OFR) Oversized Frames Received */ +/* -------- GMAC_JR : (GMAC Offset: 0x18C) Jabbers Received Register -------- */ +#define GMAC_JR_JRX_Pos 0 +#define GMAC_JR_JRX_Msk (0x3ffu << GMAC_JR_JRX_Pos) /**< \brief (GMAC_JR) Jabbers Received */ +/* -------- GMAC_FCSE : (GMAC Offset: 0x190) Frame Check Sequence Errors Register -------- */ +#define GMAC_FCSE_FCKR_Pos 0 +#define GMAC_FCSE_FCKR_Msk (0x3ffu << GMAC_FCSE_FCKR_Pos) /**< \brief (GMAC_FCSE) Frame Check Sequence Errors */ +/* -------- GMAC_LFFE : (GMAC Offset: 0x194) Length Field Frame Errors Register -------- */ +#define GMAC_LFFE_LFER_Pos 0 +#define GMAC_LFFE_LFER_Msk (0x3ffu << GMAC_LFFE_LFER_Pos) /**< \brief (GMAC_LFFE) Length Field Frame Errors */ +/* -------- GMAC_RSE : (GMAC Offset: 0x198) Receive Symbol Errors Register -------- */ +#define GMAC_RSE_RXSE_Pos 0 +#define GMAC_RSE_RXSE_Msk (0x3ffu << GMAC_RSE_RXSE_Pos) /**< \brief (GMAC_RSE) Receive Symbol Errors */ +/* -------- GMAC_AE : (GMAC Offset: 0x19C) Alignment Errors Register -------- */ +#define GMAC_AE_AER_Pos 0 +#define GMAC_AE_AER_Msk (0x3ffu << GMAC_AE_AER_Pos) /**< \brief (GMAC_AE) Alignment Errors */ +/* -------- GMAC_RRE : (GMAC Offset: 0x1A0) Receive Resource Errors Register -------- */ +#define GMAC_RRE_RXRER_Pos 0 +#define GMAC_RRE_RXRER_Msk (0x3ffffu << GMAC_RRE_RXRER_Pos) /**< \brief (GMAC_RRE) Receive Resource Errors */ +/* -------- GMAC_ROE : (GMAC Offset: 0x1A4) Receive Overrun Register -------- */ +#define GMAC_ROE_RXOVR_Pos 0 +#define GMAC_ROE_RXOVR_Msk (0x3ffu << GMAC_ROE_RXOVR_Pos) /**< \brief (GMAC_ROE) Receive Overruns */ +/* -------- GMAC_IHCE : (GMAC Offset: 0x1A8) IP Header Checksum Errors Register -------- */ +#define GMAC_IHCE_HCKER_Pos 0 +#define GMAC_IHCE_HCKER_Msk (0xffu << GMAC_IHCE_HCKER_Pos) /**< \brief (GMAC_IHCE) IP Header Checksum Errors */ +/* -------- GMAC_TCE : (GMAC Offset: 0x1AC) TCP Checksum Errors Register -------- */ +#define GMAC_TCE_TCKER_Pos 0 +#define GMAC_TCE_TCKER_Msk (0xffu << GMAC_TCE_TCKER_Pos) /**< \brief (GMAC_TCE) TCP Checksum Errors */ +/* -------- GMAC_UCE : (GMAC Offset: 0x1B0) UDP Checksum Errors Register -------- */ +#define GMAC_UCE_UCKER_Pos 0 +#define GMAC_UCE_UCKER_Msk (0xffu << GMAC_UCE_UCKER_Pos) /**< \brief (GMAC_UCE) UDP Checksum Errors */ +/* -------- GMAC_TSSSL : (GMAC Offset: 0x1C8) 1588 Timer Sync Strobe Seconds [31:0] Register -------- */ +#define GMAC_TSSSL_VTS_Pos 0 +#define GMAC_TSSSL_VTS_Msk (0xffffffffu << GMAC_TSSSL_VTS_Pos) /**< \brief (GMAC_TSSSL) Value of Timer Seconds Register Capture */ +#define GMAC_TSSSL_VTS(value) ((GMAC_TSSSL_VTS_Msk & ((value) << GMAC_TSSSL_VTS_Pos))) +/* -------- GMAC_TSSN : (GMAC Offset: 0x1CC) 1588 Timer Sync Strobe Nanoseconds Register -------- */ +#define GMAC_TSSN_VTN_Pos 0 +#define GMAC_TSSN_VTN_Msk (0x3fffffffu << GMAC_TSSN_VTN_Pos) /**< \brief (GMAC_TSSN) Value Timer Nanoseconds Register Capture */ +#define GMAC_TSSN_VTN(value) ((GMAC_TSSN_VTN_Msk & ((value) << GMAC_TSSN_VTN_Pos))) +/* -------- GMAC_TSL : (GMAC Offset: 0x1D0) 1588 Timer Seconds [31:0] Register -------- */ +#define GMAC_TSL_TCS_Pos 0 +#define GMAC_TSL_TCS_Msk (0xffffffffu << GMAC_TSL_TCS_Pos) /**< \brief (GMAC_TSL) Timer Count in Seconds */ +#define GMAC_TSL_TCS(value) ((GMAC_TSL_TCS_Msk & ((value) << GMAC_TSL_TCS_Pos))) +/* -------- GMAC_TN : (GMAC Offset: 0x1D4) 1588 Timer Nanoseconds Register -------- */ +#define GMAC_TN_TNS_Pos 0 +#define GMAC_TN_TNS_Msk (0x3fffffffu << GMAC_TN_TNS_Pos) /**< \brief (GMAC_TN) Timer Count in Nanoseconds */ +#define GMAC_TN_TNS(value) ((GMAC_TN_TNS_Msk & ((value) << GMAC_TN_TNS_Pos))) +/* -------- GMAC_TA : (GMAC Offset: 0x1D8) 1588 Timer Adjust Register -------- */ +#define GMAC_TA_ITDT_Pos 0 +#define GMAC_TA_ITDT_Msk (0x3fffffffu << GMAC_TA_ITDT_Pos) /**< \brief (GMAC_TA) Increment/Decrement */ +#define GMAC_TA_ITDT(value) ((GMAC_TA_ITDT_Msk & ((value) << GMAC_TA_ITDT_Pos))) +#define GMAC_TA_ADJ (0x1u << 31) /**< \brief (GMAC_TA) Adjust 1588 Timer */ +/* -------- GMAC_TI : (GMAC Offset: 0x1DC) 1588 Timer Increment Register -------- */ +#define GMAC_TI_CNS_Pos 0 +#define GMAC_TI_CNS_Msk (0xffu << GMAC_TI_CNS_Pos) /**< \brief (GMAC_TI) Count Nanoseconds */ +#define GMAC_TI_CNS(value) ((GMAC_TI_CNS_Msk & ((value) << GMAC_TI_CNS_Pos))) +#define GMAC_TI_ACNS_Pos 8 +#define GMAC_TI_ACNS_Msk (0xffu << GMAC_TI_ACNS_Pos) /**< \brief (GMAC_TI) Alternative Count Nanoseconds */ +#define GMAC_TI_ACNS(value) ((GMAC_TI_ACNS_Msk & ((value) << GMAC_TI_ACNS_Pos))) +#define GMAC_TI_NIT_Pos 16 +#define GMAC_TI_NIT_Msk (0xffu << GMAC_TI_NIT_Pos) /**< \brief (GMAC_TI) Number of Increments */ +#define GMAC_TI_NIT(value) ((GMAC_TI_NIT_Msk & ((value) << GMAC_TI_NIT_Pos))) +/* -------- GMAC_EFTS : (GMAC Offset: 0x1E0) PTP Event Frame Transmitted Seconds -------- */ +#define GMAC_EFTS_RUD_Pos 0 +#define GMAC_EFTS_RUD_Msk (0xffffffffu << GMAC_EFTS_RUD_Pos) /**< \brief (GMAC_EFTS) Register Update */ +/* -------- GMAC_EFTN : (GMAC Offset: 0x1E4) PTP Event Frame Transmitted Nanoseconds -------- */ +#define GMAC_EFTN_RUD_Pos 0 +#define GMAC_EFTN_RUD_Msk (0x3fffffffu << GMAC_EFTN_RUD_Pos) /**< \brief (GMAC_EFTN) Register Update */ +/* -------- GMAC_EFRS : (GMAC Offset: 0x1E8) PTP Event Frame Received Seconds -------- */ +#define GMAC_EFRS_RUD_Pos 0 +#define GMAC_EFRS_RUD_Msk (0xffffffffu << GMAC_EFRS_RUD_Pos) /**< \brief (GMAC_EFRS) Register Update */ +/* -------- GMAC_EFRN : (GMAC Offset: 0x1EC) PTP Event Frame Received Nanoseconds -------- */ +#define GMAC_EFRN_RUD_Pos 0 +#define GMAC_EFRN_RUD_Msk (0x3fffffffu << GMAC_EFRN_RUD_Pos) /**< \brief (GMAC_EFRN) Register Update */ +/* -------- GMAC_PEFTS : (GMAC Offset: 0x1F0) PTP Peer Event Frame Transmitted Seconds -------- */ +#define GMAC_PEFTS_RUD_Pos 0 +#define GMAC_PEFTS_RUD_Msk (0xffffffffu << GMAC_PEFTS_RUD_Pos) /**< \brief (GMAC_PEFTS) Register Update */ +/* -------- GMAC_PEFTN : (GMAC Offset: 0x1F4) PTP Peer Event Frame Transmitted Nanoseconds -------- */ +#define GMAC_PEFTN_RUD_Pos 0 +#define GMAC_PEFTN_RUD_Msk (0x3fffffffu << GMAC_PEFTN_RUD_Pos) /**< \brief (GMAC_PEFTN) Register Update */ +/* -------- GMAC_PEFRS : (GMAC Offset: 0x1F8) PTP Peer Event Frame Received Seconds -------- */ +#define GMAC_PEFRS_RUD_Pos 0 +#define GMAC_PEFRS_RUD_Msk (0xffffffffu << GMAC_PEFRS_RUD_Pos) /**< \brief (GMAC_PEFRS) Register Update */ +/* -------- GMAC_PEFRN : (GMAC Offset: 0x1FC) PTP Peer Event Frame Received Nanoseconds -------- */ +#define GMAC_PEFRN_RUD_Pos 0 +#define GMAC_PEFRN_RUD_Msk (0x3fffffffu << GMAC_PEFRN_RUD_Pos) /**< \brief (GMAC_PEFRN) Register Update */ + +/*@}*/ + + +#endif /* _SAM4E_GMAC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gpbr.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gpbr.h new file mode 100644 index 0000000..f4ec0ae --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/gpbr.h @@ -0,0 +1,68 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_GPBR_COMPONENT_ +#define _SAM4E_GPBR_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR General Purpose Backup Registers */ +/* ============================================================================= */ +/** \addtogroup SAM4E_GPBR General Purpose Backup Registers */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Gpbr hardware registers */ +typedef struct { + __IO uint32_t SYS_GPBR[20]; /**< \brief (Gpbr Offset: 0x0) General Purpose Backup Register */ +} Gpbr; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- SYS_GPBR[20] : (GPBR Offset: 0x0) General Purpose Backup Register -------- */ +#define SYS_GPBR_GPBR_VALUE_Pos 0 +#define SYS_GPBR_GPBR_VALUE_Msk (0xffffffffu << SYS_GPBR_GPBR_VALUE_Pos) /**< \brief (SYS_GPBR[20]) Value of GPBR x */ +#define SYS_GPBR_GPBR_VALUE(value) ((SYS_GPBR_GPBR_VALUE_Msk & ((value) << SYS_GPBR_GPBR_VALUE_Pos))) + +/*@}*/ + + +#endif /* _SAM4E_GPBR_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/hsmci.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/hsmci.h new file mode 100644 index 0000000..e7d9e8e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/hsmci.h @@ -0,0 +1,393 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_HSMCI_COMPONENT_ +#define _SAM4E_HSMCI_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR High Speed MultiMedia Card Interface */ +/* ============================================================================= */ +/** \addtogroup SAM4E_HSMCI High Speed MultiMedia Card Interface */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Hsmci hardware registers */ +typedef struct { + __O uint32_t HSMCI_CR; /**< \brief (Hsmci Offset: 0x00) Control Register */ + __IO uint32_t HSMCI_MR; /**< \brief (Hsmci Offset: 0x04) Mode Register */ + __IO uint32_t HSMCI_DTOR; /**< \brief (Hsmci Offset: 0x08) Data Timeout Register */ + __IO uint32_t HSMCI_SDCR; /**< \brief (Hsmci Offset: 0x0C) SD/SDIO Card Register */ + __IO uint32_t HSMCI_ARGR; /**< \brief (Hsmci Offset: 0x10) Argument Register */ + __O uint32_t HSMCI_CMDR; /**< \brief (Hsmci Offset: 0x14) Command Register */ + __IO uint32_t HSMCI_BLKR; /**< \brief (Hsmci Offset: 0x18) Block Register */ + __IO uint32_t HSMCI_CSTOR; /**< \brief (Hsmci Offset: 0x1C) Completion Signal Timeout Register */ + __I uint32_t HSMCI_RSPR[4]; /**< \brief (Hsmci Offset: 0x20) Response Register */ + __I uint32_t HSMCI_RDR; /**< \brief (Hsmci Offset: 0x30) Receive Data Register */ + __O uint32_t HSMCI_TDR; /**< \brief (Hsmci Offset: 0x34) Transmit Data Register */ + __I uint32_t Reserved1[2]; + __I uint32_t HSMCI_SR; /**< \brief (Hsmci Offset: 0x40) Status Register */ + __O uint32_t HSMCI_IER; /**< \brief (Hsmci Offset: 0x44) Interrupt Enable Register */ + __O uint32_t HSMCI_IDR; /**< \brief (Hsmci Offset: 0x48) Interrupt Disable Register */ + __I uint32_t HSMCI_IMR; /**< \brief (Hsmci Offset: 0x4C) Interrupt Mask Register */ + __I uint32_t Reserved2[1]; + __IO uint32_t HSMCI_CFG; /**< \brief (Hsmci Offset: 0x54) Configuration Register */ + __I uint32_t Reserved3[35]; + __IO uint32_t HSMCI_WPMR; /**< \brief (Hsmci Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t HSMCI_WPSR; /**< \brief (Hsmci Offset: 0xE8) Write Protection Status Register */ + __I uint32_t Reserved4[5]; + __IO uint32_t HSMCI_RPR; /**< \brief (Hsmci Offset: 0x100) Receive Pointer Register */ + __IO uint32_t HSMCI_RCR; /**< \brief (Hsmci Offset: 0x104) Receive Counter Register */ + __IO uint32_t HSMCI_TPR; /**< \brief (Hsmci Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t HSMCI_TCR; /**< \brief (Hsmci Offset: 0x10C) Transmit Counter Register */ + __IO uint32_t HSMCI_RNPR; /**< \brief (Hsmci Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t HSMCI_RNCR; /**< \brief (Hsmci Offset: 0x114) Receive Next Counter Register */ + __IO uint32_t HSMCI_TNPR; /**< \brief (Hsmci Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t HSMCI_TNCR; /**< \brief (Hsmci Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t HSMCI_PTCR; /**< \brief (Hsmci Offset: 0x120) Transfer Control Register */ + __I uint32_t HSMCI_PTSR; /**< \brief (Hsmci Offset: 0x124) Transfer Status Register */ + __I uint32_t Reserved5[54]; + __IO uint32_t HSMCI_FIFO[256]; /**< \brief (Hsmci Offset: 0x200) FIFO Memory Aperture0 */ +} Hsmci; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- HSMCI_CR : (HSMCI Offset: 0x00) Control Register -------- */ +#define HSMCI_CR_MCIEN (0x1u << 0) /**< \brief (HSMCI_CR) Multi-Media Interface Enable */ +#define HSMCI_CR_MCIDIS (0x1u << 1) /**< \brief (HSMCI_CR) Multi-Media Interface Disable */ +#define HSMCI_CR_PWSEN (0x1u << 2) /**< \brief (HSMCI_CR) Power Save Mode Enable */ +#define HSMCI_CR_PWSDIS (0x1u << 3) /**< \brief (HSMCI_CR) Power Save Mode Disable */ +#define HSMCI_CR_SWRST (0x1u << 7) /**< \brief (HSMCI_CR) Software Reset */ +/* -------- HSMCI_MR : (HSMCI Offset: 0x04) Mode Register -------- */ +#define HSMCI_MR_CLKDIV_Pos 0 +#define HSMCI_MR_CLKDIV_Msk (0xffu << HSMCI_MR_CLKDIV_Pos) /**< \brief (HSMCI_MR) Clock Divider */ +#define HSMCI_MR_CLKDIV(value) ((HSMCI_MR_CLKDIV_Msk & ((value) << HSMCI_MR_CLKDIV_Pos))) +#define HSMCI_MR_PWSDIV_Pos 8 +#define HSMCI_MR_PWSDIV_Msk (0x7u << HSMCI_MR_PWSDIV_Pos) /**< \brief (HSMCI_MR) Power Saving Divider */ +#define HSMCI_MR_PWSDIV(value) ((HSMCI_MR_PWSDIV_Msk & ((value) << HSMCI_MR_PWSDIV_Pos))) +#define HSMCI_MR_RDPROOF (0x1u << 11) /**< \brief (HSMCI_MR) Read Proof Enable */ +#define HSMCI_MR_WRPROOF (0x1u << 12) /**< \brief (HSMCI_MR) Write Proof Enable */ +#define HSMCI_MR_FBYTE (0x1u << 13) /**< \brief (HSMCI_MR) Force Byte Transfer */ +#define HSMCI_MR_PADV (0x1u << 14) /**< \brief (HSMCI_MR) Padding Value */ +#define HSMCI_MR_PDCMODE (0x1u << 15) /**< \brief (HSMCI_MR) PDC-oriented Mode */ +#define HSMCI_MR_CLKODD (0x1u << 16) /**< \brief (HSMCI_MR) Clock divider is odd */ +/* -------- HSMCI_DTOR : (HSMCI Offset: 0x08) Data Timeout Register -------- */ +#define HSMCI_DTOR_DTOCYC_Pos 0 +#define HSMCI_DTOR_DTOCYC_Msk (0xfu << HSMCI_DTOR_DTOCYC_Pos) /**< \brief (HSMCI_DTOR) Data Timeout Cycle Number */ +#define HSMCI_DTOR_DTOCYC(value) ((HSMCI_DTOR_DTOCYC_Msk & ((value) << HSMCI_DTOR_DTOCYC_Pos))) +#define HSMCI_DTOR_DTOMUL_Pos 4 +#define HSMCI_DTOR_DTOMUL_Msk (0x7u << HSMCI_DTOR_DTOMUL_Pos) /**< \brief (HSMCI_DTOR) Data Timeout Multiplier */ +#define HSMCI_DTOR_DTOMUL_1 (0x0u << 4) /**< \brief (HSMCI_DTOR) DTOCYC */ +#define HSMCI_DTOR_DTOMUL_16 (0x1u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 16 */ +#define HSMCI_DTOR_DTOMUL_128 (0x2u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 128 */ +#define HSMCI_DTOR_DTOMUL_256 (0x3u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 256 */ +#define HSMCI_DTOR_DTOMUL_1024 (0x4u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 1024 */ +#define HSMCI_DTOR_DTOMUL_4096 (0x5u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 4096 */ +#define HSMCI_DTOR_DTOMUL_65536 (0x6u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 65536 */ +#define HSMCI_DTOR_DTOMUL_1048576 (0x7u << 4) /**< \brief (HSMCI_DTOR) DTOCYC x 1048576 */ +/* -------- HSMCI_SDCR : (HSMCI Offset: 0x0C) SD/SDIO Card Register -------- */ +#define HSMCI_SDCR_SDCSEL_Pos 0 +#define HSMCI_SDCR_SDCSEL_Msk (0x3u << HSMCI_SDCR_SDCSEL_Pos) /**< \brief (HSMCI_SDCR) SDCard/SDIO Slot */ +#define HSMCI_SDCR_SDCSEL_SLOTA (0x0u << 0) /**< \brief (HSMCI_SDCR) Slot A is selected. */ +#define HSMCI_SDCR_SDCSEL_SLOTB (0x1u << 0) /**< \brief (HSMCI_SDCR) - */ +#define HSMCI_SDCR_SDCSEL_SLOTC (0x2u << 0) /**< \brief (HSMCI_SDCR) - */ +#define HSMCI_SDCR_SDCSEL_SLOTD (0x3u << 0) /**< \brief (HSMCI_SDCR) - */ +#define HSMCI_SDCR_SDCBUS_Pos 6 +#define HSMCI_SDCR_SDCBUS_Msk (0x3u << HSMCI_SDCR_SDCBUS_Pos) /**< \brief (HSMCI_SDCR) SDCard/SDIO Bus Width */ +#define HSMCI_SDCR_SDCBUS_1 (0x0u << 6) /**< \brief (HSMCI_SDCR) 1 bit */ +#define HSMCI_SDCR_SDCBUS_4 (0x2u << 6) /**< \brief (HSMCI_SDCR) 4 bits */ +#define HSMCI_SDCR_SDCBUS_8 (0x3u << 6) /**< \brief (HSMCI_SDCR) 8 bits */ +/* -------- HSMCI_ARGR : (HSMCI Offset: 0x10) Argument Register -------- */ +#define HSMCI_ARGR_ARG_Pos 0 +#define HSMCI_ARGR_ARG_Msk (0xffffffffu << HSMCI_ARGR_ARG_Pos) /**< \brief (HSMCI_ARGR) Command Argument */ +#define HSMCI_ARGR_ARG(value) ((HSMCI_ARGR_ARG_Msk & ((value) << HSMCI_ARGR_ARG_Pos))) +/* -------- HSMCI_CMDR : (HSMCI Offset: 0x14) Command Register -------- */ +#define HSMCI_CMDR_CMDNB_Pos 0 +#define HSMCI_CMDR_CMDNB_Msk (0x3fu << HSMCI_CMDR_CMDNB_Pos) /**< \brief (HSMCI_CMDR) Command Number */ +#define HSMCI_CMDR_CMDNB(value) ((HSMCI_CMDR_CMDNB_Msk & ((value) << HSMCI_CMDR_CMDNB_Pos))) +#define HSMCI_CMDR_RSPTYP_Pos 6 +#define HSMCI_CMDR_RSPTYP_Msk (0x3u << HSMCI_CMDR_RSPTYP_Pos) /**< \brief (HSMCI_CMDR) Response Type */ +#define HSMCI_CMDR_RSPTYP_NORESP (0x0u << 6) /**< \brief (HSMCI_CMDR) No response */ +#define HSMCI_CMDR_RSPTYP_48_BIT (0x1u << 6) /**< \brief (HSMCI_CMDR) 48-bit response */ +#define HSMCI_CMDR_RSPTYP_136_BIT (0x2u << 6) /**< \brief (HSMCI_CMDR) 136-bit response */ +#define HSMCI_CMDR_RSPTYP_R1B (0x3u << 6) /**< \brief (HSMCI_CMDR) R1b response type */ +#define HSMCI_CMDR_SPCMD_Pos 8 +#define HSMCI_CMDR_SPCMD_Msk (0x7u << HSMCI_CMDR_SPCMD_Pos) /**< \brief (HSMCI_CMDR) Special Command */ +#define HSMCI_CMDR_SPCMD_STD (0x0u << 8) /**< \brief (HSMCI_CMDR) Not a special CMD. */ +#define HSMCI_CMDR_SPCMD_INIT (0x1u << 8) /**< \brief (HSMCI_CMDR) Initialization CMD: 74 clock cycles for initialization sequence. */ +#define HSMCI_CMDR_SPCMD_SYNC (0x2u << 8) /**< \brief (HSMCI_CMDR) Synchronized CMD: Wait for the end of the current data block transfer before sending the pending command. */ +#define HSMCI_CMDR_SPCMD_CE_ATA (0x3u << 8) /**< \brief (HSMCI_CMDR) CE-ATA Completion Signal disable Command. The host cancels the ability for the device to return a command completion signal on the command line. */ +#define HSMCI_CMDR_SPCMD_IT_CMD (0x4u << 8) /**< \brief (HSMCI_CMDR) Interrupt command: Corresponds to the Interrupt Mode (CMD40). */ +#define HSMCI_CMDR_SPCMD_IT_RESP (0x5u << 8) /**< \brief (HSMCI_CMDR) Interrupt response: Corresponds to the Interrupt Mode (CMD40). */ +#define HSMCI_CMDR_SPCMD_BOR (0x6u << 8) /**< \brief (HSMCI_CMDR) Boot Operation Request. Start a boot operation mode, the host processor can read boot data from the MMC device directly. */ +#define HSMCI_CMDR_SPCMD_EBO (0x7u << 8) /**< \brief (HSMCI_CMDR) End Boot Operation. This command allows the host processor to terminate the boot operation mode. */ +#define HSMCI_CMDR_OPDCMD (0x1u << 11) /**< \brief (HSMCI_CMDR) Open Drain Command */ +#define HSMCI_CMDR_OPDCMD_PUSHPULL (0x0u << 11) /**< \brief (HSMCI_CMDR) Push pull command. */ +#define HSMCI_CMDR_OPDCMD_OPENDRAIN (0x1u << 11) /**< \brief (HSMCI_CMDR) Open drain command. */ +#define HSMCI_CMDR_MAXLAT (0x1u << 12) /**< \brief (HSMCI_CMDR) Max Latency for Command to Response */ +#define HSMCI_CMDR_MAXLAT_5 (0x0u << 12) /**< \brief (HSMCI_CMDR) 5-cycle max latency. */ +#define HSMCI_CMDR_MAXLAT_64 (0x1u << 12) /**< \brief (HSMCI_CMDR) 64-cycle max latency. */ +#define HSMCI_CMDR_TRCMD_Pos 16 +#define HSMCI_CMDR_TRCMD_Msk (0x3u << HSMCI_CMDR_TRCMD_Pos) /**< \brief (HSMCI_CMDR) Transfer Command */ +#define HSMCI_CMDR_TRCMD_NO_DATA (0x0u << 16) /**< \brief (HSMCI_CMDR) No data transfer */ +#define HSMCI_CMDR_TRCMD_START_DATA (0x1u << 16) /**< \brief (HSMCI_CMDR) Start data transfer */ +#define HSMCI_CMDR_TRCMD_STOP_DATA (0x2u << 16) /**< \brief (HSMCI_CMDR) Stop data transfer */ +#define HSMCI_CMDR_TRDIR (0x1u << 18) /**< \brief (HSMCI_CMDR) Transfer Direction */ +#define HSMCI_CMDR_TRDIR_WRITE (0x0u << 18) /**< \brief (HSMCI_CMDR) Write. */ +#define HSMCI_CMDR_TRDIR_READ (0x1u << 18) /**< \brief (HSMCI_CMDR) Read. */ +#define HSMCI_CMDR_TRTYP_Pos 19 +#define HSMCI_CMDR_TRTYP_Msk (0x7u << HSMCI_CMDR_TRTYP_Pos) /**< \brief (HSMCI_CMDR) Transfer Type */ +#define HSMCI_CMDR_TRTYP_SINGLE (0x0u << 19) /**< \brief (HSMCI_CMDR) MMC/SD Card Single Block */ +#define HSMCI_CMDR_TRTYP_MULTIPLE (0x1u << 19) /**< \brief (HSMCI_CMDR) MMC/SD Card Multiple Block */ +#define HSMCI_CMDR_TRTYP_STREAM (0x2u << 19) /**< \brief (HSMCI_CMDR) MMC Stream */ +#define HSMCI_CMDR_TRTYP_BYTE (0x4u << 19) /**< \brief (HSMCI_CMDR) SDIO Byte */ +#define HSMCI_CMDR_TRTYP_BLOCK (0x5u << 19) /**< \brief (HSMCI_CMDR) SDIO Block */ +#define HSMCI_CMDR_IOSPCMD_Pos 24 +#define HSMCI_CMDR_IOSPCMD_Msk (0x3u << HSMCI_CMDR_IOSPCMD_Pos) /**< \brief (HSMCI_CMDR) SDIO Special Command */ +#define HSMCI_CMDR_IOSPCMD_STD (0x0u << 24) /**< \brief (HSMCI_CMDR) Not an SDIO Special Command */ +#define HSMCI_CMDR_IOSPCMD_SUSPEND (0x1u << 24) /**< \brief (HSMCI_CMDR) SDIO Suspend Command */ +#define HSMCI_CMDR_IOSPCMD_RESUME (0x2u << 24) /**< \brief (HSMCI_CMDR) SDIO Resume Command */ +#define HSMCI_CMDR_ATACS (0x1u << 26) /**< \brief (HSMCI_CMDR) ATA with Command Completion Signal */ +#define HSMCI_CMDR_ATACS_NORMAL (0x0u << 26) /**< \brief (HSMCI_CMDR) Normal operation mode. */ +#define HSMCI_CMDR_ATACS_COMPLETION (0x1u << 26) /**< \brief (HSMCI_CMDR) This bit indicates that a completion signal is expected within a programmed amount of time (HSMCI_CSTOR). */ +#define HSMCI_CMDR_BOOT_ACK (0x1u << 27) /**< \brief (HSMCI_CMDR) Boot Operation Acknowledge */ +/* -------- HSMCI_BLKR : (HSMCI Offset: 0x18) Block Register -------- */ +#define HSMCI_BLKR_BCNT_Pos 0 +#define HSMCI_BLKR_BCNT_Msk (0xffffu << HSMCI_BLKR_BCNT_Pos) /**< \brief (HSMCI_BLKR) MMC/SDIO Block Count - SDIO Byte Count */ +#define HSMCI_BLKR_BCNT(value) ((HSMCI_BLKR_BCNT_Msk & ((value) << HSMCI_BLKR_BCNT_Pos))) +#define HSMCI_BLKR_BLKLEN_Pos 16 +#define HSMCI_BLKR_BLKLEN_Msk (0xffffu << HSMCI_BLKR_BLKLEN_Pos) /**< \brief (HSMCI_BLKR) Data Block Length */ +#define HSMCI_BLKR_BLKLEN(value) ((HSMCI_BLKR_BLKLEN_Msk & ((value) << HSMCI_BLKR_BLKLEN_Pos))) +/* -------- HSMCI_CSTOR : (HSMCI Offset: 0x1C) Completion Signal Timeout Register -------- */ +#define HSMCI_CSTOR_CSTOCYC_Pos 0 +#define HSMCI_CSTOR_CSTOCYC_Msk (0xfu << HSMCI_CSTOR_CSTOCYC_Pos) /**< \brief (HSMCI_CSTOR) Completion Signal Timeout Cycle Number */ +#define HSMCI_CSTOR_CSTOCYC(value) ((HSMCI_CSTOR_CSTOCYC_Msk & ((value) << HSMCI_CSTOR_CSTOCYC_Pos))) +#define HSMCI_CSTOR_CSTOMUL_Pos 4 +#define HSMCI_CSTOR_CSTOMUL_Msk (0x7u << HSMCI_CSTOR_CSTOMUL_Pos) /**< \brief (HSMCI_CSTOR) Completion Signal Timeout Multiplier */ +#define HSMCI_CSTOR_CSTOMUL_1 (0x0u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1 */ +#define HSMCI_CSTOR_CSTOMUL_16 (0x1u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 16 */ +#define HSMCI_CSTOR_CSTOMUL_128 (0x2u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 128 */ +#define HSMCI_CSTOR_CSTOMUL_256 (0x3u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 256 */ +#define HSMCI_CSTOR_CSTOMUL_1024 (0x4u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1024 */ +#define HSMCI_CSTOR_CSTOMUL_4096 (0x5u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 4096 */ +#define HSMCI_CSTOR_CSTOMUL_65536 (0x6u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 65536 */ +#define HSMCI_CSTOR_CSTOMUL_1048576 (0x7u << 4) /**< \brief (HSMCI_CSTOR) CSTOCYC x 1048576 */ +/* -------- HSMCI_RSPR[4] : (HSMCI Offset: 0x20) Response Register -------- */ +#define HSMCI_RSPR_RSP_Pos 0 +#define HSMCI_RSPR_RSP_Msk (0xffffffffu << HSMCI_RSPR_RSP_Pos) /**< \brief (HSMCI_RSPR[4]) Response */ +/* -------- HSMCI_RDR : (HSMCI Offset: 0x30) Receive Data Register -------- */ +#define HSMCI_RDR_DATA_Pos 0 +#define HSMCI_RDR_DATA_Msk (0xffffffffu << HSMCI_RDR_DATA_Pos) /**< \brief (HSMCI_RDR) Data to Read */ +/* -------- HSMCI_TDR : (HSMCI Offset: 0x34) Transmit Data Register -------- */ +#define HSMCI_TDR_DATA_Pos 0 +#define HSMCI_TDR_DATA_Msk (0xffffffffu << HSMCI_TDR_DATA_Pos) /**< \brief (HSMCI_TDR) Data to Write */ +#define HSMCI_TDR_DATA(value) ((HSMCI_TDR_DATA_Msk & ((value) << HSMCI_TDR_DATA_Pos))) +/* -------- HSMCI_SR : (HSMCI Offset: 0x40) Status Register -------- */ +#define HSMCI_SR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_SR) Command Ready */ +#define HSMCI_SR_RXRDY (0x1u << 1) /**< \brief (HSMCI_SR) Receiver Ready */ +#define HSMCI_SR_TXRDY (0x1u << 2) /**< \brief (HSMCI_SR) Transmit Ready */ +#define HSMCI_SR_BLKE (0x1u << 3) /**< \brief (HSMCI_SR) Data Block Ended */ +#define HSMCI_SR_DTIP (0x1u << 4) /**< \brief (HSMCI_SR) Data Transfer in Progress */ +#define HSMCI_SR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_SR) HSMCI Not Busy */ +#define HSMCI_SR_ENDRX (0x1u << 6) /**< \brief (HSMCI_SR) End of RX Buffer */ +#define HSMCI_SR_ENDTX (0x1u << 7) /**< \brief (HSMCI_SR) End of TX Buffer */ +#define HSMCI_SR_SDIOIRQA (0x1u << 8) /**< \brief (HSMCI_SR) SDIO Interrupt for Slot A */ +#define HSMCI_SR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_SR) SDIO Read Wait Operation Status */ +#define HSMCI_SR_CSRCV (0x1u << 13) /**< \brief (HSMCI_SR) CE-ATA Completion Signal Received */ +#define HSMCI_SR_RXBUFF (0x1u << 14) /**< \brief (HSMCI_SR) RX Buffer Full */ +#define HSMCI_SR_TXBUFE (0x1u << 15) /**< \brief (HSMCI_SR) TX Buffer Empty */ +#define HSMCI_SR_RINDE (0x1u << 16) /**< \brief (HSMCI_SR) Response Index Error */ +#define HSMCI_SR_RDIRE (0x1u << 17) /**< \brief (HSMCI_SR) Response Direction Error */ +#define HSMCI_SR_RCRCE (0x1u << 18) /**< \brief (HSMCI_SR) Response CRC Error */ +#define HSMCI_SR_RENDE (0x1u << 19) /**< \brief (HSMCI_SR) Response End Bit Error */ +#define HSMCI_SR_RTOE (0x1u << 20) /**< \brief (HSMCI_SR) Response Time-out Error */ +#define HSMCI_SR_DCRCE (0x1u << 21) /**< \brief (HSMCI_SR) Data CRC Error */ +#define HSMCI_SR_DTOE (0x1u << 22) /**< \brief (HSMCI_SR) Data Time-out Error */ +#define HSMCI_SR_CSTOE (0x1u << 23) /**< \brief (HSMCI_SR) Completion Signal Time-out Error */ +#define HSMCI_SR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_SR) FIFO empty flag */ +#define HSMCI_SR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_SR) Transfer Done flag */ +#define HSMCI_SR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_SR) Boot Operation Acknowledge Received */ +#define HSMCI_SR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_SR) Boot Operation Acknowledge Error */ +#define HSMCI_SR_OVRE (0x1u << 30) /**< \brief (HSMCI_SR) Overrun */ +#define HSMCI_SR_UNRE (0x1u << 31) /**< \brief (HSMCI_SR) Underrun */ +/* -------- HSMCI_IER : (HSMCI Offset: 0x44) Interrupt Enable Register -------- */ +#define HSMCI_IER_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IER) Command Ready Interrupt Enable */ +#define HSMCI_IER_RXRDY (0x1u << 1) /**< \brief (HSMCI_IER) Receiver Ready Interrupt Enable */ +#define HSMCI_IER_TXRDY (0x1u << 2) /**< \brief (HSMCI_IER) Transmit Ready Interrupt Enable */ +#define HSMCI_IER_BLKE (0x1u << 3) /**< \brief (HSMCI_IER) Data Block Ended Interrupt Enable */ +#define HSMCI_IER_DTIP (0x1u << 4) /**< \brief (HSMCI_IER) Data Transfer in Progress Interrupt Enable */ +#define HSMCI_IER_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IER) Data Not Busy Interrupt Enable */ +#define HSMCI_IER_ENDRX (0x1u << 6) /**< \brief (HSMCI_IER) End of Receive Buffer Interrupt Enable */ +#define HSMCI_IER_ENDTX (0x1u << 7) /**< \brief (HSMCI_IER) End of Transmit Buffer Interrupt Enable */ +#define HSMCI_IER_SDIOIRQA (0x1u << 8) /**< \brief (HSMCI_IER) SDIO Interrupt for Slot A Interrupt Enable */ +#define HSMCI_IER_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IER) SDIO Read Wait Operation Status Interrupt Enable */ +#define HSMCI_IER_CSRCV (0x1u << 13) /**< \brief (HSMCI_IER) Completion Signal Received Interrupt Enable */ +#define HSMCI_IER_RXBUFF (0x1u << 14) /**< \brief (HSMCI_IER) Receive Buffer Full Interrupt Enable */ +#define HSMCI_IER_TXBUFE (0x1u << 15) /**< \brief (HSMCI_IER) Transmit Buffer Empty Interrupt Enable */ +#define HSMCI_IER_RINDE (0x1u << 16) /**< \brief (HSMCI_IER) Response Index Error Interrupt Enable */ +#define HSMCI_IER_RDIRE (0x1u << 17) /**< \brief (HSMCI_IER) Response Direction Error Interrupt Enable */ +#define HSMCI_IER_RCRCE (0x1u << 18) /**< \brief (HSMCI_IER) Response CRC Error Interrupt Enable */ +#define HSMCI_IER_RENDE (0x1u << 19) /**< \brief (HSMCI_IER) Response End Bit Error Interrupt Enable */ +#define HSMCI_IER_RTOE (0x1u << 20) /**< \brief (HSMCI_IER) Response Time-out Error Interrupt Enable */ +#define HSMCI_IER_DCRCE (0x1u << 21) /**< \brief (HSMCI_IER) Data CRC Error Interrupt Enable */ +#define HSMCI_IER_DTOE (0x1u << 22) /**< \brief (HSMCI_IER) Data Time-out Error Interrupt Enable */ +#define HSMCI_IER_CSTOE (0x1u << 23) /**< \brief (HSMCI_IER) Completion Signal Timeout Error Interrupt Enable */ +#define HSMCI_IER_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IER) FIFO empty Interrupt enable */ +#define HSMCI_IER_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IER) Transfer Done Interrupt enable */ +#define HSMCI_IER_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IER) Boot Acknowledge Interrupt Enable */ +#define HSMCI_IER_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IER) Boot Acknowledge Error Interrupt Enable */ +#define HSMCI_IER_OVRE (0x1u << 30) /**< \brief (HSMCI_IER) Overrun Interrupt Enable */ +#define HSMCI_IER_UNRE (0x1u << 31) /**< \brief (HSMCI_IER) Underrun Interrupt Enable */ +/* -------- HSMCI_IDR : (HSMCI Offset: 0x48) Interrupt Disable Register -------- */ +#define HSMCI_IDR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IDR) Command Ready Interrupt Disable */ +#define HSMCI_IDR_RXRDY (0x1u << 1) /**< \brief (HSMCI_IDR) Receiver Ready Interrupt Disable */ +#define HSMCI_IDR_TXRDY (0x1u << 2) /**< \brief (HSMCI_IDR) Transmit Ready Interrupt Disable */ +#define HSMCI_IDR_BLKE (0x1u << 3) /**< \brief (HSMCI_IDR) Data Block Ended Interrupt Disable */ +#define HSMCI_IDR_DTIP (0x1u << 4) /**< \brief (HSMCI_IDR) Data Transfer in Progress Interrupt Disable */ +#define HSMCI_IDR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IDR) Data Not Busy Interrupt Disable */ +#define HSMCI_IDR_ENDRX (0x1u << 6) /**< \brief (HSMCI_IDR) End of Receive Buffer Interrupt Disable */ +#define HSMCI_IDR_ENDTX (0x1u << 7) /**< \brief (HSMCI_IDR) End of Transmit Buffer Interrupt Disable */ +#define HSMCI_IDR_SDIOIRQA (0x1u << 8) /**< \brief (HSMCI_IDR) SDIO Interrupt for Slot A Interrupt Disable */ +#define HSMCI_IDR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IDR) SDIO Read Wait Operation Status Interrupt Disable */ +#define HSMCI_IDR_CSRCV (0x1u << 13) /**< \brief (HSMCI_IDR) Completion Signal received interrupt Disable */ +#define HSMCI_IDR_RXBUFF (0x1u << 14) /**< \brief (HSMCI_IDR) Receive Buffer Full Interrupt Disable */ +#define HSMCI_IDR_TXBUFE (0x1u << 15) /**< \brief (HSMCI_IDR) Transmit Buffer Empty Interrupt Disable */ +#define HSMCI_IDR_RINDE (0x1u << 16) /**< \brief (HSMCI_IDR) Response Index Error Interrupt Disable */ +#define HSMCI_IDR_RDIRE (0x1u << 17) /**< \brief (HSMCI_IDR) Response Direction Error Interrupt Disable */ +#define HSMCI_IDR_RCRCE (0x1u << 18) /**< \brief (HSMCI_IDR) Response CRC Error Interrupt Disable */ +#define HSMCI_IDR_RENDE (0x1u << 19) /**< \brief (HSMCI_IDR) Response End Bit Error Interrupt Disable */ +#define HSMCI_IDR_RTOE (0x1u << 20) /**< \brief (HSMCI_IDR) Response Time-out Error Interrupt Disable */ +#define HSMCI_IDR_DCRCE (0x1u << 21) /**< \brief (HSMCI_IDR) Data CRC Error Interrupt Disable */ +#define HSMCI_IDR_DTOE (0x1u << 22) /**< \brief (HSMCI_IDR) Data Time-out Error Interrupt Disable */ +#define HSMCI_IDR_CSTOE (0x1u << 23) /**< \brief (HSMCI_IDR) Completion Signal Time out Error Interrupt Disable */ +#define HSMCI_IDR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IDR) FIFO empty Interrupt Disable */ +#define HSMCI_IDR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IDR) Transfer Done Interrupt Disable */ +#define HSMCI_IDR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IDR) Boot Acknowledge Interrupt Disable */ +#define HSMCI_IDR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IDR) Boot Acknowledge Error Interrupt Disable */ +#define HSMCI_IDR_OVRE (0x1u << 30) /**< \brief (HSMCI_IDR) Overrun Interrupt Disable */ +#define HSMCI_IDR_UNRE (0x1u << 31) /**< \brief (HSMCI_IDR) Underrun Interrupt Disable */ +/* -------- HSMCI_IMR : (HSMCI Offset: 0x4C) Interrupt Mask Register -------- */ +#define HSMCI_IMR_CMDRDY (0x1u << 0) /**< \brief (HSMCI_IMR) Command Ready Interrupt Mask */ +#define HSMCI_IMR_RXRDY (0x1u << 1) /**< \brief (HSMCI_IMR) Receiver Ready Interrupt Mask */ +#define HSMCI_IMR_TXRDY (0x1u << 2) /**< \brief (HSMCI_IMR) Transmit Ready Interrupt Mask */ +#define HSMCI_IMR_BLKE (0x1u << 3) /**< \brief (HSMCI_IMR) Data Block Ended Interrupt Mask */ +#define HSMCI_IMR_DTIP (0x1u << 4) /**< \brief (HSMCI_IMR) Data Transfer in Progress Interrupt Mask */ +#define HSMCI_IMR_NOTBUSY (0x1u << 5) /**< \brief (HSMCI_IMR) Data Not Busy Interrupt Mask */ +#define HSMCI_IMR_ENDRX (0x1u << 6) /**< \brief (HSMCI_IMR) End of Receive Buffer Interrupt Mask */ +#define HSMCI_IMR_ENDTX (0x1u << 7) /**< \brief (HSMCI_IMR) End of Transmit Buffer Interrupt Mask */ +#define HSMCI_IMR_SDIOIRQA (0x1u << 8) /**< \brief (HSMCI_IMR) SDIO Interrupt for Slot A Interrupt Mask */ +#define HSMCI_IMR_SDIOWAIT (0x1u << 12) /**< \brief (HSMCI_IMR) SDIO Read Wait Operation Status Interrupt Mask */ +#define HSMCI_IMR_CSRCV (0x1u << 13) /**< \brief (HSMCI_IMR) Completion Signal Received Interrupt Mask */ +#define HSMCI_IMR_RXBUFF (0x1u << 14) /**< \brief (HSMCI_IMR) Receive Buffer Full Interrupt Mask */ +#define HSMCI_IMR_TXBUFE (0x1u << 15) /**< \brief (HSMCI_IMR) Transmit Buffer Empty Interrupt Mask */ +#define HSMCI_IMR_RINDE (0x1u << 16) /**< \brief (HSMCI_IMR) Response Index Error Interrupt Mask */ +#define HSMCI_IMR_RDIRE (0x1u << 17) /**< \brief (HSMCI_IMR) Response Direction Error Interrupt Mask */ +#define HSMCI_IMR_RCRCE (0x1u << 18) /**< \brief (HSMCI_IMR) Response CRC Error Interrupt Mask */ +#define HSMCI_IMR_RENDE (0x1u << 19) /**< \brief (HSMCI_IMR) Response End Bit Error Interrupt Mask */ +#define HSMCI_IMR_RTOE (0x1u << 20) /**< \brief (HSMCI_IMR) Response Time-out Error Interrupt Mask */ +#define HSMCI_IMR_DCRCE (0x1u << 21) /**< \brief (HSMCI_IMR) Data CRC Error Interrupt Mask */ +#define HSMCI_IMR_DTOE (0x1u << 22) /**< \brief (HSMCI_IMR) Data Time-out Error Interrupt Mask */ +#define HSMCI_IMR_CSTOE (0x1u << 23) /**< \brief (HSMCI_IMR) Completion Signal Time-out Error Interrupt Mask */ +#define HSMCI_IMR_FIFOEMPTY (0x1u << 26) /**< \brief (HSMCI_IMR) FIFO Empty Interrupt Mask */ +#define HSMCI_IMR_XFRDONE (0x1u << 27) /**< \brief (HSMCI_IMR) Transfer Done Interrupt Mask */ +#define HSMCI_IMR_ACKRCV (0x1u << 28) /**< \brief (HSMCI_IMR) Boot Operation Acknowledge Received Interrupt Mask */ +#define HSMCI_IMR_ACKRCVE (0x1u << 29) /**< \brief (HSMCI_IMR) Boot Operation Acknowledge Error Interrupt Mask */ +#define HSMCI_IMR_OVRE (0x1u << 30) /**< \brief (HSMCI_IMR) Overrun Interrupt Mask */ +#define HSMCI_IMR_UNRE (0x1u << 31) /**< \brief (HSMCI_IMR) Underrun Interrupt Mask */ +/* -------- HSMCI_CFG : (HSMCI Offset: 0x54) Configuration Register -------- */ +#define HSMCI_CFG_FIFOMODE (0x1u << 0) /**< \brief (HSMCI_CFG) HSMCI Internal FIFO control mode */ +#define HSMCI_CFG_FERRCTRL (0x1u << 4) /**< \brief (HSMCI_CFG) Flow Error flag reset control mode */ +#define HSMCI_CFG_HSMODE (0x1u << 8) /**< \brief (HSMCI_CFG) High Speed Mode */ +#define HSMCI_CFG_LSYNC (0x1u << 12) /**< \brief (HSMCI_CFG) Synchronize on the last block */ +/* -------- HSMCI_WPMR : (HSMCI Offset: 0xE4) Write Protection Mode Register -------- */ +#define HSMCI_WPMR_WPEN (0x1u << 0) /**< \brief (HSMCI_WPMR) Write Protect Enable */ +#define HSMCI_WPMR_WPKEY_Pos 8 +#define HSMCI_WPMR_WPKEY_Msk (0xffffffu << HSMCI_WPMR_WPKEY_Pos) /**< \brief (HSMCI_WPMR) Write Protect Key */ +#define HSMCI_WPMR_WPKEY_PASSWD (0x4D4349u << 8) /**< \brief (HSMCI_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- HSMCI_WPSR : (HSMCI Offset: 0xE8) Write Protection Status Register -------- */ +#define HSMCI_WPSR_WPVS (0x1u << 0) /**< \brief (HSMCI_WPSR) Write Protection Violation Status */ +#define HSMCI_WPSR_WPVSRC_Pos 8 +#define HSMCI_WPSR_WPVSRC_Msk (0xffffu << HSMCI_WPSR_WPVSRC_Pos) /**< \brief (HSMCI_WPSR) Write Protection Violation Source */ +/* -------- HSMCI_RPR : (HSMCI Offset: 0x100) Receive Pointer Register -------- */ +#define HSMCI_RPR_RXPTR_Pos 0 +#define HSMCI_RPR_RXPTR_Msk (0xffffffffu << HSMCI_RPR_RXPTR_Pos) /**< \brief (HSMCI_RPR) Receive Pointer Register */ +#define HSMCI_RPR_RXPTR(value) ((HSMCI_RPR_RXPTR_Msk & ((value) << HSMCI_RPR_RXPTR_Pos))) +/* -------- HSMCI_RCR : (HSMCI Offset: 0x104) Receive Counter Register -------- */ +#define HSMCI_RCR_RXCTR_Pos 0 +#define HSMCI_RCR_RXCTR_Msk (0xffffu << HSMCI_RCR_RXCTR_Pos) /**< \brief (HSMCI_RCR) Receive Counter Register */ +#define HSMCI_RCR_RXCTR(value) ((HSMCI_RCR_RXCTR_Msk & ((value) << HSMCI_RCR_RXCTR_Pos))) +/* -------- HSMCI_TPR : (HSMCI Offset: 0x108) Transmit Pointer Register -------- */ +#define HSMCI_TPR_TXPTR_Pos 0 +#define HSMCI_TPR_TXPTR_Msk (0xffffffffu << HSMCI_TPR_TXPTR_Pos) /**< \brief (HSMCI_TPR) Transmit Counter Register */ +#define HSMCI_TPR_TXPTR(value) ((HSMCI_TPR_TXPTR_Msk & ((value) << HSMCI_TPR_TXPTR_Pos))) +/* -------- HSMCI_TCR : (HSMCI Offset: 0x10C) Transmit Counter Register -------- */ +#define HSMCI_TCR_TXCTR_Pos 0 +#define HSMCI_TCR_TXCTR_Msk (0xffffu << HSMCI_TCR_TXCTR_Pos) /**< \brief (HSMCI_TCR) Transmit Counter Register */ +#define HSMCI_TCR_TXCTR(value) ((HSMCI_TCR_TXCTR_Msk & ((value) << HSMCI_TCR_TXCTR_Pos))) +/* -------- HSMCI_RNPR : (HSMCI Offset: 0x110) Receive Next Pointer Register -------- */ +#define HSMCI_RNPR_RXNPTR_Pos 0 +#define HSMCI_RNPR_RXNPTR_Msk (0xffffffffu << HSMCI_RNPR_RXNPTR_Pos) /**< \brief (HSMCI_RNPR) Receive Next Pointer */ +#define HSMCI_RNPR_RXNPTR(value) ((HSMCI_RNPR_RXNPTR_Msk & ((value) << HSMCI_RNPR_RXNPTR_Pos))) +/* -------- HSMCI_RNCR : (HSMCI Offset: 0x114) Receive Next Counter Register -------- */ +#define HSMCI_RNCR_RXNCTR_Pos 0 +#define HSMCI_RNCR_RXNCTR_Msk (0xffffu << HSMCI_RNCR_RXNCTR_Pos) /**< \brief (HSMCI_RNCR) Receive Next Counter */ +#define HSMCI_RNCR_RXNCTR(value) ((HSMCI_RNCR_RXNCTR_Msk & ((value) << HSMCI_RNCR_RXNCTR_Pos))) +/* -------- HSMCI_TNPR : (HSMCI Offset: 0x118) Transmit Next Pointer Register -------- */ +#define HSMCI_TNPR_TXNPTR_Pos 0 +#define HSMCI_TNPR_TXNPTR_Msk (0xffffffffu << HSMCI_TNPR_TXNPTR_Pos) /**< \brief (HSMCI_TNPR) Transmit Next Pointer */ +#define HSMCI_TNPR_TXNPTR(value) ((HSMCI_TNPR_TXNPTR_Msk & ((value) << HSMCI_TNPR_TXNPTR_Pos))) +/* -------- HSMCI_TNCR : (HSMCI Offset: 0x11C) Transmit Next Counter Register -------- */ +#define HSMCI_TNCR_TXNCTR_Pos 0 +#define HSMCI_TNCR_TXNCTR_Msk (0xffffu << HSMCI_TNCR_TXNCTR_Pos) /**< \brief (HSMCI_TNCR) Transmit Counter Next */ +#define HSMCI_TNCR_TXNCTR(value) ((HSMCI_TNCR_TXNCTR_Msk & ((value) << HSMCI_TNCR_TXNCTR_Pos))) +/* -------- HSMCI_PTCR : (HSMCI Offset: 0x120) Transfer Control Register -------- */ +#define HSMCI_PTCR_RXTEN (0x1u << 0) /**< \brief (HSMCI_PTCR) Receiver Transfer Enable */ +#define HSMCI_PTCR_RXTDIS (0x1u << 1) /**< \brief (HSMCI_PTCR) Receiver Transfer Disable */ +#define HSMCI_PTCR_TXTEN (0x1u << 8) /**< \brief (HSMCI_PTCR) Transmitter Transfer Enable */ +#define HSMCI_PTCR_TXTDIS (0x1u << 9) /**< \brief (HSMCI_PTCR) Transmitter Transfer Disable */ +/* -------- HSMCI_PTSR : (HSMCI Offset: 0x124) Transfer Status Register -------- */ +#define HSMCI_PTSR_RXTEN (0x1u << 0) /**< \brief (HSMCI_PTSR) Receiver Transfer Enable */ +#define HSMCI_PTSR_TXTEN (0x1u << 8) /**< \brief (HSMCI_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_HSMCI_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/matrix.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/matrix.h new file mode 100644 index 0000000..7c6f797 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/matrix.h @@ -0,0 +1,264 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_MATRIX_COMPONENT_ +#define _SAM4E_MATRIX_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR AHB Bus Matrix */ +/* ============================================================================= */ +/** \addtogroup SAM4E_MATRIX AHB Bus Matrix */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Matrix hardware registers */ +typedef struct { + __IO uint32_t MATRIX_MCFG[7]; /**< \brief (Matrix Offset: 0x0000) Master Configuration Register */ + __I uint32_t Reserved1[9]; + __IO uint32_t MATRIX_SCFG[6]; /**< \brief (Matrix Offset: 0x0040) Slave Configuration Register */ + __I uint32_t Reserved2[10]; + __IO uint32_t MATRIX_PRAS0; /**< \brief (Matrix Offset: 0x0080) Priority Register A for Slave 0 */ + __I uint32_t Reserved3[1]; + __IO uint32_t MATRIX_PRAS1; /**< \brief (Matrix Offset: 0x0088) Priority Register A for Slave 1 */ + __I uint32_t Reserved4[1]; + __IO uint32_t MATRIX_PRAS2; /**< \brief (Matrix Offset: 0x0090) Priority Register A for Slave 2 */ + __I uint32_t Reserved5[1]; + __IO uint32_t MATRIX_PRAS3; /**< \brief (Matrix Offset: 0x0098) Priority Register A for Slave 3 */ + __I uint32_t Reserved6[1]; + __IO uint32_t MATRIX_PRAS4; /**< \brief (Matrix Offset: 0x00A0) Priority Register A for Slave 4 */ + __I uint32_t Reserved7[1]; + __IO uint32_t MATRIX_PRAS5; /**< \brief (Matrix Offset: 0x00A8) Priority Register A for Slave 5 */ + __I uint32_t Reserved8[1]; + __I uint32_t Reserved9[20]; + __IO uint32_t MATRIX_MRCR; /**< \brief (Matrix Offset: 0x0100) Master Remap Control Register */ + __I uint32_t Reserved10[4]; + __IO uint32_t CCFG_SYSIO; /**< \brief (Matrix Offset: 0x0114) System I/O Configuration Register */ + __I uint32_t Reserved11[3]; + __IO uint32_t CCFG_SMCNFCS; /**< \brief (Matrix Offset: 0x0124) SMC NAND Flash Chip Select Configuration Register */ + __I uint32_t Reserved12[47]; + __IO uint32_t MATRIX_WPMR; /**< \brief (Matrix Offset: 0x01E4) Write Protect Mode Register */ + __I uint32_t MATRIX_WPSR; /**< \brief (Matrix Offset: 0x01E8) Write Protect Status Register */ +} Matrix; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- MATRIX_MCFG[7] : (MATRIX Offset: 0x0000) Master Configuration Register -------- */ +#define MATRIX_MCFG_ULBT_Pos 0 +#define MATRIX_MCFG_ULBT_Msk (0x7u << MATRIX_MCFG_ULBT_Pos) /**< \brief (MATRIX_MCFG[7]) Undefined Length Burst Type */ +#define MATRIX_MCFG_ULBT(value) ((MATRIX_MCFG_ULBT_Msk & ((value) << MATRIX_MCFG_ULBT_Pos))) +/* -------- MATRIX_SCFG[6] : (MATRIX Offset: 0x0040) Slave Configuration Register -------- */ +#define MATRIX_SCFG_SLOT_CYCLE_Pos 0 +#define MATRIX_SCFG_SLOT_CYCLE_Msk (0x1ffu << MATRIX_SCFG_SLOT_CYCLE_Pos) /**< \brief (MATRIX_SCFG[6]) Maximum Bus Grant Duration for Masters */ +#define MATRIX_SCFG_SLOT_CYCLE(value) ((MATRIX_SCFG_SLOT_CYCLE_Msk & ((value) << MATRIX_SCFG_SLOT_CYCLE_Pos))) +#define MATRIX_SCFG_DEFMSTR_TYPE_Pos 16 +#define MATRIX_SCFG_DEFMSTR_TYPE_Msk (0x3u << MATRIX_SCFG_DEFMSTR_TYPE_Pos) /**< \brief (MATRIX_SCFG[6]) Default Master Type */ +#define MATRIX_SCFG_DEFMSTR_TYPE(value) ((MATRIX_SCFG_DEFMSTR_TYPE_Msk & ((value) << MATRIX_SCFG_DEFMSTR_TYPE_Pos))) +#define MATRIX_SCFG_FIXED_DEFMSTR_Pos 18 +#define MATRIX_SCFG_FIXED_DEFMSTR_Msk (0xfu << MATRIX_SCFG_FIXED_DEFMSTR_Pos) /**< \brief (MATRIX_SCFG[6]) Fixed Default Master */ +#define MATRIX_SCFG_FIXED_DEFMSTR(value) ((MATRIX_SCFG_FIXED_DEFMSTR_Msk & ((value) << MATRIX_SCFG_FIXED_DEFMSTR_Pos))) +/* -------- MATRIX_PRAS0 : (MATRIX Offset: 0x0080) Priority Register A for Slave 0 -------- */ +#define MATRIX_PRAS0_M0PR_Pos 0 +#define MATRIX_PRAS0_M0PR_Msk (0x3u << MATRIX_PRAS0_M0PR_Pos) /**< \brief (MATRIX_PRAS0) Master 0 Priority */ +#define MATRIX_PRAS0_M0PR(value) ((MATRIX_PRAS0_M0PR_Msk & ((value) << MATRIX_PRAS0_M0PR_Pos))) +#define MATRIX_PRAS0_M1PR_Pos 4 +#define MATRIX_PRAS0_M1PR_Msk (0x3u << MATRIX_PRAS0_M1PR_Pos) /**< \brief (MATRIX_PRAS0) Master 1 Priority */ +#define MATRIX_PRAS0_M1PR(value) ((MATRIX_PRAS0_M1PR_Msk & ((value) << MATRIX_PRAS0_M1PR_Pos))) +#define MATRIX_PRAS0_M2PR_Pos 8 +#define MATRIX_PRAS0_M2PR_Msk (0x3u << MATRIX_PRAS0_M2PR_Pos) /**< \brief (MATRIX_PRAS0) Master 2 Priority */ +#define MATRIX_PRAS0_M2PR(value) ((MATRIX_PRAS0_M2PR_Msk & ((value) << MATRIX_PRAS0_M2PR_Pos))) +#define MATRIX_PRAS0_M3PR_Pos 12 +#define MATRIX_PRAS0_M3PR_Msk (0x3u << MATRIX_PRAS0_M3PR_Pos) /**< \brief (MATRIX_PRAS0) Master 3 Priority */ +#define MATRIX_PRAS0_M3PR(value) ((MATRIX_PRAS0_M3PR_Msk & ((value) << MATRIX_PRAS0_M3PR_Pos))) +#define MATRIX_PRAS0_M4PR_Pos 16 +#define MATRIX_PRAS0_M4PR_Msk (0x3u << MATRIX_PRAS0_M4PR_Pos) /**< \brief (MATRIX_PRAS0) Master 4 Priority */ +#define MATRIX_PRAS0_M4PR(value) ((MATRIX_PRAS0_M4PR_Msk & ((value) << MATRIX_PRAS0_M4PR_Pos))) +#define MATRIX_PRAS0_M5PR_Pos 20 +#define MATRIX_PRAS0_M5PR_Msk (0x3u << MATRIX_PRAS0_M5PR_Pos) /**< \brief (MATRIX_PRAS0) Master 5 Priority */ +#define MATRIX_PRAS0_M5PR(value) ((MATRIX_PRAS0_M5PR_Msk & ((value) << MATRIX_PRAS0_M5PR_Pos))) +#define MATRIX_PRAS0_M6PR_Pos 24 +#define MATRIX_PRAS0_M6PR_Msk (0x3u << MATRIX_PRAS0_M6PR_Pos) /**< \brief (MATRIX_PRAS0) Master 6 Priority */ +#define MATRIX_PRAS0_M6PR(value) ((MATRIX_PRAS0_M6PR_Msk & ((value) << MATRIX_PRAS0_M6PR_Pos))) +/* -------- MATRIX_PRAS1 : (MATRIX Offset: 0x0088) Priority Register A for Slave 1 -------- */ +#define MATRIX_PRAS1_M0PR_Pos 0 +#define MATRIX_PRAS1_M0PR_Msk (0x3u << MATRIX_PRAS1_M0PR_Pos) /**< \brief (MATRIX_PRAS1) Master 0 Priority */ +#define MATRIX_PRAS1_M0PR(value) ((MATRIX_PRAS1_M0PR_Msk & ((value) << MATRIX_PRAS1_M0PR_Pos))) +#define MATRIX_PRAS1_M1PR_Pos 4 +#define MATRIX_PRAS1_M1PR_Msk (0x3u << MATRIX_PRAS1_M1PR_Pos) /**< \brief (MATRIX_PRAS1) Master 1 Priority */ +#define MATRIX_PRAS1_M1PR(value) ((MATRIX_PRAS1_M1PR_Msk & ((value) << MATRIX_PRAS1_M1PR_Pos))) +#define MATRIX_PRAS1_M2PR_Pos 8 +#define MATRIX_PRAS1_M2PR_Msk (0x3u << MATRIX_PRAS1_M2PR_Pos) /**< \brief (MATRIX_PRAS1) Master 2 Priority */ +#define MATRIX_PRAS1_M2PR(value) ((MATRIX_PRAS1_M2PR_Msk & ((value) << MATRIX_PRAS1_M2PR_Pos))) +#define MATRIX_PRAS1_M3PR_Pos 12 +#define MATRIX_PRAS1_M3PR_Msk (0x3u << MATRIX_PRAS1_M3PR_Pos) /**< \brief (MATRIX_PRAS1) Master 3 Priority */ +#define MATRIX_PRAS1_M3PR(value) ((MATRIX_PRAS1_M3PR_Msk & ((value) << MATRIX_PRAS1_M3PR_Pos))) +#define MATRIX_PRAS1_M4PR_Pos 16 +#define MATRIX_PRAS1_M4PR_Msk (0x3u << MATRIX_PRAS1_M4PR_Pos) /**< \brief (MATRIX_PRAS1) Master 4 Priority */ +#define MATRIX_PRAS1_M4PR(value) ((MATRIX_PRAS1_M4PR_Msk & ((value) << MATRIX_PRAS1_M4PR_Pos))) +#define MATRIX_PRAS1_M5PR_Pos 20 +#define MATRIX_PRAS1_M5PR_Msk (0x3u << MATRIX_PRAS1_M5PR_Pos) /**< \brief (MATRIX_PRAS1) Master 5 Priority */ +#define MATRIX_PRAS1_M5PR(value) ((MATRIX_PRAS1_M5PR_Msk & ((value) << MATRIX_PRAS1_M5PR_Pos))) +#define MATRIX_PRAS1_M6PR_Pos 24 +#define MATRIX_PRAS1_M6PR_Msk (0x3u << MATRIX_PRAS1_M6PR_Pos) /**< \brief (MATRIX_PRAS1) Master 6 Priority */ +#define MATRIX_PRAS1_M6PR(value) ((MATRIX_PRAS1_M6PR_Msk & ((value) << MATRIX_PRAS1_M6PR_Pos))) +/* -------- MATRIX_PRAS2 : (MATRIX Offset: 0x0090) Priority Register A for Slave 2 -------- */ +#define MATRIX_PRAS2_M0PR_Pos 0 +#define MATRIX_PRAS2_M0PR_Msk (0x3u << MATRIX_PRAS2_M0PR_Pos) /**< \brief (MATRIX_PRAS2) Master 0 Priority */ +#define MATRIX_PRAS2_M0PR(value) ((MATRIX_PRAS2_M0PR_Msk & ((value) << MATRIX_PRAS2_M0PR_Pos))) +#define MATRIX_PRAS2_M1PR_Pos 4 +#define MATRIX_PRAS2_M1PR_Msk (0x3u << MATRIX_PRAS2_M1PR_Pos) /**< \brief (MATRIX_PRAS2) Master 1 Priority */ +#define MATRIX_PRAS2_M1PR(value) ((MATRIX_PRAS2_M1PR_Msk & ((value) << MATRIX_PRAS2_M1PR_Pos))) +#define MATRIX_PRAS2_M2PR_Pos 8 +#define MATRIX_PRAS2_M2PR_Msk (0x3u << MATRIX_PRAS2_M2PR_Pos) /**< \brief (MATRIX_PRAS2) Master 2 Priority */ +#define MATRIX_PRAS2_M2PR(value) ((MATRIX_PRAS2_M2PR_Msk & ((value) << MATRIX_PRAS2_M2PR_Pos))) +#define MATRIX_PRAS2_M3PR_Pos 12 +#define MATRIX_PRAS2_M3PR_Msk (0x3u << MATRIX_PRAS2_M3PR_Pos) /**< \brief (MATRIX_PRAS2) Master 3 Priority */ +#define MATRIX_PRAS2_M3PR(value) ((MATRIX_PRAS2_M3PR_Msk & ((value) << MATRIX_PRAS2_M3PR_Pos))) +#define MATRIX_PRAS2_M4PR_Pos 16 +#define MATRIX_PRAS2_M4PR_Msk (0x3u << MATRIX_PRAS2_M4PR_Pos) /**< \brief (MATRIX_PRAS2) Master 4 Priority */ +#define MATRIX_PRAS2_M4PR(value) ((MATRIX_PRAS2_M4PR_Msk & ((value) << MATRIX_PRAS2_M4PR_Pos))) +#define MATRIX_PRAS2_M5PR_Pos 20 +#define MATRIX_PRAS2_M5PR_Msk (0x3u << MATRIX_PRAS2_M5PR_Pos) /**< \brief (MATRIX_PRAS2) Master 5 Priority */ +#define MATRIX_PRAS2_M5PR(value) ((MATRIX_PRAS2_M5PR_Msk & ((value) << MATRIX_PRAS2_M5PR_Pos))) +#define MATRIX_PRAS2_M6PR_Pos 24 +#define MATRIX_PRAS2_M6PR_Msk (0x3u << MATRIX_PRAS2_M6PR_Pos) /**< \brief (MATRIX_PRAS2) Master 6 Priority */ +#define MATRIX_PRAS2_M6PR(value) ((MATRIX_PRAS2_M6PR_Msk & ((value) << MATRIX_PRAS2_M6PR_Pos))) +/* -------- MATRIX_PRAS3 : (MATRIX Offset: 0x0098) Priority Register A for Slave 3 -------- */ +#define MATRIX_PRAS3_M0PR_Pos 0 +#define MATRIX_PRAS3_M0PR_Msk (0x3u << MATRIX_PRAS3_M0PR_Pos) /**< \brief (MATRIX_PRAS3) Master 0 Priority */ +#define MATRIX_PRAS3_M0PR(value) ((MATRIX_PRAS3_M0PR_Msk & ((value) << MATRIX_PRAS3_M0PR_Pos))) +#define MATRIX_PRAS3_M1PR_Pos 4 +#define MATRIX_PRAS3_M1PR_Msk (0x3u << MATRIX_PRAS3_M1PR_Pos) /**< \brief (MATRIX_PRAS3) Master 1 Priority */ +#define MATRIX_PRAS3_M1PR(value) ((MATRIX_PRAS3_M1PR_Msk & ((value) << MATRIX_PRAS3_M1PR_Pos))) +#define MATRIX_PRAS3_M2PR_Pos 8 +#define MATRIX_PRAS3_M2PR_Msk (0x3u << MATRIX_PRAS3_M2PR_Pos) /**< \brief (MATRIX_PRAS3) Master 2 Priority */ +#define MATRIX_PRAS3_M2PR(value) ((MATRIX_PRAS3_M2PR_Msk & ((value) << MATRIX_PRAS3_M2PR_Pos))) +#define MATRIX_PRAS3_M3PR_Pos 12 +#define MATRIX_PRAS3_M3PR_Msk (0x3u << MATRIX_PRAS3_M3PR_Pos) /**< \brief (MATRIX_PRAS3) Master 3 Priority */ +#define MATRIX_PRAS3_M3PR(value) ((MATRIX_PRAS3_M3PR_Msk & ((value) << MATRIX_PRAS3_M3PR_Pos))) +#define MATRIX_PRAS3_M4PR_Pos 16 +#define MATRIX_PRAS3_M4PR_Msk (0x3u << MATRIX_PRAS3_M4PR_Pos) /**< \brief (MATRIX_PRAS3) Master 4 Priority */ +#define MATRIX_PRAS3_M4PR(value) ((MATRIX_PRAS3_M4PR_Msk & ((value) << MATRIX_PRAS3_M4PR_Pos))) +#define MATRIX_PRAS3_M5PR_Pos 20 +#define MATRIX_PRAS3_M5PR_Msk (0x3u << MATRIX_PRAS3_M5PR_Pos) /**< \brief (MATRIX_PRAS3) Master 5 Priority */ +#define MATRIX_PRAS3_M5PR(value) ((MATRIX_PRAS3_M5PR_Msk & ((value) << MATRIX_PRAS3_M5PR_Pos))) +#define MATRIX_PRAS3_M6PR_Pos 24 +#define MATRIX_PRAS3_M6PR_Msk (0x3u << MATRIX_PRAS3_M6PR_Pos) /**< \brief (MATRIX_PRAS3) Master 6 Priority */ +#define MATRIX_PRAS3_M6PR(value) ((MATRIX_PRAS3_M6PR_Msk & ((value) << MATRIX_PRAS3_M6PR_Pos))) +/* -------- MATRIX_PRAS4 : (MATRIX Offset: 0x00A0) Priority Register A for Slave 4 -------- */ +#define MATRIX_PRAS4_M0PR_Pos 0 +#define MATRIX_PRAS4_M0PR_Msk (0x3u << MATRIX_PRAS4_M0PR_Pos) /**< \brief (MATRIX_PRAS4) Master 0 Priority */ +#define MATRIX_PRAS4_M0PR(value) ((MATRIX_PRAS4_M0PR_Msk & ((value) << MATRIX_PRAS4_M0PR_Pos))) +#define MATRIX_PRAS4_M1PR_Pos 4 +#define MATRIX_PRAS4_M1PR_Msk (0x3u << MATRIX_PRAS4_M1PR_Pos) /**< \brief (MATRIX_PRAS4) Master 1 Priority */ +#define MATRIX_PRAS4_M1PR(value) ((MATRIX_PRAS4_M1PR_Msk & ((value) << MATRIX_PRAS4_M1PR_Pos))) +#define MATRIX_PRAS4_M2PR_Pos 8 +#define MATRIX_PRAS4_M2PR_Msk (0x3u << MATRIX_PRAS4_M2PR_Pos) /**< \brief (MATRIX_PRAS4) Master 2 Priority */ +#define MATRIX_PRAS4_M2PR(value) ((MATRIX_PRAS4_M2PR_Msk & ((value) << MATRIX_PRAS4_M2PR_Pos))) +#define MATRIX_PRAS4_M3PR_Pos 12 +#define MATRIX_PRAS4_M3PR_Msk (0x3u << MATRIX_PRAS4_M3PR_Pos) /**< \brief (MATRIX_PRAS4) Master 3 Priority */ +#define MATRIX_PRAS4_M3PR(value) ((MATRIX_PRAS4_M3PR_Msk & ((value) << MATRIX_PRAS4_M3PR_Pos))) +#define MATRIX_PRAS4_M4PR_Pos 16 +#define MATRIX_PRAS4_M4PR_Msk (0x3u << MATRIX_PRAS4_M4PR_Pos) /**< \brief (MATRIX_PRAS4) Master 4 Priority */ +#define MATRIX_PRAS4_M4PR(value) ((MATRIX_PRAS4_M4PR_Msk & ((value) << MATRIX_PRAS4_M4PR_Pos))) +#define MATRIX_PRAS4_M5PR_Pos 20 +#define MATRIX_PRAS4_M5PR_Msk (0x3u << MATRIX_PRAS4_M5PR_Pos) /**< \brief (MATRIX_PRAS4) Master 5 Priority */ +#define MATRIX_PRAS4_M5PR(value) ((MATRIX_PRAS4_M5PR_Msk & ((value) << MATRIX_PRAS4_M5PR_Pos))) +#define MATRIX_PRAS4_M6PR_Pos 24 +#define MATRIX_PRAS4_M6PR_Msk (0x3u << MATRIX_PRAS4_M6PR_Pos) /**< \brief (MATRIX_PRAS4) Master 6 Priority */ +#define MATRIX_PRAS4_M6PR(value) ((MATRIX_PRAS4_M6PR_Msk & ((value) << MATRIX_PRAS4_M6PR_Pos))) +/* -------- MATRIX_PRAS5 : (MATRIX Offset: 0x00A8) Priority Register A for Slave 5 -------- */ +#define MATRIX_PRAS5_M0PR_Pos 0 +#define MATRIX_PRAS5_M0PR_Msk (0x3u << MATRIX_PRAS5_M0PR_Pos) /**< \brief (MATRIX_PRAS5) Master 0 Priority */ +#define MATRIX_PRAS5_M0PR(value) ((MATRIX_PRAS5_M0PR_Msk & ((value) << MATRIX_PRAS5_M0PR_Pos))) +#define MATRIX_PRAS5_M1PR_Pos 4 +#define MATRIX_PRAS5_M1PR_Msk (0x3u << MATRIX_PRAS5_M1PR_Pos) /**< \brief (MATRIX_PRAS5) Master 1 Priority */ +#define MATRIX_PRAS5_M1PR(value) ((MATRIX_PRAS5_M1PR_Msk & ((value) << MATRIX_PRAS5_M1PR_Pos))) +#define MATRIX_PRAS5_M2PR_Pos 8 +#define MATRIX_PRAS5_M2PR_Msk (0x3u << MATRIX_PRAS5_M2PR_Pos) /**< \brief (MATRIX_PRAS5) Master 2 Priority */ +#define MATRIX_PRAS5_M2PR(value) ((MATRIX_PRAS5_M2PR_Msk & ((value) << MATRIX_PRAS5_M2PR_Pos))) +#define MATRIX_PRAS5_M3PR_Pos 12 +#define MATRIX_PRAS5_M3PR_Msk (0x3u << MATRIX_PRAS5_M3PR_Pos) /**< \brief (MATRIX_PRAS5) Master 3 Priority */ +#define MATRIX_PRAS5_M3PR(value) ((MATRIX_PRAS5_M3PR_Msk & ((value) << MATRIX_PRAS5_M3PR_Pos))) +#define MATRIX_PRAS5_M4PR_Pos 16 +#define MATRIX_PRAS5_M4PR_Msk (0x3u << MATRIX_PRAS5_M4PR_Pos) /**< \brief (MATRIX_PRAS5) Master 4 Priority */ +#define MATRIX_PRAS5_M4PR(value) ((MATRIX_PRAS5_M4PR_Msk & ((value) << MATRIX_PRAS5_M4PR_Pos))) +#define MATRIX_PRAS5_M5PR_Pos 20 +#define MATRIX_PRAS5_M5PR_Msk (0x3u << MATRIX_PRAS5_M5PR_Pos) /**< \brief (MATRIX_PRAS5) Master 5 Priority */ +#define MATRIX_PRAS5_M5PR(value) ((MATRIX_PRAS5_M5PR_Msk & ((value) << MATRIX_PRAS5_M5PR_Pos))) +#define MATRIX_PRAS5_M6PR_Pos 24 +#define MATRIX_PRAS5_M6PR_Msk (0x3u << MATRIX_PRAS5_M6PR_Pos) /**< \brief (MATRIX_PRAS5) Master 6 Priority */ +#define MATRIX_PRAS5_M6PR(value) ((MATRIX_PRAS5_M6PR_Msk & ((value) << MATRIX_PRAS5_M6PR_Pos))) +/* -------- MATRIX_MRCR : (MATRIX Offset: 0x0100) Master Remap Control Register -------- */ +#define MATRIX_MRCR_RCB0 (0x1u << 0) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 0 */ +#define MATRIX_MRCR_RCB1 (0x1u << 1) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 1 */ +#define MATRIX_MRCR_RCB2 (0x1u << 2) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 2 */ +#define MATRIX_MRCR_RCB3 (0x1u << 3) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 3 */ +#define MATRIX_MRCR_RCB4 (0x1u << 4) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 4 */ +#define MATRIX_MRCR_RCB5 (0x1u << 5) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 5 */ +#define MATRIX_MRCR_RCB6 (0x1u << 6) /**< \brief (MATRIX_MRCR) Remap Command Bit for Master 6 */ +/* -------- CCFG_SYSIO : (MATRIX Offset: 0x0114) System I/O Configuration Register -------- */ +#define CCFG_SYSIO_SYSIO4 (0x1u << 4) /**< \brief (CCFG_SYSIO) PB4 or TDI Assignment */ +#define CCFG_SYSIO_SYSIO5 (0x1u << 5) /**< \brief (CCFG_SYSIO) PB5 or TDO/TRACESWO Assignment */ +#define CCFG_SYSIO_SYSIO6 (0x1u << 6) /**< \brief (CCFG_SYSIO) PB6 or TMS/SWDIO Assignment */ +#define CCFG_SYSIO_SYSIO7 (0x1u << 7) /**< \brief (CCFG_SYSIO) PB7 or TCK/SWCLK Assignment */ +#define CCFG_SYSIO_SYSIO10 (0x1u << 10) /**< \brief (CCFG_SYSIO) PB10 or DDM Assignment */ +#define CCFG_SYSIO_SYSIO11 (0x1u << 11) /**< \brief (CCFG_SYSIO) PB11 or DDP Assignment */ +#define CCFG_SYSIO_SYSIO12 (0x1u << 12) /**< \brief (CCFG_SYSIO) PB12 or ERASE Assignment */ +/* -------- CCFG_SMCNFCS : (MATRIX Offset: 0x0124) SMC NAND Flash Chip Select Configuration Register -------- */ +#define CCFG_SMCNFCS_SMC_NFCS0 (0x1u << 0) /**< \brief (CCFG_SMCNFCS) SMC NAND Flash Chip Select 0 Assignment */ +#define CCFG_SMCNFCS_SMC_NFCS1 (0x1u << 1) /**< \brief (CCFG_SMCNFCS) SMC NAND Flash Chip Select 1 Assignment */ +#define CCFG_SMCNFCS_SMC_NFCS2 (0x1u << 2) /**< \brief (CCFG_SMCNFCS) SMC NAND Flash Chip Select 2 Assignment */ +#define CCFG_SMCNFCS_SMC_NFCS3 (0x1u << 3) /**< \brief (CCFG_SMCNFCS) SMC NAND Flash Chip Select 3 Assignment */ +/* -------- MATRIX_WPMR : (MATRIX Offset: 0x01E4) Write Protect Mode Register -------- */ +#define MATRIX_WPMR_WPEN (0x1u << 0) /**< \brief (MATRIX_WPMR) Write Protect Enable */ +#define MATRIX_WPMR_WPKEY_Pos 8 +#define MATRIX_WPMR_WPKEY_Msk (0xffffffu << MATRIX_WPMR_WPKEY_Pos) /**< \brief (MATRIX_WPMR) Write Protect KEY (Write-only) */ +#define MATRIX_WPMR_WPKEY_PASSWD (0x4D4154u << 8) /**< \brief (MATRIX_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- MATRIX_WPSR : (MATRIX Offset: 0x01E8) Write Protect Status Register -------- */ +#define MATRIX_WPSR_WPVS (0x1u << 0) /**< \brief (MATRIX_WPSR) Write Protect Violation Status */ +#define MATRIX_WPSR_WPVSRC_Pos 8 +#define MATRIX_WPSR_WPVSRC_Msk (0xffffu << MATRIX_WPSR_WPVSRC_Pos) /**< \brief (MATRIX_WPSR) Write Protect Violation Source */ + +/*@}*/ + + +#endif /* _SAM4E_MATRIX_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pdc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pdc.h new file mode 100644 index 0000000..113adee --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pdc.h @@ -0,0 +1,113 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PDC_COMPONENT_ +#define _SAM4E_PDC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Peripheral DMA Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_PDC Peripheral DMA Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Pdc hardware registers */ +typedef struct { + __IO uint32_t PERIPH_RPR; /**< \brief (Pdc Offset: 0x00) Receive Pointer Register */ + __IO uint32_t PERIPH_RCR; /**< \brief (Pdc Offset: 0x04) Receive Counter Register */ + __IO uint32_t PERIPH_TPR; /**< \brief (Pdc Offset: 0x08) Transmit Pointer Register */ + __IO uint32_t PERIPH_TCR; /**< \brief (Pdc Offset: 0x0C) Transmit Counter Register */ + __IO uint32_t PERIPH_RNPR; /**< \brief (Pdc Offset: 0x10) Receive Next Pointer Register */ + __IO uint32_t PERIPH_RNCR; /**< \brief (Pdc Offset: 0x14) Receive Next Counter Register */ + __IO uint32_t PERIPH_TNPR; /**< \brief (Pdc Offset: 0x18) Transmit Next Pointer Register */ + __IO uint32_t PERIPH_TNCR; /**< \brief (Pdc Offset: 0x1C) Transmit Next Counter Register */ + __O uint32_t PERIPH_PTCR; /**< \brief (Pdc Offset: 0x20) Transfer Control Register */ + __I uint32_t PERIPH_PTSR; /**< \brief (Pdc Offset: 0x24) Transfer Status Register */ +} Pdc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- PERIPH_RPR : (PDC Offset: 0x00) Receive Pointer Register -------- */ +#define PERIPH_RPR_RXPTR_Pos 0 +#define PERIPH_RPR_RXPTR_Msk (0xffffffffu << PERIPH_RPR_RXPTR_Pos) /**< \brief (PERIPH_RPR) Receive Pointer Register */ +#define PERIPH_RPR_RXPTR(value) ((PERIPH_RPR_RXPTR_Msk & ((value) << PERIPH_RPR_RXPTR_Pos))) +/* -------- PERIPH_RCR : (PDC Offset: 0x04) Receive Counter Register -------- */ +#define PERIPH_RCR_RXCTR_Pos 0 +#define PERIPH_RCR_RXCTR_Msk (0xffffu << PERIPH_RCR_RXCTR_Pos) /**< \brief (PERIPH_RCR) Receive Counter Register */ +#define PERIPH_RCR_RXCTR(value) ((PERIPH_RCR_RXCTR_Msk & ((value) << PERIPH_RCR_RXCTR_Pos))) +/* -------- PERIPH_TPR : (PDC Offset: 0x08) Transmit Pointer Register -------- */ +#define PERIPH_TPR_TXPTR_Pos 0 +#define PERIPH_TPR_TXPTR_Msk (0xffffffffu << PERIPH_TPR_TXPTR_Pos) /**< \brief (PERIPH_TPR) Transmit Counter Register */ +#define PERIPH_TPR_TXPTR(value) ((PERIPH_TPR_TXPTR_Msk & ((value) << PERIPH_TPR_TXPTR_Pos))) +/* -------- PERIPH_TCR : (PDC Offset: 0x0C) Transmit Counter Register -------- */ +#define PERIPH_TCR_TXCTR_Pos 0 +#define PERIPH_TCR_TXCTR_Msk (0xffffu << PERIPH_TCR_TXCTR_Pos) /**< \brief (PERIPH_TCR) Transmit Counter Register */ +#define PERIPH_TCR_TXCTR(value) ((PERIPH_TCR_TXCTR_Msk & ((value) << PERIPH_TCR_TXCTR_Pos))) +/* -------- PERIPH_RNPR : (PDC Offset: 0x10) Receive Next Pointer Register -------- */ +#define PERIPH_RNPR_RXNPTR_Pos 0 +#define PERIPH_RNPR_RXNPTR_Msk (0xffffffffu << PERIPH_RNPR_RXNPTR_Pos) /**< \brief (PERIPH_RNPR) Receive Next Pointer */ +#define PERIPH_RNPR_RXNPTR(value) ((PERIPH_RNPR_RXNPTR_Msk & ((value) << PERIPH_RNPR_RXNPTR_Pos))) +/* -------- PERIPH_RNCR : (PDC Offset: 0x14) Receive Next Counter Register -------- */ +#define PERIPH_RNCR_RXNCTR_Pos 0 +#define PERIPH_RNCR_RXNCTR_Msk (0xffffu << PERIPH_RNCR_RXNCTR_Pos) /**< \brief (PERIPH_RNCR) Receive Next Counter */ +#define PERIPH_RNCR_RXNCTR(value) ((PERIPH_RNCR_RXNCTR_Msk & ((value) << PERIPH_RNCR_RXNCTR_Pos))) +/* -------- PERIPH_TNPR : (PDC Offset: 0x18) Transmit Next Pointer Register -------- */ +#define PERIPH_TNPR_TXNPTR_Pos 0 +#define PERIPH_TNPR_TXNPTR_Msk (0xffffffffu << PERIPH_TNPR_TXNPTR_Pos) /**< \brief (PERIPH_TNPR) Transmit Next Pointer */ +#define PERIPH_TNPR_TXNPTR(value) ((PERIPH_TNPR_TXNPTR_Msk & ((value) << PERIPH_TNPR_TXNPTR_Pos))) +/* -------- PERIPH_TNCR : (PDC Offset: 0x1C) Transmit Next Counter Register -------- */ +#define PERIPH_TNCR_TXNCTR_Pos 0 +#define PERIPH_TNCR_TXNCTR_Msk (0xffffu << PERIPH_TNCR_TXNCTR_Pos) /**< \brief (PERIPH_TNCR) Transmit Counter Next */ +#define PERIPH_TNCR_TXNCTR(value) ((PERIPH_TNCR_TXNCTR_Msk & ((value) << PERIPH_TNCR_TXNCTR_Pos))) +/* -------- PERIPH_PTCR : (PDC Offset: 0x20) Transfer Control Register -------- */ +#define PERIPH_PTCR_RXTEN (0x1u << 0) /**< \brief (PERIPH_PTCR) Receiver Transfer Enable */ +#define PERIPH_PTCR_RXTDIS (0x1u << 1) /**< \brief (PERIPH_PTCR) Receiver Transfer Disable */ +#define PERIPH_PTCR_TXTEN (0x1u << 8) /**< \brief (PERIPH_PTCR) Transmitter Transfer Enable */ +#define PERIPH_PTCR_TXTDIS (0x1u << 9) /**< \brief (PERIPH_PTCR) Transmitter Transfer Disable */ +/* -------- PERIPH_PTSR : (PDC Offset: 0x24) Transfer Status Register -------- */ +#define PERIPH_PTSR_RXTEN (0x1u << 0) /**< \brief (PERIPH_PTSR) Receiver Transfer Enable */ +#define PERIPH_PTSR_TXTEN (0x1u << 8) /**< \brief (PERIPH_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_PDC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pio.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pio.h new file mode 100644 index 0000000..68bea35 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pio.h @@ -0,0 +1,1686 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIO_COMPONENT_ +#define _SAM4E_PIO_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Parallel Input/Output Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_PIO Parallel Input/Output Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Pio hardware registers */ +typedef struct { + __O uint32_t PIO_PER; /**< \brief (Pio Offset: 0x0000) PIO Enable Register */ + __O uint32_t PIO_PDR; /**< \brief (Pio Offset: 0x0004) PIO Disable Register */ + __I uint32_t PIO_PSR; /**< \brief (Pio Offset: 0x0008) PIO Status Register */ + __I uint32_t Reserved1[1]; + __O uint32_t PIO_OER; /**< \brief (Pio Offset: 0x0010) Output Enable Register */ + __O uint32_t PIO_ODR; /**< \brief (Pio Offset: 0x0014) Output Disable Register */ + __I uint32_t PIO_OSR; /**< \brief (Pio Offset: 0x0018) Output Status Register */ + __I uint32_t Reserved2[1]; + __O uint32_t PIO_IFER; /**< \brief (Pio Offset: 0x0020) Glitch Input Filter Enable Register */ + __O uint32_t PIO_IFDR; /**< \brief (Pio Offset: 0x0024) Glitch Input Filter Disable Register */ + __I uint32_t PIO_IFSR; /**< \brief (Pio Offset: 0x0028) Glitch Input Filter Status Register */ + __I uint32_t Reserved3[1]; + __O uint32_t PIO_SODR; /**< \brief (Pio Offset: 0x0030) Set Output Data Register */ + __O uint32_t PIO_CODR; /**< \brief (Pio Offset: 0x0034) Clear Output Data Register */ + __IO uint32_t PIO_ODSR; /**< \brief (Pio Offset: 0x0038) Output Data Status Register */ + __I uint32_t PIO_PDSR; /**< \brief (Pio Offset: 0x003C) Pin Data Status Register */ + __O uint32_t PIO_IER; /**< \brief (Pio Offset: 0x0040) Interrupt Enable Register */ + __O uint32_t PIO_IDR; /**< \brief (Pio Offset: 0x0044) Interrupt Disable Register */ + __I uint32_t PIO_IMR; /**< \brief (Pio Offset: 0x0048) Interrupt Mask Register */ + __I uint32_t PIO_ISR; /**< \brief (Pio Offset: 0x004C) Interrupt Status Register */ + __O uint32_t PIO_MDER; /**< \brief (Pio Offset: 0x0050) Multi-driver Enable Register */ + __O uint32_t PIO_MDDR; /**< \brief (Pio Offset: 0x0054) Multi-driver Disable Register */ + __I uint32_t PIO_MDSR; /**< \brief (Pio Offset: 0x0058) Multi-driver Status Register */ + __I uint32_t Reserved4[1]; + __O uint32_t PIO_PUDR; /**< \brief (Pio Offset: 0x0060) Pull-up Disable Register */ + __O uint32_t PIO_PUER; /**< \brief (Pio Offset: 0x0064) Pull-up Enable Register */ + __I uint32_t PIO_PUSR; /**< \brief (Pio Offset: 0x0068) Pad Pull-up Status Register */ + __I uint32_t Reserved5[1]; + __IO uint32_t PIO_ABCDSR[2]; /**< \brief (Pio Offset: 0x0070) Peripheral Select Register */ + __I uint32_t Reserved6[2]; + __O uint32_t PIO_IFSCDR; /**< \brief (Pio Offset: 0x0080) Input Filter Slow Clock Disable Register */ + __O uint32_t PIO_IFSCER; /**< \brief (Pio Offset: 0x0084) Input Filter Slow Clock Enable Register */ + __I uint32_t PIO_IFSCSR; /**< \brief (Pio Offset: 0x0088) Input Filter Slow Clock Status Register */ + __IO uint32_t PIO_SCDR; /**< \brief (Pio Offset: 0x008C) Slow Clock Divider Debouncing Register */ + __O uint32_t PIO_PPDDR; /**< \brief (Pio Offset: 0x0090) Pad Pull-down Disable Register */ + __O uint32_t PIO_PPDER; /**< \brief (Pio Offset: 0x0094) Pad Pull-down Enable Register */ + __I uint32_t PIO_PPDSR; /**< \brief (Pio Offset: 0x0098) Pad Pull-down Status Register */ + __I uint32_t Reserved7[1]; + __O uint32_t PIO_OWER; /**< \brief (Pio Offset: 0x00A0) Output Write Enable */ + __O uint32_t PIO_OWDR; /**< \brief (Pio Offset: 0x00A4) Output Write Disable */ + __I uint32_t PIO_OWSR; /**< \brief (Pio Offset: 0x00A8) Output Write Status Register */ + __I uint32_t Reserved8[1]; + __O uint32_t PIO_AIMER; /**< \brief (Pio Offset: 0x00B0) Additional Interrupt Modes Enable Register */ + __O uint32_t PIO_AIMDR; /**< \brief (Pio Offset: 0x00B4) Additional Interrupt Modes Disable Register */ + __I uint32_t PIO_AIMMR; /**< \brief (Pio Offset: 0x00B8) Additional Interrupt Modes Mask Register */ + __I uint32_t Reserved9[1]; + __O uint32_t PIO_ESR; /**< \brief (Pio Offset: 0x00C0) Edge Select Register */ + __O uint32_t PIO_LSR; /**< \brief (Pio Offset: 0x00C4) Level Select Register */ + __I uint32_t PIO_ELSR; /**< \brief (Pio Offset: 0x00C8) Edge/Level Status Register */ + __I uint32_t Reserved10[1]; + __O uint32_t PIO_FELLSR; /**< \brief (Pio Offset: 0x00D0) Falling Edge/Low-Level Select Register */ + __O uint32_t PIO_REHLSR; /**< \brief (Pio Offset: 0x00D4) Rising Edge/High-Level Select Register */ + __I uint32_t PIO_FRLHSR; /**< \brief (Pio Offset: 0x00D8) Fall/Rise - Low/High Status Register */ + __I uint32_t Reserved11[1]; + __I uint32_t PIO_LOCKSR; /**< \brief (Pio Offset: 0x00E0) Lock Status */ + __IO uint32_t PIO_WPMR; /**< \brief (Pio Offset: 0x00E4) Write Protection Mode Register */ + __I uint32_t PIO_WPSR; /**< \brief (Pio Offset: 0x00E8) Write Protection Status Register */ + __I uint32_t Reserved12[5]; + __IO uint32_t PIO_SCHMITT; /**< \brief (Pio Offset: 0x0100) Schmitt Trigger Register */ + __I uint32_t Reserved13[3]; + __IO uint32_t PIO_DELAYR; /**< \brief (Pio Offset: 0x0110) I/O Delay Register */ + __I uint32_t Reserved14[15]; + __IO uint32_t PIO_PCMR; /**< \brief (Pio Offset: 0x150) Parallel Capture Mode Register */ + __O uint32_t PIO_PCIER; /**< \brief (Pio Offset: 0x154) Parallel Capture Interrupt Enable Register */ + __O uint32_t PIO_PCIDR; /**< \brief (Pio Offset: 0x158) Parallel Capture Interrupt Disable Register */ + __I uint32_t PIO_PCIMR; /**< \brief (Pio Offset: 0x15C) Parallel Capture Interrupt Mask Register */ + __I uint32_t PIO_PCISR; /**< \brief (Pio Offset: 0x160) Parallel Capture Interrupt Status Register */ + __I uint32_t PIO_PCRHR; /**< \brief (Pio Offset: 0x164) Parallel Capture Reception Holding Register */ + __IO uint32_t PIO_RPR; /**< \brief (Pio Offset: 0x168) Receive Pointer Register */ + __IO uint32_t PIO_RCR; /**< \brief (Pio Offset: 0x16C) Receive Counter Register */ + __I uint32_t Reserved15[2]; + __IO uint32_t PIO_RNPR; /**< \brief (Pio Offset: 0x178) Receive Next Pointer Register */ + __IO uint32_t PIO_RNCR; /**< \brief (Pio Offset: 0x17C) Receive Next Counter Register */ + __I uint32_t Reserved16[2]; + __O uint32_t PIO_PTCR; /**< \brief (Pio Offset: 0x188) Transfer Control Register */ + __I uint32_t PIO_PTSR; /**< \brief (Pio Offset: 0x18C) Transfer Status Register */ +} Pio; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- PIO_PER : (PIO Offset: 0x0000) PIO Enable Register -------- */ +#define PIO_PER_P0 (0x1u << 0) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P1 (0x1u << 1) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P2 (0x1u << 2) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P3 (0x1u << 3) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P4 (0x1u << 4) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P5 (0x1u << 5) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P6 (0x1u << 6) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P7 (0x1u << 7) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P8 (0x1u << 8) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P9 (0x1u << 9) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P10 (0x1u << 10) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P11 (0x1u << 11) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P12 (0x1u << 12) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P13 (0x1u << 13) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P14 (0x1u << 14) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P15 (0x1u << 15) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P16 (0x1u << 16) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P17 (0x1u << 17) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P18 (0x1u << 18) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P19 (0x1u << 19) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P20 (0x1u << 20) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P21 (0x1u << 21) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P22 (0x1u << 22) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P23 (0x1u << 23) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P24 (0x1u << 24) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P25 (0x1u << 25) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P26 (0x1u << 26) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P27 (0x1u << 27) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P28 (0x1u << 28) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P29 (0x1u << 29) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P30 (0x1u << 30) /**< \brief (PIO_PER) PIO Enable */ +#define PIO_PER_P31 (0x1u << 31) /**< \brief (PIO_PER) PIO Enable */ +/* -------- PIO_PDR : (PIO Offset: 0x0004) PIO Disable Register -------- */ +#define PIO_PDR_P0 (0x1u << 0) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P1 (0x1u << 1) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P2 (0x1u << 2) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P3 (0x1u << 3) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P4 (0x1u << 4) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P5 (0x1u << 5) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P6 (0x1u << 6) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P7 (0x1u << 7) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P8 (0x1u << 8) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P9 (0x1u << 9) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P10 (0x1u << 10) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P11 (0x1u << 11) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P12 (0x1u << 12) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P13 (0x1u << 13) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P14 (0x1u << 14) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P15 (0x1u << 15) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P16 (0x1u << 16) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P17 (0x1u << 17) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P18 (0x1u << 18) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P19 (0x1u << 19) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P20 (0x1u << 20) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P21 (0x1u << 21) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P22 (0x1u << 22) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P23 (0x1u << 23) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P24 (0x1u << 24) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P25 (0x1u << 25) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P26 (0x1u << 26) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P27 (0x1u << 27) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P28 (0x1u << 28) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P29 (0x1u << 29) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P30 (0x1u << 30) /**< \brief (PIO_PDR) PIO Disable */ +#define PIO_PDR_P31 (0x1u << 31) /**< \brief (PIO_PDR) PIO Disable */ +/* -------- PIO_PSR : (PIO Offset: 0x0008) PIO Status Register -------- */ +#define PIO_PSR_P0 (0x1u << 0) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P1 (0x1u << 1) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P2 (0x1u << 2) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P3 (0x1u << 3) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P4 (0x1u << 4) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P5 (0x1u << 5) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P6 (0x1u << 6) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P7 (0x1u << 7) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P8 (0x1u << 8) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P9 (0x1u << 9) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P10 (0x1u << 10) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P11 (0x1u << 11) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P12 (0x1u << 12) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P13 (0x1u << 13) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P14 (0x1u << 14) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P15 (0x1u << 15) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P16 (0x1u << 16) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P17 (0x1u << 17) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P18 (0x1u << 18) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P19 (0x1u << 19) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P20 (0x1u << 20) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P21 (0x1u << 21) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P22 (0x1u << 22) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P23 (0x1u << 23) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P24 (0x1u << 24) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P25 (0x1u << 25) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P26 (0x1u << 26) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P27 (0x1u << 27) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P28 (0x1u << 28) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P29 (0x1u << 29) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P30 (0x1u << 30) /**< \brief (PIO_PSR) PIO Status */ +#define PIO_PSR_P31 (0x1u << 31) /**< \brief (PIO_PSR) PIO Status */ +/* -------- PIO_OER : (PIO Offset: 0x0010) Output Enable Register -------- */ +#define PIO_OER_P0 (0x1u << 0) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P1 (0x1u << 1) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P2 (0x1u << 2) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P3 (0x1u << 3) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P4 (0x1u << 4) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P5 (0x1u << 5) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P6 (0x1u << 6) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P7 (0x1u << 7) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P8 (0x1u << 8) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P9 (0x1u << 9) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P10 (0x1u << 10) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P11 (0x1u << 11) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P12 (0x1u << 12) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P13 (0x1u << 13) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P14 (0x1u << 14) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P15 (0x1u << 15) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P16 (0x1u << 16) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P17 (0x1u << 17) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P18 (0x1u << 18) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P19 (0x1u << 19) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P20 (0x1u << 20) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P21 (0x1u << 21) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P22 (0x1u << 22) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P23 (0x1u << 23) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P24 (0x1u << 24) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P25 (0x1u << 25) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P26 (0x1u << 26) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P27 (0x1u << 27) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P28 (0x1u << 28) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P29 (0x1u << 29) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P30 (0x1u << 30) /**< \brief (PIO_OER) Output Enable */ +#define PIO_OER_P31 (0x1u << 31) /**< \brief (PIO_OER) Output Enable */ +/* -------- PIO_ODR : (PIO Offset: 0x0014) Output Disable Register -------- */ +#define PIO_ODR_P0 (0x1u << 0) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P1 (0x1u << 1) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P2 (0x1u << 2) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P3 (0x1u << 3) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P4 (0x1u << 4) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P5 (0x1u << 5) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P6 (0x1u << 6) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P7 (0x1u << 7) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P8 (0x1u << 8) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P9 (0x1u << 9) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P10 (0x1u << 10) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P11 (0x1u << 11) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P12 (0x1u << 12) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P13 (0x1u << 13) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P14 (0x1u << 14) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P15 (0x1u << 15) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P16 (0x1u << 16) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P17 (0x1u << 17) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P18 (0x1u << 18) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P19 (0x1u << 19) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P20 (0x1u << 20) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P21 (0x1u << 21) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P22 (0x1u << 22) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P23 (0x1u << 23) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P24 (0x1u << 24) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P25 (0x1u << 25) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P26 (0x1u << 26) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P27 (0x1u << 27) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P28 (0x1u << 28) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P29 (0x1u << 29) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P30 (0x1u << 30) /**< \brief (PIO_ODR) Output Disable */ +#define PIO_ODR_P31 (0x1u << 31) /**< \brief (PIO_ODR) Output Disable */ +/* -------- PIO_OSR : (PIO Offset: 0x0018) Output Status Register -------- */ +#define PIO_OSR_P0 (0x1u << 0) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P1 (0x1u << 1) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P2 (0x1u << 2) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P3 (0x1u << 3) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P4 (0x1u << 4) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P5 (0x1u << 5) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P6 (0x1u << 6) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P7 (0x1u << 7) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P8 (0x1u << 8) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P9 (0x1u << 9) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P10 (0x1u << 10) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P11 (0x1u << 11) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P12 (0x1u << 12) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P13 (0x1u << 13) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P14 (0x1u << 14) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P15 (0x1u << 15) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P16 (0x1u << 16) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P17 (0x1u << 17) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P18 (0x1u << 18) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P19 (0x1u << 19) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P20 (0x1u << 20) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P21 (0x1u << 21) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P22 (0x1u << 22) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P23 (0x1u << 23) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P24 (0x1u << 24) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P25 (0x1u << 25) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P26 (0x1u << 26) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P27 (0x1u << 27) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P28 (0x1u << 28) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P29 (0x1u << 29) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P30 (0x1u << 30) /**< \brief (PIO_OSR) Output Status */ +#define PIO_OSR_P31 (0x1u << 31) /**< \brief (PIO_OSR) Output Status */ +/* -------- PIO_IFER : (PIO Offset: 0x0020) Glitch Input Filter Enable Register -------- */ +#define PIO_IFER_P0 (0x1u << 0) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P1 (0x1u << 1) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P2 (0x1u << 2) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P3 (0x1u << 3) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P4 (0x1u << 4) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P5 (0x1u << 5) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P6 (0x1u << 6) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P7 (0x1u << 7) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P8 (0x1u << 8) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P9 (0x1u << 9) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P10 (0x1u << 10) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P11 (0x1u << 11) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P12 (0x1u << 12) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P13 (0x1u << 13) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P14 (0x1u << 14) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P15 (0x1u << 15) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P16 (0x1u << 16) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P17 (0x1u << 17) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P18 (0x1u << 18) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P19 (0x1u << 19) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P20 (0x1u << 20) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P21 (0x1u << 21) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P22 (0x1u << 22) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P23 (0x1u << 23) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P24 (0x1u << 24) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P25 (0x1u << 25) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P26 (0x1u << 26) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P27 (0x1u << 27) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P28 (0x1u << 28) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P29 (0x1u << 29) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P30 (0x1u << 30) /**< \brief (PIO_IFER) Input Filter Enable */ +#define PIO_IFER_P31 (0x1u << 31) /**< \brief (PIO_IFER) Input Filter Enable */ +/* -------- PIO_IFDR : (PIO Offset: 0x0024) Glitch Input Filter Disable Register -------- */ +#define PIO_IFDR_P0 (0x1u << 0) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P1 (0x1u << 1) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P2 (0x1u << 2) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P3 (0x1u << 3) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P4 (0x1u << 4) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P5 (0x1u << 5) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P6 (0x1u << 6) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P7 (0x1u << 7) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P8 (0x1u << 8) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P9 (0x1u << 9) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P10 (0x1u << 10) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P11 (0x1u << 11) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P12 (0x1u << 12) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P13 (0x1u << 13) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P14 (0x1u << 14) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P15 (0x1u << 15) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P16 (0x1u << 16) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P17 (0x1u << 17) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P18 (0x1u << 18) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P19 (0x1u << 19) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P20 (0x1u << 20) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P21 (0x1u << 21) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P22 (0x1u << 22) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P23 (0x1u << 23) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P24 (0x1u << 24) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P25 (0x1u << 25) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P26 (0x1u << 26) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P27 (0x1u << 27) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P28 (0x1u << 28) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P29 (0x1u << 29) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P30 (0x1u << 30) /**< \brief (PIO_IFDR) Input Filter Disable */ +#define PIO_IFDR_P31 (0x1u << 31) /**< \brief (PIO_IFDR) Input Filter Disable */ +/* -------- PIO_IFSR : (PIO Offset: 0x0028) Glitch Input Filter Status Register -------- */ +#define PIO_IFSR_P0 (0x1u << 0) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P1 (0x1u << 1) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P2 (0x1u << 2) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P3 (0x1u << 3) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P4 (0x1u << 4) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P5 (0x1u << 5) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P6 (0x1u << 6) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P7 (0x1u << 7) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P8 (0x1u << 8) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P9 (0x1u << 9) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P10 (0x1u << 10) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P11 (0x1u << 11) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P12 (0x1u << 12) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P13 (0x1u << 13) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P14 (0x1u << 14) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P15 (0x1u << 15) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P16 (0x1u << 16) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P17 (0x1u << 17) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P18 (0x1u << 18) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P19 (0x1u << 19) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P20 (0x1u << 20) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P21 (0x1u << 21) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P22 (0x1u << 22) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P23 (0x1u << 23) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P24 (0x1u << 24) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P25 (0x1u << 25) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P26 (0x1u << 26) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P27 (0x1u << 27) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P28 (0x1u << 28) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P29 (0x1u << 29) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P30 (0x1u << 30) /**< \brief (PIO_IFSR) Input Filer Status */ +#define PIO_IFSR_P31 (0x1u << 31) /**< \brief (PIO_IFSR) Input Filer Status */ +/* -------- PIO_SODR : (PIO Offset: 0x0030) Set Output Data Register -------- */ +#define PIO_SODR_P0 (0x1u << 0) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P1 (0x1u << 1) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P2 (0x1u << 2) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P3 (0x1u << 3) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P4 (0x1u << 4) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P5 (0x1u << 5) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P6 (0x1u << 6) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P7 (0x1u << 7) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P8 (0x1u << 8) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P9 (0x1u << 9) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P10 (0x1u << 10) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P11 (0x1u << 11) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P12 (0x1u << 12) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P13 (0x1u << 13) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P14 (0x1u << 14) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P15 (0x1u << 15) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P16 (0x1u << 16) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P17 (0x1u << 17) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P18 (0x1u << 18) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P19 (0x1u << 19) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P20 (0x1u << 20) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P21 (0x1u << 21) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P22 (0x1u << 22) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P23 (0x1u << 23) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P24 (0x1u << 24) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P25 (0x1u << 25) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P26 (0x1u << 26) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P27 (0x1u << 27) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P28 (0x1u << 28) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P29 (0x1u << 29) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P30 (0x1u << 30) /**< \brief (PIO_SODR) Set Output Data */ +#define PIO_SODR_P31 (0x1u << 31) /**< \brief (PIO_SODR) Set Output Data */ +/* -------- PIO_CODR : (PIO Offset: 0x0034) Clear Output Data Register -------- */ +#define PIO_CODR_P0 (0x1u << 0) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P1 (0x1u << 1) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P2 (0x1u << 2) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P3 (0x1u << 3) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P4 (0x1u << 4) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P5 (0x1u << 5) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P6 (0x1u << 6) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P7 (0x1u << 7) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P8 (0x1u << 8) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P9 (0x1u << 9) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P10 (0x1u << 10) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P11 (0x1u << 11) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P12 (0x1u << 12) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P13 (0x1u << 13) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P14 (0x1u << 14) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P15 (0x1u << 15) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P16 (0x1u << 16) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P17 (0x1u << 17) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P18 (0x1u << 18) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P19 (0x1u << 19) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P20 (0x1u << 20) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P21 (0x1u << 21) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P22 (0x1u << 22) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P23 (0x1u << 23) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P24 (0x1u << 24) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P25 (0x1u << 25) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P26 (0x1u << 26) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P27 (0x1u << 27) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P28 (0x1u << 28) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P29 (0x1u << 29) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P30 (0x1u << 30) /**< \brief (PIO_CODR) Clear Output Data */ +#define PIO_CODR_P31 (0x1u << 31) /**< \brief (PIO_CODR) Clear Output Data */ +/* -------- PIO_ODSR : (PIO Offset: 0x0038) Output Data Status Register -------- */ +#define PIO_ODSR_P0 (0x1u << 0) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P1 (0x1u << 1) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P2 (0x1u << 2) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P3 (0x1u << 3) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P4 (0x1u << 4) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P5 (0x1u << 5) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P6 (0x1u << 6) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P7 (0x1u << 7) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P8 (0x1u << 8) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P9 (0x1u << 9) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P10 (0x1u << 10) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P11 (0x1u << 11) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P12 (0x1u << 12) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P13 (0x1u << 13) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P14 (0x1u << 14) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P15 (0x1u << 15) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P16 (0x1u << 16) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P17 (0x1u << 17) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P18 (0x1u << 18) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P19 (0x1u << 19) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P20 (0x1u << 20) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P21 (0x1u << 21) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P22 (0x1u << 22) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P23 (0x1u << 23) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P24 (0x1u << 24) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P25 (0x1u << 25) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P26 (0x1u << 26) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P27 (0x1u << 27) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P28 (0x1u << 28) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P29 (0x1u << 29) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P30 (0x1u << 30) /**< \brief (PIO_ODSR) Output Data Status */ +#define PIO_ODSR_P31 (0x1u << 31) /**< \brief (PIO_ODSR) Output Data Status */ +/* -------- PIO_PDSR : (PIO Offset: 0x003C) Pin Data Status Register -------- */ +#define PIO_PDSR_P0 (0x1u << 0) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P1 (0x1u << 1) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P2 (0x1u << 2) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P3 (0x1u << 3) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P4 (0x1u << 4) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P5 (0x1u << 5) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P6 (0x1u << 6) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P7 (0x1u << 7) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P8 (0x1u << 8) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P9 (0x1u << 9) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P10 (0x1u << 10) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P11 (0x1u << 11) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P12 (0x1u << 12) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P13 (0x1u << 13) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P14 (0x1u << 14) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P15 (0x1u << 15) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P16 (0x1u << 16) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P17 (0x1u << 17) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P18 (0x1u << 18) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P19 (0x1u << 19) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P20 (0x1u << 20) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P21 (0x1u << 21) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P22 (0x1u << 22) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P23 (0x1u << 23) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P24 (0x1u << 24) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P25 (0x1u << 25) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P26 (0x1u << 26) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P27 (0x1u << 27) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P28 (0x1u << 28) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P29 (0x1u << 29) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P30 (0x1u << 30) /**< \brief (PIO_PDSR) Output Data Status */ +#define PIO_PDSR_P31 (0x1u << 31) /**< \brief (PIO_PDSR) Output Data Status */ +/* -------- PIO_IER : (PIO Offset: 0x0040) Interrupt Enable Register -------- */ +#define PIO_IER_P0 (0x1u << 0) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P1 (0x1u << 1) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P2 (0x1u << 2) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P3 (0x1u << 3) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P4 (0x1u << 4) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P5 (0x1u << 5) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P6 (0x1u << 6) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P7 (0x1u << 7) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P8 (0x1u << 8) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P9 (0x1u << 9) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P10 (0x1u << 10) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P11 (0x1u << 11) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P12 (0x1u << 12) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P13 (0x1u << 13) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P14 (0x1u << 14) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P15 (0x1u << 15) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P16 (0x1u << 16) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P17 (0x1u << 17) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P18 (0x1u << 18) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P19 (0x1u << 19) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P20 (0x1u << 20) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P21 (0x1u << 21) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P22 (0x1u << 22) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P23 (0x1u << 23) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P24 (0x1u << 24) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P25 (0x1u << 25) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P26 (0x1u << 26) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P27 (0x1u << 27) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P28 (0x1u << 28) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P29 (0x1u << 29) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P30 (0x1u << 30) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +#define PIO_IER_P31 (0x1u << 31) /**< \brief (PIO_IER) Input Change Interrupt Enable */ +/* -------- PIO_IDR : (PIO Offset: 0x0044) Interrupt Disable Register -------- */ +#define PIO_IDR_P0 (0x1u << 0) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P1 (0x1u << 1) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P2 (0x1u << 2) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P3 (0x1u << 3) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P4 (0x1u << 4) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P5 (0x1u << 5) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P6 (0x1u << 6) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P7 (0x1u << 7) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P8 (0x1u << 8) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P9 (0x1u << 9) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P10 (0x1u << 10) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P11 (0x1u << 11) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P12 (0x1u << 12) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P13 (0x1u << 13) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P14 (0x1u << 14) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P15 (0x1u << 15) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P16 (0x1u << 16) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P17 (0x1u << 17) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P18 (0x1u << 18) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P19 (0x1u << 19) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P20 (0x1u << 20) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P21 (0x1u << 21) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P22 (0x1u << 22) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P23 (0x1u << 23) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P24 (0x1u << 24) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P25 (0x1u << 25) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P26 (0x1u << 26) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P27 (0x1u << 27) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P28 (0x1u << 28) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P29 (0x1u << 29) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P30 (0x1u << 30) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +#define PIO_IDR_P31 (0x1u << 31) /**< \brief (PIO_IDR) Input Change Interrupt Disable */ +/* -------- PIO_IMR : (PIO Offset: 0x0048) Interrupt Mask Register -------- */ +#define PIO_IMR_P0 (0x1u << 0) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P1 (0x1u << 1) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P2 (0x1u << 2) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P3 (0x1u << 3) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P4 (0x1u << 4) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P5 (0x1u << 5) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P6 (0x1u << 6) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P7 (0x1u << 7) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P8 (0x1u << 8) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P9 (0x1u << 9) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P10 (0x1u << 10) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P11 (0x1u << 11) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P12 (0x1u << 12) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P13 (0x1u << 13) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P14 (0x1u << 14) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P15 (0x1u << 15) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P16 (0x1u << 16) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P17 (0x1u << 17) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P18 (0x1u << 18) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P19 (0x1u << 19) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P20 (0x1u << 20) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P21 (0x1u << 21) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P22 (0x1u << 22) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P23 (0x1u << 23) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P24 (0x1u << 24) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P25 (0x1u << 25) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P26 (0x1u << 26) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P27 (0x1u << 27) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P28 (0x1u << 28) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P29 (0x1u << 29) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P30 (0x1u << 30) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +#define PIO_IMR_P31 (0x1u << 31) /**< \brief (PIO_IMR) Input Change Interrupt Mask */ +/* -------- PIO_ISR : (PIO Offset: 0x004C) Interrupt Status Register -------- */ +#define PIO_ISR_P0 (0x1u << 0) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P1 (0x1u << 1) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P2 (0x1u << 2) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P3 (0x1u << 3) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P4 (0x1u << 4) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P5 (0x1u << 5) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P6 (0x1u << 6) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P7 (0x1u << 7) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P8 (0x1u << 8) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P9 (0x1u << 9) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P10 (0x1u << 10) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P11 (0x1u << 11) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P12 (0x1u << 12) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P13 (0x1u << 13) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P14 (0x1u << 14) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P15 (0x1u << 15) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P16 (0x1u << 16) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P17 (0x1u << 17) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P18 (0x1u << 18) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P19 (0x1u << 19) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P20 (0x1u << 20) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P21 (0x1u << 21) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P22 (0x1u << 22) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P23 (0x1u << 23) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P24 (0x1u << 24) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P25 (0x1u << 25) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P26 (0x1u << 26) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P27 (0x1u << 27) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P28 (0x1u << 28) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P29 (0x1u << 29) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P30 (0x1u << 30) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +#define PIO_ISR_P31 (0x1u << 31) /**< \brief (PIO_ISR) Input Change Interrupt Status */ +/* -------- PIO_MDER : (PIO Offset: 0x0050) Multi-driver Enable Register -------- */ +#define PIO_MDER_P0 (0x1u << 0) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P1 (0x1u << 1) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P2 (0x1u << 2) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P3 (0x1u << 3) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P4 (0x1u << 4) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P5 (0x1u << 5) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P6 (0x1u << 6) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P7 (0x1u << 7) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P8 (0x1u << 8) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P9 (0x1u << 9) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P10 (0x1u << 10) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P11 (0x1u << 11) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P12 (0x1u << 12) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P13 (0x1u << 13) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P14 (0x1u << 14) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P15 (0x1u << 15) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P16 (0x1u << 16) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P17 (0x1u << 17) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P18 (0x1u << 18) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P19 (0x1u << 19) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P20 (0x1u << 20) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P21 (0x1u << 21) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P22 (0x1u << 22) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P23 (0x1u << 23) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P24 (0x1u << 24) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P25 (0x1u << 25) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P26 (0x1u << 26) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P27 (0x1u << 27) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P28 (0x1u << 28) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P29 (0x1u << 29) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P30 (0x1u << 30) /**< \brief (PIO_MDER) Multi-drive Enable */ +#define PIO_MDER_P31 (0x1u << 31) /**< \brief (PIO_MDER) Multi-drive Enable */ +/* -------- PIO_MDDR : (PIO Offset: 0x0054) Multi-driver Disable Register -------- */ +#define PIO_MDDR_P0 (0x1u << 0) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P1 (0x1u << 1) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P2 (0x1u << 2) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P3 (0x1u << 3) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P4 (0x1u << 4) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P5 (0x1u << 5) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P6 (0x1u << 6) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P7 (0x1u << 7) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P8 (0x1u << 8) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P9 (0x1u << 9) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P10 (0x1u << 10) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P11 (0x1u << 11) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P12 (0x1u << 12) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P13 (0x1u << 13) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P14 (0x1u << 14) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P15 (0x1u << 15) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P16 (0x1u << 16) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P17 (0x1u << 17) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P18 (0x1u << 18) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P19 (0x1u << 19) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P20 (0x1u << 20) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P21 (0x1u << 21) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P22 (0x1u << 22) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P23 (0x1u << 23) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P24 (0x1u << 24) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P25 (0x1u << 25) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P26 (0x1u << 26) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P27 (0x1u << 27) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P28 (0x1u << 28) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P29 (0x1u << 29) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P30 (0x1u << 30) /**< \brief (PIO_MDDR) Multi-drive Disable */ +#define PIO_MDDR_P31 (0x1u << 31) /**< \brief (PIO_MDDR) Multi-drive Disable */ +/* -------- PIO_MDSR : (PIO Offset: 0x0058) Multi-driver Status Register -------- */ +#define PIO_MDSR_P0 (0x1u << 0) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P1 (0x1u << 1) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P2 (0x1u << 2) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P3 (0x1u << 3) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P4 (0x1u << 4) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P5 (0x1u << 5) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P6 (0x1u << 6) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P7 (0x1u << 7) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P8 (0x1u << 8) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P9 (0x1u << 9) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P10 (0x1u << 10) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P11 (0x1u << 11) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P12 (0x1u << 12) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P13 (0x1u << 13) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P14 (0x1u << 14) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P15 (0x1u << 15) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P16 (0x1u << 16) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P17 (0x1u << 17) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P18 (0x1u << 18) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P19 (0x1u << 19) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P20 (0x1u << 20) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P21 (0x1u << 21) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P22 (0x1u << 22) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P23 (0x1u << 23) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P24 (0x1u << 24) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P25 (0x1u << 25) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P26 (0x1u << 26) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P27 (0x1u << 27) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P28 (0x1u << 28) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P29 (0x1u << 29) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P30 (0x1u << 30) /**< \brief (PIO_MDSR) Multi-drive Status */ +#define PIO_MDSR_P31 (0x1u << 31) /**< \brief (PIO_MDSR) Multi-drive Status */ +/* -------- PIO_PUDR : (PIO Offset: 0x0060) Pull-up Disable Register -------- */ +#define PIO_PUDR_P0 (0x1u << 0) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P1 (0x1u << 1) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P2 (0x1u << 2) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P3 (0x1u << 3) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P4 (0x1u << 4) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P5 (0x1u << 5) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P6 (0x1u << 6) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P7 (0x1u << 7) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P8 (0x1u << 8) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P9 (0x1u << 9) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P10 (0x1u << 10) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P11 (0x1u << 11) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P12 (0x1u << 12) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P13 (0x1u << 13) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P14 (0x1u << 14) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P15 (0x1u << 15) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P16 (0x1u << 16) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P17 (0x1u << 17) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P18 (0x1u << 18) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P19 (0x1u << 19) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P20 (0x1u << 20) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P21 (0x1u << 21) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P22 (0x1u << 22) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P23 (0x1u << 23) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P24 (0x1u << 24) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P25 (0x1u << 25) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P26 (0x1u << 26) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P27 (0x1u << 27) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P28 (0x1u << 28) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P29 (0x1u << 29) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P30 (0x1u << 30) /**< \brief (PIO_PUDR) Pull-Up Disable */ +#define PIO_PUDR_P31 (0x1u << 31) /**< \brief (PIO_PUDR) Pull-Up Disable */ +/* -------- PIO_PUER : (PIO Offset: 0x0064) Pull-up Enable Register -------- */ +#define PIO_PUER_P0 (0x1u << 0) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P1 (0x1u << 1) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P2 (0x1u << 2) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P3 (0x1u << 3) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P4 (0x1u << 4) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P5 (0x1u << 5) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P6 (0x1u << 6) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P7 (0x1u << 7) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P8 (0x1u << 8) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P9 (0x1u << 9) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P10 (0x1u << 10) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P11 (0x1u << 11) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P12 (0x1u << 12) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P13 (0x1u << 13) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P14 (0x1u << 14) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P15 (0x1u << 15) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P16 (0x1u << 16) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P17 (0x1u << 17) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P18 (0x1u << 18) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P19 (0x1u << 19) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P20 (0x1u << 20) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P21 (0x1u << 21) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P22 (0x1u << 22) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P23 (0x1u << 23) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P24 (0x1u << 24) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P25 (0x1u << 25) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P26 (0x1u << 26) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P27 (0x1u << 27) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P28 (0x1u << 28) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P29 (0x1u << 29) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P30 (0x1u << 30) /**< \brief (PIO_PUER) Pull-Up Enable */ +#define PIO_PUER_P31 (0x1u << 31) /**< \brief (PIO_PUER) Pull-Up Enable */ +/* -------- PIO_PUSR : (PIO Offset: 0x0068) Pad Pull-up Status Register -------- */ +#define PIO_PUSR_P0 (0x1u << 0) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P1 (0x1u << 1) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P2 (0x1u << 2) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P3 (0x1u << 3) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P4 (0x1u << 4) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P5 (0x1u << 5) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P6 (0x1u << 6) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P7 (0x1u << 7) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P8 (0x1u << 8) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P9 (0x1u << 9) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P10 (0x1u << 10) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P11 (0x1u << 11) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P12 (0x1u << 12) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P13 (0x1u << 13) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P14 (0x1u << 14) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P15 (0x1u << 15) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P16 (0x1u << 16) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P17 (0x1u << 17) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P18 (0x1u << 18) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P19 (0x1u << 19) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P20 (0x1u << 20) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P21 (0x1u << 21) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P22 (0x1u << 22) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P23 (0x1u << 23) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P24 (0x1u << 24) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P25 (0x1u << 25) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P26 (0x1u << 26) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P27 (0x1u << 27) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P28 (0x1u << 28) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P29 (0x1u << 29) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P30 (0x1u << 30) /**< \brief (PIO_PUSR) Pull-Up Status */ +#define PIO_PUSR_P31 (0x1u << 31) /**< \brief (PIO_PUSR) Pull-Up Status */ +/* -------- PIO_ABCDSR[2] : (PIO Offset: 0x0070) Peripheral Select Register -------- */ +#define PIO_ABCDSR_P0 (0x1u << 0) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P1 (0x1u << 1) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P2 (0x1u << 2) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P3 (0x1u << 3) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P4 (0x1u << 4) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P5 (0x1u << 5) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P6 (0x1u << 6) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P7 (0x1u << 7) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P8 (0x1u << 8) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P9 (0x1u << 9) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P10 (0x1u << 10) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P11 (0x1u << 11) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P12 (0x1u << 12) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P13 (0x1u << 13) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P14 (0x1u << 14) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P15 (0x1u << 15) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P16 (0x1u << 16) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P17 (0x1u << 17) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P18 (0x1u << 18) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P19 (0x1u << 19) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P20 (0x1u << 20) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P21 (0x1u << 21) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P22 (0x1u << 22) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P23 (0x1u << 23) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P24 (0x1u << 24) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P25 (0x1u << 25) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P26 (0x1u << 26) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P27 (0x1u << 27) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P28 (0x1u << 28) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P29 (0x1u << 29) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P30 (0x1u << 30) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +#define PIO_ABCDSR_P31 (0x1u << 31) /**< \brief (PIO_ABCDSR[2]) Peripheral Select */ +/* -------- PIO_IFSCDR : (PIO Offset: 0x0080) Input Filter Slow Clock Disable Register -------- */ +#define PIO_IFSCDR_P0 (0x1u << 0) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P1 (0x1u << 1) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P2 (0x1u << 2) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P3 (0x1u << 3) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P4 (0x1u << 4) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P5 (0x1u << 5) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P6 (0x1u << 6) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P7 (0x1u << 7) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P8 (0x1u << 8) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P9 (0x1u << 9) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P10 (0x1u << 10) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P11 (0x1u << 11) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P12 (0x1u << 12) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P13 (0x1u << 13) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P14 (0x1u << 14) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P15 (0x1u << 15) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P16 (0x1u << 16) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P17 (0x1u << 17) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P18 (0x1u << 18) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P19 (0x1u << 19) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P20 (0x1u << 20) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P21 (0x1u << 21) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P22 (0x1u << 22) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P23 (0x1u << 23) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P24 (0x1u << 24) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P25 (0x1u << 25) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P26 (0x1u << 26) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P27 (0x1u << 27) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P28 (0x1u << 28) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P29 (0x1u << 29) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P30 (0x1u << 30) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +#define PIO_IFSCDR_P31 (0x1u << 31) /**< \brief (PIO_IFSCDR) Peripheral Clock Glitch Filtering Select */ +/* -------- PIO_IFSCER : (PIO Offset: 0x0084) Input Filter Slow Clock Enable Register -------- */ +#define PIO_IFSCER_P0 (0x1u << 0) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P1 (0x1u << 1) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P2 (0x1u << 2) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P3 (0x1u << 3) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P4 (0x1u << 4) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P5 (0x1u << 5) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P6 (0x1u << 6) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P7 (0x1u << 7) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P8 (0x1u << 8) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P9 (0x1u << 9) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P10 (0x1u << 10) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P11 (0x1u << 11) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P12 (0x1u << 12) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P13 (0x1u << 13) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P14 (0x1u << 14) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P15 (0x1u << 15) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P16 (0x1u << 16) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P17 (0x1u << 17) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P18 (0x1u << 18) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P19 (0x1u << 19) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P20 (0x1u << 20) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P21 (0x1u << 21) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P22 (0x1u << 22) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P23 (0x1u << 23) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P24 (0x1u << 24) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P25 (0x1u << 25) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P26 (0x1u << 26) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P27 (0x1u << 27) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P28 (0x1u << 28) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P29 (0x1u << 29) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P30 (0x1u << 30) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +#define PIO_IFSCER_P31 (0x1u << 31) /**< \brief (PIO_IFSCER) Slow Clock Debouncing Filtering Select */ +/* -------- PIO_IFSCSR : (PIO Offset: 0x0088) Input Filter Slow Clock Status Register -------- */ +#define PIO_IFSCSR_P0 (0x1u << 0) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P1 (0x1u << 1) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P2 (0x1u << 2) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P3 (0x1u << 3) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P4 (0x1u << 4) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P5 (0x1u << 5) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P6 (0x1u << 6) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P7 (0x1u << 7) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P8 (0x1u << 8) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P9 (0x1u << 9) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P10 (0x1u << 10) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P11 (0x1u << 11) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P12 (0x1u << 12) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P13 (0x1u << 13) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P14 (0x1u << 14) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P15 (0x1u << 15) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P16 (0x1u << 16) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P17 (0x1u << 17) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P18 (0x1u << 18) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P19 (0x1u << 19) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P20 (0x1u << 20) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P21 (0x1u << 21) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P22 (0x1u << 22) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P23 (0x1u << 23) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P24 (0x1u << 24) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P25 (0x1u << 25) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P26 (0x1u << 26) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P27 (0x1u << 27) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P28 (0x1u << 28) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P29 (0x1u << 29) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P30 (0x1u << 30) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +#define PIO_IFSCSR_P31 (0x1u << 31) /**< \brief (PIO_IFSCSR) Glitch or Debouncing Filter Selection Status */ +/* -------- PIO_SCDR : (PIO Offset: 0x008C) Slow Clock Divider Debouncing Register -------- */ +#define PIO_SCDR_DIV_Pos 0 +#define PIO_SCDR_DIV_Msk (0x3fffu << PIO_SCDR_DIV_Pos) /**< \brief (PIO_SCDR) Slow Clock Divider Selection for Debouncing */ +#define PIO_SCDR_DIV(value) ((PIO_SCDR_DIV_Msk & ((value) << PIO_SCDR_DIV_Pos))) +/* -------- PIO_PPDDR : (PIO Offset: 0x0090) Pad Pull-down Disable Register -------- */ +#define PIO_PPDDR_P0 (0x1u << 0) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P1 (0x1u << 1) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P2 (0x1u << 2) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P3 (0x1u << 3) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P4 (0x1u << 4) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P5 (0x1u << 5) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P6 (0x1u << 6) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P7 (0x1u << 7) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P8 (0x1u << 8) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P9 (0x1u << 9) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P10 (0x1u << 10) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P11 (0x1u << 11) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P12 (0x1u << 12) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P13 (0x1u << 13) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P14 (0x1u << 14) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P15 (0x1u << 15) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P16 (0x1u << 16) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P17 (0x1u << 17) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P18 (0x1u << 18) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P19 (0x1u << 19) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P20 (0x1u << 20) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P21 (0x1u << 21) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P22 (0x1u << 22) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P23 (0x1u << 23) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P24 (0x1u << 24) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P25 (0x1u << 25) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P26 (0x1u << 26) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P27 (0x1u << 27) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P28 (0x1u << 28) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P29 (0x1u << 29) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P30 (0x1u << 30) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +#define PIO_PPDDR_P31 (0x1u << 31) /**< \brief (PIO_PPDDR) Pull-Down Disable */ +/* -------- PIO_PPDER : (PIO Offset: 0x0094) Pad Pull-down Enable Register -------- */ +#define PIO_PPDER_P0 (0x1u << 0) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P1 (0x1u << 1) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P2 (0x1u << 2) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P3 (0x1u << 3) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P4 (0x1u << 4) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P5 (0x1u << 5) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P6 (0x1u << 6) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P7 (0x1u << 7) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P8 (0x1u << 8) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P9 (0x1u << 9) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P10 (0x1u << 10) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P11 (0x1u << 11) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P12 (0x1u << 12) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P13 (0x1u << 13) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P14 (0x1u << 14) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P15 (0x1u << 15) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P16 (0x1u << 16) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P17 (0x1u << 17) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P18 (0x1u << 18) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P19 (0x1u << 19) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P20 (0x1u << 20) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P21 (0x1u << 21) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P22 (0x1u << 22) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P23 (0x1u << 23) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P24 (0x1u << 24) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P25 (0x1u << 25) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P26 (0x1u << 26) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P27 (0x1u << 27) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P28 (0x1u << 28) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P29 (0x1u << 29) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P30 (0x1u << 30) /**< \brief (PIO_PPDER) Pull-Down Enable */ +#define PIO_PPDER_P31 (0x1u << 31) /**< \brief (PIO_PPDER) Pull-Down Enable */ +/* -------- PIO_PPDSR : (PIO Offset: 0x0098) Pad Pull-down Status Register -------- */ +#define PIO_PPDSR_P0 (0x1u << 0) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P1 (0x1u << 1) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P2 (0x1u << 2) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P3 (0x1u << 3) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P4 (0x1u << 4) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P5 (0x1u << 5) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P6 (0x1u << 6) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P7 (0x1u << 7) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P8 (0x1u << 8) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P9 (0x1u << 9) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P10 (0x1u << 10) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P11 (0x1u << 11) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P12 (0x1u << 12) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P13 (0x1u << 13) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P14 (0x1u << 14) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P15 (0x1u << 15) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P16 (0x1u << 16) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P17 (0x1u << 17) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P18 (0x1u << 18) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P19 (0x1u << 19) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P20 (0x1u << 20) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P21 (0x1u << 21) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P22 (0x1u << 22) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P23 (0x1u << 23) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P24 (0x1u << 24) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P25 (0x1u << 25) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P26 (0x1u << 26) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P27 (0x1u << 27) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P28 (0x1u << 28) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P29 (0x1u << 29) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P30 (0x1u << 30) /**< \brief (PIO_PPDSR) Pull-Down Status */ +#define PIO_PPDSR_P31 (0x1u << 31) /**< \brief (PIO_PPDSR) Pull-Down Status */ +/* -------- PIO_OWER : (PIO Offset: 0x00A0) Output Write Enable -------- */ +#define PIO_OWER_P0 (0x1u << 0) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P1 (0x1u << 1) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P2 (0x1u << 2) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P3 (0x1u << 3) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P4 (0x1u << 4) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P5 (0x1u << 5) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P6 (0x1u << 6) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P7 (0x1u << 7) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P8 (0x1u << 8) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P9 (0x1u << 9) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P10 (0x1u << 10) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P11 (0x1u << 11) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P12 (0x1u << 12) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P13 (0x1u << 13) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P14 (0x1u << 14) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P15 (0x1u << 15) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P16 (0x1u << 16) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P17 (0x1u << 17) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P18 (0x1u << 18) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P19 (0x1u << 19) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P20 (0x1u << 20) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P21 (0x1u << 21) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P22 (0x1u << 22) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P23 (0x1u << 23) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P24 (0x1u << 24) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P25 (0x1u << 25) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P26 (0x1u << 26) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P27 (0x1u << 27) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P28 (0x1u << 28) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P29 (0x1u << 29) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P30 (0x1u << 30) /**< \brief (PIO_OWER) Output Write Enable */ +#define PIO_OWER_P31 (0x1u << 31) /**< \brief (PIO_OWER) Output Write Enable */ +/* -------- PIO_OWDR : (PIO Offset: 0x00A4) Output Write Disable -------- */ +#define PIO_OWDR_P0 (0x1u << 0) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P1 (0x1u << 1) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P2 (0x1u << 2) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P3 (0x1u << 3) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P4 (0x1u << 4) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P5 (0x1u << 5) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P6 (0x1u << 6) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P7 (0x1u << 7) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P8 (0x1u << 8) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P9 (0x1u << 9) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P10 (0x1u << 10) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P11 (0x1u << 11) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P12 (0x1u << 12) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P13 (0x1u << 13) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P14 (0x1u << 14) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P15 (0x1u << 15) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P16 (0x1u << 16) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P17 (0x1u << 17) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P18 (0x1u << 18) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P19 (0x1u << 19) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P20 (0x1u << 20) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P21 (0x1u << 21) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P22 (0x1u << 22) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P23 (0x1u << 23) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P24 (0x1u << 24) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P25 (0x1u << 25) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P26 (0x1u << 26) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P27 (0x1u << 27) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P28 (0x1u << 28) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P29 (0x1u << 29) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P30 (0x1u << 30) /**< \brief (PIO_OWDR) Output Write Disable */ +#define PIO_OWDR_P31 (0x1u << 31) /**< \brief (PIO_OWDR) Output Write Disable */ +/* -------- PIO_OWSR : (PIO Offset: 0x00A8) Output Write Status Register -------- */ +#define PIO_OWSR_P0 (0x1u << 0) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P1 (0x1u << 1) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P2 (0x1u << 2) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P3 (0x1u << 3) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P4 (0x1u << 4) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P5 (0x1u << 5) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P6 (0x1u << 6) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P7 (0x1u << 7) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P8 (0x1u << 8) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P9 (0x1u << 9) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P10 (0x1u << 10) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P11 (0x1u << 11) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P12 (0x1u << 12) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P13 (0x1u << 13) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P14 (0x1u << 14) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P15 (0x1u << 15) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P16 (0x1u << 16) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P17 (0x1u << 17) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P18 (0x1u << 18) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P19 (0x1u << 19) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P20 (0x1u << 20) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P21 (0x1u << 21) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P22 (0x1u << 22) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P23 (0x1u << 23) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P24 (0x1u << 24) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P25 (0x1u << 25) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P26 (0x1u << 26) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P27 (0x1u << 27) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P28 (0x1u << 28) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P29 (0x1u << 29) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P30 (0x1u << 30) /**< \brief (PIO_OWSR) Output Write Status */ +#define PIO_OWSR_P31 (0x1u << 31) /**< \brief (PIO_OWSR) Output Write Status */ +/* -------- PIO_AIMER : (PIO Offset: 0x00B0) Additional Interrupt Modes Enable Register -------- */ +#define PIO_AIMER_P0 (0x1u << 0) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P1 (0x1u << 1) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P2 (0x1u << 2) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P3 (0x1u << 3) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P4 (0x1u << 4) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P5 (0x1u << 5) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P6 (0x1u << 6) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P7 (0x1u << 7) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P8 (0x1u << 8) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P9 (0x1u << 9) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P10 (0x1u << 10) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P11 (0x1u << 11) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P12 (0x1u << 12) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P13 (0x1u << 13) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P14 (0x1u << 14) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P15 (0x1u << 15) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P16 (0x1u << 16) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P17 (0x1u << 17) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P18 (0x1u << 18) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P19 (0x1u << 19) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P20 (0x1u << 20) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P21 (0x1u << 21) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P22 (0x1u << 22) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P23 (0x1u << 23) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P24 (0x1u << 24) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P25 (0x1u << 25) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P26 (0x1u << 26) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P27 (0x1u << 27) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P28 (0x1u << 28) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P29 (0x1u << 29) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P30 (0x1u << 30) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +#define PIO_AIMER_P31 (0x1u << 31) /**< \brief (PIO_AIMER) Additional Interrupt Modes Enable */ +/* -------- PIO_AIMDR : (PIO Offset: 0x00B4) Additional Interrupt Modes Disable Register -------- */ +#define PIO_AIMDR_P0 (0x1u << 0) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P1 (0x1u << 1) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P2 (0x1u << 2) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P3 (0x1u << 3) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P4 (0x1u << 4) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P5 (0x1u << 5) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P6 (0x1u << 6) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P7 (0x1u << 7) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P8 (0x1u << 8) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P9 (0x1u << 9) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P10 (0x1u << 10) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P11 (0x1u << 11) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P12 (0x1u << 12) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P13 (0x1u << 13) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P14 (0x1u << 14) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P15 (0x1u << 15) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P16 (0x1u << 16) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P17 (0x1u << 17) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P18 (0x1u << 18) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P19 (0x1u << 19) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P20 (0x1u << 20) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P21 (0x1u << 21) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P22 (0x1u << 22) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P23 (0x1u << 23) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P24 (0x1u << 24) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P25 (0x1u << 25) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P26 (0x1u << 26) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P27 (0x1u << 27) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P28 (0x1u << 28) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P29 (0x1u << 29) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P30 (0x1u << 30) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +#define PIO_AIMDR_P31 (0x1u << 31) /**< \brief (PIO_AIMDR) Additional Interrupt Modes Disable */ +/* -------- PIO_AIMMR : (PIO Offset: 0x00B8) Additional Interrupt Modes Mask Register -------- */ +#define PIO_AIMMR_P0 (0x1u << 0) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P1 (0x1u << 1) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P2 (0x1u << 2) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P3 (0x1u << 3) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P4 (0x1u << 4) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P5 (0x1u << 5) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P6 (0x1u << 6) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P7 (0x1u << 7) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P8 (0x1u << 8) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P9 (0x1u << 9) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P10 (0x1u << 10) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P11 (0x1u << 11) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P12 (0x1u << 12) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P13 (0x1u << 13) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P14 (0x1u << 14) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P15 (0x1u << 15) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P16 (0x1u << 16) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P17 (0x1u << 17) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P18 (0x1u << 18) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P19 (0x1u << 19) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P20 (0x1u << 20) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P21 (0x1u << 21) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P22 (0x1u << 22) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P23 (0x1u << 23) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P24 (0x1u << 24) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P25 (0x1u << 25) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P26 (0x1u << 26) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P27 (0x1u << 27) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P28 (0x1u << 28) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P29 (0x1u << 29) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P30 (0x1u << 30) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +#define PIO_AIMMR_P31 (0x1u << 31) /**< \brief (PIO_AIMMR) Peripheral CD Status */ +/* -------- PIO_ESR : (PIO Offset: 0x00C0) Edge Select Register -------- */ +#define PIO_ESR_P0 (0x1u << 0) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P1 (0x1u << 1) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P2 (0x1u << 2) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P3 (0x1u << 3) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P4 (0x1u << 4) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P5 (0x1u << 5) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P6 (0x1u << 6) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P7 (0x1u << 7) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P8 (0x1u << 8) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P9 (0x1u << 9) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P10 (0x1u << 10) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P11 (0x1u << 11) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P12 (0x1u << 12) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P13 (0x1u << 13) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P14 (0x1u << 14) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P15 (0x1u << 15) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P16 (0x1u << 16) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P17 (0x1u << 17) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P18 (0x1u << 18) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P19 (0x1u << 19) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P20 (0x1u << 20) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P21 (0x1u << 21) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P22 (0x1u << 22) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P23 (0x1u << 23) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P24 (0x1u << 24) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P25 (0x1u << 25) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P26 (0x1u << 26) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P27 (0x1u << 27) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P28 (0x1u << 28) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P29 (0x1u << 29) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P30 (0x1u << 30) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +#define PIO_ESR_P31 (0x1u << 31) /**< \brief (PIO_ESR) Edge Interrupt Selection */ +/* -------- PIO_LSR : (PIO Offset: 0x00C4) Level Select Register -------- */ +#define PIO_LSR_P0 (0x1u << 0) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P1 (0x1u << 1) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P2 (0x1u << 2) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P3 (0x1u << 3) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P4 (0x1u << 4) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P5 (0x1u << 5) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P6 (0x1u << 6) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P7 (0x1u << 7) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P8 (0x1u << 8) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P9 (0x1u << 9) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P10 (0x1u << 10) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P11 (0x1u << 11) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P12 (0x1u << 12) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P13 (0x1u << 13) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P14 (0x1u << 14) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P15 (0x1u << 15) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P16 (0x1u << 16) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P17 (0x1u << 17) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P18 (0x1u << 18) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P19 (0x1u << 19) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P20 (0x1u << 20) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P21 (0x1u << 21) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P22 (0x1u << 22) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P23 (0x1u << 23) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P24 (0x1u << 24) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P25 (0x1u << 25) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P26 (0x1u << 26) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P27 (0x1u << 27) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P28 (0x1u << 28) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P29 (0x1u << 29) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P30 (0x1u << 30) /**< \brief (PIO_LSR) Level Interrupt Selection */ +#define PIO_LSR_P31 (0x1u << 31) /**< \brief (PIO_LSR) Level Interrupt Selection */ +/* -------- PIO_ELSR : (PIO Offset: 0x00C8) Edge/Level Status Register -------- */ +#define PIO_ELSR_P0 (0x1u << 0) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P1 (0x1u << 1) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P2 (0x1u << 2) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P3 (0x1u << 3) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P4 (0x1u << 4) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P5 (0x1u << 5) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P6 (0x1u << 6) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P7 (0x1u << 7) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P8 (0x1u << 8) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P9 (0x1u << 9) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P10 (0x1u << 10) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P11 (0x1u << 11) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P12 (0x1u << 12) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P13 (0x1u << 13) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P14 (0x1u << 14) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P15 (0x1u << 15) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P16 (0x1u << 16) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P17 (0x1u << 17) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P18 (0x1u << 18) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P19 (0x1u << 19) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P20 (0x1u << 20) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P21 (0x1u << 21) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P22 (0x1u << 22) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P23 (0x1u << 23) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P24 (0x1u << 24) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P25 (0x1u << 25) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P26 (0x1u << 26) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P27 (0x1u << 27) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P28 (0x1u << 28) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P29 (0x1u << 29) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P30 (0x1u << 30) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +#define PIO_ELSR_P31 (0x1u << 31) /**< \brief (PIO_ELSR) Edge/Level Interrupt Source Selection */ +/* -------- PIO_FELLSR : (PIO Offset: 0x00D0) Falling Edge/Low-Level Select Register -------- */ +#define PIO_FELLSR_P0 (0x1u << 0) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P1 (0x1u << 1) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P2 (0x1u << 2) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P3 (0x1u << 3) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P4 (0x1u << 4) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P5 (0x1u << 5) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P6 (0x1u << 6) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P7 (0x1u << 7) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P8 (0x1u << 8) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P9 (0x1u << 9) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P10 (0x1u << 10) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P11 (0x1u << 11) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P12 (0x1u << 12) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P13 (0x1u << 13) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P14 (0x1u << 14) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P15 (0x1u << 15) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P16 (0x1u << 16) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P17 (0x1u << 17) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P18 (0x1u << 18) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P19 (0x1u << 19) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P20 (0x1u << 20) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P21 (0x1u << 21) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P22 (0x1u << 22) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P23 (0x1u << 23) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P24 (0x1u << 24) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P25 (0x1u << 25) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P26 (0x1u << 26) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P27 (0x1u << 27) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P28 (0x1u << 28) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P29 (0x1u << 29) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P30 (0x1u << 30) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +#define PIO_FELLSR_P31 (0x1u << 31) /**< \brief (PIO_FELLSR) Falling Edge/Low-Level Interrupt Selection */ +/* -------- PIO_REHLSR : (PIO Offset: 0x00D4) Rising Edge/High-Level Select Register -------- */ +#define PIO_REHLSR_P0 (0x1u << 0) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P1 (0x1u << 1) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P2 (0x1u << 2) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P3 (0x1u << 3) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P4 (0x1u << 4) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P5 (0x1u << 5) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P6 (0x1u << 6) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P7 (0x1u << 7) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P8 (0x1u << 8) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P9 (0x1u << 9) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P10 (0x1u << 10) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P11 (0x1u << 11) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P12 (0x1u << 12) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P13 (0x1u << 13) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P14 (0x1u << 14) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P15 (0x1u << 15) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P16 (0x1u << 16) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P17 (0x1u << 17) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P18 (0x1u << 18) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P19 (0x1u << 19) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P20 (0x1u << 20) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P21 (0x1u << 21) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P22 (0x1u << 22) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P23 (0x1u << 23) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P24 (0x1u << 24) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P25 (0x1u << 25) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P26 (0x1u << 26) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P27 (0x1u << 27) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P28 (0x1u << 28) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P29 (0x1u << 29) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P30 (0x1u << 30) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +#define PIO_REHLSR_P31 (0x1u << 31) /**< \brief (PIO_REHLSR) Rising Edge/High-Level Interrupt Selection */ +/* -------- PIO_FRLHSR : (PIO Offset: 0x00D8) Fall/Rise - Low/High Status Register -------- */ +#define PIO_FRLHSR_P0 (0x1u << 0) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P1 (0x1u << 1) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P2 (0x1u << 2) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P3 (0x1u << 3) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P4 (0x1u << 4) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P5 (0x1u << 5) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P6 (0x1u << 6) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P7 (0x1u << 7) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P8 (0x1u << 8) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P9 (0x1u << 9) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P10 (0x1u << 10) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P11 (0x1u << 11) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P12 (0x1u << 12) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P13 (0x1u << 13) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P14 (0x1u << 14) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P15 (0x1u << 15) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P16 (0x1u << 16) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P17 (0x1u << 17) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P18 (0x1u << 18) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P19 (0x1u << 19) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P20 (0x1u << 20) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P21 (0x1u << 21) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P22 (0x1u << 22) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P23 (0x1u << 23) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P24 (0x1u << 24) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P25 (0x1u << 25) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P26 (0x1u << 26) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P27 (0x1u << 27) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P28 (0x1u << 28) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P29 (0x1u << 29) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P30 (0x1u << 30) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +#define PIO_FRLHSR_P31 (0x1u << 31) /**< \brief (PIO_FRLHSR) Edge/Level Interrupt Source Selection */ +/* -------- PIO_LOCKSR : (PIO Offset: 0x00E0) Lock Status -------- */ +#define PIO_LOCKSR_P0 (0x1u << 0) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P1 (0x1u << 1) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P2 (0x1u << 2) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P3 (0x1u << 3) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P4 (0x1u << 4) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P5 (0x1u << 5) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P6 (0x1u << 6) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P7 (0x1u << 7) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P8 (0x1u << 8) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P9 (0x1u << 9) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P10 (0x1u << 10) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P11 (0x1u << 11) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P12 (0x1u << 12) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P13 (0x1u << 13) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P14 (0x1u << 14) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P15 (0x1u << 15) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P16 (0x1u << 16) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P17 (0x1u << 17) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P18 (0x1u << 18) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P19 (0x1u << 19) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P20 (0x1u << 20) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P21 (0x1u << 21) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P22 (0x1u << 22) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P23 (0x1u << 23) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P24 (0x1u << 24) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P25 (0x1u << 25) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P26 (0x1u << 26) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P27 (0x1u << 27) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P28 (0x1u << 28) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P29 (0x1u << 29) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P30 (0x1u << 30) /**< \brief (PIO_LOCKSR) Lock Status */ +#define PIO_LOCKSR_P31 (0x1u << 31) /**< \brief (PIO_LOCKSR) Lock Status */ +/* -------- PIO_WPMR : (PIO Offset: 0x00E4) Write Protection Mode Register -------- */ +#define PIO_WPMR_WPEN (0x1u << 0) /**< \brief (PIO_WPMR) Write Protection Enable */ +#define PIO_WPMR_WPKEY_Pos 8 +#define PIO_WPMR_WPKEY_Msk (0xffffffu << PIO_WPMR_WPKEY_Pos) /**< \brief (PIO_WPMR) Write Protection Key */ +#define PIO_WPMR_WPKEY_PASSWD (0x50494Fu << 8) /**< \brief (PIO_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit. Always reads as 0. */ +/* -------- PIO_WPSR : (PIO Offset: 0x00E8) Write Protection Status Register -------- */ +#define PIO_WPSR_WPVS (0x1u << 0) /**< \brief (PIO_WPSR) Write Protection Violation Status */ +#define PIO_WPSR_WPVSRC_Pos 8 +#define PIO_WPSR_WPVSRC_Msk (0xffffu << PIO_WPSR_WPVSRC_Pos) /**< \brief (PIO_WPSR) Write Protection Violation Source */ +/* -------- PIO_SCHMITT : (PIO Offset: 0x0100) Schmitt Trigger Register -------- */ +#define PIO_SCHMITT_SCHMITT0 (0x1u << 0) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT1 (0x1u << 1) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT2 (0x1u << 2) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT3 (0x1u << 3) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT4 (0x1u << 4) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT5 (0x1u << 5) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT6 (0x1u << 6) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT7 (0x1u << 7) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT8 (0x1u << 8) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT9 (0x1u << 9) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT10 (0x1u << 10) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT11 (0x1u << 11) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT12 (0x1u << 12) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT13 (0x1u << 13) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT14 (0x1u << 14) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT15 (0x1u << 15) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT16 (0x1u << 16) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT17 (0x1u << 17) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT18 (0x1u << 18) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT19 (0x1u << 19) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT20 (0x1u << 20) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT21 (0x1u << 21) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT22 (0x1u << 22) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT23 (0x1u << 23) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT24 (0x1u << 24) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT25 (0x1u << 25) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT26 (0x1u << 26) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT27 (0x1u << 27) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT28 (0x1u << 28) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT29 (0x1u << 29) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT30 (0x1u << 30) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +#define PIO_SCHMITT_SCHMITT31 (0x1u << 31) /**< \brief (PIO_SCHMITT) Schmitt Trigger Control */ +/* -------- PIO_DELAYR : (PIO Offset: 0x0110) I/O Delay Register -------- */ +#define PIO_DELAYR_Delay0_Pos 0 +#define PIO_DELAYR_Delay0_Msk (0xfu << PIO_DELAYR_Delay0_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay0(value) ((PIO_DELAYR_Delay0_Msk & ((value) << PIO_DELAYR_Delay0_Pos))) +#define PIO_DELAYR_Delay1_Pos 4 +#define PIO_DELAYR_Delay1_Msk (0xfu << PIO_DELAYR_Delay1_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay1(value) ((PIO_DELAYR_Delay1_Msk & ((value) << PIO_DELAYR_Delay1_Pos))) +#define PIO_DELAYR_Delay2_Pos 8 +#define PIO_DELAYR_Delay2_Msk (0xfu << PIO_DELAYR_Delay2_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay2(value) ((PIO_DELAYR_Delay2_Msk & ((value) << PIO_DELAYR_Delay2_Pos))) +#define PIO_DELAYR_Delay3_Pos 12 +#define PIO_DELAYR_Delay3_Msk (0xfu << PIO_DELAYR_Delay3_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay3(value) ((PIO_DELAYR_Delay3_Msk & ((value) << PIO_DELAYR_Delay3_Pos))) +#define PIO_DELAYR_Delay4_Pos 16 +#define PIO_DELAYR_Delay4_Msk (0xfu << PIO_DELAYR_Delay4_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay4(value) ((PIO_DELAYR_Delay4_Msk & ((value) << PIO_DELAYR_Delay4_Pos))) +#define PIO_DELAYR_Delay5_Pos 20 +#define PIO_DELAYR_Delay5_Msk (0xfu << PIO_DELAYR_Delay5_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay5(value) ((PIO_DELAYR_Delay5_Msk & ((value) << PIO_DELAYR_Delay5_Pos))) +#define PIO_DELAYR_Delay6_Pos 24 +#define PIO_DELAYR_Delay6_Msk (0xfu << PIO_DELAYR_Delay6_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay6(value) ((PIO_DELAYR_Delay6_Msk & ((value) << PIO_DELAYR_Delay6_Pos))) +#define PIO_DELAYR_Delay7_Pos 28 +#define PIO_DELAYR_Delay7_Msk (0xfu << PIO_DELAYR_Delay7_Pos) /**< \brief (PIO_DELAYR) Delay Control for Simultaneous Switch Reduction */ +#define PIO_DELAYR_Delay7(value) ((PIO_DELAYR_Delay7_Msk & ((value) << PIO_DELAYR_Delay7_Pos))) +/* -------- PIO_PCMR : (PIO Offset: 0x150) Parallel Capture Mode Register -------- */ +#define PIO_PCMR_PCEN (0x1u << 0) /**< \brief (PIO_PCMR) Parallel Capture Mode Enable */ +#define PIO_PCMR_DSIZE_Pos 4 +#define PIO_PCMR_DSIZE_Msk (0x3u << PIO_PCMR_DSIZE_Pos) /**< \brief (PIO_PCMR) Parallel Capture Mode Data Size */ +#define PIO_PCMR_DSIZE_BYTE (0x0u << 4) /**< \brief (PIO_PCMR) The reception data in the PIO_PCRHR is a byte (8-bit) */ +#define PIO_PCMR_DSIZE_HALFWORD (0x1u << 4) /**< \brief (PIO_PCMR) The reception data in the PIO_PCRHR is a half-word (16-bit) */ +#define PIO_PCMR_DSIZE_WORD (0x2u << 4) /**< \brief (PIO_PCMR) The reception data in the PIO_PCRHR is a word (32-bit) */ +#define PIO_PCMR_ALWYS (0x1u << 9) /**< \brief (PIO_PCMR) Parallel Capture Mode Always Sampling */ +#define PIO_PCMR_HALFS (0x1u << 10) /**< \brief (PIO_PCMR) Parallel Capture Mode Half Sampling */ +#define PIO_PCMR_FRSTS (0x1u << 11) /**< \brief (PIO_PCMR) Parallel Capture Mode First Sample */ +/* -------- PIO_PCIER : (PIO Offset: 0x154) Parallel Capture Interrupt Enable Register -------- */ +#define PIO_PCIER_DRDY (0x1u << 0) /**< \brief (PIO_PCIER) Parallel Capture Mode Data Ready Interrupt Enable */ +#define PIO_PCIER_OVRE (0x1u << 1) /**< \brief (PIO_PCIER) Parallel Capture Mode Overrun Error Interrupt Enable */ +#define PIO_PCIER_ENDRX (0x1u << 2) /**< \brief (PIO_PCIER) End of Reception Transfer Interrupt Enable */ +#define PIO_PCIER_RXBUFF (0x1u << 3) /**< \brief (PIO_PCIER) Reception Buffer Full Interrupt Enable */ +/* -------- PIO_PCIDR : (PIO Offset: 0x158) Parallel Capture Interrupt Disable Register -------- */ +#define PIO_PCIDR_DRDY (0x1u << 0) /**< \brief (PIO_PCIDR) Parallel Capture Mode Data Ready Interrupt Disable */ +#define PIO_PCIDR_OVRE (0x1u << 1) /**< \brief (PIO_PCIDR) Parallel Capture Mode Overrun Error Interrupt Disable */ +#define PIO_PCIDR_ENDRX (0x1u << 2) /**< \brief (PIO_PCIDR) End of Reception Transfer Interrupt Disable */ +#define PIO_PCIDR_RXBUFF (0x1u << 3) /**< \brief (PIO_PCIDR) Reception Buffer Full Interrupt Disable */ +/* -------- PIO_PCIMR : (PIO Offset: 0x15C) Parallel Capture Interrupt Mask Register -------- */ +#define PIO_PCIMR_DRDY (0x1u << 0) /**< \brief (PIO_PCIMR) Parallel Capture Mode Data Ready Interrupt Mask */ +#define PIO_PCIMR_OVRE (0x1u << 1) /**< \brief (PIO_PCIMR) Parallel Capture Mode Overrun Error Interrupt Mask */ +#define PIO_PCIMR_ENDRX (0x1u << 2) /**< \brief (PIO_PCIMR) End of Reception Transfer Interrupt Mask */ +#define PIO_PCIMR_RXBUFF (0x1u << 3) /**< \brief (PIO_PCIMR) Reception Buffer Full Interrupt Mask */ +/* -------- PIO_PCISR : (PIO Offset: 0x160) Parallel Capture Interrupt Status Register -------- */ +#define PIO_PCISR_DRDY (0x1u << 0) /**< \brief (PIO_PCISR) Parallel Capture Mode Data Ready */ +#define PIO_PCISR_OVRE (0x1u << 1) /**< \brief (PIO_PCISR) Parallel Capture Mode Overrun Error. */ +#define PIO_PCISR_ENDRX (0x1u << 2) /**< \brief (PIO_PCISR) End of Reception Transfer. */ +#define PIO_PCISR_RXBUFF (0x1u << 3) /**< \brief (PIO_PCISR) Reception Buffer Full */ +/* -------- PIO_PCRHR : (PIO Offset: 0x164) Parallel Capture Reception Holding Register -------- */ +#define PIO_PCRHR_RDATA_Pos 0 +#define PIO_PCRHR_RDATA_Msk (0xffffffffu << PIO_PCRHR_RDATA_Pos) /**< \brief (PIO_PCRHR) Parallel Capture Mode Reception Data. */ +/* -------- PIO_RPR : (PIO Offset: 0x168) Receive Pointer Register -------- */ +#define PIO_RPR_RXPTR_Pos 0 +#define PIO_RPR_RXPTR_Msk (0xffffffffu << PIO_RPR_RXPTR_Pos) /**< \brief (PIO_RPR) Receive Pointer Register */ +#define PIO_RPR_RXPTR(value) ((PIO_RPR_RXPTR_Msk & ((value) << PIO_RPR_RXPTR_Pos))) +/* -------- PIO_RCR : (PIO Offset: 0x16C) Receive Counter Register -------- */ +#define PIO_RCR_RXCTR_Pos 0 +#define PIO_RCR_RXCTR_Msk (0xffffu << PIO_RCR_RXCTR_Pos) /**< \brief (PIO_RCR) Receive Counter Register */ +#define PIO_RCR_RXCTR(value) ((PIO_RCR_RXCTR_Msk & ((value) << PIO_RCR_RXCTR_Pos))) +/* -------- PIO_RNPR : (PIO Offset: 0x178) Receive Next Pointer Register -------- */ +#define PIO_RNPR_RXNPTR_Pos 0 +#define PIO_RNPR_RXNPTR_Msk (0xffffffffu << PIO_RNPR_RXNPTR_Pos) /**< \brief (PIO_RNPR) Receive Next Pointer */ +#define PIO_RNPR_RXNPTR(value) ((PIO_RNPR_RXNPTR_Msk & ((value) << PIO_RNPR_RXNPTR_Pos))) +/* -------- PIO_RNCR : (PIO Offset: 0x17C) Receive Next Counter Register -------- */ +#define PIO_RNCR_RXNCTR_Pos 0 +#define PIO_RNCR_RXNCTR_Msk (0xffffu << PIO_RNCR_RXNCTR_Pos) /**< \brief (PIO_RNCR) Receive Next Counter */ +#define PIO_RNCR_RXNCTR(value) ((PIO_RNCR_RXNCTR_Msk & ((value) << PIO_RNCR_RXNCTR_Pos))) +/* -------- PIO_PTCR : (PIO Offset: 0x188) Transfer Control Register -------- */ +#define PIO_PTCR_RXTEN (0x1u << 0) /**< \brief (PIO_PTCR) Receiver Transfer Enable */ +#define PIO_PTCR_RXTDIS (0x1u << 1) /**< \brief (PIO_PTCR) Receiver Transfer Disable */ +#define PIO_PTCR_TXTEN (0x1u << 8) /**< \brief (PIO_PTCR) Transmitter Transfer Enable */ +#define PIO_PTCR_TXTDIS (0x1u << 9) /**< \brief (PIO_PTCR) Transmitter Transfer Disable */ +/* -------- PIO_PTSR : (PIO Offset: 0x18C) Transfer Status Register -------- */ +#define PIO_PTSR_RXTEN (0x1u << 0) /**< \brief (PIO_PTSR) Receiver Transfer Enable */ +#define PIO_PTSR_TXTEN (0x1u << 8) /**< \brief (PIO_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_PIO_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pmc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pmc.h new file mode 100644 index 0000000..bf82399 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pmc.h @@ -0,0 +1,429 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PMC_COMPONENT_ +#define _SAM4E_PMC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Power Management Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_PMC Power Management Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Pmc hardware registers */ +typedef struct { + __O uint32_t PMC_SCER; /**< \brief (Pmc Offset: 0x0000) System Clock Enable Register */ + __O uint32_t PMC_SCDR; /**< \brief (Pmc Offset: 0x0004) System Clock Disable Register */ + __I uint32_t PMC_SCSR; /**< \brief (Pmc Offset: 0x0008) System Clock Status Register */ + __I uint32_t Reserved1[1]; + __O uint32_t PMC_PCER0; /**< \brief (Pmc Offset: 0x0010) Peripheral Clock Enable Register 0 */ + __O uint32_t PMC_PCDR0; /**< \brief (Pmc Offset: 0x0014) Peripheral Clock Disable Register 0 */ + __I uint32_t PMC_PCSR0; /**< \brief (Pmc Offset: 0x0018) Peripheral Clock Status Register 0 */ + __I uint32_t Reserved2[1]; + __IO uint32_t CKGR_MOR; /**< \brief (Pmc Offset: 0x0020) Main Oscillator Register */ + __IO uint32_t CKGR_MCFR; /**< \brief (Pmc Offset: 0x0024) Main Clock Frequency Register */ + __IO uint32_t CKGR_PLLAR; /**< \brief (Pmc Offset: 0x0028) PLLA Register */ + __I uint32_t Reserved3[1]; + __IO uint32_t PMC_MCKR; /**< \brief (Pmc Offset: 0x0030) Master Clock Register */ + __I uint32_t Reserved4[1]; + __IO uint32_t PMC_USB; /**< \brief (Pmc Offset: 0x0038) USB Clock Register */ + __I uint32_t Reserved5[1]; + __IO uint32_t PMC_PCK[3]; /**< \brief (Pmc Offset: 0x0040) Programmable Clock 0 Register */ + __I uint32_t Reserved6[5]; + __O uint32_t PMC_IER; /**< \brief (Pmc Offset: 0x0060) Interrupt Enable Register */ + __O uint32_t PMC_IDR; /**< \brief (Pmc Offset: 0x0064) Interrupt Disable Register */ + __I uint32_t PMC_SR; /**< \brief (Pmc Offset: 0x0068) Status Register */ + __I uint32_t PMC_IMR; /**< \brief (Pmc Offset: 0x006C) Interrupt Mask Register */ + __IO uint32_t PMC_FSMR; /**< \brief (Pmc Offset: 0x0070) Fast Startup Mode Register */ + __IO uint32_t PMC_FSPR; /**< \brief (Pmc Offset: 0x0074) Fast Startup Polarity Register */ + __O uint32_t PMC_FOCR; /**< \brief (Pmc Offset: 0x0078) Fault Output Clear Register */ + __I uint32_t Reserved7[26]; + __IO uint32_t PMC_WPMR; /**< \brief (Pmc Offset: 0x00E4) Write Protection Mode Register */ + __I uint32_t PMC_WPSR; /**< \brief (Pmc Offset: 0x00E8) Write Protection Status Register */ + __I uint32_t Reserved8[5]; + __O uint32_t PMC_PCER1; /**< \brief (Pmc Offset: 0x0100) Peripheral Clock Enable Register 1 */ + __O uint32_t PMC_PCDR1; /**< \brief (Pmc Offset: 0x0104) Peripheral Clock Disable Register 1 */ + __I uint32_t PMC_PCSR1; /**< \brief (Pmc Offset: 0x0108) Peripheral Clock Status Register 1 */ + __I uint32_t Reserved9[1]; + __IO uint32_t PMC_OCR; /**< \brief (Pmc Offset: 0x0110) Oscillator Calibration Register */ + __I uint32_t Reserved10[7]; + __IO uint32_t PMC_PMMR; /**< \brief (Pmc Offset: 0x130) PLL Maximum Multiplier Value Register */ +} Pmc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- PMC_SCER : (PMC Offset: 0x0000) System Clock Enable Register -------- */ +#define PMC_SCER_UDP (0x1u << 7) /**< \brief (PMC_SCER) USB Device Port Clock Enable */ +#define PMC_SCER_PCK0 (0x1u << 8) /**< \brief (PMC_SCER) Programmable Clock 0 Output Enable */ +#define PMC_SCER_PCK1 (0x1u << 9) /**< \brief (PMC_SCER) Programmable Clock 1 Output Enable */ +#define PMC_SCER_PCK2 (0x1u << 10) /**< \brief (PMC_SCER) Programmable Clock 2 Output Enable */ +/* -------- PMC_SCDR : (PMC Offset: 0x0004) System Clock Disable Register -------- */ +#define PMC_SCDR_UDP (0x1u << 7) /**< \brief (PMC_SCDR) USB Device Port Clock Disable */ +#define PMC_SCDR_PCK0 (0x1u << 8) /**< \brief (PMC_SCDR) Programmable Clock 0 Output Disable */ +#define PMC_SCDR_PCK1 (0x1u << 9) /**< \brief (PMC_SCDR) Programmable Clock 1 Output Disable */ +#define PMC_SCDR_PCK2 (0x1u << 10) /**< \brief (PMC_SCDR) Programmable Clock 2 Output Disable */ +/* -------- PMC_SCSR : (PMC Offset: 0x0008) System Clock Status Register -------- */ +#define PMC_SCSR_UDP (0x1u << 7) /**< \brief (PMC_SCSR) USB Device Port Clock Status */ +#define PMC_SCSR_PCK0 (0x1u << 8) /**< \brief (PMC_SCSR) Programmable Clock 0 Output Status */ +#define PMC_SCSR_PCK1 (0x1u << 9) /**< \brief (PMC_SCSR) Programmable Clock 1 Output Status */ +#define PMC_SCSR_PCK2 (0x1u << 10) /**< \brief (PMC_SCSR) Programmable Clock 2 Output Status */ +/* -------- PMC_PCER0 : (PMC Offset: 0x0010) Peripheral Clock Enable Register 0 -------- */ +#define PMC_PCER0_PID7 (0x1u << 7) /**< \brief (PMC_PCER0) Peripheral Clock 7 Enable */ +#define PMC_PCER0_PID8 (0x1u << 8) /**< \brief (PMC_PCER0) Peripheral Clock 8 Enable */ +#define PMC_PCER0_PID9 (0x1u << 9) /**< \brief (PMC_PCER0) Peripheral Clock 9 Enable */ +#define PMC_PCER0_PID10 (0x1u << 10) /**< \brief (PMC_PCER0) Peripheral Clock 10 Enable */ +#define PMC_PCER0_PID11 (0x1u << 11) /**< \brief (PMC_PCER0) Peripheral Clock 11 Enable */ +#define PMC_PCER0_PID12 (0x1u << 12) /**< \brief (PMC_PCER0) Peripheral Clock 12 Enable */ +#define PMC_PCER0_PID13 (0x1u << 13) /**< \brief (PMC_PCER0) Peripheral Clock 13 Enable */ +#define PMC_PCER0_PID14 (0x1u << 14) /**< \brief (PMC_PCER0) Peripheral Clock 14 Enable */ +#define PMC_PCER0_PID15 (0x1u << 15) /**< \brief (PMC_PCER0) Peripheral Clock 15 Enable */ +#define PMC_PCER0_PID16 (0x1u << 16) /**< \brief (PMC_PCER0) Peripheral Clock 16 Enable */ +#define PMC_PCER0_PID17 (0x1u << 17) /**< \brief (PMC_PCER0) Peripheral Clock 17 Enable */ +#define PMC_PCER0_PID18 (0x1u << 18) /**< \brief (PMC_PCER0) Peripheral Clock 18 Enable */ +#define PMC_PCER0_PID19 (0x1u << 19) /**< \brief (PMC_PCER0) Peripheral Clock 19 Enable */ +#define PMC_PCER0_PID20 (0x1u << 20) /**< \brief (PMC_PCER0) Peripheral Clock 20 Enable */ +#define PMC_PCER0_PID21 (0x1u << 21) /**< \brief (PMC_PCER0) Peripheral Clock 21 Enable */ +#define PMC_PCER0_PID22 (0x1u << 22) /**< \brief (PMC_PCER0) Peripheral Clock 22 Enable */ +#define PMC_PCER0_PID23 (0x1u << 23) /**< \brief (PMC_PCER0) Peripheral Clock 23 Enable */ +#define PMC_PCER0_PID24 (0x1u << 24) /**< \brief (PMC_PCER0) Peripheral Clock 24 Enable */ +#define PMC_PCER0_PID25 (0x1u << 25) /**< \brief (PMC_PCER0) Peripheral Clock 25 Enable */ +#define PMC_PCER0_PID26 (0x1u << 26) /**< \brief (PMC_PCER0) Peripheral Clock 26 Enable */ +#define PMC_PCER0_PID27 (0x1u << 27) /**< \brief (PMC_PCER0) Peripheral Clock 27 Enable */ +#define PMC_PCER0_PID28 (0x1u << 28) /**< \brief (PMC_PCER0) Peripheral Clock 28 Enable */ +#define PMC_PCER0_PID29 (0x1u << 29) /**< \brief (PMC_PCER0) Peripheral Clock 29 Enable */ +#define PMC_PCER0_PID30 (0x1u << 30) /**< \brief (PMC_PCER0) Peripheral Clock 30 Enable */ +#define PMC_PCER0_PID31 (0x1u << 31) /**< \brief (PMC_PCER0) Peripheral Clock 31 Enable */ +/* -------- PMC_PCDR0 : (PMC Offset: 0x0014) Peripheral Clock Disable Register 0 -------- */ +#define PMC_PCDR0_PID7 (0x1u << 7) /**< \brief (PMC_PCDR0) Peripheral Clock 7 Disable */ +#define PMC_PCDR0_PID8 (0x1u << 8) /**< \brief (PMC_PCDR0) Peripheral Clock 8 Disable */ +#define PMC_PCDR0_PID9 (0x1u << 9) /**< \brief (PMC_PCDR0) Peripheral Clock 9 Disable */ +#define PMC_PCDR0_PID10 (0x1u << 10) /**< \brief (PMC_PCDR0) Peripheral Clock 10 Disable */ +#define PMC_PCDR0_PID11 (0x1u << 11) /**< \brief (PMC_PCDR0) Peripheral Clock 11 Disable */ +#define PMC_PCDR0_PID12 (0x1u << 12) /**< \brief (PMC_PCDR0) Peripheral Clock 12 Disable */ +#define PMC_PCDR0_PID13 (0x1u << 13) /**< \brief (PMC_PCDR0) Peripheral Clock 13 Disable */ +#define PMC_PCDR0_PID14 (0x1u << 14) /**< \brief (PMC_PCDR0) Peripheral Clock 14 Disable */ +#define PMC_PCDR0_PID15 (0x1u << 15) /**< \brief (PMC_PCDR0) Peripheral Clock 15 Disable */ +#define PMC_PCDR0_PID16 (0x1u << 16) /**< \brief (PMC_PCDR0) Peripheral Clock 16 Disable */ +#define PMC_PCDR0_PID17 (0x1u << 17) /**< \brief (PMC_PCDR0) Peripheral Clock 17 Disable */ +#define PMC_PCDR0_PID18 (0x1u << 18) /**< \brief (PMC_PCDR0) Peripheral Clock 18 Disable */ +#define PMC_PCDR0_PID19 (0x1u << 19) /**< \brief (PMC_PCDR0) Peripheral Clock 19 Disable */ +#define PMC_PCDR0_PID20 (0x1u << 20) /**< \brief (PMC_PCDR0) Peripheral Clock 20 Disable */ +#define PMC_PCDR0_PID21 (0x1u << 21) /**< \brief (PMC_PCDR0) Peripheral Clock 21 Disable */ +#define PMC_PCDR0_PID22 (0x1u << 22) /**< \brief (PMC_PCDR0) Peripheral Clock 22 Disable */ +#define PMC_PCDR0_PID23 (0x1u << 23) /**< \brief (PMC_PCDR0) Peripheral Clock 23 Disable */ +#define PMC_PCDR0_PID24 (0x1u << 24) /**< \brief (PMC_PCDR0) Peripheral Clock 24 Disable */ +#define PMC_PCDR0_PID25 (0x1u << 25) /**< \brief (PMC_PCDR0) Peripheral Clock 25 Disable */ +#define PMC_PCDR0_PID26 (0x1u << 26) /**< \brief (PMC_PCDR0) Peripheral Clock 26 Disable */ +#define PMC_PCDR0_PID27 (0x1u << 27) /**< \brief (PMC_PCDR0) Peripheral Clock 27 Disable */ +#define PMC_PCDR0_PID28 (0x1u << 28) /**< \brief (PMC_PCDR0) Peripheral Clock 28 Disable */ +#define PMC_PCDR0_PID29 (0x1u << 29) /**< \brief (PMC_PCDR0) Peripheral Clock 29 Disable */ +#define PMC_PCDR0_PID30 (0x1u << 30) /**< \brief (PMC_PCDR0) Peripheral Clock 30 Disable */ +#define PMC_PCDR0_PID31 (0x1u << 31) /**< \brief (PMC_PCDR0) Peripheral Clock 31 Disable */ +/* -------- PMC_PCSR0 : (PMC Offset: 0x0018) Peripheral Clock Status Register 0 -------- */ +#define PMC_PCSR0_PID7 (0x1u << 7) /**< \brief (PMC_PCSR0) Peripheral Clock 7 Status */ +#define PMC_PCSR0_PID8 (0x1u << 8) /**< \brief (PMC_PCSR0) Peripheral Clock 8 Status */ +#define PMC_PCSR0_PID9 (0x1u << 9) /**< \brief (PMC_PCSR0) Peripheral Clock 9 Status */ +#define PMC_PCSR0_PID10 (0x1u << 10) /**< \brief (PMC_PCSR0) Peripheral Clock 10 Status */ +#define PMC_PCSR0_PID11 (0x1u << 11) /**< \brief (PMC_PCSR0) Peripheral Clock 11 Status */ +#define PMC_PCSR0_PID12 (0x1u << 12) /**< \brief (PMC_PCSR0) Peripheral Clock 12 Status */ +#define PMC_PCSR0_PID13 (0x1u << 13) /**< \brief (PMC_PCSR0) Peripheral Clock 13 Status */ +#define PMC_PCSR0_PID14 (0x1u << 14) /**< \brief (PMC_PCSR0) Peripheral Clock 14 Status */ +#define PMC_PCSR0_PID15 (0x1u << 15) /**< \brief (PMC_PCSR0) Peripheral Clock 15 Status */ +#define PMC_PCSR0_PID16 (0x1u << 16) /**< \brief (PMC_PCSR0) Peripheral Clock 16 Status */ +#define PMC_PCSR0_PID17 (0x1u << 17) /**< \brief (PMC_PCSR0) Peripheral Clock 17 Status */ +#define PMC_PCSR0_PID18 (0x1u << 18) /**< \brief (PMC_PCSR0) Peripheral Clock 18 Status */ +#define PMC_PCSR0_PID19 (0x1u << 19) /**< \brief (PMC_PCSR0) Peripheral Clock 19 Status */ +#define PMC_PCSR0_PID20 (0x1u << 20) /**< \brief (PMC_PCSR0) Peripheral Clock 20 Status */ +#define PMC_PCSR0_PID21 (0x1u << 21) /**< \brief (PMC_PCSR0) Peripheral Clock 21 Status */ +#define PMC_PCSR0_PID22 (0x1u << 22) /**< \brief (PMC_PCSR0) Peripheral Clock 22 Status */ +#define PMC_PCSR0_PID23 (0x1u << 23) /**< \brief (PMC_PCSR0) Peripheral Clock 23 Status */ +#define PMC_PCSR0_PID24 (0x1u << 24) /**< \brief (PMC_PCSR0) Peripheral Clock 24 Status */ +#define PMC_PCSR0_PID25 (0x1u << 25) /**< \brief (PMC_PCSR0) Peripheral Clock 25 Status */ +#define PMC_PCSR0_PID26 (0x1u << 26) /**< \brief (PMC_PCSR0) Peripheral Clock 26 Status */ +#define PMC_PCSR0_PID27 (0x1u << 27) /**< \brief (PMC_PCSR0) Peripheral Clock 27 Status */ +#define PMC_PCSR0_PID28 (0x1u << 28) /**< \brief (PMC_PCSR0) Peripheral Clock 28 Status */ +#define PMC_PCSR0_PID29 (0x1u << 29) /**< \brief (PMC_PCSR0) Peripheral Clock 29 Status */ +#define PMC_PCSR0_PID30 (0x1u << 30) /**< \brief (PMC_PCSR0) Peripheral Clock 30 Status */ +#define PMC_PCSR0_PID31 (0x1u << 31) /**< \brief (PMC_PCSR0) Peripheral Clock 31 Status */ +/* -------- CKGR_MOR : (PMC Offset: 0x0020) Main Oscillator Register -------- */ +#define CKGR_MOR_MOSCXTEN (0x1u << 0) /**< \brief (CKGR_MOR) Main Crystal Oscillator Enable */ +#define CKGR_MOR_MOSCXTBY (0x1u << 1) /**< \brief (CKGR_MOR) Main Crystal Oscillator Bypass */ +#define CKGR_MOR_WAITMODE (0x1u << 2) /**< \brief (CKGR_MOR) Wait Mode Command */ +#define CKGR_MOR_MOSCRCEN (0x1u << 3) /**< \brief (CKGR_MOR) Main On-Chip RC Oscillator Enable */ +#define CKGR_MOR_MOSCRCF_Pos 4 +#define CKGR_MOR_MOSCRCF_Msk (0x7u << CKGR_MOR_MOSCRCF_Pos) /**< \brief (CKGR_MOR) Main On-Chip RC Oscillator Frequency Selection */ +#define CKGR_MOR_MOSCRCF_4_MHz (0x0u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 4 MHz (default) */ +#define CKGR_MOR_MOSCRCF_8_MHz (0x1u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 8 MHz */ +#define CKGR_MOR_MOSCRCF_12_MHz (0x2u << 4) /**< \brief (CKGR_MOR) The Fast RC Oscillator Frequency is at 12 MHz */ +#define CKGR_MOR_MOSCXTST_Pos 8 +#define CKGR_MOR_MOSCXTST_Msk (0xffu << CKGR_MOR_MOSCXTST_Pos) /**< \brief (CKGR_MOR) Main Crystal Oscillator Start-up Time */ +#define CKGR_MOR_MOSCXTST(value) ((CKGR_MOR_MOSCXTST_Msk & ((value) << CKGR_MOR_MOSCXTST_Pos))) +#define CKGR_MOR_KEY_Pos 16 +#define CKGR_MOR_KEY_Msk (0xffu << CKGR_MOR_KEY_Pos) /**< \brief (CKGR_MOR) Write Access Password */ +#define CKGR_MOR_KEY_PASSWD (0x37u << 16) /**< \brief (CKGR_MOR) Writing any other value in this field aborts the write operation.Always reads as 0. */ +#define CKGR_MOR_MOSCSEL (0x1u << 24) /**< \brief (CKGR_MOR) Main Oscillator Selection */ +#define CKGR_MOR_CFDEN (0x1u << 25) /**< \brief (CKGR_MOR) Clock Failure Detector Enable */ +/* -------- CKGR_MCFR : (PMC Offset: 0x0024) Main Clock Frequency Register -------- */ +#define CKGR_MCFR_MAINF_Pos 0 +#define CKGR_MCFR_MAINF_Msk (0xffffu << CKGR_MCFR_MAINF_Pos) /**< \brief (CKGR_MCFR) Main Clock Frequency */ +#define CKGR_MCFR_MAINF(value) ((CKGR_MCFR_MAINF_Msk & ((value) << CKGR_MCFR_MAINF_Pos))) +#define CKGR_MCFR_MAINFRDY (0x1u << 16) /**< \brief (CKGR_MCFR) Main Clock Ready */ +#define CKGR_MCFR_RCMEAS (0x1u << 20) /**< \brief (CKGR_MCFR) RC Oscillator Frequency Measure (write-only) */ +/* -------- CKGR_PLLAR : (PMC Offset: 0x0028) PLLA Register -------- */ +#define CKGR_PLLAR_DIVA_Pos 0 +#define CKGR_PLLAR_DIVA_Msk (0xffu << CKGR_PLLAR_DIVA_Pos) /**< \brief (CKGR_PLLAR) PLLA Front_End Divider */ +#define CKGR_PLLAR_DIVA(value) ((CKGR_PLLAR_DIVA_Msk & ((value) << CKGR_PLLAR_DIVA_Pos))) +#define CKGR_PLLAR_PLLACOUNT_Pos 8 +#define CKGR_PLLAR_PLLACOUNT_Msk (0x3fu << CKGR_PLLAR_PLLACOUNT_Pos) /**< \brief (CKGR_PLLAR) PLLA Counter */ +#define CKGR_PLLAR_PLLACOUNT(value) ((CKGR_PLLAR_PLLACOUNT_Msk & ((value) << CKGR_PLLAR_PLLACOUNT_Pos))) +#define CKGR_PLLAR_MULA_Pos 16 +#define CKGR_PLLAR_MULA_Msk (0x7ffu << CKGR_PLLAR_MULA_Pos) /**< \brief (CKGR_PLLAR) PLLA Multiplier */ +#define CKGR_PLLAR_MULA(value) ((CKGR_PLLAR_MULA_Msk & ((value) << CKGR_PLLAR_MULA_Pos))) +#define CKGR_PLLAR_ONE (0x1u << 29) /**< \brief (CKGR_PLLAR) Must Be Set to 1 */ +/* -------- PMC_MCKR : (PMC Offset: 0x0030) Master Clock Register -------- */ +#define PMC_MCKR_CSS_Pos 0 +#define PMC_MCKR_CSS_Msk (0x3u << PMC_MCKR_CSS_Pos) /**< \brief (PMC_MCKR) Master Clock Source Selection */ +#define PMC_MCKR_CSS_SLOW_CLK (0x0u << 0) /**< \brief (PMC_MCKR) Slow Clock is selected */ +#define PMC_MCKR_CSS_MAIN_CLK (0x1u << 0) /**< \brief (PMC_MCKR) Main Clock is selected */ +#define PMC_MCKR_CSS_PLLA_CLK (0x2u << 0) /**< \brief (PMC_MCKR) PLLA Clock is selected */ +#define PMC_MCKR_PRES_Pos 4 +#define PMC_MCKR_PRES_Msk (0x7u << PMC_MCKR_PRES_Pos) /**< \brief (PMC_MCKR) Processor Clock Prescaler */ +#define PMC_MCKR_PRES_CLK_1 (0x0u << 4) /**< \brief (PMC_MCKR) Selected clock */ +#define PMC_MCKR_PRES_CLK_2 (0x1u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 2 */ +#define PMC_MCKR_PRES_CLK_4 (0x2u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 4 */ +#define PMC_MCKR_PRES_CLK_8 (0x3u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 8 */ +#define PMC_MCKR_PRES_CLK_16 (0x4u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 16 */ +#define PMC_MCKR_PRES_CLK_32 (0x5u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 32 */ +#define PMC_MCKR_PRES_CLK_64 (0x6u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 64 */ +#define PMC_MCKR_PRES_CLK_3 (0x7u << 4) /**< \brief (PMC_MCKR) Selected clock divided by 3 */ +#define PMC_MCKR_PLLADIV2 (0x1u << 12) /**< \brief (PMC_MCKR) PLLA Divisor by 2 */ +/* -------- PMC_USB : (PMC Offset: 0x0038) USB Clock Register -------- */ +#define PMC_USB_USBDIV_Pos 8 +#define PMC_USB_USBDIV_Msk (0xfu << PMC_USB_USBDIV_Pos) /**< \brief (PMC_USB) Divider for USB Clock */ +#define PMC_USB_USBDIV(value) ((PMC_USB_USBDIV_Msk & ((value) << PMC_USB_USBDIV_Pos))) +/* -------- PMC_PCK[3] : (PMC Offset: 0x0040) Programmable Clock 0 Register -------- */ +#define PMC_PCK_CSS_Pos 0 +#define PMC_PCK_CSS_Msk (0x7u << PMC_PCK_CSS_Pos) /**< \brief (PMC_PCK[3]) Master Clock Source Selection */ +#define PMC_PCK_CSS_SLOW_CLK (0x0u << 0) /**< \brief (PMC_PCK[3]) Slow Clock is selected */ +#define PMC_PCK_CSS_MAIN_CLK (0x1u << 0) /**< \brief (PMC_PCK[3]) Main Clock is selected */ +#define PMC_PCK_CSS_PLLA_CLK (0x2u << 0) /**< \brief (PMC_PCK[3]) PLLA Clock is selected */ +#define PMC_PCK_CSS_MCK (0x4u << 0) /**< \brief (PMC_PCK[3]) Master Clock is selected */ +#define PMC_PCK_PRES_Pos 4 +#define PMC_PCK_PRES_Msk (0x7u << PMC_PCK_PRES_Pos) /**< \brief (PMC_PCK[3]) Programmable Clock Prescaler */ +#define PMC_PCK_PRES_CLK_1 (0x0u << 4) /**< \brief (PMC_PCK[3]) Selected clock */ +#define PMC_PCK_PRES_CLK_2 (0x1u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 2 */ +#define PMC_PCK_PRES_CLK_4 (0x2u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 4 */ +#define PMC_PCK_PRES_CLK_8 (0x3u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 8 */ +#define PMC_PCK_PRES_CLK_16 (0x4u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 16 */ +#define PMC_PCK_PRES_CLK_32 (0x5u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 32 */ +#define PMC_PCK_PRES_CLK_64 (0x6u << 4) /**< \brief (PMC_PCK[3]) Selected clock divided by 64 */ +/* -------- PMC_IER : (PMC Offset: 0x0060) Interrupt Enable Register -------- */ +#define PMC_IER_MOSCXTS (0x1u << 0) /**< \brief (PMC_IER) Main Crystal Oscillator Status Interrupt Enable */ +#define PMC_IER_LOCKA (0x1u << 1) /**< \brief (PMC_IER) PLLA Lock Interrupt Enable */ +#define PMC_IER_MCKRDY (0x1u << 3) /**< \brief (PMC_IER) Master Clock Ready Interrupt Enable */ +#define PMC_IER_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IER) Programmable Clock Ready 0 Interrupt Enable */ +#define PMC_IER_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IER) Programmable Clock Ready 1 Interrupt Enable */ +#define PMC_IER_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IER) Programmable Clock Ready 2 Interrupt Enable */ +#define PMC_IER_MOSCSELS (0x1u << 16) /**< \brief (PMC_IER) Main Oscillator Selection Status Interrupt Enable */ +#define PMC_IER_MOSCRCS (0x1u << 17) /**< \brief (PMC_IER) Main On-Chip RC Status Interrupt Enable */ +#define PMC_IER_CFDEV (0x1u << 18) /**< \brief (PMC_IER) Clock Failure Detector Event Interrupt Enable */ +/* -------- PMC_IDR : (PMC Offset: 0x0064) Interrupt Disable Register -------- */ +#define PMC_IDR_MOSCXTS (0x1u << 0) /**< \brief (PMC_IDR) Main Crystal Oscillator Status Interrupt Disable */ +#define PMC_IDR_LOCKA (0x1u << 1) /**< \brief (PMC_IDR) PLLA Lock Interrupt Disable */ +#define PMC_IDR_MCKRDY (0x1u << 3) /**< \brief (PMC_IDR) Master Clock Ready Interrupt Disable */ +#define PMC_IDR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IDR) Programmable Clock Ready 0 Interrupt Disable */ +#define PMC_IDR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IDR) Programmable Clock Ready 1 Interrupt Disable */ +#define PMC_IDR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IDR) Programmable Clock Ready 2 Interrupt Disable */ +#define PMC_IDR_MOSCSELS (0x1u << 16) /**< \brief (PMC_IDR) Main Oscillator Selection Status Interrupt Disable */ +#define PMC_IDR_MOSCRCS (0x1u << 17) /**< \brief (PMC_IDR) Main On-Chip RC Status Interrupt Disable */ +#define PMC_IDR_CFDEV (0x1u << 18) /**< \brief (PMC_IDR) Clock Failure Detector Event Interrupt Disable */ +/* -------- PMC_SR : (PMC Offset: 0x0068) Status Register -------- */ +#define PMC_SR_MOSCXTS (0x1u << 0) /**< \brief (PMC_SR) Main XTAL Oscillator Status */ +#define PMC_SR_LOCKA (0x1u << 1) /**< \brief (PMC_SR) PLLA Lock Status */ +#define PMC_SR_MCKRDY (0x1u << 3) /**< \brief (PMC_SR) Master Clock Status */ +#define PMC_SR_OSCSELS (0x1u << 7) /**< \brief (PMC_SR) Slow Clock Oscillator Selection */ +#define PMC_SR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_SR) Programmable Clock Ready Status */ +#define PMC_SR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_SR) Programmable Clock Ready Status */ +#define PMC_SR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_SR) Programmable Clock Ready Status */ +#define PMC_SR_MOSCSELS (0x1u << 16) /**< \brief (PMC_SR) Main Oscillator Selection Status */ +#define PMC_SR_MOSCRCS (0x1u << 17) /**< \brief (PMC_SR) Main On-Chip RC Oscillator Status */ +#define PMC_SR_CFDEV (0x1u << 18) /**< \brief (PMC_SR) Clock Failure Detector Event */ +#define PMC_SR_CFDS (0x1u << 19) /**< \brief (PMC_SR) Clock Failure Detector Status */ +#define PMC_SR_FOS (0x1u << 20) /**< \brief (PMC_SR) Clock Failure Detector Fault Output Status */ +/* -------- PMC_IMR : (PMC Offset: 0x006C) Interrupt Mask Register -------- */ +#define PMC_IMR_MOSCXTS (0x1u << 0) /**< \brief (PMC_IMR) Main Crystal Oscillator Status Interrupt Mask */ +#define PMC_IMR_LOCKA (0x1u << 1) /**< \brief (PMC_IMR) PLLA Lock Interrupt Mask */ +#define PMC_IMR_MCKRDY (0x1u << 3) /**< \brief (PMC_IMR) Master Clock Ready Interrupt Mask */ +#define PMC_IMR_PCKRDY0 (0x1u << 8) /**< \brief (PMC_IMR) Programmable Clock Ready 0 Interrupt Mask */ +#define PMC_IMR_PCKRDY1 (0x1u << 9) /**< \brief (PMC_IMR) Programmable Clock Ready 1 Interrupt Mask */ +#define PMC_IMR_PCKRDY2 (0x1u << 10) /**< \brief (PMC_IMR) Programmable Clock Ready 2 Interrupt Mask */ +#define PMC_IMR_MOSCSELS (0x1u << 16) /**< \brief (PMC_IMR) Main Oscillator Selection Status Interrupt Mask */ +#define PMC_IMR_MOSCRCS (0x1u << 17) /**< \brief (PMC_IMR) Main On-Chip RC Status Interrupt Mask */ +#define PMC_IMR_CFDEV (0x1u << 18) /**< \brief (PMC_IMR) Clock Failure Detector Event Interrupt Mask */ +/* -------- PMC_FSMR : (PMC Offset: 0x0070) Fast Startup Mode Register -------- */ +#define PMC_FSMR_FSTT0 (0x1u << 0) /**< \brief (PMC_FSMR) Fast Startup Input Enable 0 */ +#define PMC_FSMR_FSTT1 (0x1u << 1) /**< \brief (PMC_FSMR) Fast Startup Input Enable 1 */ +#define PMC_FSMR_FSTT2 (0x1u << 2) /**< \brief (PMC_FSMR) Fast Startup Input Enable 2 */ +#define PMC_FSMR_FSTT3 (0x1u << 3) /**< \brief (PMC_FSMR) Fast Startup Input Enable 3 */ +#define PMC_FSMR_FSTT4 (0x1u << 4) /**< \brief (PMC_FSMR) Fast Startup Input Enable 4 */ +#define PMC_FSMR_FSTT5 (0x1u << 5) /**< \brief (PMC_FSMR) Fast Startup Input Enable 5 */ +#define PMC_FSMR_FSTT6 (0x1u << 6) /**< \brief (PMC_FSMR) Fast Startup Input Enable 6 */ +#define PMC_FSMR_FSTT7 (0x1u << 7) /**< \brief (PMC_FSMR) Fast Startup Input Enable 7 */ +#define PMC_FSMR_FSTT8 (0x1u << 8) /**< \brief (PMC_FSMR) Fast Startup Input Enable 8 */ +#define PMC_FSMR_FSTT9 (0x1u << 9) /**< \brief (PMC_FSMR) Fast Startup Input Enable 9 */ +#define PMC_FSMR_FSTT10 (0x1u << 10) /**< \brief (PMC_FSMR) Fast Startup Input Enable 10 */ +#define PMC_FSMR_FSTT11 (0x1u << 11) /**< \brief (PMC_FSMR) Fast Startup Input Enable 11 */ +#define PMC_FSMR_FSTT12 (0x1u << 12) /**< \brief (PMC_FSMR) Fast Startup Input Enable 12 */ +#define PMC_FSMR_FSTT13 (0x1u << 13) /**< \brief (PMC_FSMR) Fast Startup Input Enable 13 */ +#define PMC_FSMR_FSTT14 (0x1u << 14) /**< \brief (PMC_FSMR) Fast Startup Input Enable 14 */ +#define PMC_FSMR_FSTT15 (0x1u << 15) /**< \brief (PMC_FSMR) Fast Startup Input Enable 15 */ +#define PMC_FSMR_RTTAL (0x1u << 16) /**< \brief (PMC_FSMR) RTT Alarm Enable */ +#define PMC_FSMR_RTCAL (0x1u << 17) /**< \brief (PMC_FSMR) RTC Alarm Enable */ +#define PMC_FSMR_USBAL (0x1u << 18) /**< \brief (PMC_FSMR) USB Alarm Enable */ +#define PMC_FSMR_LPM (0x1u << 20) /**< \brief (PMC_FSMR) Low-power Mode */ +#define PMC_FSMR_FLPM_Pos 21 +#define PMC_FSMR_FLPM_Msk (0x3u << PMC_FSMR_FLPM_Pos) /**< \brief (PMC_FSMR) Flash Low-power Mode */ +#define PMC_FSMR_FLPM_FLASH_STANDBY (0x0u << 21) /**< \brief (PMC_FSMR) Flash is in Standby Mode when system enters Wait Mode */ +#define PMC_FSMR_FLPM_FLASH_DEEP_POWERDOWN (0x1u << 21) /**< \brief (PMC_FSMR) Flash is in deep-power-down mode when system enters Wait Mode */ +#define PMC_FSMR_FLPM_FLASH_IDLE (0x2u << 21) /**< \brief (PMC_FSMR) idle mode */ +/* -------- PMC_FSPR : (PMC Offset: 0x0074) Fast Startup Polarity Register -------- */ +#define PMC_FSPR_FSTP0 (0x1u << 0) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP1 (0x1u << 1) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP2 (0x1u << 2) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP3 (0x1u << 3) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP4 (0x1u << 4) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP5 (0x1u << 5) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP6 (0x1u << 6) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP7 (0x1u << 7) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP8 (0x1u << 8) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP9 (0x1u << 9) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP10 (0x1u << 10) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP11 (0x1u << 11) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP12 (0x1u << 12) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP13 (0x1u << 13) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP14 (0x1u << 14) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +#define PMC_FSPR_FSTP15 (0x1u << 15) /**< \brief (PMC_FSPR) Fast Startup Input Polarityx */ +/* -------- PMC_FOCR : (PMC Offset: 0x0078) Fault Output Clear Register -------- */ +#define PMC_FOCR_FOCLR (0x1u << 0) /**< \brief (PMC_FOCR) Fault Output Clear */ +/* -------- PMC_WPMR : (PMC Offset: 0x00E4) Write Protection Mode Register -------- */ +#define PMC_WPMR_WPEN (0x1u << 0) /**< \brief (PMC_WPMR) Write Protection Enable */ +#define PMC_WPMR_WPKEY_Pos 8 +#define PMC_WPMR_WPKEY_Msk (0xffffffu << PMC_WPMR_WPKEY_Pos) /**< \brief (PMC_WPMR) Write Protection Key */ +#define PMC_WPMR_WPKEY_PASSWD (0x504D43u << 8) /**< \brief (PMC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit. Always reads as 0. */ +/* -------- PMC_WPSR : (PMC Offset: 0x00E8) Write Protection Status Register -------- */ +#define PMC_WPSR_WPVS (0x1u << 0) /**< \brief (PMC_WPSR) Write Protection Violation Status */ +#define PMC_WPSR_WPVSRC_Pos 8 +#define PMC_WPSR_WPVSRC_Msk (0xffffu << PMC_WPSR_WPVSRC_Pos) /**< \brief (PMC_WPSR) Write Protection Violation Source */ +/* -------- PMC_PCER1 : (PMC Offset: 0x0100) Peripheral Clock Enable Register 1 -------- */ +#define PMC_PCER1_PID32 (0x1u << 0) /**< \brief (PMC_PCER1) Peripheral Clock 32 Enable */ +#define PMC_PCER1_PID33 (0x1u << 1) /**< \brief (PMC_PCER1) Peripheral Clock 33 Enable */ +#define PMC_PCER1_PID34 (0x1u << 2) /**< \brief (PMC_PCER1) Peripheral Clock 34 Enable */ +#define PMC_PCER1_PID35 (0x1u << 3) /**< \brief (PMC_PCER1) Peripheral Clock 35 Enable */ +#define PMC_PCER1_PID36 (0x1u << 4) /**< \brief (PMC_PCER1) Peripheral Clock 36 Enable */ +#define PMC_PCER1_PID37 (0x1u << 5) /**< \brief (PMC_PCER1) Peripheral Clock 37 Enable */ +#define PMC_PCER1_PID38 (0x1u << 6) /**< \brief (PMC_PCER1) Peripheral Clock 38 Enable */ +#define PMC_PCER1_PID39 (0x1u << 7) /**< \brief (PMC_PCER1) Peripheral Clock 39 Enable */ +#define PMC_PCER1_PID40 (0x1u << 8) /**< \brief (PMC_PCER1) Peripheral Clock 40 Enable */ +#define PMC_PCER1_PID41 (0x1u << 9) /**< \brief (PMC_PCER1) Peripheral Clock 41 Enable */ +#define PMC_PCER1_PID42 (0x1u << 10) /**< \brief (PMC_PCER1) Peripheral Clock 42 Enable */ +#define PMC_PCER1_PID43 (0x1u << 11) /**< \brief (PMC_PCER1) Peripheral Clock 43 Enable */ +#define PMC_PCER1_PID44 (0x1u << 12) /**< \brief (PMC_PCER1) Peripheral Clock 44 Enable */ +#define PMC_PCER1_PID45 (0x1u << 13) /**< \brief (PMC_PCER1) Peripheral Clock 45 Enable */ +#define PMC_PCER1_PID46 (0x1u << 14) /**< \brief (PMC_PCER1) Peripheral Clock 46 Enable */ +#define PMC_PCER1_PID47 (0x1u << 15) /**< \brief (PMC_PCER1) Peripheral Clock 47 Enable */ +/* -------- PMC_PCDR1 : (PMC Offset: 0x0104) Peripheral Clock Disable Register 1 -------- */ +#define PMC_PCDR1_PID32 (0x1u << 0) /**< \brief (PMC_PCDR1) Peripheral Clock 32 Disable */ +#define PMC_PCDR1_PID33 (0x1u << 1) /**< \brief (PMC_PCDR1) Peripheral Clock 33 Disable */ +#define PMC_PCDR1_PID34 (0x1u << 2) /**< \brief (PMC_PCDR1) Peripheral Clock 34 Disable */ +#define PMC_PCDR1_PID35 (0x1u << 3) /**< \brief (PMC_PCDR1) Peripheral Clock 35 Disable */ +#define PMC_PCDR1_PID36 (0x1u << 4) /**< \brief (PMC_PCDR1) Peripheral Clock 36 Disable */ +#define PMC_PCDR1_PID37 (0x1u << 5) /**< \brief (PMC_PCDR1) Peripheral Clock 37 Disable */ +#define PMC_PCDR1_PID38 (0x1u << 6) /**< \brief (PMC_PCDR1) Peripheral Clock 38 Disable */ +#define PMC_PCDR1_PID39 (0x1u << 7) /**< \brief (PMC_PCDR1) Peripheral Clock 39 Disable */ +#define PMC_PCDR1_PID40 (0x1u << 8) /**< \brief (PMC_PCDR1) Peripheral Clock 40 Disable */ +#define PMC_PCDR1_PID41 (0x1u << 9) /**< \brief (PMC_PCDR1) Peripheral Clock 41 Disable */ +#define PMC_PCDR1_PID42 (0x1u << 10) /**< \brief (PMC_PCDR1) Peripheral Clock 42 Disable */ +#define PMC_PCDR1_PID43 (0x1u << 11) /**< \brief (PMC_PCDR1) Peripheral Clock 43 Disable */ +#define PMC_PCDR1_PID44 (0x1u << 12) /**< \brief (PMC_PCDR1) Peripheral Clock 44 Disable */ +#define PMC_PCDR1_PID45 (0x1u << 13) /**< \brief (PMC_PCDR1) Peripheral Clock 45 Disable */ +#define PMC_PCDR1_PID46 (0x1u << 14) /**< \brief (PMC_PCDR1) Peripheral Clock 46 Disable */ +#define PMC_PCDR1_PID47 (0x1u << 15) /**< \brief (PMC_PCDR1) Peripheral Clock 47 Disable */ +/* -------- PMC_PCSR1 : (PMC Offset: 0x0108) Peripheral Clock Status Register 1 -------- */ +#define PMC_PCSR1_PID32 (0x1u << 0) /**< \brief (PMC_PCSR1) Peripheral Clock 32 Status */ +#define PMC_PCSR1_PID33 (0x1u << 1) /**< \brief (PMC_PCSR1) Peripheral Clock 33 Status */ +#define PMC_PCSR1_PID34 (0x1u << 2) /**< \brief (PMC_PCSR1) Peripheral Clock 34 Status */ +#define PMC_PCSR1_PID35 (0x1u << 3) /**< \brief (PMC_PCSR1) Peripheral Clock 35 Status */ +#define PMC_PCSR1_PID36 (0x1u << 4) /**< \brief (PMC_PCSR1) Peripheral Clock 36 Status */ +#define PMC_PCSR1_PID37 (0x1u << 5) /**< \brief (PMC_PCSR1) Peripheral Clock 37 Status */ +#define PMC_PCSR1_PID38 (0x1u << 6) /**< \brief (PMC_PCSR1) Peripheral Clock 38 Status */ +#define PMC_PCSR1_PID39 (0x1u << 7) /**< \brief (PMC_PCSR1) Peripheral Clock 39 Status */ +#define PMC_PCSR1_PID40 (0x1u << 8) /**< \brief (PMC_PCSR1) Peripheral Clock 40 Status */ +#define PMC_PCSR1_PID41 (0x1u << 9) /**< \brief (PMC_PCSR1) Peripheral Clock 41 Status */ +#define PMC_PCSR1_PID42 (0x1u << 10) /**< \brief (PMC_PCSR1) Peripheral Clock 42 Status */ +#define PMC_PCSR1_PID43 (0x1u << 11) /**< \brief (PMC_PCSR1) Peripheral Clock 43 Status */ +#define PMC_PCSR1_PID44 (0x1u << 12) /**< \brief (PMC_PCSR1) Peripheral Clock 44 Status */ +#define PMC_PCSR1_PID45 (0x1u << 13) /**< \brief (PMC_PCSR1) Peripheral Clock 45 Status */ +#define PMC_PCSR1_PID46 (0x1u << 14) /**< \brief (PMC_PCSR1) Peripheral Clock 46 Status */ +#define PMC_PCSR1_PID47 (0x1u << 15) /**< \brief (PMC_PCSR1) Peripheral Clock 47 Status */ +/* -------- PMC_OCR : (PMC Offset: 0x0110) Oscillator Calibration Register -------- */ +#define PMC_OCR_CAL4_Pos 0 +#define PMC_OCR_CAL4_Msk (0x7fu << PMC_OCR_CAL4_Pos) /**< \brief (PMC_OCR) RC Oscillator Calibration bits for 4 MHz */ +#define PMC_OCR_CAL4(value) ((PMC_OCR_CAL4_Msk & ((value) << PMC_OCR_CAL4_Pos))) +#define PMC_OCR_SEL4 (0x1u << 7) /**< \brief (PMC_OCR) Selection of RC Oscillator Calibration bits for 4 MHz */ +#define PMC_OCR_CAL8_Pos 8 +#define PMC_OCR_CAL8_Msk (0x7fu << PMC_OCR_CAL8_Pos) /**< \brief (PMC_OCR) RC Oscillator Calibration bits for 8 MHz */ +#define PMC_OCR_CAL8(value) ((PMC_OCR_CAL8_Msk & ((value) << PMC_OCR_CAL8_Pos))) +#define PMC_OCR_SEL8 (0x1u << 15) /**< \brief (PMC_OCR) Selection of RC Oscillator Calibration bits for 8 MHz */ +#define PMC_OCR_CAL12_Pos 16 +#define PMC_OCR_CAL12_Msk (0x7fu << PMC_OCR_CAL12_Pos) /**< \brief (PMC_OCR) RC Oscillator Calibration bits for 12 MHz */ +#define PMC_OCR_CAL12(value) ((PMC_OCR_CAL12_Msk & ((value) << PMC_OCR_CAL12_Pos))) +#define PMC_OCR_SEL12 (0x1u << 23) /**< \brief (PMC_OCR) Selection of RC Oscillator Calibration bits for 12 MHz */ +/* -------- PMC_PMMR : (PMC Offset: 0x130) PLL Maximum Multiplier Value Register -------- */ +#define PMC_PMMR_PLLA_MMAX_Pos 0 +#define PMC_PMMR_PLLA_MMAX_Msk (0x7ffu << PMC_PMMR_PLLA_MMAX_Pos) /**< \brief (PMC_PMMR) PLLA Maximum Allowed Multiplier Value */ +#define PMC_PMMR_PLLA_MMAX(value) ((PMC_PMMR_PLLA_MMAX_Msk & ((value) << PMC_PMMR_PLLA_MMAX_Pos))) + +/*@}*/ + + +#endif /* _SAM4E_PMC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pwm.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pwm.h new file mode 100644 index 0000000..f0e6a78 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/pwm.h @@ -0,0 +1,621 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PWM_COMPONENT_ +#define _SAM4E_PWM_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Pulse Width Modulation Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_PWM Pulse Width Modulation Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief PwmCh_num hardware registers */ +typedef struct { + __IO uint32_t PWM_CMR; /**< \brief (PwmCh_num Offset: 0x0) PWM Channel Mode Register */ + __IO uint32_t PWM_CDTY; /**< \brief (PwmCh_num Offset: 0x4) PWM Channel Duty Cycle Register */ + __O uint32_t PWM_CDTYUPD; /**< \brief (PwmCh_num Offset: 0x8) PWM Channel Duty Cycle Update Register */ + __IO uint32_t PWM_CPRD; /**< \brief (PwmCh_num Offset: 0xC) PWM Channel Period Register */ + __O uint32_t PWM_CPRDUPD; /**< \brief (PwmCh_num Offset: 0x10) PWM Channel Period Update Register */ + __I uint32_t PWM_CCNT; /**< \brief (PwmCh_num Offset: 0x14) PWM Channel Counter Register */ + __IO uint32_t PWM_DT; /**< \brief (PwmCh_num Offset: 0x18) PWM Channel Dead Time Register */ + __O uint32_t PWM_DTUPD; /**< \brief (PwmCh_num Offset: 0x1C) PWM Channel Dead Time Update Register */ +} PwmCh_num; +/** \brief PwmCh_num_0x400 hardware registers */ +typedef struct { + __IO uint32_t PWM_CMUPD; /**< \brief (PwmCh_num_0x400 Offset: 0x0) PWM Channel Mode Update Register */ + __IO uint32_t PWM_CAE; /**< \brief (PwmCh_num_0x400 Offset: 0x4) PWM Channel Additional Edge Register */ + __IO uint32_t PWM_CAEUPD; /**< \brief (PwmCh_num_0x400 Offset: 0x8) PWM Channel Additional Edge Update Register */ + __I uint32_t Reserved1[5]; +} PwmCh_num_0x400; +/** \brief PwmCmp hardware registers */ +typedef struct { + __IO uint32_t PWM_CMPV; /**< \brief (PwmCmp Offset: 0x0) PWM Comparison 0 Value Register */ + __IO uint32_t PWM_CMPVUPD; /**< \brief (PwmCmp Offset: 0x4) PWM Comparison 0 Value Update Register */ + __IO uint32_t PWM_CMPM; /**< \brief (PwmCmp Offset: 0x8) PWM Comparison 0 Mode Register */ + __IO uint32_t PWM_CMPMUPD; /**< \brief (PwmCmp Offset: 0xC) PWM Comparison 0 Mode Update Register */ +} PwmCmp; +/** \brief Pwm hardware registers */ +#define PWMCMP_NUMBER 8 +#define PWMCH_NUM_NUMBER 4 +#define PWMCH_NUM_0X400_NUMBER 4 +typedef struct { + __IO uint32_t PWM_CLK; /**< \brief (Pwm Offset: 0x00) PWM Clock Register */ + __O uint32_t PWM_ENA; /**< \brief (Pwm Offset: 0x04) PWM Enable Register */ + __O uint32_t PWM_DIS; /**< \brief (Pwm Offset: 0x08) PWM Disable Register */ + __I uint32_t PWM_SR; /**< \brief (Pwm Offset: 0x0C) PWM Status Register */ + __O uint32_t PWM_IER1; /**< \brief (Pwm Offset: 0x10) PWM Interrupt Enable Register 1 */ + __O uint32_t PWM_IDR1; /**< \brief (Pwm Offset: 0x14) PWM Interrupt Disable Register 1 */ + __I uint32_t PWM_IMR1; /**< \brief (Pwm Offset: 0x18) PWM Interrupt Mask Register 1 */ + __I uint32_t PWM_ISR1; /**< \brief (Pwm Offset: 0x1C) PWM Interrupt Status Register 1 */ + __IO uint32_t PWM_SCM; /**< \brief (Pwm Offset: 0x20) PWM Sync Channels Mode Register */ + __O uint32_t PWM_DMAR; /**< \brief (Pwm Offset: 0x24) PWM DMA Register */ + __IO uint32_t PWM_SCUC; /**< \brief (Pwm Offset: 0x28) PWM Sync Channels Update Control Register */ + __IO uint32_t PWM_SCUP; /**< \brief (Pwm Offset: 0x2C) PWM Sync Channels Update Period Register */ + __O uint32_t PWM_SCUPUPD; /**< \brief (Pwm Offset: 0x30) PWM Sync Channels Update Period Update Register */ + __O uint32_t PWM_IER2; /**< \brief (Pwm Offset: 0x34) PWM Interrupt Enable Register 2 */ + __O uint32_t PWM_IDR2; /**< \brief (Pwm Offset: 0x38) PWM Interrupt Disable Register 2 */ + __I uint32_t PWM_IMR2; /**< \brief (Pwm Offset: 0x3C) PWM Interrupt Mask Register 2 */ + __I uint32_t PWM_ISR2; /**< \brief (Pwm Offset: 0x40) PWM Interrupt Status Register 2 */ + __IO uint32_t PWM_OOV; /**< \brief (Pwm Offset: 0x44) PWM Output Override Value Register */ + __IO uint32_t PWM_OS; /**< \brief (Pwm Offset: 0x48) PWM Output Selection Register */ + __O uint32_t PWM_OSS; /**< \brief (Pwm Offset: 0x4C) PWM Output Selection Set Register */ + __O uint32_t PWM_OSC; /**< \brief (Pwm Offset: 0x50) PWM Output Selection Clear Register */ + __O uint32_t PWM_OSSUPD; /**< \brief (Pwm Offset: 0x54) PWM Output Selection Set Update Register */ + __O uint32_t PWM_OSCUPD; /**< \brief (Pwm Offset: 0x58) PWM Output Selection Clear Update Register */ + __IO uint32_t PWM_FMR; /**< \brief (Pwm Offset: 0x5C) PWM Fault Mode Register */ + __I uint32_t PWM_FSR; /**< \brief (Pwm Offset: 0x60) PWM Fault Status Register */ + __O uint32_t PWM_FCR; /**< \brief (Pwm Offset: 0x64) PWM Fault Clear Register */ + __IO uint32_t PWM_FPV1; /**< \brief (Pwm Offset: 0x68) PWM Fault Protection Value Register 1 */ + __IO uint32_t PWM_FPE; /**< \brief (Pwm Offset: 0x6C) PWM Fault Protection Enable Register */ + __I uint32_t Reserved2[3]; + __IO uint32_t PWM_ELMR[2]; /**< \brief (Pwm Offset: 0x7C) PWM Event Line 0 Mode Register */ + __I uint32_t Reserved3[7]; + __IO uint32_t PWM_SSPR; /**< \brief (Pwm Offset: 0xA0) PWM Spread Spectrum Register */ + __O uint32_t PWM_SSPUP; /**< \brief (Pwm Offset: 0xA4) PWM Spread Spectrum Update Register */ + __I uint32_t Reserved4[2]; + __IO uint32_t PWM_SMMR; /**< \brief (Pwm Offset: 0xB0) PWM Stepper Motor Mode Register */ + __I uint32_t Reserved5[3]; + __IO uint32_t PWM_FPV2; /**< \brief (Pwm Offset: 0xC0) PWM Fault Protection Value 2 Register */ + __I uint32_t Reserved6[8]; + __O uint32_t PWM_WPCR; /**< \brief (Pwm Offset: 0xE4) PWM Write Protection Control Register */ + __I uint32_t PWM_WPSR; /**< \brief (Pwm Offset: 0xE8) PWM Write Protectiong Status Register */ + __I uint32_t Reserved7[7]; + __IO uint32_t PWM_TPR; /**< \brief (Pwm Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t PWM_TCR; /**< \brief (Pwm Offset: 0x10C) Transmit Counter Register */ + __I uint32_t Reserved8[2]; + __IO uint32_t PWM_TNPR; /**< \brief (Pwm Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t PWM_TNCR; /**< \brief (Pwm Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t PWM_PTCR; /**< \brief (Pwm Offset: 0x120) Transfer Control Register */ + __I uint32_t PWM_PTSR; /**< \brief (Pwm Offset: 0x124) Transfer Status Register */ + __I uint32_t Reserved9[2]; + PwmCmp PWM_CMP[PWMCMP_NUMBER]; /**< \brief (Pwm Offset: 0x130) 0 .. 7 */ + __I uint32_t Reserved10[20]; + PwmCh_num PWM_CH_NUM[PWMCH_NUM_NUMBER]; /**< \brief (Pwm Offset: 0x200) ch_num = 0 .. 3 */ + __I uint32_t Reserved11[96]; + PwmCh_num_0x400 PWM_CH_NUM_0X400[PWMCH_NUM_0X400_NUMBER]; /**< \brief (Pwm Offset: 0x400) ch_num = 0 .. 3 */ +} Pwm; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- PWM_CLK : (PWM Offset: 0x00) PWM Clock Register -------- */ +#define PWM_CLK_DIVA_Pos 0 +#define PWM_CLK_DIVA_Msk (0xffu << PWM_CLK_DIVA_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Divide Factor */ +#define PWM_CLK_DIVA(value) ((PWM_CLK_DIVA_Msk & ((value) << PWM_CLK_DIVA_Pos))) +#define PWM_CLK_PREA_Pos 8 +#define PWM_CLK_PREA_Msk (0xfu << PWM_CLK_PREA_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Source Clock Selection */ +#define PWM_CLK_PREA(value) ((PWM_CLK_PREA_Msk & ((value) << PWM_CLK_PREA_Pos))) +#define PWM_CLK_DIVB_Pos 16 +#define PWM_CLK_DIVB_Msk (0xffu << PWM_CLK_DIVB_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Divide Factor */ +#define PWM_CLK_DIVB(value) ((PWM_CLK_DIVB_Msk & ((value) << PWM_CLK_DIVB_Pos))) +#define PWM_CLK_PREB_Pos 24 +#define PWM_CLK_PREB_Msk (0xfu << PWM_CLK_PREB_Pos) /**< \brief (PWM_CLK) CLKA, CLKB Source Clock Selection */ +#define PWM_CLK_PREB(value) ((PWM_CLK_PREB_Msk & ((value) << PWM_CLK_PREB_Pos))) +/* -------- PWM_ENA : (PWM Offset: 0x04) PWM Enable Register -------- */ +#define PWM_ENA_CHID0 (0x1u << 0) /**< \brief (PWM_ENA) Channel ID */ +#define PWM_ENA_CHID1 (0x1u << 1) /**< \brief (PWM_ENA) Channel ID */ +#define PWM_ENA_CHID2 (0x1u << 2) /**< \brief (PWM_ENA) Channel ID */ +#define PWM_ENA_CHID3 (0x1u << 3) /**< \brief (PWM_ENA) Channel ID */ +/* -------- PWM_DIS : (PWM Offset: 0x08) PWM Disable Register -------- */ +#define PWM_DIS_CHID0 (0x1u << 0) /**< \brief (PWM_DIS) Channel ID */ +#define PWM_DIS_CHID1 (0x1u << 1) /**< \brief (PWM_DIS) Channel ID */ +#define PWM_DIS_CHID2 (0x1u << 2) /**< \brief (PWM_DIS) Channel ID */ +#define PWM_DIS_CHID3 (0x1u << 3) /**< \brief (PWM_DIS) Channel ID */ +/* -------- PWM_SR : (PWM Offset: 0x0C) PWM Status Register -------- */ +#define PWM_SR_CHID0 (0x1u << 0) /**< \brief (PWM_SR) Channel ID */ +#define PWM_SR_CHID1 (0x1u << 1) /**< \brief (PWM_SR) Channel ID */ +#define PWM_SR_CHID2 (0x1u << 2) /**< \brief (PWM_SR) Channel ID */ +#define PWM_SR_CHID3 (0x1u << 3) /**< \brief (PWM_SR) Channel ID */ +/* -------- PWM_IER1 : (PWM Offset: 0x10) PWM Interrupt Enable Register 1 -------- */ +#define PWM_IER1_CHID0 (0x1u << 0) /**< \brief (PWM_IER1) Counter Event on Channel 0 Interrupt Enable */ +#define PWM_IER1_CHID1 (0x1u << 1) /**< \brief (PWM_IER1) Counter Event on Channel 1 Interrupt Enable */ +#define PWM_IER1_CHID2 (0x1u << 2) /**< \brief (PWM_IER1) Counter Event on Channel 2 Interrupt Enable */ +#define PWM_IER1_CHID3 (0x1u << 3) /**< \brief (PWM_IER1) Counter Event on Channel 3 Interrupt Enable */ +#define PWM_IER1_FCHID0 (0x1u << 16) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 0 Interrupt Enable */ +#define PWM_IER1_FCHID1 (0x1u << 17) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 1 Interrupt Enable */ +#define PWM_IER1_FCHID2 (0x1u << 18) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 2 Interrupt Enable */ +#define PWM_IER1_FCHID3 (0x1u << 19) /**< \brief (PWM_IER1) Fault Protection Trigger on Channel 3 Interrupt Enable */ +/* -------- PWM_IDR1 : (PWM Offset: 0x14) PWM Interrupt Disable Register 1 -------- */ +#define PWM_IDR1_CHID0 (0x1u << 0) /**< \brief (PWM_IDR1) Counter Event on Channel 0 Interrupt Disable */ +#define PWM_IDR1_CHID1 (0x1u << 1) /**< \brief (PWM_IDR1) Counter Event on Channel 1 Interrupt Disable */ +#define PWM_IDR1_CHID2 (0x1u << 2) /**< \brief (PWM_IDR1) Counter Event on Channel 2 Interrupt Disable */ +#define PWM_IDR1_CHID3 (0x1u << 3) /**< \brief (PWM_IDR1) Counter Event on Channel 3 Interrupt Disable */ +#define PWM_IDR1_FCHID0 (0x1u << 16) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 0 Interrupt Disable */ +#define PWM_IDR1_FCHID1 (0x1u << 17) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 1 Interrupt Disable */ +#define PWM_IDR1_FCHID2 (0x1u << 18) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 2 Interrupt Disable */ +#define PWM_IDR1_FCHID3 (0x1u << 19) /**< \brief (PWM_IDR1) Fault Protection Trigger on Channel 3 Interrupt Disable */ +/* -------- PWM_IMR1 : (PWM Offset: 0x18) PWM Interrupt Mask Register 1 -------- */ +#define PWM_IMR1_CHID0 (0x1u << 0) /**< \brief (PWM_IMR1) Counter Event on Channel 0 Interrupt Mask */ +#define PWM_IMR1_CHID1 (0x1u << 1) /**< \brief (PWM_IMR1) Counter Event on Channel 1 Interrupt Mask */ +#define PWM_IMR1_CHID2 (0x1u << 2) /**< \brief (PWM_IMR1) Counter Event on Channel 2 Interrupt Mask */ +#define PWM_IMR1_CHID3 (0x1u << 3) /**< \brief (PWM_IMR1) Counter Event on Channel 3 Interrupt Mask */ +#define PWM_IMR1_FCHID0 (0x1u << 16) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 0 Interrupt Mask */ +#define PWM_IMR1_FCHID1 (0x1u << 17) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 1 Interrupt Mask */ +#define PWM_IMR1_FCHID2 (0x1u << 18) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 2 Interrupt Mask */ +#define PWM_IMR1_FCHID3 (0x1u << 19) /**< \brief (PWM_IMR1) Fault Protection Trigger on Channel 3 Interrupt Mask */ +/* -------- PWM_ISR1 : (PWM Offset: 0x1C) PWM Interrupt Status Register 1 -------- */ +#define PWM_ISR1_CHID0 (0x1u << 0) /**< \brief (PWM_ISR1) Counter Event on Channel 0 */ +#define PWM_ISR1_CHID1 (0x1u << 1) /**< \brief (PWM_ISR1) Counter Event on Channel 1 */ +#define PWM_ISR1_CHID2 (0x1u << 2) /**< \brief (PWM_ISR1) Counter Event on Channel 2 */ +#define PWM_ISR1_CHID3 (0x1u << 3) /**< \brief (PWM_ISR1) Counter Event on Channel 3 */ +#define PWM_ISR1_FCHID0 (0x1u << 16) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 0 */ +#define PWM_ISR1_FCHID1 (0x1u << 17) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 1 */ +#define PWM_ISR1_FCHID2 (0x1u << 18) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 2 */ +#define PWM_ISR1_FCHID3 (0x1u << 19) /**< \brief (PWM_ISR1) Fault Protection Trigger on Channel 3 */ +/* -------- PWM_SCM : (PWM Offset: 0x20) PWM Sync Channels Mode Register -------- */ +#define PWM_SCM_SYNC0 (0x1u << 0) /**< \brief (PWM_SCM) Synchronous Channel 0 */ +#define PWM_SCM_SYNC1 (0x1u << 1) /**< \brief (PWM_SCM) Synchronous Channel 1 */ +#define PWM_SCM_SYNC2 (0x1u << 2) /**< \brief (PWM_SCM) Synchronous Channel 2 */ +#define PWM_SCM_SYNC3 (0x1u << 3) /**< \brief (PWM_SCM) Synchronous Channel 3 */ +#define PWM_SCM_UPDM_Pos 16 +#define PWM_SCM_UPDM_Msk (0x3u << PWM_SCM_UPDM_Pos) /**< \brief (PWM_SCM) Synchronous Channels Update Mode */ +#define PWM_SCM_UPDM_MODE0 (0x0u << 16) /**< \brief (PWM_SCM) Manual write of double buffer registers and manual update of synchronous channels */ +#define PWM_SCM_UPDM_MODE1 (0x1u << 16) /**< \brief (PWM_SCM) Manual write of double buffer registers and automatic update of synchronous channels */ +#define PWM_SCM_UPDM_MODE2 (0x2u << 16) /**< \brief (PWM_SCM) Automatic write of duty-cycle update registers by the PDCPDC or DMA and automatic update of synchronous channels */ +#define PWM_SCM_PTRM (0x1u << 20) /**< \brief (PWM_SCM) PDCPDC or DMA Transfer Request Mode */ +#define PWM_SCM_PTRCS_Pos 21 +#define PWM_SCM_PTRCS_Msk (0x7u << PWM_SCM_PTRCS_Pos) /**< \brief (PWM_SCM) PDCPDC or DMA Transfer Request Comparison Selection */ +#define PWM_SCM_PTRCS(value) ((PWM_SCM_PTRCS_Msk & ((value) << PWM_SCM_PTRCS_Pos))) +/* -------- PWM_DMAR : (PWM Offset: 0x24) PWM DMA Register -------- */ +#define PWM_DMAR_DMADUTY_Pos 0 +#define PWM_DMAR_DMADUTY_Msk (0xffffffu << PWM_DMAR_DMADUTY_Pos) /**< \brief (PWM_DMAR) Duty-Cycle Holding Register for DMA Access */ +#define PWM_DMAR_DMADUTY(value) ((PWM_DMAR_DMADUTY_Msk & ((value) << PWM_DMAR_DMADUTY_Pos))) +/* -------- PWM_SCUC : (PWM Offset: 0x28) PWM Sync Channels Update Control Register -------- */ +#define PWM_SCUC_UPDULOCK (0x1u << 0) /**< \brief (PWM_SCUC) Synchronous Channels Update Unlock */ +/* -------- PWM_SCUP : (PWM Offset: 0x2C) PWM Sync Channels Update Period Register -------- */ +#define PWM_SCUP_UPR_Pos 0 +#define PWM_SCUP_UPR_Msk (0xfu << PWM_SCUP_UPR_Pos) /**< \brief (PWM_SCUP) Update Period */ +#define PWM_SCUP_UPR(value) ((PWM_SCUP_UPR_Msk & ((value) << PWM_SCUP_UPR_Pos))) +#define PWM_SCUP_UPRCNT_Pos 4 +#define PWM_SCUP_UPRCNT_Msk (0xfu << PWM_SCUP_UPRCNT_Pos) /**< \brief (PWM_SCUP) Update Period Counter */ +#define PWM_SCUP_UPRCNT(value) ((PWM_SCUP_UPRCNT_Msk & ((value) << PWM_SCUP_UPRCNT_Pos))) +/* -------- PWM_SCUPUPD : (PWM Offset: 0x30) PWM Sync Channels Update Period Update Register -------- */ +#define PWM_SCUPUPD_UPRUPD_Pos 0 +#define PWM_SCUPUPD_UPRUPD_Msk (0xfu << PWM_SCUPUPD_UPRUPD_Pos) /**< \brief (PWM_SCUPUPD) Update Period Update */ +#define PWM_SCUPUPD_UPRUPD(value) ((PWM_SCUPUPD_UPRUPD_Msk & ((value) << PWM_SCUPUPD_UPRUPD_Pos))) +/* -------- PWM_IER2 : (PWM Offset: 0x34) PWM Interrupt Enable Register 2 -------- */ +#define PWM_IER2_WRDY (0x1u << 0) /**< \brief (PWM_IER2) Write Ready for Synchronous Channels Update Interrupt Enable */ +#define PWM_IER2_ENDTX (0x1u << 1) /**< \brief (PWM_IER2) PDC End of TX Buffer Interrupt Enable */ +#define PWM_IER2_TXBUFE (0x1u << 2) /**< \brief (PWM_IER2) PDC TX Buffer Empty Interrupt Enable */ +#define PWM_IER2_UNRE (0x1u << 3) /**< \brief (PWM_IER2) Synchronous Channels Update Underrun Error Interrupt Enable */ +#define PWM_IER2_CMPM0 (0x1u << 8) /**< \brief (PWM_IER2) Comparison 0 Match Interrupt Enable */ +#define PWM_IER2_CMPM1 (0x1u << 9) /**< \brief (PWM_IER2) Comparison 1 Match Interrupt Enable */ +#define PWM_IER2_CMPM2 (0x1u << 10) /**< \brief (PWM_IER2) Comparison 2 Match Interrupt Enable */ +#define PWM_IER2_CMPM3 (0x1u << 11) /**< \brief (PWM_IER2) Comparison 3 Match Interrupt Enable */ +#define PWM_IER2_CMPM4 (0x1u << 12) /**< \brief (PWM_IER2) Comparison 4 Match Interrupt Enable */ +#define PWM_IER2_CMPM5 (0x1u << 13) /**< \brief (PWM_IER2) Comparison 5 Match Interrupt Enable */ +#define PWM_IER2_CMPM6 (0x1u << 14) /**< \brief (PWM_IER2) Comparison 6 Match Interrupt Enable */ +#define PWM_IER2_CMPM7 (0x1u << 15) /**< \brief (PWM_IER2) Comparison 7 Match Interrupt Enable */ +#define PWM_IER2_CMPU0 (0x1u << 16) /**< \brief (PWM_IER2) Comparison 0 Update Interrupt Enable */ +#define PWM_IER2_CMPU1 (0x1u << 17) /**< \brief (PWM_IER2) Comparison 1 Update Interrupt Enable */ +#define PWM_IER2_CMPU2 (0x1u << 18) /**< \brief (PWM_IER2) Comparison 2 Update Interrupt Enable */ +#define PWM_IER2_CMPU3 (0x1u << 19) /**< \brief (PWM_IER2) Comparison 3 Update Interrupt Enable */ +#define PWM_IER2_CMPU4 (0x1u << 20) /**< \brief (PWM_IER2) Comparison 4 Update Interrupt Enable */ +#define PWM_IER2_CMPU5 (0x1u << 21) /**< \brief (PWM_IER2) Comparison 5 Update Interrupt Enable */ +#define PWM_IER2_CMPU6 (0x1u << 22) /**< \brief (PWM_IER2) Comparison 6 Update Interrupt Enable */ +#define PWM_IER2_CMPU7 (0x1u << 23) /**< \brief (PWM_IER2) Comparison 7 Update Interrupt Enable */ +/* -------- PWM_IDR2 : (PWM Offset: 0x38) PWM Interrupt Disable Register 2 -------- */ +#define PWM_IDR2_WRDY (0x1u << 0) /**< \brief (PWM_IDR2) Write Ready for Synchronous Channels Update Interrupt Disable */ +#define PWM_IDR2_ENDTX (0x1u << 1) /**< \brief (PWM_IDR2) PDC End of TX Buffer Interrupt Disable */ +#define PWM_IDR2_TXBUFE (0x1u << 2) /**< \brief (PWM_IDR2) PDC TX Buffer Empty Interrupt Disable */ +#define PWM_IDR2_UNRE (0x1u << 3) /**< \brief (PWM_IDR2) Synchronous Channels Update Underrun Error Interrupt Disable */ +#define PWM_IDR2_CMPM0 (0x1u << 8) /**< \brief (PWM_IDR2) Comparison 0 Match Interrupt Disable */ +#define PWM_IDR2_CMPM1 (0x1u << 9) /**< \brief (PWM_IDR2) Comparison 1 Match Interrupt Disable */ +#define PWM_IDR2_CMPM2 (0x1u << 10) /**< \brief (PWM_IDR2) Comparison 2 Match Interrupt Disable */ +#define PWM_IDR2_CMPM3 (0x1u << 11) /**< \brief (PWM_IDR2) Comparison 3 Match Interrupt Disable */ +#define PWM_IDR2_CMPM4 (0x1u << 12) /**< \brief (PWM_IDR2) Comparison 4 Match Interrupt Disable */ +#define PWM_IDR2_CMPM5 (0x1u << 13) /**< \brief (PWM_IDR2) Comparison 5 Match Interrupt Disable */ +#define PWM_IDR2_CMPM6 (0x1u << 14) /**< \brief (PWM_IDR2) Comparison 6 Match Interrupt Disable */ +#define PWM_IDR2_CMPM7 (0x1u << 15) /**< \brief (PWM_IDR2) Comparison 7 Match Interrupt Disable */ +#define PWM_IDR2_CMPU0 (0x1u << 16) /**< \brief (PWM_IDR2) Comparison 0 Update Interrupt Disable */ +#define PWM_IDR2_CMPU1 (0x1u << 17) /**< \brief (PWM_IDR2) Comparison 1 Update Interrupt Disable */ +#define PWM_IDR2_CMPU2 (0x1u << 18) /**< \brief (PWM_IDR2) Comparison 2 Update Interrupt Disable */ +#define PWM_IDR2_CMPU3 (0x1u << 19) /**< \brief (PWM_IDR2) Comparison 3 Update Interrupt Disable */ +#define PWM_IDR2_CMPU4 (0x1u << 20) /**< \brief (PWM_IDR2) Comparison 4 Update Interrupt Disable */ +#define PWM_IDR2_CMPU5 (0x1u << 21) /**< \brief (PWM_IDR2) Comparison 5 Update Interrupt Disable */ +#define PWM_IDR2_CMPU6 (0x1u << 22) /**< \brief (PWM_IDR2) Comparison 6 Update Interrupt Disable */ +#define PWM_IDR2_CMPU7 (0x1u << 23) /**< \brief (PWM_IDR2) Comparison 7 Update Interrupt Disable */ +/* -------- PWM_IMR2 : (PWM Offset: 0x3C) PWM Interrupt Mask Register 2 -------- */ +#define PWM_IMR2_WRDY (0x1u << 0) /**< \brief (PWM_IMR2) Write Ready for Synchronous Channels Update Interrupt Mask */ +#define PWM_IMR2_ENDTX (0x1u << 1) /**< \brief (PWM_IMR2) PDC End of TX Buffer Interrupt Mask */ +#define PWM_IMR2_TXBUFE (0x1u << 2) /**< \brief (PWM_IMR2) PDC TX Buffer Empty Interrupt Mask */ +#define PWM_IMR2_UNRE (0x1u << 3) /**< \brief (PWM_IMR2) Synchronous Channels Update Underrun Error Interrupt Mask */ +#define PWM_IMR2_CMPM0 (0x1u << 8) /**< \brief (PWM_IMR2) Comparison 0 Match Interrupt Mask */ +#define PWM_IMR2_CMPM1 (0x1u << 9) /**< \brief (PWM_IMR2) Comparison 1 Match Interrupt Mask */ +#define PWM_IMR2_CMPM2 (0x1u << 10) /**< \brief (PWM_IMR2) Comparison 2 Match Interrupt Mask */ +#define PWM_IMR2_CMPM3 (0x1u << 11) /**< \brief (PWM_IMR2) Comparison 3 Match Interrupt Mask */ +#define PWM_IMR2_CMPM4 (0x1u << 12) /**< \brief (PWM_IMR2) Comparison 4 Match Interrupt Mask */ +#define PWM_IMR2_CMPM5 (0x1u << 13) /**< \brief (PWM_IMR2) Comparison 5 Match Interrupt Mask */ +#define PWM_IMR2_CMPM6 (0x1u << 14) /**< \brief (PWM_IMR2) Comparison 6 Match Interrupt Mask */ +#define PWM_IMR2_CMPM7 (0x1u << 15) /**< \brief (PWM_IMR2) Comparison 7 Match Interrupt Mask */ +#define PWM_IMR2_CMPU0 (0x1u << 16) /**< \brief (PWM_IMR2) Comparison 0 Update Interrupt Mask */ +#define PWM_IMR2_CMPU1 (0x1u << 17) /**< \brief (PWM_IMR2) Comparison 1 Update Interrupt Mask */ +#define PWM_IMR2_CMPU2 (0x1u << 18) /**< \brief (PWM_IMR2) Comparison 2 Update Interrupt Mask */ +#define PWM_IMR2_CMPU3 (0x1u << 19) /**< \brief (PWM_IMR2) Comparison 3 Update Interrupt Mask */ +#define PWM_IMR2_CMPU4 (0x1u << 20) /**< \brief (PWM_IMR2) Comparison 4 Update Interrupt Mask */ +#define PWM_IMR2_CMPU5 (0x1u << 21) /**< \brief (PWM_IMR2) Comparison 5 Update Interrupt Mask */ +#define PWM_IMR2_CMPU6 (0x1u << 22) /**< \brief (PWM_IMR2) Comparison 6 Update Interrupt Mask */ +#define PWM_IMR2_CMPU7 (0x1u << 23) /**< \brief (PWM_IMR2) Comparison 7 Update Interrupt Mask */ +/* -------- PWM_ISR2 : (PWM Offset: 0x40) PWM Interrupt Status Register 2 -------- */ +#define PWM_ISR2_WRDY (0x1u << 0) /**< \brief (PWM_ISR2) Write Ready for Synchronous Channels Update */ +#define PWM_ISR2_ENDTX (0x1u << 1) /**< \brief (PWM_ISR2) PDC End of TX Buffer */ +#define PWM_ISR2_TXBUFE (0x1u << 2) /**< \brief (PWM_ISR2) PDC TX Buffer Empty */ +#define PWM_ISR2_UNRE (0x1u << 3) /**< \brief (PWM_ISR2) Synchronous Channels Update Underrun Error */ +#define PWM_ISR2_CMPM0 (0x1u << 8) /**< \brief (PWM_ISR2) Comparison 0 Match */ +#define PWM_ISR2_CMPM1 (0x1u << 9) /**< \brief (PWM_ISR2) Comparison 1 Match */ +#define PWM_ISR2_CMPM2 (0x1u << 10) /**< \brief (PWM_ISR2) Comparison 2 Match */ +#define PWM_ISR2_CMPM3 (0x1u << 11) /**< \brief (PWM_ISR2) Comparison 3 Match */ +#define PWM_ISR2_CMPM4 (0x1u << 12) /**< \brief (PWM_ISR2) Comparison 4 Match */ +#define PWM_ISR2_CMPM5 (0x1u << 13) /**< \brief (PWM_ISR2) Comparison 5 Match */ +#define PWM_ISR2_CMPM6 (0x1u << 14) /**< \brief (PWM_ISR2) Comparison 6 Match */ +#define PWM_ISR2_CMPM7 (0x1u << 15) /**< \brief (PWM_ISR2) Comparison 7 Match */ +#define PWM_ISR2_CMPU0 (0x1u << 16) /**< \brief (PWM_ISR2) Comparison 0 Update */ +#define PWM_ISR2_CMPU1 (0x1u << 17) /**< \brief (PWM_ISR2) Comparison 1 Update */ +#define PWM_ISR2_CMPU2 (0x1u << 18) /**< \brief (PWM_ISR2) Comparison 2 Update */ +#define PWM_ISR2_CMPU3 (0x1u << 19) /**< \brief (PWM_ISR2) Comparison 3 Update */ +#define PWM_ISR2_CMPU4 (0x1u << 20) /**< \brief (PWM_ISR2) Comparison 4 Update */ +#define PWM_ISR2_CMPU5 (0x1u << 21) /**< \brief (PWM_ISR2) Comparison 5 Update */ +#define PWM_ISR2_CMPU6 (0x1u << 22) /**< \brief (PWM_ISR2) Comparison 6 Update */ +#define PWM_ISR2_CMPU7 (0x1u << 23) /**< \brief (PWM_ISR2) Comparison 7 Update */ +/* -------- PWM_OOV : (PWM Offset: 0x44) PWM Output Override Value Register -------- */ +#define PWM_OOV_OOVH0 (0x1u << 0) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 0 */ +#define PWM_OOV_OOVH1 (0x1u << 1) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 1 */ +#define PWM_OOV_OOVH2 (0x1u << 2) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 2 */ +#define PWM_OOV_OOVH3 (0x1u << 3) /**< \brief (PWM_OOV) Output Override Value for PWMH output of the channel 3 */ +#define PWM_OOV_OOVL0 (0x1u << 16) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 0 */ +#define PWM_OOV_OOVL1 (0x1u << 17) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 1 */ +#define PWM_OOV_OOVL2 (0x1u << 18) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 2 */ +#define PWM_OOV_OOVL3 (0x1u << 19) /**< \brief (PWM_OOV) Output Override Value for PWML output of the channel 3 */ +/* -------- PWM_OS : (PWM Offset: 0x48) PWM Output Selection Register -------- */ +#define PWM_OS_OSH0 (0x1u << 0) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 0 */ +#define PWM_OS_OSH1 (0x1u << 1) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 1 */ +#define PWM_OS_OSH2 (0x1u << 2) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 2 */ +#define PWM_OS_OSH3 (0x1u << 3) /**< \brief (PWM_OS) Output Selection for PWMH output of the channel 3 */ +#define PWM_OS_OSL0 (0x1u << 16) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 0 */ +#define PWM_OS_OSL1 (0x1u << 17) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 1 */ +#define PWM_OS_OSL2 (0x1u << 18) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 2 */ +#define PWM_OS_OSL3 (0x1u << 19) /**< \brief (PWM_OS) Output Selection for PWML output of the channel 3 */ +/* -------- PWM_OSS : (PWM Offset: 0x4C) PWM Output Selection Set Register -------- */ +#define PWM_OSS_OSSH0 (0x1u << 0) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 0 */ +#define PWM_OSS_OSSH1 (0x1u << 1) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 1 */ +#define PWM_OSS_OSSH2 (0x1u << 2) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 2 */ +#define PWM_OSS_OSSH3 (0x1u << 3) /**< \brief (PWM_OSS) Output Selection Set for PWMH output of the channel 3 */ +#define PWM_OSS_OSSL0 (0x1u << 16) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 0 */ +#define PWM_OSS_OSSL1 (0x1u << 17) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 1 */ +#define PWM_OSS_OSSL2 (0x1u << 18) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 2 */ +#define PWM_OSS_OSSL3 (0x1u << 19) /**< \brief (PWM_OSS) Output Selection Set for PWML output of the channel 3 */ +/* -------- PWM_OSC : (PWM Offset: 0x50) PWM Output Selection Clear Register -------- */ +#define PWM_OSC_OSCH0 (0x1u << 0) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 0 */ +#define PWM_OSC_OSCH1 (0x1u << 1) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 1 */ +#define PWM_OSC_OSCH2 (0x1u << 2) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 2 */ +#define PWM_OSC_OSCH3 (0x1u << 3) /**< \brief (PWM_OSC) Output Selection Clear for PWMH output of the channel 3 */ +#define PWM_OSC_OSCL0 (0x1u << 16) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 0 */ +#define PWM_OSC_OSCL1 (0x1u << 17) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 1 */ +#define PWM_OSC_OSCL2 (0x1u << 18) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 2 */ +#define PWM_OSC_OSCL3 (0x1u << 19) /**< \brief (PWM_OSC) Output Selection Clear for PWML output of the channel 3 */ +/* -------- PWM_OSSUPD : (PWM Offset: 0x54) PWM Output Selection Set Update Register -------- */ +#define PWM_OSSUPD_OSSUPH0 (0x1u << 0) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 0 */ +#define PWM_OSSUPD_OSSUPH1 (0x1u << 1) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 1 */ +#define PWM_OSSUPD_OSSUPH2 (0x1u << 2) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 2 */ +#define PWM_OSSUPD_OSSUPH3 (0x1u << 3) /**< \brief (PWM_OSSUPD) Output Selection Set for PWMH output of the channel 3 */ +#define PWM_OSSUPD_OSSUPL0 (0x1u << 16) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 0 */ +#define PWM_OSSUPD_OSSUPL1 (0x1u << 17) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 1 */ +#define PWM_OSSUPD_OSSUPL2 (0x1u << 18) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 2 */ +#define PWM_OSSUPD_OSSUPL3 (0x1u << 19) /**< \brief (PWM_OSSUPD) Output Selection Set for PWML output of the channel 3 */ +/* -------- PWM_OSCUPD : (PWM Offset: 0x58) PWM Output Selection Clear Update Register -------- */ +#define PWM_OSCUPD_OSCUPH0 (0x1u << 0) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 0 */ +#define PWM_OSCUPD_OSCUPH1 (0x1u << 1) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 1 */ +#define PWM_OSCUPD_OSCUPH2 (0x1u << 2) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 2 */ +#define PWM_OSCUPD_OSCUPH3 (0x1u << 3) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWMH output of the channel 3 */ +#define PWM_OSCUPD_OSCUPL0 (0x1u << 16) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 0 */ +#define PWM_OSCUPD_OSCUPL1 (0x1u << 17) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 1 */ +#define PWM_OSCUPD_OSCUPL2 (0x1u << 18) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 2 */ +#define PWM_OSCUPD_OSCUPL3 (0x1u << 19) /**< \brief (PWM_OSCUPD) Output Selection Clear for PWML output of the channel 3 */ +/* -------- PWM_FMR : (PWM Offset: 0x5C) PWM Fault Mode Register -------- */ +#define PWM_FMR_FPOL_Pos 0 +#define PWM_FMR_FPOL_Msk (0xffu << PWM_FMR_FPOL_Pos) /**< \brief (PWM_FMR) Fault Polarity */ +#define PWM_FMR_FPOL(value) ((PWM_FMR_FPOL_Msk & ((value) << PWM_FMR_FPOL_Pos))) +#define PWM_FMR_FMOD_Pos 8 +#define PWM_FMR_FMOD_Msk (0xffu << PWM_FMR_FMOD_Pos) /**< \brief (PWM_FMR) Fault Activation Mode */ +#define PWM_FMR_FMOD(value) ((PWM_FMR_FMOD_Msk & ((value) << PWM_FMR_FMOD_Pos))) +#define PWM_FMR_FFIL_Pos 16 +#define PWM_FMR_FFIL_Msk (0xffu << PWM_FMR_FFIL_Pos) /**< \brief (PWM_FMR) Fault Filtering */ +#define PWM_FMR_FFIL(value) ((PWM_FMR_FFIL_Msk & ((value) << PWM_FMR_FFIL_Pos))) +/* -------- PWM_FSR : (PWM Offset: 0x60) PWM Fault Status Register -------- */ +#define PWM_FSR_FIV_Pos 0 +#define PWM_FSR_FIV_Msk (0xffu << PWM_FSR_FIV_Pos) /**< \brief (PWM_FSR) Fault Input Value */ +#define PWM_FSR_FS_Pos 8 +#define PWM_FSR_FS_Msk (0xffu << PWM_FSR_FS_Pos) /**< \brief (PWM_FSR) Fault Status */ +/* -------- PWM_FCR : (PWM Offset: 0x64) PWM Fault Clear Register -------- */ +#define PWM_FCR_FCLR_Pos 0 +#define PWM_FCR_FCLR_Msk (0xffu << PWM_FCR_FCLR_Pos) /**< \brief (PWM_FCR) Fault Clear */ +#define PWM_FCR_FCLR(value) ((PWM_FCR_FCLR_Msk & ((value) << PWM_FCR_FCLR_Pos))) +/* -------- PWM_FPV1 : (PWM Offset: 0x68) PWM Fault Protection Value Register 1 -------- */ +#define PWM_FPV1_FPVH0 (0x1u << 0) /**< \brief (PWM_FPV1) Fault Protection Value for PWMH output on channel 0 */ +#define PWM_FPV1_FPVH1 (0x1u << 1) /**< \brief (PWM_FPV1) Fault Protection Value for PWMH output on channel 1 */ +#define PWM_FPV1_FPVH2 (0x1u << 2) /**< \brief (PWM_FPV1) Fault Protection Value for PWMH output on channel 2 */ +#define PWM_FPV1_FPVH3 (0x1u << 3) /**< \brief (PWM_FPV1) Fault Protection Value for PWMH output on channel 3 */ +#define PWM_FPV1_FPVL0 (0x1u << 16) /**< \brief (PWM_FPV1) Fault Protection Value for PWML output on channel 0 */ +#define PWM_FPV1_FPVL1 (0x1u << 17) /**< \brief (PWM_FPV1) Fault Protection Value for PWML output on channel 1 */ +#define PWM_FPV1_FPVL2 (0x1u << 18) /**< \brief (PWM_FPV1) Fault Protection Value for PWML output on channel 2 */ +#define PWM_FPV1_FPVL3 (0x1u << 19) /**< \brief (PWM_FPV1) Fault Protection Value for PWML output on channel 3 */ +/* -------- PWM_FPE : (PWM Offset: 0x6C) PWM Fault Protection Enable Register -------- */ +#define PWM_FPE_FPE0_Pos 0 +#define PWM_FPE_FPE0_Msk (0xffu << PWM_FPE_FPE0_Pos) /**< \brief (PWM_FPE) Fault Protection Enable for channel 0 */ +#define PWM_FPE_FPE0(value) ((PWM_FPE_FPE0_Msk & ((value) << PWM_FPE_FPE0_Pos))) +#define PWM_FPE_FPE1_Pos 8 +#define PWM_FPE_FPE1_Msk (0xffu << PWM_FPE_FPE1_Pos) /**< \brief (PWM_FPE) Fault Protection Enable for channel 1 */ +#define PWM_FPE_FPE1(value) ((PWM_FPE_FPE1_Msk & ((value) << PWM_FPE_FPE1_Pos))) +#define PWM_FPE_FPE2_Pos 16 +#define PWM_FPE_FPE2_Msk (0xffu << PWM_FPE_FPE2_Pos) /**< \brief (PWM_FPE) Fault Protection Enable for channel 2 */ +#define PWM_FPE_FPE2(value) ((PWM_FPE_FPE2_Msk & ((value) << PWM_FPE_FPE2_Pos))) +#define PWM_FPE_FPE3_Pos 24 +#define PWM_FPE_FPE3_Msk (0xffu << PWM_FPE_FPE3_Pos) /**< \brief (PWM_FPE) Fault Protection Enable for channel 3 */ +#define PWM_FPE_FPE3(value) ((PWM_FPE_FPE3_Msk & ((value) << PWM_FPE_FPE3_Pos))) +/* -------- PWM_ELMR[2] : (PWM Offset: 0x7C) PWM Event Line 0 Mode Register -------- */ +#define PWM_ELMR_CSEL0 (0x1u << 0) /**< \brief (PWM_ELMR[2]) Comparison 0 Selection */ +#define PWM_ELMR_CSEL1 (0x1u << 1) /**< \brief (PWM_ELMR[2]) Comparison 1 Selection */ +#define PWM_ELMR_CSEL2 (0x1u << 2) /**< \brief (PWM_ELMR[2]) Comparison 2 Selection */ +#define PWM_ELMR_CSEL3 (0x1u << 3) /**< \brief (PWM_ELMR[2]) Comparison 3 Selection */ +#define PWM_ELMR_CSEL4 (0x1u << 4) /**< \brief (PWM_ELMR[2]) Comparison 4 Selection */ +#define PWM_ELMR_CSEL5 (0x1u << 5) /**< \brief (PWM_ELMR[2]) Comparison 5 Selection */ +#define PWM_ELMR_CSEL6 (0x1u << 6) /**< \brief (PWM_ELMR[2]) Comparison 6 Selection */ +#define PWM_ELMR_CSEL7 (0x1u << 7) /**< \brief (PWM_ELMR[2]) Comparison 7 Selection */ +/* -------- PWM_SSPR : (PWM Offset: 0xA0) PWM Spread Spectrum Register -------- */ +#define PWM_SSPR_SPRD_Pos 0 +#define PWM_SSPR_SPRD_Msk (0xffffffu << PWM_SSPR_SPRD_Pos) /**< \brief (PWM_SSPR) Spread Spectrum Limit Value */ +#define PWM_SSPR_SPRD(value) ((PWM_SSPR_SPRD_Msk & ((value) << PWM_SSPR_SPRD_Pos))) +#define PWM_SSPR_SPRDM (0x1u << 24) /**< \brief (PWM_SSPR) Spread Spectrum Counter Mode */ +/* -------- PWM_SSPUP : (PWM Offset: 0xA4) PWM Spread Spectrum Update Register -------- */ +#define PWM_SSPUP_SPRDUP_Pos 0 +#define PWM_SSPUP_SPRDUP_Msk (0xffffffu << PWM_SSPUP_SPRDUP_Pos) /**< \brief (PWM_SSPUP) Spread Spectrum Limit Value Update */ +#define PWM_SSPUP_SPRDUP(value) ((PWM_SSPUP_SPRDUP_Msk & ((value) << PWM_SSPUP_SPRDUP_Pos))) +/* -------- PWM_SMMR : (PWM Offset: 0xB0) PWM Stepper Motor Mode Register -------- */ +#define PWM_SMMR_GCEN0 (0x1u << 0) /**< \brief (PWM_SMMR) Gray Count ENable */ +#define PWM_SMMR_GCEN1 (0x1u << 1) /**< \brief (PWM_SMMR) Gray Count ENable */ +#define PWM_SMMR_DOWN0 (0x1u << 16) /**< \brief (PWM_SMMR) DOWN Count */ +#define PWM_SMMR_DOWN1 (0x1u << 17) /**< \brief (PWM_SMMR) DOWN Count */ +/* -------- PWM_FPV2 : (PWM Offset: 0xC0) PWM Fault Protection Value 2 Register -------- */ +#define PWM_FPV2_FPZH0 (0x1u << 0) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWMH output on channel 0 */ +#define PWM_FPV2_FPZH1 (0x1u << 1) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWMH output on channel 1 */ +#define PWM_FPV2_FPZH2 (0x1u << 2) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWMH output on channel 2 */ +#define PWM_FPV2_FPZH3 (0x1u << 3) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWMH output on channel 3 */ +#define PWM_FPV2_FPZL0 (0x1u << 16) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWML output on channel 0 */ +#define PWM_FPV2_FPZL1 (0x1u << 17) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWML output on channel 1 */ +#define PWM_FPV2_FPZL2 (0x1u << 18) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWML output on channel 2 */ +#define PWM_FPV2_FPZL3 (0x1u << 19) /**< \brief (PWM_FPV2) Fault Protection to Hi-Z for PWML output on channel 3 */ +/* -------- PWM_WPCR : (PWM Offset: 0xE4) PWM Write Protection Control Register -------- */ +#define PWM_WPCR_WPCMD_Pos 0 +#define PWM_WPCR_WPCMD_Msk (0x3u << PWM_WPCR_WPCMD_Pos) /**< \brief (PWM_WPCR) Write Protection Command */ +#define PWM_WPCR_WPCMD_DISABLE_SW_PROT (0x0u << 0) /**< \brief (PWM_WPCR) Disables the software write protection of the register groups of which the bit WPRGx is at '1'. */ +#define PWM_WPCR_WPCMD_ENABLE_SW_PROT (0x1u << 0) /**< \brief (PWM_WPCR) Enables the software write protection of the register groups of which the bit WPRGx is at '1'. */ +#define PWM_WPCR_WPCMD_ENABLE_HW_PROT (0x2u << 0) /**< \brief (PWM_WPCR) Enables the hardware write protection of the register groups of which the bit WPRGx is at '1'. Only a hardware reset of the PWM controller can disable the hardware write protection. Moreover, to meet security requirements, the PIO lines associated with the PWM can not be configured through the PIO interface. */ +#define PWM_WPCR_WPRG0 (0x1u << 2) /**< \brief (PWM_WPCR) Write Protection Register Group 0 */ +#define PWM_WPCR_WPRG1 (0x1u << 3) /**< \brief (PWM_WPCR) Write Protection Register Group 1 */ +#define PWM_WPCR_WPRG2 (0x1u << 4) /**< \brief (PWM_WPCR) Write Protection Register Group 2 */ +#define PWM_WPCR_WPRG3 (0x1u << 5) /**< \brief (PWM_WPCR) Write Protection Register Group 3 */ +#define PWM_WPCR_WPRG4 (0x1u << 6) /**< \brief (PWM_WPCR) Write Protection Register Group 4 */ +#define PWM_WPCR_WPRG5 (0x1u << 7) /**< \brief (PWM_WPCR) Write Protection Register Group 5 */ +#define PWM_WPCR_WPKEY_Pos 8 +#define PWM_WPCR_WPKEY_Msk (0xffffffu << PWM_WPCR_WPKEY_Pos) /**< \brief (PWM_WPCR) Write Protection Key */ +#define PWM_WPCR_WPKEY_PASSWD (0x50574Du << 8) /**< \brief (PWM_WPCR) Writing any other value in this field aborts the write operation of the WPCMD field.Always reads as 0 */ +/* -------- PWM_WPSR : (PWM Offset: 0xE8) PWM Write Protection Status Register -------- */ +#define PWM_WPSR_WPSWS0 (0x1u << 0) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPSWS1 (0x1u << 1) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPSWS2 (0x1u << 2) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPSWS3 (0x1u << 3) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPSWS4 (0x1u << 4) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPSWS5 (0x1u << 5) /**< \brief (PWM_WPSR) Write Protect SW Status */ +#define PWM_WPSR_WPVS (0x1u << 7) /**< \brief (PWM_WPSR) Write Protect Violation Status */ +#define PWM_WPSR_WPHWS0 (0x1u << 8) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPHWS1 (0x1u << 9) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPHWS2 (0x1u << 10) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPHWS3 (0x1u << 11) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPHWS4 (0x1u << 12) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPHWS5 (0x1u << 13) /**< \brief (PWM_WPSR) Write Protect HW Status */ +#define PWM_WPSR_WPVSRC_Pos 16 +#define PWM_WPSR_WPVSRC_Msk (0xffffu << PWM_WPSR_WPVSRC_Pos) /**< \brief (PWM_WPSR) Write Protect Violation Source */ +/* -------- PWM_TPR : (PWM Offset: 0x108) Transmit Pointer Register -------- */ +#define PWM_TPR_TXPTR_Pos 0 +#define PWM_TPR_TXPTR_Msk (0xffffffffu << PWM_TPR_TXPTR_Pos) /**< \brief (PWM_TPR) Transmit Counter Register */ +#define PWM_TPR_TXPTR(value) ((PWM_TPR_TXPTR_Msk & ((value) << PWM_TPR_TXPTR_Pos))) +/* -------- PWM_TCR : (PWM Offset: 0x10C) Transmit Counter Register -------- */ +#define PWM_TCR_TXCTR_Pos 0 +#define PWM_TCR_TXCTR_Msk (0xffffu << PWM_TCR_TXCTR_Pos) /**< \brief (PWM_TCR) Transmit Counter Register */ +#define PWM_TCR_TXCTR(value) ((PWM_TCR_TXCTR_Msk & ((value) << PWM_TCR_TXCTR_Pos))) +/* -------- PWM_TNPR : (PWM Offset: 0x118) Transmit Next Pointer Register -------- */ +#define PWM_TNPR_TXNPTR_Pos 0 +#define PWM_TNPR_TXNPTR_Msk (0xffffffffu << PWM_TNPR_TXNPTR_Pos) /**< \brief (PWM_TNPR) Transmit Next Pointer */ +#define PWM_TNPR_TXNPTR(value) ((PWM_TNPR_TXNPTR_Msk & ((value) << PWM_TNPR_TXNPTR_Pos))) +/* -------- PWM_TNCR : (PWM Offset: 0x11C) Transmit Next Counter Register -------- */ +#define PWM_TNCR_TXNCTR_Pos 0 +#define PWM_TNCR_TXNCTR_Msk (0xffffu << PWM_TNCR_TXNCTR_Pos) /**< \brief (PWM_TNCR) Transmit Counter Next */ +#define PWM_TNCR_TXNCTR(value) ((PWM_TNCR_TXNCTR_Msk & ((value) << PWM_TNCR_TXNCTR_Pos))) +/* -------- PWM_PTCR : (PWM Offset: 0x120) Transfer Control Register -------- */ +#define PWM_PTCR_RXTEN (0x1u << 0) /**< \brief (PWM_PTCR) Receiver Transfer Enable */ +#define PWM_PTCR_RXTDIS (0x1u << 1) /**< \brief (PWM_PTCR) Receiver Transfer Disable */ +#define PWM_PTCR_TXTEN (0x1u << 8) /**< \brief (PWM_PTCR) Transmitter Transfer Enable */ +#define PWM_PTCR_TXTDIS (0x1u << 9) /**< \brief (PWM_PTCR) Transmitter Transfer Disable */ +/* -------- PWM_PTSR : (PWM Offset: 0x124) Transfer Status Register -------- */ +#define PWM_PTSR_RXTEN (0x1u << 0) /**< \brief (PWM_PTSR) Receiver Transfer Enable */ +#define PWM_PTSR_TXTEN (0x1u << 8) /**< \brief (PWM_PTSR) Transmitter Transfer Enable */ +/* -------- PWM_CMPV : (PWM Offset: N/A) PWM Comparison 0 Value Register -------- */ +#define PWM_CMPV_CV_Pos 0 +#define PWM_CMPV_CV_Msk (0xffffffu << PWM_CMPV_CV_Pos) /**< \brief (PWM_CMPV) Comparison x Value */ +#define PWM_CMPV_CV(value) ((PWM_CMPV_CV_Msk & ((value) << PWM_CMPV_CV_Pos))) +#define PWM_CMPV_CVM (0x1u << 24) /**< \brief (PWM_CMPV) Comparison x Value Mode */ +/* -------- PWM_CMPVUPD : (PWM Offset: N/A) PWM Comparison 0 Value Update Register -------- */ +#define PWM_CMPVUPD_CVUPD_Pos 0 +#define PWM_CMPVUPD_CVUPD_Msk (0xffffffu << PWM_CMPVUPD_CVUPD_Pos) /**< \brief (PWM_CMPVUPD) Comparison x Value Update */ +#define PWM_CMPVUPD_CVUPD(value) ((PWM_CMPVUPD_CVUPD_Msk & ((value) << PWM_CMPVUPD_CVUPD_Pos))) +#define PWM_CMPVUPD_CVMUPD (0x1u << 24) /**< \brief (PWM_CMPVUPD) Comparison x Value Mode Update */ +/* -------- PWM_CMPM : (PWM Offset: N/A) PWM Comparison 0 Mode Register -------- */ +#define PWM_CMPM_CEN (0x1u << 0) /**< \brief (PWM_CMPM) Comparison x Enable */ +#define PWM_CMPM_CTR_Pos 4 +#define PWM_CMPM_CTR_Msk (0xfu << PWM_CMPM_CTR_Pos) /**< \brief (PWM_CMPM) Comparison x Trigger */ +#define PWM_CMPM_CTR(value) ((PWM_CMPM_CTR_Msk & ((value) << PWM_CMPM_CTR_Pos))) +#define PWM_CMPM_CPR_Pos 8 +#define PWM_CMPM_CPR_Msk (0xfu << PWM_CMPM_CPR_Pos) /**< \brief (PWM_CMPM) Comparison x Period */ +#define PWM_CMPM_CPR(value) ((PWM_CMPM_CPR_Msk & ((value) << PWM_CMPM_CPR_Pos))) +#define PWM_CMPM_CPRCNT_Pos 12 +#define PWM_CMPM_CPRCNT_Msk (0xfu << PWM_CMPM_CPRCNT_Pos) /**< \brief (PWM_CMPM) Comparison x Period Counter */ +#define PWM_CMPM_CPRCNT(value) ((PWM_CMPM_CPRCNT_Msk & ((value) << PWM_CMPM_CPRCNT_Pos))) +#define PWM_CMPM_CUPR_Pos 16 +#define PWM_CMPM_CUPR_Msk (0xfu << PWM_CMPM_CUPR_Pos) /**< \brief (PWM_CMPM) Comparison x Update Period */ +#define PWM_CMPM_CUPR(value) ((PWM_CMPM_CUPR_Msk & ((value) << PWM_CMPM_CUPR_Pos))) +#define PWM_CMPM_CUPRCNT_Pos 20 +#define PWM_CMPM_CUPRCNT_Msk (0xfu << PWM_CMPM_CUPRCNT_Pos) /**< \brief (PWM_CMPM) Comparison x Update Period Counter */ +#define PWM_CMPM_CUPRCNT(value) ((PWM_CMPM_CUPRCNT_Msk & ((value) << PWM_CMPM_CUPRCNT_Pos))) +/* -------- PWM_CMPMUPD : (PWM Offset: N/A) PWM Comparison 0 Mode Update Register -------- */ +#define PWM_CMPMUPD_CENUPD (0x1u << 0) /**< \brief (PWM_CMPMUPD) Comparison x Enable Update */ +#define PWM_CMPMUPD_CTRUPD_Pos 4 +#define PWM_CMPMUPD_CTRUPD_Msk (0xfu << PWM_CMPMUPD_CTRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Trigger Update */ +#define PWM_CMPMUPD_CTRUPD(value) ((PWM_CMPMUPD_CTRUPD_Msk & ((value) << PWM_CMPMUPD_CTRUPD_Pos))) +#define PWM_CMPMUPD_CPRUPD_Pos 8 +#define PWM_CMPMUPD_CPRUPD_Msk (0xfu << PWM_CMPMUPD_CPRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Period Update */ +#define PWM_CMPMUPD_CPRUPD(value) ((PWM_CMPMUPD_CPRUPD_Msk & ((value) << PWM_CMPMUPD_CPRUPD_Pos))) +#define PWM_CMPMUPD_CUPRUPD_Pos 16 +#define PWM_CMPMUPD_CUPRUPD_Msk (0xfu << PWM_CMPMUPD_CUPRUPD_Pos) /**< \brief (PWM_CMPMUPD) Comparison x Update Period Update */ +#define PWM_CMPMUPD_CUPRUPD(value) ((PWM_CMPMUPD_CUPRUPD_Msk & ((value) << PWM_CMPMUPD_CUPRUPD_Pos))) +/* -------- PWM_CMR : (PWM Offset: N/A) PWM Channel Mode Register -------- */ +#define PWM_CMR_CPRE_Pos 0 +#define PWM_CMR_CPRE_Msk (0xfu << PWM_CMR_CPRE_Pos) /**< \brief (PWM_CMR) Channel Pre-scaler */ +#define PWM_CMR_CPRE_MCK (0x0u << 0) /**< \brief (PWM_CMR) Peripheral clock */ +#define PWM_CMR_CPRE_MCK_DIV_2 (0x1u << 0) /**< \brief (PWM_CMR) Peripheral clock/2 */ +#define PWM_CMR_CPRE_MCK_DIV_4 (0x2u << 0) /**< \brief (PWM_CMR) Peripheral clock/4 */ +#define PWM_CMR_CPRE_MCK_DIV_8 (0x3u << 0) /**< \brief (PWM_CMR) Peripheral clock/8 */ +#define PWM_CMR_CPRE_MCK_DIV_16 (0x4u << 0) /**< \brief (PWM_CMR) Peripheral clock/16 */ +#define PWM_CMR_CPRE_MCK_DIV_32 (0x5u << 0) /**< \brief (PWM_CMR) Peripheral clock/32 */ +#define PWM_CMR_CPRE_MCK_DIV_64 (0x6u << 0) /**< \brief (PWM_CMR) Peripheral clock/64 */ +#define PWM_CMR_CPRE_MCK_DIV_128 (0x7u << 0) /**< \brief (PWM_CMR) Peripheral clock/128 */ +#define PWM_CMR_CPRE_MCK_DIV_256 (0x8u << 0) /**< \brief (PWM_CMR) Peripheral clock/256 */ +#define PWM_CMR_CPRE_MCK_DIV_512 (0x9u << 0) /**< \brief (PWM_CMR) Peripheral clock/512 */ +#define PWM_CMR_CPRE_MCK_DIV_1024 (0xAu << 0) /**< \brief (PWM_CMR) Peripheral clock/1024 */ +#define PWM_CMR_CPRE_CLKA (0xBu << 0) /**< \brief (PWM_CMR) Clock A */ +#define PWM_CMR_CPRE_CLKB (0xCu << 0) /**< \brief (PWM_CMR) Clock B */ +#define PWM_CMR_CALG (0x1u << 8) /**< \brief (PWM_CMR) Channel Alignment */ +#define PWM_CMR_CPOL (0x1u << 9) /**< \brief (PWM_CMR) Channel Polarity */ +#define PWM_CMR_CES (0x1u << 10) /**< \brief (PWM_CMR) Counter Event Selection */ +#define PWM_CMR_UPDS (0x1u << 11) /**< \brief (PWM_CMR) Update Selection */ +#define PWM_CMR_DTE (0x1u << 16) /**< \brief (PWM_CMR) Dead-Time Generator Enable */ +#define PWM_CMR_DTHI (0x1u << 17) /**< \brief (PWM_CMR) Dead-Time PWMHx Output Inverted */ +#define PWM_CMR_DTLI (0x1u << 18) /**< \brief (PWM_CMR) Dead-Time PWMLx Output Inverted */ +/* -------- PWM_CDTY : (PWM Offset: N/A) PWM Channel Duty Cycle Register -------- */ +#define PWM_CDTY_CDTY_Pos 0 +#define PWM_CDTY_CDTY_Msk (0xffffffu << PWM_CDTY_CDTY_Pos) /**< \brief (PWM_CDTY) Channel Duty-Cycle */ +#define PWM_CDTY_CDTY(value) ((PWM_CDTY_CDTY_Msk & ((value) << PWM_CDTY_CDTY_Pos))) +/* -------- PWM_CDTYUPD : (PWM Offset: N/A) PWM Channel Duty Cycle Update Register -------- */ +#define PWM_CDTYUPD_CDTYUPD_Pos 0 +#define PWM_CDTYUPD_CDTYUPD_Msk (0xffffffu << PWM_CDTYUPD_CDTYUPD_Pos) /**< \brief (PWM_CDTYUPD) Channel Duty-Cycle Update */ +#define PWM_CDTYUPD_CDTYUPD(value) ((PWM_CDTYUPD_CDTYUPD_Msk & ((value) << PWM_CDTYUPD_CDTYUPD_Pos))) +/* -------- PWM_CPRD : (PWM Offset: N/A) PWM Channel Period Register -------- */ +#define PWM_CPRD_CPRD_Pos 0 +#define PWM_CPRD_CPRD_Msk (0xffffffu << PWM_CPRD_CPRD_Pos) /**< \brief (PWM_CPRD) Channel Period */ +#define PWM_CPRD_CPRD(value) ((PWM_CPRD_CPRD_Msk & ((value) << PWM_CPRD_CPRD_Pos))) +/* -------- PWM_CPRDUPD : (PWM Offset: N/A) PWM Channel Period Update Register -------- */ +#define PWM_CPRDUPD_CPRDUPD_Pos 0 +#define PWM_CPRDUPD_CPRDUPD_Msk (0xffffffu << PWM_CPRDUPD_CPRDUPD_Pos) /**< \brief (PWM_CPRDUPD) Channel Period Update */ +#define PWM_CPRDUPD_CPRDUPD(value) ((PWM_CPRDUPD_CPRDUPD_Msk & ((value) << PWM_CPRDUPD_CPRDUPD_Pos))) +/* -------- PWM_CCNT : (PWM Offset: N/A) PWM Channel Counter Register -------- */ +#define PWM_CCNT_CNT_Pos 0 +#define PWM_CCNT_CNT_Msk (0xffffffu << PWM_CCNT_CNT_Pos) /**< \brief (PWM_CCNT) Channel Counter Register */ +/* -------- PWM_DT : (PWM Offset: N/A) PWM Channel Dead Time Register -------- */ +#define PWM_DT_DTH_Pos 0 +#define PWM_DT_DTH_Msk (0xffffu << PWM_DT_DTH_Pos) /**< \brief (PWM_DT) Dead-Time Value for PWMHx Output */ +#define PWM_DT_DTH(value) ((PWM_DT_DTH_Msk & ((value) << PWM_DT_DTH_Pos))) +#define PWM_DT_DTL_Pos 16 +#define PWM_DT_DTL_Msk (0xffffu << PWM_DT_DTL_Pos) /**< \brief (PWM_DT) Dead-Time Value for PWMLx Output */ +#define PWM_DT_DTL(value) ((PWM_DT_DTL_Msk & ((value) << PWM_DT_DTL_Pos))) +/* -------- PWM_DTUPD : (PWM Offset: N/A) PWM Channel Dead Time Update Register -------- */ +#define PWM_DTUPD_DTHUPD_Pos 0 +#define PWM_DTUPD_DTHUPD_Msk (0xffffu << PWM_DTUPD_DTHUPD_Pos) /**< \brief (PWM_DTUPD) Dead-Time Value Update for PWMHx Output */ +#define PWM_DTUPD_DTHUPD(value) ((PWM_DTUPD_DTHUPD_Msk & ((value) << PWM_DTUPD_DTHUPD_Pos))) +#define PWM_DTUPD_DTLUPD_Pos 16 +#define PWM_DTUPD_DTLUPD_Msk (0xffffu << PWM_DTUPD_DTLUPD_Pos) /**< \brief (PWM_DTUPD) Dead-Time Value Update for PWMLx Output */ +#define PWM_DTUPD_DTLUPD(value) ((PWM_DTUPD_DTLUPD_Msk & ((value) << PWM_DTUPD_DTLUPD_Pos))) +/* -------- PWM_CMUPD : (PWM Offset: N/A) PWM Channel Mode Update Register -------- */ +#define PWM_CMUPD_CPOLUP (0x1u << 9) /**< \brief (PWM_CMUPD) Channel Polarity Update */ +#define PWM_CMUPD_CPOLINVUP (0x1u << 13) /**< \brief (PWM_CMUPD) Channel Polarity Inversion Update */ +/* -------- PWM_CAE : (PWM Offset: N/A) PWM Channel Additional Edge Register -------- */ +#define PWM_CAE_ADEDGV_Pos 0 +#define PWM_CAE_ADEDGV_Msk (0xffffffu << PWM_CAE_ADEDGV_Pos) /**< \brief (PWM_CAE) Channel Additional Edge Value */ +#define PWM_CAE_ADEDGV(value) ((PWM_CAE_ADEDGV_Msk & ((value) << PWM_CAE_ADEDGV_Pos))) +#define PWM_CAE_ADEDGM_Pos 24 +#define PWM_CAE_ADEDGM_Msk (0x3u << PWM_CAE_ADEDGM_Pos) /**< \brief (PWM_CAE) Channel Additional Edge Mode */ +#define PWM_CAE_ADEDGM_INC (0x0u << 24) /**< \brief (PWM_CAE) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGV and the counter of the channel x is incrementing. */ +#define PWM_CAE_ADEDGM_DEC (0x1u << 24) /**< \brief (PWM_CAE) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGV and the counter of the channel x is incrementing. */ +#define PWM_CAE_ADEDGM_BOTH (0x2u << 24) /**< \brief (PWM_CAE) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGV, whether the counter is incrementing or not. */ +/* -------- PWM_CAEUPD : (PWM Offset: N/A) PWM Channel Additional Edge Update Register -------- */ +#define PWM_CAEUPD_ADEDGVUP_Pos 0 +#define PWM_CAEUPD_ADEDGVUP_Msk (0xffffffu << PWM_CAEUPD_ADEDGVUP_Pos) /**< \brief (PWM_CAEUPD) Channel Additional Edge Value Update */ +#define PWM_CAEUPD_ADEDGVUP(value) ((PWM_CAEUPD_ADEDGVUP_Msk & ((value) << PWM_CAEUPD_ADEDGVUP_Pos))) +#define PWM_CAEUPD_ADEDGMUP_Pos 24 +#define PWM_CAEUPD_ADEDGMUP_Msk (0x3u << PWM_CAEUPD_ADEDGMUP_Pos) /**< \brief (PWM_CAEUPD) Channel Additional Edge Mode Update */ +#define PWM_CAEUPD_ADEDGMUP_INC (0x0u << 24) /**< \brief (PWM_CAEUPD) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGVUP and the counter of the channel x is incrementing. */ +#define PWM_CAEUPD_ADEDGMUP_DEC (0x1u << 24) /**< \brief (PWM_CAEUPD) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGVUP and the counter of the channel x is incrementing. */ +#define PWM_CAEUPD_ADEDGMUP_BOTH (0x2u << 24) /**< \brief (PWM_CAEUPD) The additional edge of the channel x output waveform occurs when CCNTx reaches ADEDGVUP, whether the counter is incrementing or not. */ + +/*@}*/ + + +#endif /* _SAM4E_PWM_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rstc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rstc.h new file mode 100644 index 0000000..a726129 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rstc.h @@ -0,0 +1,93 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RSTC_COMPONENT_ +#define _SAM4E_RSTC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Reset Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_RSTC Reset Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Rstc hardware registers */ +typedef struct { + __O uint32_t RSTC_CR; /**< \brief (Rstc Offset: 0x00) Control Register */ + __I uint32_t RSTC_SR; /**< \brief (Rstc Offset: 0x04) Status Register */ + __IO uint32_t RSTC_MR; /**< \brief (Rstc Offset: 0x08) Mode Register */ +} Rstc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- RSTC_CR : (RSTC Offset: 0x00) Control Register -------- */ +#define RSTC_CR_PROCRST (0x1u << 0) /**< \brief (RSTC_CR) Processor Reset */ +#define RSTC_CR_PERRST (0x1u << 2) /**< \brief (RSTC_CR) Peripheral Reset */ +#define RSTC_CR_EXTRST (0x1u << 3) /**< \brief (RSTC_CR) External Reset */ +#define RSTC_CR_KEY_Pos 24 +#define RSTC_CR_KEY_Msk (0xffu << RSTC_CR_KEY_Pos) /**< \brief (RSTC_CR) System Reset Key */ +#define RSTC_CR_KEY_PASSWD (0xA5u << 24) /**< \brief (RSTC_CR) Writing any other value in this field aborts the write operation. */ +/* -------- RSTC_SR : (RSTC Offset: 0x04) Status Register -------- */ +#define RSTC_SR_URSTS (0x1u << 0) /**< \brief (RSTC_SR) User Reset Status */ +#define RSTC_SR_RSTTYP_Pos 8 +#define RSTC_SR_RSTTYP_Msk (0x7u << RSTC_SR_RSTTYP_Pos) /**< \brief (RSTC_SR) Reset Type */ +#define RSTC_SR_RSTTYP_GENERAL_RST (0x0u << 8) /**< \brief (RSTC_SR) First power-up reset */ +#define RSTC_SR_RSTTYP_BACKUP_RST (0x1u << 8) /**< \brief (RSTC_SR) Return from Backup Mode */ +#define RSTC_SR_RSTTYP_WDT_RST (0x2u << 8) /**< \brief (RSTC_SR) Watchdog fault occurred */ +#define RSTC_SR_RSTTYP_SOFT_RST (0x3u << 8) /**< \brief (RSTC_SR) Processor reset required by the software */ +#define RSTC_SR_RSTTYP_USER_RST (0x4u << 8) /**< \brief (RSTC_SR) NRST pin detected low */ +#define RSTC_SR_NRSTL (0x1u << 16) /**< \brief (RSTC_SR) NRST Pin Level */ +#define RSTC_SR_SRCMP (0x1u << 17) /**< \brief (RSTC_SR) Software Reset Command in Progress */ +/* -------- RSTC_MR : (RSTC Offset: 0x08) Mode Register -------- */ +#define RSTC_MR_URSTEN (0x1u << 0) /**< \brief (RSTC_MR) User Reset Enable */ +#define RSTC_MR_URSTIEN (0x1u << 4) /**< \brief (RSTC_MR) User Reset Interrupt Enable */ +#define RSTC_MR_ERSTL_Pos 8 +#define RSTC_MR_ERSTL_Msk (0xfu << RSTC_MR_ERSTL_Pos) /**< \brief (RSTC_MR) External Reset Length */ +#define RSTC_MR_ERSTL(value) ((RSTC_MR_ERSTL_Msk & ((value) << RSTC_MR_ERSTL_Pos))) +#define RSTC_MR_KEY_Pos 24 +#define RSTC_MR_KEY_Msk (0xffu << RSTC_MR_KEY_Pos) /**< \brief (RSTC_MR) Write Access Password */ +#define RSTC_MR_KEY_PASSWD (0xA5u << 24) /**< \brief (RSTC_MR) Writing any other value in this field aborts the write operation.Always reads as 0. */ + +/*@}*/ + + +#endif /* _SAM4E_RSTC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rswdt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rswdt.h new file mode 100644 index 0000000..4f849c1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rswdt.h @@ -0,0 +1,87 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RSWDT_COMPONENT_ +#define _SAM4E_RSWDT_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Reinforced Safety Watchdog Timer */ +/* ============================================================================= */ +/** \addtogroup SAM4E_RSWDT Reinforced Safety Watchdog Timer */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Rswdt hardware registers */ +typedef struct { + __O uint32_t RSWDT_CR; /**< \brief (Rswdt Offset: 0x00) Control Register */ + __IO uint32_t RSWDT_MR; /**< \brief (Rswdt Offset: 0x04) Mode Register */ + __I uint32_t RSWDT_SR; /**< \brief (Rswdt Offset: 0x08) Status Register */ +} Rswdt; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- RSWDT_CR : (RSWDT Offset: 0x00) Control Register -------- */ +#define RSWDT_CR_WDRSTT (0x1u << 0) /**< \brief (RSWDT_CR) Watchdog Restart */ +#define RSWDT_CR_KEY_Pos 24 +#define RSWDT_CR_KEY_Msk (0xffu << RSWDT_CR_KEY_Pos) /**< \brief (RSWDT_CR) Password */ +#define RSWDT_CR_KEY_PASSWD (0xC4u << 24) /**< \brief (RSWDT_CR) Writing any other value in this field aborts the write operation. */ +/* -------- RSWDT_MR : (RSWDT Offset: 0x04) Mode Register -------- */ +#define RSWDT_MR_WDV_Pos 0 +#define RSWDT_MR_WDV_Msk (0xfffu << RSWDT_MR_WDV_Pos) /**< \brief (RSWDT_MR) Watchdog Counter Value */ +#define RSWDT_MR_WDV(value) ((RSWDT_MR_WDV_Msk & ((value) << RSWDT_MR_WDV_Pos))) +#define RSWDT_MR_WDFIEN (0x1u << 12) /**< \brief (RSWDT_MR) Watchdog Fault Interrupt Enable */ +#define RSWDT_MR_WDRSTEN (0x1u << 13) /**< \brief (RSWDT_MR) Watchdog Reset Enable */ +#define RSWDT_MR_WDRPROC (0x1u << 14) /**< \brief (RSWDT_MR) Watchdog Reset Processor */ +#define RSWDT_MR_WDDIS (0x1u << 15) /**< \brief (RSWDT_MR) Watchdog Disable */ +#define RSWDT_MR_WDD_Pos 16 +#define RSWDT_MR_WDD_Msk (0xfffu << RSWDT_MR_WDD_Pos) /**< \brief (RSWDT_MR) Watchdog Delta Value */ +#define RSWDT_MR_WDD(value) ((RSWDT_MR_WDD_Msk & ((value) << RSWDT_MR_WDD_Pos))) +#define RSWDT_MR_WDDBGHLT (0x1u << 28) /**< \brief (RSWDT_MR) Watchdog Debug Halt */ +#define RSWDT_MR_WDIDLEHLT (0x1u << 29) /**< \brief (RSWDT_MR) Watchdog Idle Halt */ +/* -------- RSWDT_SR : (RSWDT Offset: 0x08) Status Register -------- */ +#define RSWDT_SR_WDUNF (0x1u << 0) /**< \brief (RSWDT_SR) Watchdog Underflow */ +#define RSWDT_SR_WDERR (0x1u << 1) /**< \brief (RSWDT_SR) Watchdog Error */ + +/*@}*/ + + +#endif /* _SAM4E_RSWDT_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtc.h new file mode 100644 index 0000000..56c0737 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtc.h @@ -0,0 +1,234 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RTC_COMPONENT_ +#define _SAM4E_RTC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Real-time Clock */ +/* ============================================================================= */ +/** \addtogroup SAM4E_RTC Real-time Clock */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Rtc hardware registers */ +typedef struct { + __IO uint32_t RTC_CR; /**< \brief (Rtc Offset: 0x00) Control Register */ + __IO uint32_t RTC_MR; /**< \brief (Rtc Offset: 0x04) Mode Register */ + __IO uint32_t RTC_TIMR; /**< \brief (Rtc Offset: 0x08) Time Register */ + __IO uint32_t RTC_CALR; /**< \brief (Rtc Offset: 0x0C) Calendar Register */ + __IO uint32_t RTC_TIMALR; /**< \brief (Rtc Offset: 0x10) Time Alarm Register */ + __IO uint32_t RTC_CALALR; /**< \brief (Rtc Offset: 0x14) Calendar Alarm Register */ + __I uint32_t RTC_SR; /**< \brief (Rtc Offset: 0x18) Status Register */ + __O uint32_t RTC_SCCR; /**< \brief (Rtc Offset: 0x1C) Status Clear Command Register */ + __O uint32_t RTC_IER; /**< \brief (Rtc Offset: 0x20) Interrupt Enable Register */ + __O uint32_t RTC_IDR; /**< \brief (Rtc Offset: 0x24) Interrupt Disable Register */ + __I uint32_t RTC_IMR; /**< \brief (Rtc Offset: 0x28) Interrupt Mask Register */ + __I uint32_t RTC_VER; /**< \brief (Rtc Offset: 0x2C) Valid Entry Register */ +} Rtc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- RTC_CR : (RTC Offset: 0x00) Control Register -------- */ +#define RTC_CR_UPDTIM (0x1u << 0) /**< \brief (RTC_CR) Update Request Time Register */ +#define RTC_CR_UPDCAL (0x1u << 1) /**< \brief (RTC_CR) Update Request Calendar Register */ +#define RTC_CR_TIMEVSEL_Pos 8 +#define RTC_CR_TIMEVSEL_Msk (0x3u << RTC_CR_TIMEVSEL_Pos) /**< \brief (RTC_CR) Time Event Selection */ +#define RTC_CR_TIMEVSEL_MINUTE (0x0u << 8) /**< \brief (RTC_CR) Minute change */ +#define RTC_CR_TIMEVSEL_HOUR (0x1u << 8) /**< \brief (RTC_CR) Hour change */ +#define RTC_CR_TIMEVSEL_MIDNIGHT (0x2u << 8) /**< \brief (RTC_CR) Every day at midnight */ +#define RTC_CR_TIMEVSEL_NOON (0x3u << 8) /**< \brief (RTC_CR) Every day at noon */ +#define RTC_CR_CALEVSEL_Pos 16 +#define RTC_CR_CALEVSEL_Msk (0x3u << RTC_CR_CALEVSEL_Pos) /**< \brief (RTC_CR) Calendar Event Selection */ +#define RTC_CR_CALEVSEL_WEEK (0x0u << 16) /**< \brief (RTC_CR) Week change (every Monday at time 00:00:00) */ +#define RTC_CR_CALEVSEL_MONTH (0x1u << 16) /**< \brief (RTC_CR) Month change (every 01 of each month at time 00:00:00) */ +#define RTC_CR_CALEVSEL_YEAR (0x2u << 16) /**< \brief (RTC_CR) Year change (every January 1 at time 00:00:00) */ +/* -------- RTC_MR : (RTC Offset: 0x04) Mode Register -------- */ +#define RTC_MR_HRMOD (0x1u << 0) /**< \brief (RTC_MR) 12-/24-hour Mode */ +#define RTC_MR_PERSIAN (0x1u << 1) /**< \brief (RTC_MR) PERSIAN Calendar */ +#define RTC_MR_NEGPPM (0x1u << 4) /**< \brief (RTC_MR) NEGative PPM Correction */ +#define RTC_MR_CORRECTION_Pos 8 +#define RTC_MR_CORRECTION_Msk (0x7fu << RTC_MR_CORRECTION_Pos) /**< \brief (RTC_MR) Slow Clock Correction */ +#define RTC_MR_CORRECTION(value) ((RTC_MR_CORRECTION_Msk & ((value) << RTC_MR_CORRECTION_Pos))) +#define RTC_MR_HIGHPPM (0x1u << 15) /**< \brief (RTC_MR) HIGH PPM Correction */ +#define RTC_MR_OUT0_Pos 16 +#define RTC_MR_OUT0_Msk (0x7u << RTC_MR_OUT0_Pos) /**< \brief (RTC_MR) RTCOUT0 OutputSource Selection */ +#define RTC_MR_OUT0_NO_WAVE (0x0u << 16) /**< \brief (RTC_MR) No waveform, stuck at '0' */ +#define RTC_MR_OUT0_FREQ1HZ (0x1u << 16) /**< \brief (RTC_MR) 1 Hz square wave */ +#define RTC_MR_OUT0_FREQ32HZ (0x2u << 16) /**< \brief (RTC_MR) 32 Hz square wave */ +#define RTC_MR_OUT0_FREQ64HZ (0x3u << 16) /**< \brief (RTC_MR) 64 Hz square wave */ +#define RTC_MR_OUT0_FREQ512HZ (0x4u << 16) /**< \brief (RTC_MR) 512 Hz square wave */ +#define RTC_MR_OUT0_ALARM_TOGGLE (0x5u << 16) /**< \brief (RTC_MR) Output toggles when alarm flag rises */ +#define RTC_MR_OUT0_ALARM_FLAG (0x6u << 16) /**< \brief (RTC_MR) Output is a copy of the alarm flag */ +#define RTC_MR_OUT0_PROG_PULSE (0x7u << 16) /**< \brief (RTC_MR) Duty cycle programmable pulse */ +#define RTC_MR_OUT1_Pos 20 +#define RTC_MR_OUT1_Msk (0x7u << RTC_MR_OUT1_Pos) /**< \brief (RTC_MR) RTCOUT1 Output Source Selection */ +#define RTC_MR_OUT1_NO_WAVE (0x0u << 20) /**< \brief (RTC_MR) No waveform, stuck at '0' */ +#define RTC_MR_OUT1_FREQ1HZ (0x1u << 20) /**< \brief (RTC_MR) 1 Hz square wave */ +#define RTC_MR_OUT1_FREQ32HZ (0x2u << 20) /**< \brief (RTC_MR) 32 Hz square wave */ +#define RTC_MR_OUT1_FREQ64HZ (0x3u << 20) /**< \brief (RTC_MR) 64 Hz square wave */ +#define RTC_MR_OUT1_FREQ512HZ (0x4u << 20) /**< \brief (RTC_MR) 512 Hz square wave */ +#define RTC_MR_OUT1_ALARM_TOGGLE (0x5u << 20) /**< \brief (RTC_MR) Output toggles when alarm flag rises */ +#define RTC_MR_OUT1_ALARM_FLAG (0x6u << 20) /**< \brief (RTC_MR) Output is a copy of the alarm flag */ +#define RTC_MR_OUT1_PROG_PULSE (0x7u << 20) /**< \brief (RTC_MR) Duty cycle programmable pulse */ +#define RTC_MR_THIGH_Pos 24 +#define RTC_MR_THIGH_Msk (0x7u << RTC_MR_THIGH_Pos) /**< \brief (RTC_MR) High Duration of the Output Pulse */ +#define RTC_MR_THIGH_H_31MS (0x0u << 24) /**< \brief (RTC_MR) 31.2 ms */ +#define RTC_MR_THIGH_H_16MS (0x1u << 24) /**< \brief (RTC_MR) 15.6 ms */ +#define RTC_MR_THIGH_H_4MS (0x2u << 24) /**< \brief (RTC_MR) 3.91 ms */ +#define RTC_MR_THIGH_H_976US (0x3u << 24) /**< \brief (RTC_MR) 976 us */ +#define RTC_MR_THIGH_H_488US (0x4u << 24) /**< \brief (RTC_MR) 488 us */ +#define RTC_MR_THIGH_H_122US (0x5u << 24) /**< \brief (RTC_MR) 122 us */ +#define RTC_MR_THIGH_H_30US (0x6u << 24) /**< \brief (RTC_MR) 30.5 us */ +#define RTC_MR_THIGH_H_15US (0x7u << 24) /**< \brief (RTC_MR) 15.2 us */ +#define RTC_MR_TPERIOD_Pos 28 +#define RTC_MR_TPERIOD_Msk (0x3u << RTC_MR_TPERIOD_Pos) /**< \brief (RTC_MR) Period of the Output Pulse */ +#define RTC_MR_TPERIOD_P_1S (0x0u << 28) /**< \brief (RTC_MR) 1 second */ +#define RTC_MR_TPERIOD_P_500MS (0x1u << 28) /**< \brief (RTC_MR) 500 ms */ +#define RTC_MR_TPERIOD_P_250MS (0x2u << 28) /**< \brief (RTC_MR) 250 ms */ +#define RTC_MR_TPERIOD_P_125MS (0x3u << 28) /**< \brief (RTC_MR) 125 ms */ +/* -------- RTC_TIMR : (RTC Offset: 0x08) Time Register -------- */ +#define RTC_TIMR_SEC_Pos 0 +#define RTC_TIMR_SEC_Msk (0x7fu << RTC_TIMR_SEC_Pos) /**< \brief (RTC_TIMR) Current Second */ +#define RTC_TIMR_SEC(value) ((RTC_TIMR_SEC_Msk & ((value) << RTC_TIMR_SEC_Pos))) +#define RTC_TIMR_MIN_Pos 8 +#define RTC_TIMR_MIN_Msk (0x7fu << RTC_TIMR_MIN_Pos) /**< \brief (RTC_TIMR) Current Minute */ +#define RTC_TIMR_MIN(value) ((RTC_TIMR_MIN_Msk & ((value) << RTC_TIMR_MIN_Pos))) +#define RTC_TIMR_HOUR_Pos 16 +#define RTC_TIMR_HOUR_Msk (0x3fu << RTC_TIMR_HOUR_Pos) /**< \brief (RTC_TIMR) Current Hour */ +#define RTC_TIMR_HOUR(value) ((RTC_TIMR_HOUR_Msk & ((value) << RTC_TIMR_HOUR_Pos))) +#define RTC_TIMR_AMPM (0x1u << 22) /**< \brief (RTC_TIMR) Ante Meridiem Post Meridiem Indicator */ +/* -------- RTC_CALR : (RTC Offset: 0x0C) Calendar Register -------- */ +#define RTC_CALR_CENT_Pos 0 +#define RTC_CALR_CENT_Msk (0x7fu << RTC_CALR_CENT_Pos) /**< \brief (RTC_CALR) Current Century */ +#define RTC_CALR_CENT(value) ((RTC_CALR_CENT_Msk & ((value) << RTC_CALR_CENT_Pos))) +#define RTC_CALR_YEAR_Pos 8 +#define RTC_CALR_YEAR_Msk (0xffu << RTC_CALR_YEAR_Pos) /**< \brief (RTC_CALR) Current Year */ +#define RTC_CALR_YEAR(value) ((RTC_CALR_YEAR_Msk & ((value) << RTC_CALR_YEAR_Pos))) +#define RTC_CALR_MONTH_Pos 16 +#define RTC_CALR_MONTH_Msk (0x1fu << RTC_CALR_MONTH_Pos) /**< \brief (RTC_CALR) Current Month */ +#define RTC_CALR_MONTH(value) ((RTC_CALR_MONTH_Msk & ((value) << RTC_CALR_MONTH_Pos))) +#define RTC_CALR_DAY_Pos 21 +#define RTC_CALR_DAY_Msk (0x7u << RTC_CALR_DAY_Pos) /**< \brief (RTC_CALR) Current Day in Current Week */ +#define RTC_CALR_DAY(value) ((RTC_CALR_DAY_Msk & ((value) << RTC_CALR_DAY_Pos))) +#define RTC_CALR_DATE_Pos 24 +#define RTC_CALR_DATE_Msk (0x3fu << RTC_CALR_DATE_Pos) /**< \brief (RTC_CALR) Current Day in Current Month */ +#define RTC_CALR_DATE(value) ((RTC_CALR_DATE_Msk & ((value) << RTC_CALR_DATE_Pos))) +/* -------- RTC_TIMALR : (RTC Offset: 0x10) Time Alarm Register -------- */ +#define RTC_TIMALR_SEC_Pos 0 +#define RTC_TIMALR_SEC_Msk (0x7fu << RTC_TIMALR_SEC_Pos) /**< \brief (RTC_TIMALR) Second Alarm */ +#define RTC_TIMALR_SEC(value) ((RTC_TIMALR_SEC_Msk & ((value) << RTC_TIMALR_SEC_Pos))) +#define RTC_TIMALR_SECEN (0x1u << 7) /**< \brief (RTC_TIMALR) Second Alarm Enable */ +#define RTC_TIMALR_MIN_Pos 8 +#define RTC_TIMALR_MIN_Msk (0x7fu << RTC_TIMALR_MIN_Pos) /**< \brief (RTC_TIMALR) Minute Alarm */ +#define RTC_TIMALR_MIN(value) ((RTC_TIMALR_MIN_Msk & ((value) << RTC_TIMALR_MIN_Pos))) +#define RTC_TIMALR_MINEN (0x1u << 15) /**< \brief (RTC_TIMALR) Minute Alarm Enable */ +#define RTC_TIMALR_HOUR_Pos 16 +#define RTC_TIMALR_HOUR_Msk (0x3fu << RTC_TIMALR_HOUR_Pos) /**< \brief (RTC_TIMALR) Hour Alarm */ +#define RTC_TIMALR_HOUR(value) ((RTC_TIMALR_HOUR_Msk & ((value) << RTC_TIMALR_HOUR_Pos))) +#define RTC_TIMALR_AMPM (0x1u << 22) /**< \brief (RTC_TIMALR) AM/PM Indicator */ +#define RTC_TIMALR_HOUREN (0x1u << 23) /**< \brief (RTC_TIMALR) Hour Alarm Enable */ +/* -------- RTC_CALALR : (RTC Offset: 0x14) Calendar Alarm Register -------- */ +#define RTC_CALALR_MONTH_Pos 16 +#define RTC_CALALR_MONTH_Msk (0x1fu << RTC_CALALR_MONTH_Pos) /**< \brief (RTC_CALALR) Month Alarm */ +#define RTC_CALALR_MONTH(value) ((RTC_CALALR_MONTH_Msk & ((value) << RTC_CALALR_MONTH_Pos))) +#define RTC_CALALR_MTHEN (0x1u << 23) /**< \brief (RTC_CALALR) Month Alarm Enable */ +#define RTC_CALALR_DATE_Pos 24 +#define RTC_CALALR_DATE_Msk (0x3fu << RTC_CALALR_DATE_Pos) /**< \brief (RTC_CALALR) Date Alarm */ +#define RTC_CALALR_DATE(value) ((RTC_CALALR_DATE_Msk & ((value) << RTC_CALALR_DATE_Pos))) +#define RTC_CALALR_DATEEN (0x1u << 31) /**< \brief (RTC_CALALR) Date Alarm Enable */ +/* -------- RTC_SR : (RTC Offset: 0x18) Status Register -------- */ +#define RTC_SR_ACKUPD (0x1u << 0) /**< \brief (RTC_SR) Acknowledge for Update */ +#define RTC_SR_ACKUPD_FREERUN (0x0u << 0) /**< \brief (RTC_SR) Time and calendar registers cannot be updated. */ +#define RTC_SR_ACKUPD_UPDATE (0x1u << 0) /**< \brief (RTC_SR) Time and calendar registers can be updated. */ +#define RTC_SR_ALARM (0x1u << 1) /**< \brief (RTC_SR) Alarm Flag */ +#define RTC_SR_ALARM_NO_ALARMEVENT (0x0u << 1) /**< \brief (RTC_SR) No alarm matching condition occurred. */ +#define RTC_SR_ALARM_ALARMEVENT (0x1u << 1) /**< \brief (RTC_SR) An alarm matching condition has occurred. */ +#define RTC_SR_SEC (0x1u << 2) /**< \brief (RTC_SR) Second Event */ +#define RTC_SR_SEC_NO_SECEVENT (0x0u << 2) /**< \brief (RTC_SR) No second event has occurred since the last clear. */ +#define RTC_SR_SEC_SECEVENT (0x1u << 2) /**< \brief (RTC_SR) At least one second event has occurred since the last clear. */ +#define RTC_SR_TIMEV (0x1u << 3) /**< \brief (RTC_SR) Time Event */ +#define RTC_SR_TIMEV_NO_TIMEVENT (0x0u << 3) /**< \brief (RTC_SR) No time event has occurred since the last clear. */ +#define RTC_SR_TIMEV_TIMEVENT (0x1u << 3) /**< \brief (RTC_SR) At least one time event has occurred since the last clear. */ +#define RTC_SR_CALEV (0x1u << 4) /**< \brief (RTC_SR) Calendar Event */ +#define RTC_SR_CALEV_NO_CALEVENT (0x0u << 4) /**< \brief (RTC_SR) No calendar event has occurred since the last clear. */ +#define RTC_SR_CALEV_CALEVENT (0x1u << 4) /**< \brief (RTC_SR) At least one calendar event has occurred since the last clear. */ +#define RTC_SR_TDERR (0x1u << 5) /**< \brief (RTC_SR) Time and/or Date Free Running Error */ +#define RTC_SR_TDERR_CORRECT (0x0u << 5) /**< \brief (RTC_SR) The internal free running counters are carrying valid values since the last read of the Status Register (RTC_SR). */ +#define RTC_SR_TDERR_ERR_TIMEDATE (0x1u << 5) /**< \brief (RTC_SR) The internal free running counters have been corrupted (invalid date or time, non-BCD values) since the last read and/or they are still invalid. */ +/* -------- RTC_SCCR : (RTC Offset: 0x1C) Status Clear Command Register -------- */ +#define RTC_SCCR_ACKCLR (0x1u << 0) /**< \brief (RTC_SCCR) Acknowledge Clear */ +#define RTC_SCCR_ALRCLR (0x1u << 1) /**< \brief (RTC_SCCR) Alarm Clear */ +#define RTC_SCCR_SECCLR (0x1u << 2) /**< \brief (RTC_SCCR) Second Clear */ +#define RTC_SCCR_TIMCLR (0x1u << 3) /**< \brief (RTC_SCCR) Time Clear */ +#define RTC_SCCR_CALCLR (0x1u << 4) /**< \brief (RTC_SCCR) Calendar Clear */ +#define RTC_SCCR_TDERRCLR (0x1u << 5) /**< \brief (RTC_SCCR) Time and/or Date Free Running Error Clear */ +/* -------- RTC_IER : (RTC Offset: 0x20) Interrupt Enable Register -------- */ +#define RTC_IER_ACKEN (0x1u << 0) /**< \brief (RTC_IER) Acknowledge Update Interrupt Enable */ +#define RTC_IER_ALREN (0x1u << 1) /**< \brief (RTC_IER) Alarm Interrupt Enable */ +#define RTC_IER_SECEN (0x1u << 2) /**< \brief (RTC_IER) Second Event Interrupt Enable */ +#define RTC_IER_TIMEN (0x1u << 3) /**< \brief (RTC_IER) Time Event Interrupt Enable */ +#define RTC_IER_CALEN (0x1u << 4) /**< \brief (RTC_IER) Calendar Event Interrupt Enable */ +#define RTC_IER_TDERREN (0x1u << 5) /**< \brief (RTC_IER) Time and/or Date Error Interrupt Enable */ +/* -------- RTC_IDR : (RTC Offset: 0x24) Interrupt Disable Register -------- */ +#define RTC_IDR_ACKDIS (0x1u << 0) /**< \brief (RTC_IDR) Acknowledge Update Interrupt Disable */ +#define RTC_IDR_ALRDIS (0x1u << 1) /**< \brief (RTC_IDR) Alarm Interrupt Disable */ +#define RTC_IDR_SECDIS (0x1u << 2) /**< \brief (RTC_IDR) Second Event Interrupt Disable */ +#define RTC_IDR_TIMDIS (0x1u << 3) /**< \brief (RTC_IDR) Time Event Interrupt Disable */ +#define RTC_IDR_CALDIS (0x1u << 4) /**< \brief (RTC_IDR) Calendar Event Interrupt Disable */ +#define RTC_IDR_TDERRDIS (0x1u << 5) /**< \brief (RTC_IDR) Time and/or Date Error Interrupt Disable */ +/* -------- RTC_IMR : (RTC Offset: 0x28) Interrupt Mask Register -------- */ +#define RTC_IMR_ACK (0x1u << 0) /**< \brief (RTC_IMR) Acknowledge Update Interrupt Mask */ +#define RTC_IMR_ALR (0x1u << 1) /**< \brief (RTC_IMR) Alarm Interrupt Mask */ +#define RTC_IMR_SEC (0x1u << 2) /**< \brief (RTC_IMR) Second Event Interrupt Mask */ +#define RTC_IMR_TIM (0x1u << 3) /**< \brief (RTC_IMR) Time Event Interrupt Mask */ +#define RTC_IMR_CAL (0x1u << 4) /**< \brief (RTC_IMR) Calendar Event Interrupt Mask */ +/* -------- RTC_VER : (RTC Offset: 0x2C) Valid Entry Register -------- */ +#define RTC_VER_NVTIM (0x1u << 0) /**< \brief (RTC_VER) Non-valid Time */ +#define RTC_VER_NVCAL (0x1u << 1) /**< \brief (RTC_VER) Non-valid Calendar */ +#define RTC_VER_NVTIMALR (0x1u << 2) /**< \brief (RTC_VER) Non-valid Time Alarm */ +#define RTC_VER_NVCALALR (0x1u << 3) /**< \brief (RTC_VER) Non-valid Calendar Alarm */ + +/*@}*/ + + +#endif /* _SAM4E_RTC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtt.h new file mode 100644 index 0000000..ff6a4a6 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/rtt.h @@ -0,0 +1,86 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RTT_COMPONENT_ +#define _SAM4E_RTT_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Real-time Timer */ +/* ============================================================================= */ +/** \addtogroup SAM4E_RTT Real-time Timer */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Rtt hardware registers */ +typedef struct { + __IO uint32_t RTT_MR; /**< \brief (Rtt Offset: 0x00) Mode Register */ + __IO uint32_t RTT_AR; /**< \brief (Rtt Offset: 0x04) Alarm Register */ + __I uint32_t RTT_VR; /**< \brief (Rtt Offset: 0x08) Value Register */ + __I uint32_t RTT_SR; /**< \brief (Rtt Offset: 0x0C) Status Register */ +} Rtt; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- RTT_MR : (RTT Offset: 0x00) Mode Register -------- */ +#define RTT_MR_RTPRES_Pos 0 +#define RTT_MR_RTPRES_Msk (0xffffu << RTT_MR_RTPRES_Pos) /**< \brief (RTT_MR) Real-time Timer Prescaler Value */ +#define RTT_MR_RTPRES(value) ((RTT_MR_RTPRES_Msk & ((value) << RTT_MR_RTPRES_Pos))) +#define RTT_MR_ALMIEN (0x1u << 16) /**< \brief (RTT_MR) Alarm Interrupt Enable */ +#define RTT_MR_RTTINCIEN (0x1u << 17) /**< \brief (RTT_MR) Real-time Timer Increment Interrupt Enable */ +#define RTT_MR_RTTRST (0x1u << 18) /**< \brief (RTT_MR) Real-time Timer Restart */ +#define RTT_MR_RTTDIS (0x1u << 20) /**< \brief (RTT_MR) Real-time Timer Disable */ +#define RTT_MR_RTC1HZ (0x1u << 24) /**< \brief (RTT_MR) Real-Time Clock 1Hz Clock Selection */ +/* -------- RTT_AR : (RTT Offset: 0x04) Alarm Register -------- */ +#define RTT_AR_ALMV_Pos 0 +#define RTT_AR_ALMV_Msk (0xffffffffu << RTT_AR_ALMV_Pos) /**< \brief (RTT_AR) Alarm Value */ +#define RTT_AR_ALMV(value) ((RTT_AR_ALMV_Msk & ((value) << RTT_AR_ALMV_Pos))) +/* -------- RTT_VR : (RTT Offset: 0x08) Value Register -------- */ +#define RTT_VR_CRTV_Pos 0 +#define RTT_VR_CRTV_Msk (0xffffffffu << RTT_VR_CRTV_Pos) /**< \brief (RTT_VR) Current Real-time Value */ +/* -------- RTT_SR : (RTT Offset: 0x0C) Status Register -------- */ +#define RTT_SR_ALMS (0x1u << 0) /**< \brief (RTT_SR) Real-time Alarm Status */ +#define RTT_SR_RTTINC (0x1u << 1) /**< \brief (RTT_SR) Prescaler Roll-over Status */ + +/*@}*/ + + +#endif /* _SAM4E_RTT_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/smc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/smc.h new file mode 100644 index 0000000..d0f7207 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/smc.h @@ -0,0 +1,154 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SMC_COMPONENT_ +#define _SAM4E_SMC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Static Memory Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_SMC Static Memory Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief SmcCs_number hardware registers */ +typedef struct { + __IO uint32_t SMC_SETUP; /**< \brief (SmcCs_number Offset: 0x0) SMC Setup Register */ + __IO uint32_t SMC_PULSE; /**< \brief (SmcCs_number Offset: 0x4) SMC Pulse Register */ + __IO uint32_t SMC_CYCLE; /**< \brief (SmcCs_number Offset: 0x8) SMC Cycle Register */ + __IO uint32_t SMC_MODE; /**< \brief (SmcCs_number Offset: 0xC) SMC Mode Register */ +} SmcCs_number; +/** \brief Smc hardware registers */ +#define SMCCS_NUMBER_NUMBER 4 +typedef struct { + SmcCs_number SMC_CS_NUMBER[SMCCS_NUMBER_NUMBER]; /**< \brief (Smc Offset: 0x0) CS_number = 0 .. 3 */ + __I uint32_t Reserved1[16]; + __IO uint32_t SMC_OCMS; /**< \brief (Smc Offset: 0x80) SMC OCMS MODE Register */ + __O uint32_t SMC_KEY1; /**< \brief (Smc Offset: 0x84) SMC OCMS KEY1 Register */ + __O uint32_t SMC_KEY2; /**< \brief (Smc Offset: 0x88) SMC OCMS KEY2 Register */ + __I uint32_t Reserved2[22]; + __IO uint32_t SMC_WPMR; /**< \brief (Smc Offset: 0xE4) SMC Write Protect Mode Register */ + __I uint32_t SMC_WPSR; /**< \brief (Smc Offset: 0xE8) SMC Write Protect Status Register */ +} Smc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- SMC_SETUP : (SMC Offset: N/A) SMC Setup Register -------- */ +#define SMC_SETUP_NWE_SETUP_Pos 0 +#define SMC_SETUP_NWE_SETUP_Msk (0x3fu << SMC_SETUP_NWE_SETUP_Pos) /**< \brief (SMC_SETUP) NWE Setup Length */ +#define SMC_SETUP_NWE_SETUP(value) ((SMC_SETUP_NWE_SETUP_Msk & ((value) << SMC_SETUP_NWE_SETUP_Pos))) +#define SMC_SETUP_NCS_WR_SETUP_Pos 8 +#define SMC_SETUP_NCS_WR_SETUP_Msk (0x3fu << SMC_SETUP_NCS_WR_SETUP_Pos) /**< \brief (SMC_SETUP) NCS Setup Length in WRITE Access */ +#define SMC_SETUP_NCS_WR_SETUP(value) ((SMC_SETUP_NCS_WR_SETUP_Msk & ((value) << SMC_SETUP_NCS_WR_SETUP_Pos))) +#define SMC_SETUP_NRD_SETUP_Pos 16 +#define SMC_SETUP_NRD_SETUP_Msk (0x3fu << SMC_SETUP_NRD_SETUP_Pos) /**< \brief (SMC_SETUP) NRD Setup Length */ +#define SMC_SETUP_NRD_SETUP(value) ((SMC_SETUP_NRD_SETUP_Msk & ((value) << SMC_SETUP_NRD_SETUP_Pos))) +#define SMC_SETUP_NCS_RD_SETUP_Pos 24 +#define SMC_SETUP_NCS_RD_SETUP_Msk (0x3fu << SMC_SETUP_NCS_RD_SETUP_Pos) /**< \brief (SMC_SETUP) NCS Setup Length in READ Access */ +#define SMC_SETUP_NCS_RD_SETUP(value) ((SMC_SETUP_NCS_RD_SETUP_Msk & ((value) << SMC_SETUP_NCS_RD_SETUP_Pos))) +/* -------- SMC_PULSE : (SMC Offset: N/A) SMC Pulse Register -------- */ +#define SMC_PULSE_NWE_PULSE_Pos 0 +#define SMC_PULSE_NWE_PULSE_Msk (0x7fu << SMC_PULSE_NWE_PULSE_Pos) /**< \brief (SMC_PULSE) NWE Pulse Length */ +#define SMC_PULSE_NWE_PULSE(value) ((SMC_PULSE_NWE_PULSE_Msk & ((value) << SMC_PULSE_NWE_PULSE_Pos))) +#define SMC_PULSE_NCS_WR_PULSE_Pos 8 +#define SMC_PULSE_NCS_WR_PULSE_Msk (0x7fu << SMC_PULSE_NCS_WR_PULSE_Pos) /**< \brief (SMC_PULSE) NCS Pulse Length in WRITE Access */ +#define SMC_PULSE_NCS_WR_PULSE(value) ((SMC_PULSE_NCS_WR_PULSE_Msk & ((value) << SMC_PULSE_NCS_WR_PULSE_Pos))) +#define SMC_PULSE_NRD_PULSE_Pos 16 +#define SMC_PULSE_NRD_PULSE_Msk (0x7fu << SMC_PULSE_NRD_PULSE_Pos) /**< \brief (SMC_PULSE) NRD Pulse Length */ +#define SMC_PULSE_NRD_PULSE(value) ((SMC_PULSE_NRD_PULSE_Msk & ((value) << SMC_PULSE_NRD_PULSE_Pos))) +#define SMC_PULSE_NCS_RD_PULSE_Pos 24 +#define SMC_PULSE_NCS_RD_PULSE_Msk (0x7fu << SMC_PULSE_NCS_RD_PULSE_Pos) /**< \brief (SMC_PULSE) NCS Pulse Length in READ Access */ +#define SMC_PULSE_NCS_RD_PULSE(value) ((SMC_PULSE_NCS_RD_PULSE_Msk & ((value) << SMC_PULSE_NCS_RD_PULSE_Pos))) +/* -------- SMC_CYCLE : (SMC Offset: N/A) SMC Cycle Register -------- */ +#define SMC_CYCLE_NWE_CYCLE_Pos 0 +#define SMC_CYCLE_NWE_CYCLE_Msk (0x1ffu << SMC_CYCLE_NWE_CYCLE_Pos) /**< \brief (SMC_CYCLE) Total Write Cycle Length */ +#define SMC_CYCLE_NWE_CYCLE(value) ((SMC_CYCLE_NWE_CYCLE_Msk & ((value) << SMC_CYCLE_NWE_CYCLE_Pos))) +#define SMC_CYCLE_NRD_CYCLE_Pos 16 +#define SMC_CYCLE_NRD_CYCLE_Msk (0x1ffu << SMC_CYCLE_NRD_CYCLE_Pos) /**< \brief (SMC_CYCLE) Total Read Cycle Length */ +#define SMC_CYCLE_NRD_CYCLE(value) ((SMC_CYCLE_NRD_CYCLE_Msk & ((value) << SMC_CYCLE_NRD_CYCLE_Pos))) +/* -------- SMC_MODE : (SMC Offset: N/A) SMC Mode Register -------- */ +#define SMC_MODE_READ_MODE (0x1u << 0) /**< \brief (SMC_MODE) */ +#define SMC_MODE_WRITE_MODE (0x1u << 1) /**< \brief (SMC_MODE) */ +#define SMC_MODE_EXNW_MODE_Pos 4 +#define SMC_MODE_EXNW_MODE_Msk (0x3u << SMC_MODE_EXNW_MODE_Pos) /**< \brief (SMC_MODE) NWAIT Mode */ +#define SMC_MODE_EXNW_MODE_DISABLED (0x0u << 4) /**< \brief (SMC_MODE) Disabled */ +#define SMC_MODE_EXNW_MODE_FROZEN (0x2u << 4) /**< \brief (SMC_MODE) Frozen Mode */ +#define SMC_MODE_EXNW_MODE_READY (0x3u << 4) /**< \brief (SMC_MODE) Ready Mode */ +#define SMC_MODE_TDF_CYCLES_Pos 16 +#define SMC_MODE_TDF_CYCLES_Msk (0xfu << SMC_MODE_TDF_CYCLES_Pos) /**< \brief (SMC_MODE) Data Float Time */ +#define SMC_MODE_TDF_CYCLES(value) ((SMC_MODE_TDF_CYCLES_Msk & ((value) << SMC_MODE_TDF_CYCLES_Pos))) +#define SMC_MODE_TDF_MODE (0x1u << 20) /**< \brief (SMC_MODE) TDF Optimization */ +#define SMC_MODE_PMEN (0x1u << 24) /**< \brief (SMC_MODE) Page Mode Enabled */ +#define SMC_MODE_PS_Pos 28 +#define SMC_MODE_PS_Msk (0x3u << SMC_MODE_PS_Pos) /**< \brief (SMC_MODE) Page Size */ +#define SMC_MODE_PS_4_BYTE (0x0u << 28) /**< \brief (SMC_MODE) 4-byte page */ +#define SMC_MODE_PS_8_BYTE (0x1u << 28) /**< \brief (SMC_MODE) 8-byte page */ +#define SMC_MODE_PS_16_BYTE (0x2u << 28) /**< \brief (SMC_MODE) 16-byte page */ +#define SMC_MODE_PS_32_BYTE (0x3u << 28) /**< \brief (SMC_MODE) 32-byte page */ +/* -------- SMC_OCMS : (SMC Offset: 0x80) SMC OCMS MODE Register -------- */ +#define SMC_OCMS_SMSE (0x1u << 0) /**< \brief (SMC_OCMS) Static Memory Controller Scrambling Enable */ +#define SMC_OCMS_CS0SE (0x1u << 16) /**< \brief (SMC_OCMS) Chip Select (x = 0 to 3) Scrambling Enable */ +#define SMC_OCMS_CS1SE (0x1u << 17) /**< \brief (SMC_OCMS) Chip Select (x = 0 to 3) Scrambling Enable */ +#define SMC_OCMS_CS2SE (0x1u << 18) /**< \brief (SMC_OCMS) Chip Select (x = 0 to 3) Scrambling Enable */ +#define SMC_OCMS_CS3SE (0x1u << 19) /**< \brief (SMC_OCMS) Chip Select (x = 0 to 3) Scrambling Enable */ +/* -------- SMC_KEY1 : (SMC Offset: 0x84) SMC OCMS KEY1 Register -------- */ +#define SMC_KEY1_KEY1_Pos 0 +#define SMC_KEY1_KEY1_Msk (0xffffffffu << SMC_KEY1_KEY1_Pos) /**< \brief (SMC_KEY1) Off Chip Memory Scrambling (OCMS) Key Part 1 */ +#define SMC_KEY1_KEY1(value) ((SMC_KEY1_KEY1_Msk & ((value) << SMC_KEY1_KEY1_Pos))) +/* -------- SMC_KEY2 : (SMC Offset: 0x88) SMC OCMS KEY2 Register -------- */ +#define SMC_KEY2_KEY2_Pos 0 +#define SMC_KEY2_KEY2_Msk (0xffffffffu << SMC_KEY2_KEY2_Pos) /**< \brief (SMC_KEY2) Off Chip Memory Scrambling (OCMS) Key Part 2 */ +#define SMC_KEY2_KEY2(value) ((SMC_KEY2_KEY2_Msk & ((value) << SMC_KEY2_KEY2_Pos))) +/* -------- SMC_WPMR : (SMC Offset: 0xE4) SMC Write Protect Mode Register -------- */ +#define SMC_WPMR_WPEN (0x1u << 0) /**< \brief (SMC_WPMR) Write Protect Enable */ +#define SMC_WPMR_WPKEY_Pos 8 +#define SMC_WPMR_WPKEY_Msk (0xffffffu << SMC_WPMR_WPKEY_Pos) /**< \brief (SMC_WPMR) Write Protect KEY */ +#define SMC_WPMR_WPKEY(value) ((SMC_WPMR_WPKEY_Msk & ((value) << SMC_WPMR_WPKEY_Pos))) +/* -------- SMC_WPSR : (SMC Offset: 0xE8) SMC Write Protect Status Register -------- */ +#define SMC_WPSR_WPVS (0x1u << 0) /**< \brief (SMC_WPSR) Write Protect Enable */ +#define SMC_WPSR_WPVSRC_Pos 8 +#define SMC_WPSR_WPVSRC_Msk (0xffffu << SMC_WPSR_WPVSRC_Pos) /**< \brief (SMC_WPSR) Write Protect Violation Source */ + +/*@}*/ + + +#endif /* _SAM4E_SMC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/spi.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/spi.h new file mode 100644 index 0000000..c50f227 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/spi.h @@ -0,0 +1,241 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SPI_COMPONENT_ +#define _SAM4E_SPI_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Serial Peripheral Interface */ +/* ============================================================================= */ +/** \addtogroup SAM4E_SPI Serial Peripheral Interface */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Spi hardware registers */ +typedef struct { + __O uint32_t SPI_CR; /**< \brief (Spi Offset: 0x00) Control Register */ + __IO uint32_t SPI_MR; /**< \brief (Spi Offset: 0x04) Mode Register */ + __I uint32_t SPI_RDR; /**< \brief (Spi Offset: 0x08) Receive Data Register */ + __O uint32_t SPI_TDR; /**< \brief (Spi Offset: 0x0C) Transmit Data Register */ + __I uint32_t SPI_SR; /**< \brief (Spi Offset: 0x10) Status Register */ + __O uint32_t SPI_IER; /**< \brief (Spi Offset: 0x14) Interrupt Enable Register */ + __O uint32_t SPI_IDR; /**< \brief (Spi Offset: 0x18) Interrupt Disable Register */ + __I uint32_t SPI_IMR; /**< \brief (Spi Offset: 0x1C) Interrupt Mask Register */ + __I uint32_t Reserved1[4]; + __IO uint32_t SPI_CSR[4]; /**< \brief (Spi Offset: 0x30) Chip Select Register */ + __I uint32_t Reserved2[41]; + __IO uint32_t SPI_WPMR; /**< \brief (Spi Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t SPI_WPSR; /**< \brief (Spi Offset: 0xE8) Write Protection Status Register */ + __I uint32_t Reserved3[5]; + __IO uint32_t SPI_RPR; /**< \brief (Spi Offset: 0x100) Receive Pointer Register */ + __IO uint32_t SPI_RCR; /**< \brief (Spi Offset: 0x104) Receive Counter Register */ + __IO uint32_t SPI_TPR; /**< \brief (Spi Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t SPI_TCR; /**< \brief (Spi Offset: 0x10C) Transmit Counter Register */ + __IO uint32_t SPI_RNPR; /**< \brief (Spi Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t SPI_RNCR; /**< \brief (Spi Offset: 0x114) Receive Next Counter Register */ + __IO uint32_t SPI_TNPR; /**< \brief (Spi Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t SPI_TNCR; /**< \brief (Spi Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t SPI_PTCR; /**< \brief (Spi Offset: 0x120) Transfer Control Register */ + __I uint32_t SPI_PTSR; /**< \brief (Spi Offset: 0x124) Transfer Status Register */ +} Spi; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- SPI_CR : (SPI Offset: 0x00) Control Register -------- */ +#define SPI_CR_SPIEN (0x1u << 0) /**< \brief (SPI_CR) SPI Enable */ +#define SPI_CR_SPIDIS (0x1u << 1) /**< \brief (SPI_CR) SPI Disable */ +#define SPI_CR_SWRST (0x1u << 7) /**< \brief (SPI_CR) SPI Software Reset */ +#define SPI_CR_LASTXFER (0x1u << 24) /**< \brief (SPI_CR) Last Transfer */ +/* -------- SPI_MR : (SPI Offset: 0x04) Mode Register -------- */ +#define SPI_MR_MSTR (0x1u << 0) /**< \brief (SPI_MR) Master/Slave Mode */ +#define SPI_MR_PS (0x1u << 1) /**< \brief (SPI_MR) Peripheral Select */ +#define SPI_MR_PCSDEC (0x1u << 2) /**< \brief (SPI_MR) Chip Select Decode */ +#define SPI_MR_MODFDIS (0x1u << 4) /**< \brief (SPI_MR) Mode Fault Detection */ +#define SPI_MR_WDRBT (0x1u << 5) /**< \brief (SPI_MR) Wait Data Read Before Transfer */ +#define SPI_MR_LLB (0x1u << 7) /**< \brief (SPI_MR) Local Loopback Enable */ +#define SPI_MR_PCS_Pos 16 +#define SPI_MR_PCS_Msk (0xfu << SPI_MR_PCS_Pos) /**< \brief (SPI_MR) Peripheral Chip Select */ +#define SPI_MR_PCS(value) ((SPI_MR_PCS_Msk & ((value) << SPI_MR_PCS_Pos))) +#define SPI_MR_DLYBCS_Pos 24 +#define SPI_MR_DLYBCS_Msk (0xffu << SPI_MR_DLYBCS_Pos) /**< \brief (SPI_MR) Delay Between Chip Selects */ +#define SPI_MR_DLYBCS(value) ((SPI_MR_DLYBCS_Msk & ((value) << SPI_MR_DLYBCS_Pos))) +/* -------- SPI_RDR : (SPI Offset: 0x08) Receive Data Register -------- */ +#define SPI_RDR_RD_Pos 0 +#define SPI_RDR_RD_Msk (0xffffu << SPI_RDR_RD_Pos) /**< \brief (SPI_RDR) Receive Data */ +#define SPI_RDR_PCS_Pos 16 +#define SPI_RDR_PCS_Msk (0xfu << SPI_RDR_PCS_Pos) /**< \brief (SPI_RDR) Peripheral Chip Select */ +/* -------- SPI_TDR : (SPI Offset: 0x0C) Transmit Data Register -------- */ +#define SPI_TDR_TD_Pos 0 +#define SPI_TDR_TD_Msk (0xffffu << SPI_TDR_TD_Pos) /**< \brief (SPI_TDR) Transmit Data */ +#define SPI_TDR_TD(value) ((SPI_TDR_TD_Msk & ((value) << SPI_TDR_TD_Pos))) +#define SPI_TDR_PCS_Pos 16 +#define SPI_TDR_PCS_Msk (0xfu << SPI_TDR_PCS_Pos) /**< \brief (SPI_TDR) Peripheral Chip Select */ +#define SPI_TDR_PCS(value) ((SPI_TDR_PCS_Msk & ((value) << SPI_TDR_PCS_Pos))) +#define SPI_TDR_LASTXFER (0x1u << 24) /**< \brief (SPI_TDR) Last Transfer */ +/* -------- SPI_SR : (SPI Offset: 0x10) Status Register -------- */ +#define SPI_SR_RDRF (0x1u << 0) /**< \brief (SPI_SR) Receive Data Register Full */ +#define SPI_SR_TDRE (0x1u << 1) /**< \brief (SPI_SR) Transmit Data Register Empty */ +#define SPI_SR_MODF (0x1u << 2) /**< \brief (SPI_SR) Mode Fault Error */ +#define SPI_SR_OVRES (0x1u << 3) /**< \brief (SPI_SR) Overrun Error Status */ +#define SPI_SR_ENDRX (0x1u << 4) /**< \brief (SPI_SR) End of RX Buffer */ +#define SPI_SR_ENDTX (0x1u << 5) /**< \brief (SPI_SR) End of TX Buffer */ +#define SPI_SR_RXBUFF (0x1u << 6) /**< \brief (SPI_SR) RX Buffer Full */ +#define SPI_SR_TXBUFE (0x1u << 7) /**< \brief (SPI_SR) TX Buffer Empty */ +#define SPI_SR_NSSR (0x1u << 8) /**< \brief (SPI_SR) NSS Rising */ +#define SPI_SR_TXEMPTY (0x1u << 9) /**< \brief (SPI_SR) Transmission Registers Empty */ +#define SPI_SR_UNDES (0x1u << 10) /**< \brief (SPI_SR) Underrun Error Status (Slave mode Only) */ +#define SPI_SR_SPIENS (0x1u << 16) /**< \brief (SPI_SR) SPI Enable Status */ +/* -------- SPI_IER : (SPI Offset: 0x14) Interrupt Enable Register -------- */ +#define SPI_IER_RDRF (0x1u << 0) /**< \brief (SPI_IER) Receive Data Register Full Interrupt Enable */ +#define SPI_IER_TDRE (0x1u << 1) /**< \brief (SPI_IER) SPI Transmit Data Register Empty Interrupt Enable */ +#define SPI_IER_MODF (0x1u << 2) /**< \brief (SPI_IER) Mode Fault Error Interrupt Enable */ +#define SPI_IER_OVRES (0x1u << 3) /**< \brief (SPI_IER) Overrun Error Interrupt Enable */ +#define SPI_IER_ENDRX (0x1u << 4) /**< \brief (SPI_IER) End of Receive Buffer Interrupt Enable */ +#define SPI_IER_ENDTX (0x1u << 5) /**< \brief (SPI_IER) End of Transmit Buffer Interrupt Enable */ +#define SPI_IER_RXBUFF (0x1u << 6) /**< \brief (SPI_IER) Receive Buffer Full Interrupt Enable */ +#define SPI_IER_TXBUFE (0x1u << 7) /**< \brief (SPI_IER) Transmit Buffer Empty Interrupt Enable */ +#define SPI_IER_NSSR (0x1u << 8) /**< \brief (SPI_IER) NSS Rising Interrupt Enable */ +#define SPI_IER_TXEMPTY (0x1u << 9) /**< \brief (SPI_IER) Transmission Registers Empty Enable */ +#define SPI_IER_UNDES (0x1u << 10) /**< \brief (SPI_IER) Underrun Error Interrupt Enable */ +/* -------- SPI_IDR : (SPI Offset: 0x18) Interrupt Disable Register -------- */ +#define SPI_IDR_RDRF (0x1u << 0) /**< \brief (SPI_IDR) Receive Data Register Full Interrupt Disable */ +#define SPI_IDR_TDRE (0x1u << 1) /**< \brief (SPI_IDR) SPI Transmit Data Register Empty Interrupt Disable */ +#define SPI_IDR_MODF (0x1u << 2) /**< \brief (SPI_IDR) Mode Fault Error Interrupt Disable */ +#define SPI_IDR_OVRES (0x1u << 3) /**< \brief (SPI_IDR) Overrun Error Interrupt Disable */ +#define SPI_IDR_ENDRX (0x1u << 4) /**< \brief (SPI_IDR) End of Receive Buffer Interrupt Disable */ +#define SPI_IDR_ENDTX (0x1u << 5) /**< \brief (SPI_IDR) End of Transmit Buffer Interrupt Disable */ +#define SPI_IDR_RXBUFF (0x1u << 6) /**< \brief (SPI_IDR) Receive Buffer Full Interrupt Disable */ +#define SPI_IDR_TXBUFE (0x1u << 7) /**< \brief (SPI_IDR) Transmit Buffer Empty Interrupt Disable */ +#define SPI_IDR_NSSR (0x1u << 8) /**< \brief (SPI_IDR) NSS Rising Interrupt Disable */ +#define SPI_IDR_TXEMPTY (0x1u << 9) /**< \brief (SPI_IDR) Transmission Registers Empty Disable */ +#define SPI_IDR_UNDES (0x1u << 10) /**< \brief (SPI_IDR) Underrun Error Interrupt Disable */ +/* -------- SPI_IMR : (SPI Offset: 0x1C) Interrupt Mask Register -------- */ +#define SPI_IMR_RDRF (0x1u << 0) /**< \brief (SPI_IMR) Receive Data Register Full Interrupt Mask */ +#define SPI_IMR_TDRE (0x1u << 1) /**< \brief (SPI_IMR) SPI Transmit Data Register Empty Interrupt Mask */ +#define SPI_IMR_MODF (0x1u << 2) /**< \brief (SPI_IMR) Mode Fault Error Interrupt Mask */ +#define SPI_IMR_OVRES (0x1u << 3) /**< \brief (SPI_IMR) Overrun Error Interrupt Mask */ +#define SPI_IMR_ENDRX (0x1u << 4) /**< \brief (SPI_IMR) End of Receive Buffer Interrupt Mask */ +#define SPI_IMR_ENDTX (0x1u << 5) /**< \brief (SPI_IMR) End of Transmit Buffer Interrupt Mask */ +#define SPI_IMR_RXBUFF (0x1u << 6) /**< \brief (SPI_IMR) Receive Buffer Full Interrupt Mask */ +#define SPI_IMR_TXBUFE (0x1u << 7) /**< \brief (SPI_IMR) Transmit Buffer Empty Interrupt Mask */ +#define SPI_IMR_NSSR (0x1u << 8) /**< \brief (SPI_IMR) NSS Rising Interrupt Mask */ +#define SPI_IMR_TXEMPTY (0x1u << 9) /**< \brief (SPI_IMR) Transmission Registers Empty Mask */ +#define SPI_IMR_UNDES (0x1u << 10) /**< \brief (SPI_IMR) Underrun Error Interrupt Mask */ +/* -------- SPI_CSR[4] : (SPI Offset: 0x30) Chip Select Register -------- */ +#define SPI_CSR_CPOL (0x1u << 0) /**< \brief (SPI_CSR[4]) Clock Polarity */ +#define SPI_CSR_NCPHA (0x1u << 1) /**< \brief (SPI_CSR[4]) Clock Phase */ +#define SPI_CSR_CSNAAT (0x1u << 2) /**< \brief (SPI_CSR[4]) Chip Select Not Active After Transfer (Ignored if CSAAT = 1) */ +#define SPI_CSR_CSAAT (0x1u << 3) /**< \brief (SPI_CSR[4]) Chip Select Active After Transfer */ +#define SPI_CSR_BITS_Pos 4 +#define SPI_CSR_BITS_Msk (0xfu << SPI_CSR_BITS_Pos) /**< \brief (SPI_CSR[4]) Bits Per Transfer */ +#define SPI_CSR_BITS_8_BIT (0x0u << 4) /**< \brief (SPI_CSR[4]) 8 bits for transfer */ +#define SPI_CSR_BITS_9_BIT (0x1u << 4) /**< \brief (SPI_CSR[4]) 9 bits for transfer */ +#define SPI_CSR_BITS_10_BIT (0x2u << 4) /**< \brief (SPI_CSR[4]) 10 bits for transfer */ +#define SPI_CSR_BITS_11_BIT (0x3u << 4) /**< \brief (SPI_CSR[4]) 11 bits for transfer */ +#define SPI_CSR_BITS_12_BIT (0x4u << 4) /**< \brief (SPI_CSR[4]) 12 bits for transfer */ +#define SPI_CSR_BITS_13_BIT (0x5u << 4) /**< \brief (SPI_CSR[4]) 13 bits for transfer */ +#define SPI_CSR_BITS_14_BIT (0x6u << 4) /**< \brief (SPI_CSR[4]) 14 bits for transfer */ +#define SPI_CSR_BITS_15_BIT (0x7u << 4) /**< \brief (SPI_CSR[4]) 15 bits for transfer */ +#define SPI_CSR_BITS_16_BIT (0x8u << 4) /**< \brief (SPI_CSR[4]) 16 bits for transfer */ +#define SPI_CSR_SCBR_Pos 8 +#define SPI_CSR_SCBR_Msk (0xffu << SPI_CSR_SCBR_Pos) /**< \brief (SPI_CSR[4]) Serial Clock Baud Rate */ +#define SPI_CSR_SCBR(value) ((SPI_CSR_SCBR_Msk & ((value) << SPI_CSR_SCBR_Pos))) +#define SPI_CSR_DLYBS_Pos 16 +#define SPI_CSR_DLYBS_Msk (0xffu << SPI_CSR_DLYBS_Pos) /**< \brief (SPI_CSR[4]) Delay Before SPCK */ +#define SPI_CSR_DLYBS(value) ((SPI_CSR_DLYBS_Msk & ((value) << SPI_CSR_DLYBS_Pos))) +#define SPI_CSR_DLYBCT_Pos 24 +#define SPI_CSR_DLYBCT_Msk (0xffu << SPI_CSR_DLYBCT_Pos) /**< \brief (SPI_CSR[4]) Delay Between Consecutive Transfers */ +#define SPI_CSR_DLYBCT(value) ((SPI_CSR_DLYBCT_Msk & ((value) << SPI_CSR_DLYBCT_Pos))) +/* -------- SPI_WPMR : (SPI Offset: 0xE4) Write Protection Mode Register -------- */ +#define SPI_WPMR_WPEN (0x1u << 0) /**< \brief (SPI_WPMR) Write Protection Enable */ +#define SPI_WPMR_WPKEY_Pos 8 +#define SPI_WPMR_WPKEY_Msk (0xffffffu << SPI_WPMR_WPKEY_Pos) /**< \brief (SPI_WPMR) Write Protect Key */ +#define SPI_WPMR_WPKEY_PASSWD (0x535049u << 8) /**< \brief (SPI_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- SPI_WPSR : (SPI Offset: 0xE8) Write Protection Status Register -------- */ +#define SPI_WPSR_WPVS (0x1u << 0) /**< \brief (SPI_WPSR) Write Protection Violation Status */ +#define SPI_WPSR_WPVSRC_Pos 8 +#define SPI_WPSR_WPVSRC_Msk (0xffu << SPI_WPSR_WPVSRC_Pos) /**< \brief (SPI_WPSR) Write Protection Violation Source */ +/* -------- SPI_RPR : (SPI Offset: 0x100) Receive Pointer Register -------- */ +#define SPI_RPR_RXPTR_Pos 0 +#define SPI_RPR_RXPTR_Msk (0xffffffffu << SPI_RPR_RXPTR_Pos) /**< \brief (SPI_RPR) Receive Pointer Register */ +#define SPI_RPR_RXPTR(value) ((SPI_RPR_RXPTR_Msk & ((value) << SPI_RPR_RXPTR_Pos))) +/* -------- SPI_RCR : (SPI Offset: 0x104) Receive Counter Register -------- */ +#define SPI_RCR_RXCTR_Pos 0 +#define SPI_RCR_RXCTR_Msk (0xffffu << SPI_RCR_RXCTR_Pos) /**< \brief (SPI_RCR) Receive Counter Register */ +#define SPI_RCR_RXCTR(value) ((SPI_RCR_RXCTR_Msk & ((value) << SPI_RCR_RXCTR_Pos))) +/* -------- SPI_TPR : (SPI Offset: 0x108) Transmit Pointer Register -------- */ +#define SPI_TPR_TXPTR_Pos 0 +#define SPI_TPR_TXPTR_Msk (0xffffffffu << SPI_TPR_TXPTR_Pos) /**< \brief (SPI_TPR) Transmit Counter Register */ +#define SPI_TPR_TXPTR(value) ((SPI_TPR_TXPTR_Msk & ((value) << SPI_TPR_TXPTR_Pos))) +/* -------- SPI_TCR : (SPI Offset: 0x10C) Transmit Counter Register -------- */ +#define SPI_TCR_TXCTR_Pos 0 +#define SPI_TCR_TXCTR_Msk (0xffffu << SPI_TCR_TXCTR_Pos) /**< \brief (SPI_TCR) Transmit Counter Register */ +#define SPI_TCR_TXCTR(value) ((SPI_TCR_TXCTR_Msk & ((value) << SPI_TCR_TXCTR_Pos))) +/* -------- SPI_RNPR : (SPI Offset: 0x110) Receive Next Pointer Register -------- */ +#define SPI_RNPR_RXNPTR_Pos 0 +#define SPI_RNPR_RXNPTR_Msk (0xffffffffu << SPI_RNPR_RXNPTR_Pos) /**< \brief (SPI_RNPR) Receive Next Pointer */ +#define SPI_RNPR_RXNPTR(value) ((SPI_RNPR_RXNPTR_Msk & ((value) << SPI_RNPR_RXNPTR_Pos))) +/* -------- SPI_RNCR : (SPI Offset: 0x114) Receive Next Counter Register -------- */ +#define SPI_RNCR_RXNCTR_Pos 0 +#define SPI_RNCR_RXNCTR_Msk (0xffffu << SPI_RNCR_RXNCTR_Pos) /**< \brief (SPI_RNCR) Receive Next Counter */ +#define SPI_RNCR_RXNCTR(value) ((SPI_RNCR_RXNCTR_Msk & ((value) << SPI_RNCR_RXNCTR_Pos))) +/* -------- SPI_TNPR : (SPI Offset: 0x118) Transmit Next Pointer Register -------- */ +#define SPI_TNPR_TXNPTR_Pos 0 +#define SPI_TNPR_TXNPTR_Msk (0xffffffffu << SPI_TNPR_TXNPTR_Pos) /**< \brief (SPI_TNPR) Transmit Next Pointer */ +#define SPI_TNPR_TXNPTR(value) ((SPI_TNPR_TXNPTR_Msk & ((value) << SPI_TNPR_TXNPTR_Pos))) +/* -------- SPI_TNCR : (SPI Offset: 0x11C) Transmit Next Counter Register -------- */ +#define SPI_TNCR_TXNCTR_Pos 0 +#define SPI_TNCR_TXNCTR_Msk (0xffffu << SPI_TNCR_TXNCTR_Pos) /**< \brief (SPI_TNCR) Transmit Counter Next */ +#define SPI_TNCR_TXNCTR(value) ((SPI_TNCR_TXNCTR_Msk & ((value) << SPI_TNCR_TXNCTR_Pos))) +/* -------- SPI_PTCR : (SPI Offset: 0x120) Transfer Control Register -------- */ +#define SPI_PTCR_RXTEN (0x1u << 0) /**< \brief (SPI_PTCR) Receiver Transfer Enable */ +#define SPI_PTCR_RXTDIS (0x1u << 1) /**< \brief (SPI_PTCR) Receiver Transfer Disable */ +#define SPI_PTCR_TXTEN (0x1u << 8) /**< \brief (SPI_PTCR) Transmitter Transfer Enable */ +#define SPI_PTCR_TXTDIS (0x1u << 9) /**< \brief (SPI_PTCR) Transmitter Transfer Disable */ +/* -------- SPI_PTSR : (SPI Offset: 0x124) Transfer Status Register -------- */ +#define SPI_PTSR_RXTEN (0x1u << 0) /**< \brief (SPI_PTSR) Receiver Transfer Enable */ +#define SPI_PTSR_TXTEN (0x1u << 8) /**< \brief (SPI_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_SPI_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/supc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/supc.h new file mode 100644 index 0000000..d5675c8 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/supc.h @@ -0,0 +1,339 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SUPC_COMPONENT_ +#define _SAM4E_SUPC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Supply Controller */ +/* ============================================================================= */ +/** \addtogroup SAM4E_SUPC Supply Controller */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Supc hardware registers */ +typedef struct { + __O uint32_t SUPC_CR; /**< \brief (Supc Offset: 0x00) Supply Controller Control Register */ + __IO uint32_t SUPC_SMMR; /**< \brief (Supc Offset: 0x04) Supply Controller Supply Monitor Mode Register */ + __IO uint32_t SUPC_MR; /**< \brief (Supc Offset: 0x08) Supply Controller Mode Register */ + __IO uint32_t SUPC_WUMR; /**< \brief (Supc Offset: 0x0C) Supply Controller Wake-up Mode Register */ + __IO uint32_t SUPC_WUIR; /**< \brief (Supc Offset: 0x10) Supply Controller Wake-up Inputs Register */ + __I uint32_t SUPC_SR; /**< \brief (Supc Offset: 0x14) Supply Controller Status Register */ +} Supc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- SUPC_CR : (SUPC Offset: 0x00) Supply Controller Control Register -------- */ +#define SUPC_CR_VROFF (0x1u << 2) /**< \brief (SUPC_CR) Voltage Regulator Off */ +#define SUPC_CR_VROFF_NO_EFFECT (0x0u << 2) /**< \brief (SUPC_CR) No effect. */ +#define SUPC_CR_VROFF_STOP_VREG (0x1u << 2) /**< \brief (SUPC_CR) If KEY is correct, asserts the vddcore_nreset and stops the voltage regulator. */ +#define SUPC_CR_XTALSEL (0x1u << 3) /**< \brief (SUPC_CR) Crystal Oscillator Select */ +#define SUPC_CR_XTALSEL_NO_EFFECT (0x0u << 3) /**< \brief (SUPC_CR) No effect. */ +#define SUPC_CR_XTALSEL_CRYSTAL_SEL (0x1u << 3) /**< \brief (SUPC_CR) If KEY is correct, switches the slow clock on the crystal oscillator output. */ +#define SUPC_CR_KEY_Pos 24 +#define SUPC_CR_KEY_Msk (0xffu << SUPC_CR_KEY_Pos) /**< \brief (SUPC_CR) Password */ +#define SUPC_CR_KEY_PASSWD (0xA5u << 24) /**< \brief (SUPC_CR) Writing any other value in this field aborts the write operation. */ +/* -------- SUPC_SMMR : (SUPC Offset: 0x04) Supply Controller Supply Monitor Mode Register -------- */ +#define SUPC_SMMR_SMTH_Pos 0 +#define SUPC_SMMR_SMTH_Msk (0xfu << SUPC_SMMR_SMTH_Pos) /**< \brief (SUPC_SMMR) Supply Monitor Threshold */ +#define SUPC_SMMR_SMTH(value) ((SUPC_SMMR_SMTH_Msk & ((value) << SUPC_SMMR_SMTH_Pos))) +#define SUPC_SMMR_SMSMPL_Pos 8 +#define SUPC_SMMR_SMSMPL_Msk (0x7u << SUPC_SMMR_SMSMPL_Pos) /**< \brief (SUPC_SMMR) Supply Monitor Sampling Period */ +#define SUPC_SMMR_SMSMPL_SMD (0x0u << 8) /**< \brief (SUPC_SMMR) Supply Monitor disabled */ +#define SUPC_SMMR_SMSMPL_CSM (0x1u << 8) /**< \brief (SUPC_SMMR) Continuous Supply Monitor */ +#define SUPC_SMMR_SMSMPL_32SLCK (0x2u << 8) /**< \brief (SUPC_SMMR) Supply Monitor enabled one SLCK period every 32 SLCK periods */ +#define SUPC_SMMR_SMSMPL_256SLCK (0x3u << 8) /**< \brief (SUPC_SMMR) Supply Monitor enabled one SLCK period every 256 SLCK periods */ +#define SUPC_SMMR_SMSMPL_2048SLCK (0x4u << 8) /**< \brief (SUPC_SMMR) Supply Monitor enabled one SLCK period every 2,048 SLCK periods */ +#define SUPC_SMMR_SMRSTEN (0x1u << 12) /**< \brief (SUPC_SMMR) Supply Monitor Reset Enable */ +#define SUPC_SMMR_SMRSTEN_NOT_ENABLE (0x0u << 12) /**< \brief (SUPC_SMMR) The core reset signal "vddcore_nreset" is not affected when a supply monitor detection occurs. */ +#define SUPC_SMMR_SMRSTEN_ENABLE (0x1u << 12) /**< \brief (SUPC_SMMR) The core reset signal, vddcore_nreset is asserted when a supply monitor detection occurs. */ +#define SUPC_SMMR_SMIEN (0x1u << 13) /**< \brief (SUPC_SMMR) Supply Monitor Interrupt Enable */ +#define SUPC_SMMR_SMIEN_NOT_ENABLE (0x0u << 13) /**< \brief (SUPC_SMMR) The SUPC interrupt signal is not affected when a supply monitor detection occurs. */ +#define SUPC_SMMR_SMIEN_ENABLE (0x1u << 13) /**< \brief (SUPC_SMMR) The SUPC interrupt signal is asserted when a supply monitor detection occurs. */ +/* -------- SUPC_MR : (SUPC Offset: 0x08) Supply Controller Mode Register -------- */ +#define SUPC_MR_BODRSTEN (0x1u << 12) /**< \brief (SUPC_MR) Brownout Detector Reset Enable */ +#define SUPC_MR_BODRSTEN_NOT_ENABLE (0x0u << 12) /**< \brief (SUPC_MR) The core reset signal "vddcore_nreset" is not affected when a brownout detection occurs. */ +#define SUPC_MR_BODRSTEN_ENABLE (0x1u << 12) /**< \brief (SUPC_MR) The core reset signal, vddcore_nreset is asserted when a brownout detection occurs. */ +#define SUPC_MR_BODDIS (0x1u << 13) /**< \brief (SUPC_MR) Brownout Detector Disable */ +#define SUPC_MR_BODDIS_ENABLE (0x0u << 13) /**< \brief (SUPC_MR) The core brownout detector is enabled. */ +#define SUPC_MR_BODDIS_DISABLE (0x1u << 13) /**< \brief (SUPC_MR) The core brownout detector is disabled. */ +#define SUPC_MR_ONREG (0x1u << 14) /**< \brief (SUPC_MR) Voltage Regulator Enable */ +#define SUPC_MR_ONREG_ONREG_UNUSED (0x0u << 14) /**< \brief (SUPC_MR) Internal voltage regulator is not used (external power supply is used). */ +#define SUPC_MR_ONREG_ONREG_USED (0x1u << 14) /**< \brief (SUPC_MR) Internal voltage regulator is used. */ +#define SUPC_MR_OSCBYPASS (0x1u << 20) /**< \brief (SUPC_MR) Oscillator Bypass */ +#define SUPC_MR_OSCBYPASS_NO_EFFECT (0x0u << 20) /**< \brief (SUPC_MR) No effect. Clock selection depends on XTALSEL value. */ +#define SUPC_MR_OSCBYPASS_BYPASS (0x1u << 20) /**< \brief (SUPC_MR) The 32 kHz crystal oscillator is selected and put in bypass mode. */ +#define SUPC_MR_KEY_Pos 24 +#define SUPC_MR_KEY_Msk (0xffu << SUPC_MR_KEY_Pos) /**< \brief (SUPC_MR) Password Key */ +#define SUPC_MR_KEY_PASSWD (0xA5u << 24) /**< \brief (SUPC_MR) Writing any other value in this field aborts the write operation. */ +/* -------- SUPC_WUMR : (SUPC Offset: 0x0C) Supply Controller Wake-up Mode Register -------- */ +#define SUPC_WUMR_FWUPEN (0x1u << 0) /**< \brief (SUPC_WUMR) Force Wake-up Enable */ +#define SUPC_WUMR_FWUPEN_NOT_ENABLE (0x0u << 0) /**< \brief (SUPC_WUMR) The force wake-up pin has no wake-up effect. */ +#define SUPC_WUMR_FWUPEN_ENABLE (0x1u << 0) /**< \brief (SUPC_WUMR) The force wake-up pin low forces the wake-up of the core power supply. */ +#define SUPC_WUMR_SMEN (0x1u << 1) /**< \brief (SUPC_WUMR) Supply Monitor Wake-up Enable */ +#define SUPC_WUMR_SMEN_NOT_ENABLE (0x0u << 1) /**< \brief (SUPC_WUMR) The supply monitor detection has no wake-up effect. */ +#define SUPC_WUMR_SMEN_ENABLE (0x1u << 1) /**< \brief (SUPC_WUMR) The supply monitor detection forces the wake-up of the core power supply. */ +#define SUPC_WUMR_RTTEN (0x1u << 2) /**< \brief (SUPC_WUMR) Real-time Timer Wake-up Enable */ +#define SUPC_WUMR_RTTEN_NOT_ENABLE (0x0u << 2) /**< \brief (SUPC_WUMR) The RTT alarm signal has no wake-up effect. */ +#define SUPC_WUMR_RTTEN_ENABLE (0x1u << 2) /**< \brief (SUPC_WUMR) The RTT alarm signal forces the wake-up of the core power supply. */ +#define SUPC_WUMR_RTCEN (0x1u << 3) /**< \brief (SUPC_WUMR) Real-time Clock Wake-up Enable */ +#define SUPC_WUMR_RTCEN_NOT_ENABLE (0x0u << 3) /**< \brief (SUPC_WUMR) The RTC alarm signal has no wake-up effect. */ +#define SUPC_WUMR_RTCEN_ENABLE (0x1u << 3) /**< \brief (SUPC_WUMR) The RTC alarm signal forces the wake-up of the core power supply. */ +#define SUPC_WUMR_LPDBCEN0 (0x1u << 5) /**< \brief (SUPC_WUMR) Low-power Debouncer Enable WKUP0 */ +#define SUPC_WUMR_LPDBCEN0_NOT_ENABLE (0x0u << 5) /**< \brief (SUPC_WUMR) The WKUP0 input pin is not connected with low-power debouncer. */ +#define SUPC_WUMR_LPDBCEN0_ENABLE (0x1u << 5) /**< \brief (SUPC_WUMR) The WKUP0 input pin is connected with low-power debouncer and forces a system wake-up. */ +#define SUPC_WUMR_LPDBCEN1 (0x1u << 6) /**< \brief (SUPC_WUMR) Low-power Debouncer Enable WKUP1 */ +#define SUPC_WUMR_LPDBCEN1_NOT_ENABLE (0x0u << 6) /**< \brief (SUPC_WUMR) The WKUP1 input pin is not connected with low-power debouncer. */ +#define SUPC_WUMR_LPDBCEN1_ENABLE (0x1u << 6) /**< \brief (SUPC_WUMR) The WKUP1 input pin is connected with low-power debouncer and forces a system wake-up. */ +#define SUPC_WUMR_LPDBCCLR (0x1u << 7) /**< \brief (SUPC_WUMR) Low-power Debouncer Clear */ +#define SUPC_WUMR_LPDBCCLR_NOT_ENABLE (0x0u << 7) /**< \brief (SUPC_WUMR) A low-power debounce event does not create an immediate clear on the first half of GPBR registers. */ +#define SUPC_WUMR_LPDBCCLR_ENABLE (0x1u << 7) /**< \brief (SUPC_WUMR) A low-power debounce event on WKUP0 or WKUP1 generates an immediate clear on the first half of GPBR registers. */ +#define SUPC_WUMR_FWUPDBC_Pos 8 +#define SUPC_WUMR_FWUPDBC_Msk (0x7u << SUPC_WUMR_FWUPDBC_Pos) /**< \brief (SUPC_WUMR) Force Wake-up Debouncer Period */ +#define SUPC_WUMR_FWUPDBC_IMMEDIATE (0x0u << 8) /**< \brief (SUPC_WUMR) Immediate, no debouncing, detected active at least on one Slow Clock edge. */ +#define SUPC_WUMR_FWUPDBC_3_SCLK (0x1u << 8) /**< \brief (SUPC_WUMR) FWUP shall be low for at least 3 SLCK periods */ +#define SUPC_WUMR_FWUPDBC_32_SCLK (0x2u << 8) /**< \brief (SUPC_WUMR) FWUP shall be low for at least 32 SLCK periods */ +#define SUPC_WUMR_FWUPDBC_512_SCLK (0x3u << 8) /**< \brief (SUPC_WUMR) FWUP shall be low for at least 512 SLCK periods */ +#define SUPC_WUMR_FWUPDBC_4096_SCLK (0x4u << 8) /**< \brief (SUPC_WUMR) FWUP shall be low for at least 4,096 SLCK periods */ +#define SUPC_WUMR_FWUPDBC_32768_SCLK (0x5u << 8) /**< \brief (SUPC_WUMR) FWUP shall be low for at least 32,768 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_Pos 12 +#define SUPC_WUMR_WKUPDBC_Msk (0x7u << SUPC_WUMR_WKUPDBC_Pos) /**< \brief (SUPC_WUMR) Wake-up Inputs Debouncer Period */ +#define SUPC_WUMR_WKUPDBC_IMMEDIATE (0x0u << 12) /**< \brief (SUPC_WUMR) Immediate, no debouncing, detected active at least on one Slow Clock edge. */ +#define SUPC_WUMR_WKUPDBC_3_SCLK (0x1u << 12) /**< \brief (SUPC_WUMR) WKUPx shall be in its active state for at least 3 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_32_SCLK (0x2u << 12) /**< \brief (SUPC_WUMR) WKUPx shall be in its active state for at least 32 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_512_SCLK (0x3u << 12) /**< \brief (SUPC_WUMR) WKUPx shall be in its active state for at least 512 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_4096_SCLK (0x4u << 12) /**< \brief (SUPC_WUMR) WKUPx shall be in its active state for at least 4,096 SLCK periods */ +#define SUPC_WUMR_WKUPDBC_32768_SCLK (0x5u << 12) /**< \brief (SUPC_WUMR) WKUPx shall be in its active state for at least 32,768 SLCK periods */ +#define SUPC_WUMR_LPDBC_Pos 16 +#define SUPC_WUMR_LPDBC_Msk (0x7u << SUPC_WUMR_LPDBC_Pos) /**< \brief (SUPC_WUMR) Low-power Debouncer Period */ +#define SUPC_WUMR_LPDBC_DISABLE (0x0u << 16) /**< \brief (SUPC_WUMR) Disable the low-power debouncers. */ +#define SUPC_WUMR_LPDBC_2_RTCOUT0 (0x1u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 2 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_3_RTCOUT0 (0x2u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 3 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_4_RTCOUT0 (0x3u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 4 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_5_RTCOUT0 (0x4u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 5 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_6_RTCOUT0 (0x5u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 6 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_7_RTCOUT0 (0x6u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 7 RTCOUTx periods */ +#define SUPC_WUMR_LPDBC_8_RTCOUT0 (0x7u << 16) /**< \brief (SUPC_WUMR) WKUP0/1 in active state for at least 8 RTCOUTx periods */ +/* -------- SUPC_WUIR : (SUPC Offset: 0x10) Supply Controller Wake-up Inputs Register -------- */ +#define SUPC_WUIR_WKUPEN0 (0x1u << 0) /**< \brief (SUPC_WUIR) Wake-up Input Enable 0 */ +#define SUPC_WUIR_WKUPEN0_DISABLE (0x0u << 0) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN0_ENABLE (0x1u << 0) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN1 (0x1u << 1) /**< \brief (SUPC_WUIR) Wake-up Input Enable 1 */ +#define SUPC_WUIR_WKUPEN1_DISABLE (0x0u << 1) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN1_ENABLE (0x1u << 1) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN2 (0x1u << 2) /**< \brief (SUPC_WUIR) Wake-up Input Enable 2 */ +#define SUPC_WUIR_WKUPEN2_DISABLE (0x0u << 2) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN2_ENABLE (0x1u << 2) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN3 (0x1u << 3) /**< \brief (SUPC_WUIR) Wake-up Input Enable 3 */ +#define SUPC_WUIR_WKUPEN3_DISABLE (0x0u << 3) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN3_ENABLE (0x1u << 3) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN4 (0x1u << 4) /**< \brief (SUPC_WUIR) Wake-up Input Enable 4 */ +#define SUPC_WUIR_WKUPEN4_DISABLE (0x0u << 4) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN4_ENABLE (0x1u << 4) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN5 (0x1u << 5) /**< \brief (SUPC_WUIR) Wake-up Input Enable 5 */ +#define SUPC_WUIR_WKUPEN5_DISABLE (0x0u << 5) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN5_ENABLE (0x1u << 5) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN6 (0x1u << 6) /**< \brief (SUPC_WUIR) Wake-up Input Enable 6 */ +#define SUPC_WUIR_WKUPEN6_DISABLE (0x0u << 6) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN6_ENABLE (0x1u << 6) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN7 (0x1u << 7) /**< \brief (SUPC_WUIR) Wake-up Input Enable 7 */ +#define SUPC_WUIR_WKUPEN7_DISABLE (0x0u << 7) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN7_ENABLE (0x1u << 7) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN8 (0x1u << 8) /**< \brief (SUPC_WUIR) Wake-up Input Enable 8 */ +#define SUPC_WUIR_WKUPEN8_DISABLE (0x0u << 8) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN8_ENABLE (0x1u << 8) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN9 (0x1u << 9) /**< \brief (SUPC_WUIR) Wake-up Input Enable 9 */ +#define SUPC_WUIR_WKUPEN9_DISABLE (0x0u << 9) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN9_ENABLE (0x1u << 9) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN10 (0x1u << 10) /**< \brief (SUPC_WUIR) Wake-up Input Enable 10 */ +#define SUPC_WUIR_WKUPEN10_DISABLE (0x0u << 10) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN10_ENABLE (0x1u << 10) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN11 (0x1u << 11) /**< \brief (SUPC_WUIR) Wake-up Input Enable 11 */ +#define SUPC_WUIR_WKUPEN11_DISABLE (0x0u << 11) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN11_ENABLE (0x1u << 11) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN12 (0x1u << 12) /**< \brief (SUPC_WUIR) Wake-up Input Enable 12 */ +#define SUPC_WUIR_WKUPEN12_DISABLE (0x0u << 12) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN12_ENABLE (0x1u << 12) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN13 (0x1u << 13) /**< \brief (SUPC_WUIR) Wake-up Input Enable 13 */ +#define SUPC_WUIR_WKUPEN13_DISABLE (0x0u << 13) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN13_ENABLE (0x1u << 13) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN14 (0x1u << 14) /**< \brief (SUPC_WUIR) Wake-up Input Enable 14 */ +#define SUPC_WUIR_WKUPEN14_DISABLE (0x0u << 14) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN14_ENABLE (0x1u << 14) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPEN15 (0x1u << 15) /**< \brief (SUPC_WUIR) Wake-up Input Enable 15 */ +#define SUPC_WUIR_WKUPEN15_DISABLE (0x0u << 15) /**< \brief (SUPC_WUIR) The corresponding wake-up input has no wake-up effect. */ +#define SUPC_WUIR_WKUPEN15_ENABLE (0x1u << 15) /**< \brief (SUPC_WUIR) The corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT0 (0x1u << 16) /**< \brief (SUPC_WUIR) Wake-up Input Type 0 */ +#define SUPC_WUIR_WKUPT0_LOW (0x0u << 16) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT0_HIGH (0x1u << 16) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT1 (0x1u << 17) /**< \brief (SUPC_WUIR) Wake-up Input Type 1 */ +#define SUPC_WUIR_WKUPT1_LOW (0x0u << 17) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT1_HIGH (0x1u << 17) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT2 (0x1u << 18) /**< \brief (SUPC_WUIR) Wake-up Input Type 2 */ +#define SUPC_WUIR_WKUPT2_LOW (0x0u << 18) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT2_HIGH (0x1u << 18) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT3 (0x1u << 19) /**< \brief (SUPC_WUIR) Wake-up Input Type 3 */ +#define SUPC_WUIR_WKUPT3_LOW (0x0u << 19) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT3_HIGH (0x1u << 19) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT4 (0x1u << 20) /**< \brief (SUPC_WUIR) Wake-up Input Type 4 */ +#define SUPC_WUIR_WKUPT4_LOW (0x0u << 20) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT4_HIGH (0x1u << 20) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT5 (0x1u << 21) /**< \brief (SUPC_WUIR) Wake-up Input Type 5 */ +#define SUPC_WUIR_WKUPT5_LOW (0x0u << 21) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT5_HIGH (0x1u << 21) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT6 (0x1u << 22) /**< \brief (SUPC_WUIR) Wake-up Input Type 6 */ +#define SUPC_WUIR_WKUPT6_LOW (0x0u << 22) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT6_HIGH (0x1u << 22) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT7 (0x1u << 23) /**< \brief (SUPC_WUIR) Wake-up Input Type 7 */ +#define SUPC_WUIR_WKUPT7_LOW (0x0u << 23) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT7_HIGH (0x1u << 23) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT8 (0x1u << 24) /**< \brief (SUPC_WUIR) Wake-up Input Type 8 */ +#define SUPC_WUIR_WKUPT8_LOW (0x0u << 24) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT8_HIGH (0x1u << 24) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT9 (0x1u << 25) /**< \brief (SUPC_WUIR) Wake-up Input Type 9 */ +#define SUPC_WUIR_WKUPT9_LOW (0x0u << 25) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT9_HIGH (0x1u << 25) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT10 (0x1u << 26) /**< \brief (SUPC_WUIR) Wake-up Input Type 10 */ +#define SUPC_WUIR_WKUPT10_LOW (0x0u << 26) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT10_HIGH (0x1u << 26) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT11 (0x1u << 27) /**< \brief (SUPC_WUIR) Wake-up Input Type 11 */ +#define SUPC_WUIR_WKUPT11_LOW (0x0u << 27) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT11_HIGH (0x1u << 27) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT12 (0x1u << 28) /**< \brief (SUPC_WUIR) Wake-up Input Type 12 */ +#define SUPC_WUIR_WKUPT12_LOW (0x0u << 28) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT12_HIGH (0x1u << 28) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT13 (0x1u << 29) /**< \brief (SUPC_WUIR) Wake-up Input Type 13 */ +#define SUPC_WUIR_WKUPT13_LOW (0x0u << 29) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT13_HIGH (0x1u << 29) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT14 (0x1u << 30) /**< \brief (SUPC_WUIR) Wake-up Input Type 14 */ +#define SUPC_WUIR_WKUPT14_LOW (0x0u << 30) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT14_HIGH (0x1u << 30) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT15 (0x1u << 31) /**< \brief (SUPC_WUIR) Wake-up Input Type 15 */ +#define SUPC_WUIR_WKUPT15_LOW (0x0u << 31) /**< \brief (SUPC_WUIR) A low level for a period defined by WKUPDBC on the corresponding wake-up input forces the wake-up of the core power supply. */ +#define SUPC_WUIR_WKUPT15_HIGH (0x1u << 31) /**< \brief (SUPC_WUIR) A high level for a period defined by WKUPDBC on the correspond-ing wake-up input forces the wake-up of the core power supply. */ +/* -------- SUPC_SR : (SUPC Offset: 0x14) Supply Controller Status Register -------- */ +#define SUPC_SR_FWUPS (0x1u << 0) /**< \brief (SUPC_SR) FWUP Wake-up Status */ +#define SUPC_SR_FWUPS_NO (0x0u << 0) /**< \brief (SUPC_SR) No wake-up due to the assertion of the FWUP pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_FWUPS_PRESENT (0x1u << 0) /**< \brief (SUPC_SR) At least one wake-up due to the assertion of the FWUP pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_WKUPS (0x1u << 1) /**< \brief (SUPC_SR) WKUP Wake-up Status */ +#define SUPC_SR_WKUPS_NO (0x0u << 1) /**< \brief (SUPC_SR) No wake-up due to the assertion of the WKUP pins has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_WKUPS_PRESENT (0x1u << 1) /**< \brief (SUPC_SR) At least one wake-up due to the assertion of the WKUP pins has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_SMWS (0x1u << 2) /**< \brief (SUPC_SR) Supply Monitor Detection Wake-up Status */ +#define SUPC_SR_SMWS_NO (0x0u << 2) /**< \brief (SUPC_SR) No wake-up due to a supply monitor detection has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_SMWS_PRESENT (0x1u << 2) /**< \brief (SUPC_SR) At least one wake-up due to a supply monitor detection has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_BODRSTS (0x1u << 3) /**< \brief (SUPC_SR) Brownout Detector Reset Status */ +#define SUPC_SR_BODRSTS_NO (0x0u << 3) /**< \brief (SUPC_SR) No core brownout rising edge event has been detected since the last read of the SUPC_SR. */ +#define SUPC_SR_BODRSTS_PRESENT (0x1u << 3) /**< \brief (SUPC_SR) At least one brownout output rising edge event has been detected since the last read of the SUPC_SR. */ +#define SUPC_SR_SMRSTS (0x1u << 4) /**< \brief (SUPC_SR) Supply Monitor Reset Status */ +#define SUPC_SR_SMRSTS_NO (0x0u << 4) /**< \brief (SUPC_SR) No supply monitor detection has generated a core reset since the last read of the SUPC_SR. */ +#define SUPC_SR_SMRSTS_PRESENT (0x1u << 4) /**< \brief (SUPC_SR) At least one supply monitor detection has generated a core reset since the last read of the SUPC_SR. */ +#define SUPC_SR_SMS (0x1u << 5) /**< \brief (SUPC_SR) Supply Monitor Status */ +#define SUPC_SR_SMS_NO (0x0u << 5) /**< \brief (SUPC_SR) No supply monitor detection since the last read of SUPC_SR. */ +#define SUPC_SR_SMS_PRESENT (0x1u << 5) /**< \brief (SUPC_SR) At least one supply monitor detection since the last read of SUPC_SR. */ +#define SUPC_SR_SMOS (0x1u << 6) /**< \brief (SUPC_SR) Supply Monitor Output Status */ +#define SUPC_SR_SMOS_HIGH (0x0u << 6) /**< \brief (SUPC_SR) The supply monitor detected VDDIO higher than its threshold at its last measurement. */ +#define SUPC_SR_SMOS_LOW (0x1u << 6) /**< \brief (SUPC_SR) The supply monitor detected VDDIO lower than its threshold at its last measurement. */ +#define SUPC_SR_OSCSEL (0x1u << 7) /**< \brief (SUPC_SR) 32-kHz Oscillator Selection Status */ +#define SUPC_SR_OSCSEL_RC (0x0u << 7) /**< \brief (SUPC_SR) The slow clock, SLCK is generated by the embedded 32 kHz RC oscillator. */ +#define SUPC_SR_OSCSEL_CRYST (0x1u << 7) /**< \brief (SUPC_SR) The slow clock, SLCK is generated by the 32 kHz crystal oscillator. */ +#define SUPC_SR_FWUPIS (0x1u << 12) /**< \brief (SUPC_SR) FWUP Input Status */ +#define SUPC_SR_FWUPIS_LOW (0x0u << 12) /**< \brief (SUPC_SR) FWUP input is tied low. */ +#define SUPC_SR_FWUPIS_HIGH (0x1u << 12) /**< \brief (SUPC_SR) FWUP input is tied high. */ +#define SUPC_SR_LPDBCS0 (0x1u << 13) /**< \brief (SUPC_SR) Low-power Debouncer Wake-up Status on WKUP0 */ +#define SUPC_SR_LPDBCS0_NO (0x0u << 13) /**< \brief (SUPC_SR) No wake-up due to the assertion of the WKUP0 pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_LPDBCS0_PRESENT (0x1u << 13) /**< \brief (SUPC_SR) At least one wake-up due to the assertion of the WKUP0 pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_LPDBCS1 (0x1u << 14) /**< \brief (SUPC_SR) Low-power Debouncer Wake-up Status on WKUP1 */ +#define SUPC_SR_LPDBCS1_NO (0x0u << 14) /**< \brief (SUPC_SR) No wake-up due to the assertion of the WKUP1 pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_LPDBCS1_PRESENT (0x1u << 14) /**< \brief (SUPC_SR) At least one wake-up due to the assertion of the WKUP1 pin has occurred since the last read of SUPC_SR. */ +#define SUPC_SR_WKUPIS0 (0x1u << 16) /**< \brief (SUPC_SR) WKUP Input Status 0 */ +#define SUPC_SR_WKUPIS0_DIS (0x0u << 16) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS0_EN (0x1u << 16) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS1 (0x1u << 17) /**< \brief (SUPC_SR) WKUP Input Status 1 */ +#define SUPC_SR_WKUPIS1_DIS (0x0u << 17) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS1_EN (0x1u << 17) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS2 (0x1u << 18) /**< \brief (SUPC_SR) WKUP Input Status 2 */ +#define SUPC_SR_WKUPIS2_DIS (0x0u << 18) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS2_EN (0x1u << 18) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS3 (0x1u << 19) /**< \brief (SUPC_SR) WKUP Input Status 3 */ +#define SUPC_SR_WKUPIS3_DIS (0x0u << 19) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS3_EN (0x1u << 19) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS4 (0x1u << 20) /**< \brief (SUPC_SR) WKUP Input Status 4 */ +#define SUPC_SR_WKUPIS4_DIS (0x0u << 20) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS4_EN (0x1u << 20) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS5 (0x1u << 21) /**< \brief (SUPC_SR) WKUP Input Status 5 */ +#define SUPC_SR_WKUPIS5_DIS (0x0u << 21) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS5_EN (0x1u << 21) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS6 (0x1u << 22) /**< \brief (SUPC_SR) WKUP Input Status 6 */ +#define SUPC_SR_WKUPIS6_DIS (0x0u << 22) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS6_EN (0x1u << 22) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS7 (0x1u << 23) /**< \brief (SUPC_SR) WKUP Input Status 7 */ +#define SUPC_SR_WKUPIS7_DIS (0x0u << 23) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS7_EN (0x1u << 23) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS8 (0x1u << 24) /**< \brief (SUPC_SR) WKUP Input Status 8 */ +#define SUPC_SR_WKUPIS8_DIS (0x0u << 24) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS8_EN (0x1u << 24) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS9 (0x1u << 25) /**< \brief (SUPC_SR) WKUP Input Status 9 */ +#define SUPC_SR_WKUPIS9_DIS (0x0u << 25) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS9_EN (0x1u << 25) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS10 (0x1u << 26) /**< \brief (SUPC_SR) WKUP Input Status 10 */ +#define SUPC_SR_WKUPIS10_DIS (0x0u << 26) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS10_EN (0x1u << 26) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS11 (0x1u << 27) /**< \brief (SUPC_SR) WKUP Input Status 11 */ +#define SUPC_SR_WKUPIS11_DIS (0x0u << 27) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS11_EN (0x1u << 27) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS12 (0x1u << 28) /**< \brief (SUPC_SR) WKUP Input Status 12 */ +#define SUPC_SR_WKUPIS12_DIS (0x0u << 28) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS12_EN (0x1u << 28) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS13 (0x1u << 29) /**< \brief (SUPC_SR) WKUP Input Status 13 */ +#define SUPC_SR_WKUPIS13_DIS (0x0u << 29) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS13_EN (0x1u << 29) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS14 (0x1u << 30) /**< \brief (SUPC_SR) WKUP Input Status 14 */ +#define SUPC_SR_WKUPIS14_DIS (0x0u << 30) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS14_EN (0x1u << 30) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS15 (0x1u << 31) /**< \brief (SUPC_SR) WKUP Input Status 15 */ +#define SUPC_SR_WKUPIS15_DIS (0x0u << 31) /**< \brief (SUPC_SR) The corresponding wake-up input is disabled, or was inactive at the time the debouncer triggered a wake-up event. */ +#define SUPC_SR_WKUPIS15_EN (0x1u << 31) /**< \brief (SUPC_SR) The corresponding wake-up input was active at the time the debouncer triggered a wake-up event. */ + +/*@}*/ + + +#endif /* _SAM4E_SUPC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/tc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/tc.h new file mode 100644 index 0000000..a5d14b4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/tc.h @@ -0,0 +1,386 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TC_COMPONENT_ +#define _SAM4E_TC_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Timer Counter */ +/* ============================================================================= */ +/** \addtogroup SAM4E_TC Timer Counter */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief TcChannel hardware registers */ +typedef struct { + __O uint32_t TC_CCR; /**< \brief (TcChannel Offset: 0x0) Channel Control Register */ + __IO uint32_t TC_CMR; /**< \brief (TcChannel Offset: 0x4) Channel Mode Register */ + __IO uint32_t TC_SMMR; /**< \brief (TcChannel Offset: 0x8) Stepper Motor Mode Register */ + __I uint32_t TC_RAB; /**< \brief (TcChannel Offset: 0xC) Register AB */ + __I uint32_t TC_CV; /**< \brief (TcChannel Offset: 0x10) Counter Value */ + __IO uint32_t TC_RA; /**< \brief (TcChannel Offset: 0x14) Register A */ + __IO uint32_t TC_RB; /**< \brief (TcChannel Offset: 0x18) Register B */ + __IO uint32_t TC_RC; /**< \brief (TcChannel Offset: 0x1C) Register C */ + __I uint32_t TC_SR; /**< \brief (TcChannel Offset: 0x20) Status Register */ + __O uint32_t TC_IER; /**< \brief (TcChannel Offset: 0x24) Interrupt Enable Register */ + __O uint32_t TC_IDR; /**< \brief (TcChannel Offset: 0x28) Interrupt Disable Register */ + __I uint32_t TC_IMR; /**< \brief (TcChannel Offset: 0x2C) Interrupt Mask Register */ + __IO uint32_t TC_EMR; /**< \brief (TcChannel Offset: 0x30) Extended Mode Register */ + __I uint32_t Reserved1[3]; +} TcChannel; +/** \brief TcPdc hardware registers */ +typedef struct { + __IO uint32_t TC_RPR; /**< \brief (TcPdc Offset: 0x0) Receive Pointer Register */ + __IO uint32_t TC_RCR; /**< \brief (TcPdc Offset: 0x4) Receive Counter Register */ + __I uint32_t Reserved2[2]; + __IO uint32_t TC_RNPR; /**< \brief (TcPdc Offset: 0x10) Receive Next Pointer Register */ + __IO uint32_t TC_RNCR; /**< \brief (TcPdc Offset: 0x14) Receive Next Counter Register */ + __I uint32_t Reserved3[2]; + __O uint32_t TC_PTCR; /**< \brief (TcPdc Offset: 0x20) Transfer Control Register */ + __I uint32_t TC_PTSR; /**< \brief (TcPdc Offset: 0x24) Transfer Status Register */ + __I uint32_t Reserved4[6]; +} TcPdc; +/** \brief Tc hardware registers */ +#define TCCHANNEL_NUMBER 3 +#define TCPDC_NUMBER 3 +typedef struct { + TcChannel TC_CHANNEL[TCCHANNEL_NUMBER]; /**< \brief (Tc Offset: 0x0) channel = 0 .. 2 */ + __O uint32_t TC_BCR; /**< \brief (Tc Offset: 0xC0) Block Control Register */ + __IO uint32_t TC_BMR; /**< \brief (Tc Offset: 0xC4) Block Mode Register */ + __O uint32_t TC_QIER; /**< \brief (Tc Offset: 0xC8) QDEC Interrupt Enable Register */ + __O uint32_t TC_QIDR; /**< \brief (Tc Offset: 0xCC) QDEC Interrupt Disable Register */ + __I uint32_t TC_QIMR; /**< \brief (Tc Offset: 0xD0) QDEC Interrupt Mask Register */ + __I uint32_t TC_QISR; /**< \brief (Tc Offset: 0xD4) QDEC Interrupt Status Register */ + __IO uint32_t TC_FMR; /**< \brief (Tc Offset: 0xD8) Fault Mode Register */ + __I uint32_t Reserved1[2]; + __IO uint32_t TC_WPMR; /**< \brief (Tc Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t Reserved2[6]; + TcPdc TC_PDC[TCPDC_NUMBER]; /**< \brief (Tc Offset: 0x100) pdc = 0 .. 2 */ +} Tc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- TC_CCR : (TC Offset: N/A) Channel Control Register -------- */ +#define TC_CCR_CLKEN (0x1u << 0) /**< \brief (TC_CCR) Counter Clock Enable Command */ +#define TC_CCR_CLKDIS (0x1u << 1) /**< \brief (TC_CCR) Counter Clock Disable Command */ +#define TC_CCR_SWTRG (0x1u << 2) /**< \brief (TC_CCR) Software Trigger Command */ +/* -------- TC_CMR : (TC Offset: N/A) Channel Mode Register -------- */ +#define TC_CMR_TCCLKS_Pos 0 +#define TC_CMR_TCCLKS_Msk (0x7u << TC_CMR_TCCLKS_Pos) /**< \brief (TC_CMR) Clock Selection */ +#define TC_CMR_TCCLKS_TIMER_CLOCK1 (0x0u << 0) /**< \brief (TC_CMR) Clock selected: internal TIMER_CLOCK1 clock signal (from PMC) */ +#define TC_CMR_TCCLKS_TIMER_CLOCK2 (0x1u << 0) /**< \brief (TC_CMR) Clock selected: internal TIMER_CLOCK2 clock signal (from PMC) */ +#define TC_CMR_TCCLKS_TIMER_CLOCK3 (0x2u << 0) /**< \brief (TC_CMR) Clock selected: internal TIMER_CLOCK3 clock signal (from PMC) */ +#define TC_CMR_TCCLKS_TIMER_CLOCK4 (0x3u << 0) /**< \brief (TC_CMR) Clock selected: internal TIMER_CLOCK4 clock signal (from PMC) */ +#define TC_CMR_TCCLKS_TIMER_CLOCK5 (0x4u << 0) /**< \brief (TC_CMR) Clock selected: internal TIMER_CLOCK5 clock signal (from PMC) */ +#define TC_CMR_TCCLKS_XC0 (0x5u << 0) /**< \brief (TC_CMR) Clock selected: XC0 */ +#define TC_CMR_TCCLKS_XC1 (0x6u << 0) /**< \brief (TC_CMR) Clock selected: XC1 */ +#define TC_CMR_TCCLKS_XC2 (0x7u << 0) /**< \brief (TC_CMR) Clock selected: XC2 */ +#define TC_CMR_CLKI (0x1u << 3) /**< \brief (TC_CMR) Clock Invert */ +#define TC_CMR_BURST_Pos 4 +#define TC_CMR_BURST_Msk (0x3u << TC_CMR_BURST_Pos) /**< \brief (TC_CMR) Burst Signal Selection */ +#define TC_CMR_BURST_NONE (0x0u << 4) /**< \brief (TC_CMR) The clock is not gated by an external signal. */ +#define TC_CMR_BURST_XC0 (0x1u << 4) /**< \brief (TC_CMR) XC0 is ANDed with the selected clock. */ +#define TC_CMR_BURST_XC1 (0x2u << 4) /**< \brief (TC_CMR) XC1 is ANDed with the selected clock. */ +#define TC_CMR_BURST_XC2 (0x3u << 4) /**< \brief (TC_CMR) XC2 is ANDed with the selected clock. */ +#define TC_CMR_LDBSTOP (0x1u << 6) /**< \brief (TC_CMR) Counter Clock Stopped with RB Loading */ +#define TC_CMR_LDBDIS (0x1u << 7) /**< \brief (TC_CMR) Counter Clock Disable with RB Loading */ +#define TC_CMR_ETRGEDG_Pos 8 +#define TC_CMR_ETRGEDG_Msk (0x3u << TC_CMR_ETRGEDG_Pos) /**< \brief (TC_CMR) External Trigger Edge Selection */ +#define TC_CMR_ETRGEDG_NONE (0x0u << 8) /**< \brief (TC_CMR) The clock is not gated by an external signal. */ +#define TC_CMR_ETRGEDG_RISING (0x1u << 8) /**< \brief (TC_CMR) Rising edge */ +#define TC_CMR_ETRGEDG_FALLING (0x2u << 8) /**< \brief (TC_CMR) Falling edge */ +#define TC_CMR_ETRGEDG_EDGE (0x3u << 8) /**< \brief (TC_CMR) Each edge */ +#define TC_CMR_ABETRG (0x1u << 10) /**< \brief (TC_CMR) TIOA or TIOB External Trigger Selection */ +#define TC_CMR_CPCTRG (0x1u << 14) /**< \brief (TC_CMR) RC Compare Trigger Enable */ +#define TC_CMR_WAVE (0x1u << 15) /**< \brief (TC_CMR) Waveform Mode */ +#define TC_CMR_LDRA_Pos 16 +#define TC_CMR_LDRA_Msk (0x3u << TC_CMR_LDRA_Pos) /**< \brief (TC_CMR) RA Loading Edge Selection */ +#define TC_CMR_LDRA_NONE (0x0u << 16) /**< \brief (TC_CMR) None */ +#define TC_CMR_LDRA_RISING (0x1u << 16) /**< \brief (TC_CMR) Rising edge of TIOA */ +#define TC_CMR_LDRA_FALLING (0x2u << 16) /**< \brief (TC_CMR) Falling edge of TIOA */ +#define TC_CMR_LDRA_EDGE (0x3u << 16) /**< \brief (TC_CMR) Each edge of TIOA */ +#define TC_CMR_LDRB_Pos 18 +#define TC_CMR_LDRB_Msk (0x3u << TC_CMR_LDRB_Pos) /**< \brief (TC_CMR) RB Loading Edge Selection */ +#define TC_CMR_LDRB_NONE (0x0u << 18) /**< \brief (TC_CMR) None */ +#define TC_CMR_LDRB_RISING (0x1u << 18) /**< \brief (TC_CMR) Rising edge of TIOA */ +#define TC_CMR_LDRB_FALLING (0x2u << 18) /**< \brief (TC_CMR) Falling edge of TIOA */ +#define TC_CMR_LDRB_EDGE (0x3u << 18) /**< \brief (TC_CMR) Each edge of TIOA */ +#define TC_CMR_SBSMPLR_Pos 20 +#define TC_CMR_SBSMPLR_Msk (0x7u << TC_CMR_SBSMPLR_Pos) /**< \brief (TC_CMR) Loading Edge Subsampling Ratio */ +#define TC_CMR_SBSMPLR_ONE (0x0u << 20) /**< \brief (TC_CMR) Load a Capture Register each selected edge */ +#define TC_CMR_SBSMPLR_HALF (0x1u << 20) /**< \brief (TC_CMR) Load a Capture Register every 2 selected edges */ +#define TC_CMR_SBSMPLR_FOURTH (0x2u << 20) /**< \brief (TC_CMR) Load a Capture Register every 4 selected edges */ +#define TC_CMR_SBSMPLR_EIGHTH (0x3u << 20) /**< \brief (TC_CMR) Load a Capture Register every 8 selected edges */ +#define TC_CMR_SBSMPLR_SIXTEENTH (0x4u << 20) /**< \brief (TC_CMR) Load a Capture Register every 16 selected edges */ +#define TC_CMR_CPCSTOP (0x1u << 6) /**< \brief (TC_CMR) Counter Clock Stopped with RC Compare */ +#define TC_CMR_CPCDIS (0x1u << 7) /**< \brief (TC_CMR) Counter Clock Disable with RC Compare */ +#define TC_CMR_EEVTEDG_Pos 8 +#define TC_CMR_EEVTEDG_Msk (0x3u << TC_CMR_EEVTEDG_Pos) /**< \brief (TC_CMR) External Event Edge Selection */ +#define TC_CMR_EEVTEDG_NONE (0x0u << 8) /**< \brief (TC_CMR) None */ +#define TC_CMR_EEVTEDG_RISING (0x1u << 8) /**< \brief (TC_CMR) Rising edge */ +#define TC_CMR_EEVTEDG_FALLING (0x2u << 8) /**< \brief (TC_CMR) Falling edge */ +#define TC_CMR_EEVTEDG_EDGE (0x3u << 8) /**< \brief (TC_CMR) Each edge */ +#define TC_CMR_EEVT_Pos 10 +#define TC_CMR_EEVT_Msk (0x3u << TC_CMR_EEVT_Pos) /**< \brief (TC_CMR) External Event Selection */ +#define TC_CMR_EEVT_TIOB (0x0u << 10) /**< \brief (TC_CMR) TIOB */ +#define TC_CMR_EEVT_XC0 (0x1u << 10) /**< \brief (TC_CMR) XC0 */ +#define TC_CMR_EEVT_XC1 (0x2u << 10) /**< \brief (TC_CMR) XC1 */ +#define TC_CMR_EEVT_XC2 (0x3u << 10) /**< \brief (TC_CMR) XC2 */ +#define TC_CMR_ENETRG (0x1u << 12) /**< \brief (TC_CMR) External Event Trigger Enable */ +#define TC_CMR_WAVSEL_Pos 13 +#define TC_CMR_WAVSEL_Msk (0x3u << TC_CMR_WAVSEL_Pos) /**< \brief (TC_CMR) Waveform Selection */ +#define TC_CMR_WAVSEL_UP (0x0u << 13) /**< \brief (TC_CMR) UP mode without automatic trigger on RC Compare */ +#define TC_CMR_WAVSEL_UPDOWN (0x1u << 13) /**< \brief (TC_CMR) UPDOWN mode without automatic trigger on RC Compare */ +#define TC_CMR_WAVSEL_UP_RC (0x2u << 13) /**< \brief (TC_CMR) UP mode with automatic trigger on RC Compare */ +#define TC_CMR_WAVSEL_UPDOWN_RC (0x3u << 13) /**< \brief (TC_CMR) UPDOWN mode with automatic trigger on RC Compare */ +#define TC_CMR_ACPA_Pos 16 +#define TC_CMR_ACPA_Msk (0x3u << TC_CMR_ACPA_Pos) /**< \brief (TC_CMR) RA Compare Effect on TIOA */ +#define TC_CMR_ACPA_NONE (0x0u << 16) /**< \brief (TC_CMR) None */ +#define TC_CMR_ACPA_SET (0x1u << 16) /**< \brief (TC_CMR) Set */ +#define TC_CMR_ACPA_CLEAR (0x2u << 16) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_ACPA_TOGGLE (0x3u << 16) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_ACPC_Pos 18 +#define TC_CMR_ACPC_Msk (0x3u << TC_CMR_ACPC_Pos) /**< \brief (TC_CMR) RC Compare Effect on TIOA */ +#define TC_CMR_ACPC_NONE (0x0u << 18) /**< \brief (TC_CMR) None */ +#define TC_CMR_ACPC_SET (0x1u << 18) /**< \brief (TC_CMR) Set */ +#define TC_CMR_ACPC_CLEAR (0x2u << 18) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_ACPC_TOGGLE (0x3u << 18) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_AEEVT_Pos 20 +#define TC_CMR_AEEVT_Msk (0x3u << TC_CMR_AEEVT_Pos) /**< \brief (TC_CMR) External Event Effect on TIOA */ +#define TC_CMR_AEEVT_NONE (0x0u << 20) /**< \brief (TC_CMR) None */ +#define TC_CMR_AEEVT_SET (0x1u << 20) /**< \brief (TC_CMR) Set */ +#define TC_CMR_AEEVT_CLEAR (0x2u << 20) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_AEEVT_TOGGLE (0x3u << 20) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_ASWTRG_Pos 22 +#define TC_CMR_ASWTRG_Msk (0x3u << TC_CMR_ASWTRG_Pos) /**< \brief (TC_CMR) Software Trigger Effect on TIOA */ +#define TC_CMR_ASWTRG_NONE (0x0u << 22) /**< \brief (TC_CMR) None */ +#define TC_CMR_ASWTRG_SET (0x1u << 22) /**< \brief (TC_CMR) Set */ +#define TC_CMR_ASWTRG_CLEAR (0x2u << 22) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_ASWTRG_TOGGLE (0x3u << 22) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_BCPB_Pos 24 +#define TC_CMR_BCPB_Msk (0x3u << TC_CMR_BCPB_Pos) /**< \brief (TC_CMR) RB Compare Effect on TIOB */ +#define TC_CMR_BCPB_NONE (0x0u << 24) /**< \brief (TC_CMR) None */ +#define TC_CMR_BCPB_SET (0x1u << 24) /**< \brief (TC_CMR) Set */ +#define TC_CMR_BCPB_CLEAR (0x2u << 24) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_BCPB_TOGGLE (0x3u << 24) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_BCPC_Pos 26 +#define TC_CMR_BCPC_Msk (0x3u << TC_CMR_BCPC_Pos) /**< \brief (TC_CMR) RC Compare Effect on TIOB */ +#define TC_CMR_BCPC_NONE (0x0u << 26) /**< \brief (TC_CMR) None */ +#define TC_CMR_BCPC_SET (0x1u << 26) /**< \brief (TC_CMR) Set */ +#define TC_CMR_BCPC_CLEAR (0x2u << 26) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_BCPC_TOGGLE (0x3u << 26) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_BEEVT_Pos 28 +#define TC_CMR_BEEVT_Msk (0x3u << TC_CMR_BEEVT_Pos) /**< \brief (TC_CMR) External Event Effect on TIOB */ +#define TC_CMR_BEEVT_NONE (0x0u << 28) /**< \brief (TC_CMR) None */ +#define TC_CMR_BEEVT_SET (0x1u << 28) /**< \brief (TC_CMR) Set */ +#define TC_CMR_BEEVT_CLEAR (0x2u << 28) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_BEEVT_TOGGLE (0x3u << 28) /**< \brief (TC_CMR) Toggle */ +#define TC_CMR_BSWTRG_Pos 30 +#define TC_CMR_BSWTRG_Msk (0x3u << TC_CMR_BSWTRG_Pos) /**< \brief (TC_CMR) Software Trigger Effect on TIOB */ +#define TC_CMR_BSWTRG_NONE (0x0u << 30) /**< \brief (TC_CMR) None */ +#define TC_CMR_BSWTRG_SET (0x1u << 30) /**< \brief (TC_CMR) Set */ +#define TC_CMR_BSWTRG_CLEAR (0x2u << 30) /**< \brief (TC_CMR) Clear */ +#define TC_CMR_BSWTRG_TOGGLE (0x3u << 30) /**< \brief (TC_CMR) Toggle */ +/* -------- TC_SMMR : (TC Offset: N/A) Stepper Motor Mode Register -------- */ +#define TC_SMMR_GCEN (0x1u << 0) /**< \brief (TC_SMMR) Gray Count Enable */ +#define TC_SMMR_DOWN (0x1u << 1) /**< \brief (TC_SMMR) DOWN Count */ +/* -------- TC_RAB : (TC Offset: N/A) Register AB -------- */ +#define TC_RAB_RAB_Pos 0 +#define TC_RAB_RAB_Msk (0xffffffffu << TC_RAB_RAB_Pos) /**< \brief (TC_RAB) Register A or Register B */ +/* -------- TC_CV : (TC Offset: N/A) Counter Value -------- */ +#define TC_CV_CV_Pos 0 +#define TC_CV_CV_Msk (0xffffffffu << TC_CV_CV_Pos) /**< \brief (TC_CV) Counter Value */ +/* -------- TC_RA : (TC Offset: N/A) Register A -------- */ +#define TC_RA_RA_Pos 0 +#define TC_RA_RA_Msk (0xffffffffu << TC_RA_RA_Pos) /**< \brief (TC_RA) Register A */ +#define TC_RA_RA(value) ((TC_RA_RA_Msk & ((value) << TC_RA_RA_Pos))) +/* -------- TC_RB : (TC Offset: N/A) Register B -------- */ +#define TC_RB_RB_Pos 0 +#define TC_RB_RB_Msk (0xffffffffu << TC_RB_RB_Pos) /**< \brief (TC_RB) Register B */ +#define TC_RB_RB(value) ((TC_RB_RB_Msk & ((value) << TC_RB_RB_Pos))) +/* -------- TC_RC : (TC Offset: N/A) Register C -------- */ +#define TC_RC_RC_Pos 0 +#define TC_RC_RC_Msk (0xffffffffu << TC_RC_RC_Pos) /**< \brief (TC_RC) Register C */ +#define TC_RC_RC(value) ((TC_RC_RC_Msk & ((value) << TC_RC_RC_Pos))) +/* -------- TC_SR : (TC Offset: N/A) Status Register -------- */ +#define TC_SR_COVFS (0x1u << 0) /**< \brief (TC_SR) Counter Overflow Status */ +#define TC_SR_LOVRS (0x1u << 1) /**< \brief (TC_SR) Load Overrun Status */ +#define TC_SR_CPAS (0x1u << 2) /**< \brief (TC_SR) RA Compare Status */ +#define TC_SR_CPBS (0x1u << 3) /**< \brief (TC_SR) RB Compare Status */ +#define TC_SR_CPCS (0x1u << 4) /**< \brief (TC_SR) RC Compare Status */ +#define TC_SR_LDRAS (0x1u << 5) /**< \brief (TC_SR) RA Loading Status */ +#define TC_SR_LDRBS (0x1u << 6) /**< \brief (TC_SR) RB Loading Status */ +#define TC_SR_ETRGS (0x1u << 7) /**< \brief (TC_SR) External Trigger Status */ +#define TC_SR_ENDRX (0x1u << 8) /**< \brief (TC_SR) End of Receiver Transfer */ +#define TC_SR_RXBUFF (0x1u << 9) /**< \brief (TC_SR) Reception Buffer Full */ +#define TC_SR_CLKSTA (0x1u << 16) /**< \brief (TC_SR) Clock Enabling Status */ +#define TC_SR_MTIOA (0x1u << 17) /**< \brief (TC_SR) TIOA Mirror */ +#define TC_SR_MTIOB (0x1u << 18) /**< \brief (TC_SR) TIOB Mirror */ +/* -------- TC_IER : (TC Offset: N/A) Interrupt Enable Register -------- */ +#define TC_IER_COVFS (0x1u << 0) /**< \brief (TC_IER) Counter Overflow */ +#define TC_IER_LOVRS (0x1u << 1) /**< \brief (TC_IER) Load Overrun */ +#define TC_IER_CPAS (0x1u << 2) /**< \brief (TC_IER) RA Compare */ +#define TC_IER_CPBS (0x1u << 3) /**< \brief (TC_IER) RB Compare */ +#define TC_IER_CPCS (0x1u << 4) /**< \brief (TC_IER) RC Compare */ +#define TC_IER_LDRAS (0x1u << 5) /**< \brief (TC_IER) RA Loading */ +#define TC_IER_LDRBS (0x1u << 6) /**< \brief (TC_IER) RB Loading */ +#define TC_IER_ETRGS (0x1u << 7) /**< \brief (TC_IER) External Trigger */ +#define TC_IER_ENDRX (0x1u << 8) /**< \brief (TC_IER) End of Receiver Transfer */ +#define TC_IER_RXBUFF (0x1u << 9) /**< \brief (TC_IER) Reception Buffer Full */ +/* -------- TC_IDR : (TC Offset: N/A) Interrupt Disable Register -------- */ +#define TC_IDR_COVFS (0x1u << 0) /**< \brief (TC_IDR) Counter Overflow */ +#define TC_IDR_LOVRS (0x1u << 1) /**< \brief (TC_IDR) Load Overrun */ +#define TC_IDR_CPAS (0x1u << 2) /**< \brief (TC_IDR) RA Compare */ +#define TC_IDR_CPBS (0x1u << 3) /**< \brief (TC_IDR) RB Compare */ +#define TC_IDR_CPCS (0x1u << 4) /**< \brief (TC_IDR) RC Compare */ +#define TC_IDR_LDRAS (0x1u << 5) /**< \brief (TC_IDR) RA Loading */ +#define TC_IDR_LDRBS (0x1u << 6) /**< \brief (TC_IDR) RB Loading */ +#define TC_IDR_ETRGS (0x1u << 7) /**< \brief (TC_IDR) External Trigger */ +#define TC_IDR_ENDRX (0x1u << 8) /**< \brief (TC_IDR) End of Receiver Transfer */ +#define TC_IDR_RXBUFF (0x1u << 9) /**< \brief (TC_IDR) Reception Buffer Full */ +/* -------- TC_IMR : (TC Offset: N/A) Interrupt Mask Register -------- */ +#define TC_IMR_COVFS (0x1u << 0) /**< \brief (TC_IMR) Counter Overflow */ +#define TC_IMR_LOVRS (0x1u << 1) /**< \brief (TC_IMR) Load Overrun */ +#define TC_IMR_CPAS (0x1u << 2) /**< \brief (TC_IMR) RA Compare */ +#define TC_IMR_CPBS (0x1u << 3) /**< \brief (TC_IMR) RB Compare */ +#define TC_IMR_CPCS (0x1u << 4) /**< \brief (TC_IMR) RC Compare */ +#define TC_IMR_LDRAS (0x1u << 5) /**< \brief (TC_IMR) RA Loading */ +#define TC_IMR_LDRBS (0x1u << 6) /**< \brief (TC_IMR) RB Loading */ +#define TC_IMR_ETRGS (0x1u << 7) /**< \brief (TC_IMR) External Trigger */ +#define TC_IMR_ENDRX (0x1u << 8) /**< \brief (TC_IMR) End of Receiver Transfer */ +#define TC_IMR_RXBUFF (0x1u << 9) /**< \brief (TC_IMR) Reception Buffer Full */ +/* -------- TC_EMR : (TC Offset: N/A) Extended Mode Register -------- */ +#define TC_EMR_TRIGSRCA_Pos 0 +#define TC_EMR_TRIGSRCA_Msk (0x3u << TC_EMR_TRIGSRCA_Pos) /**< \brief (TC_EMR) TRIGger SouRCe for input A */ +#define TC_EMR_TRIGSRCA_EXTERNAL_TIOAx (0x0u << 0) /**< \brief (TC_EMR) The trigger/capture input A is driven by external pin TIOAx */ +#define TC_EMR_TRIGSRCA_PWMx (0x1u << 0) /**< \brief (TC_EMR) The trigger/capture input A is driven internally by PWMx */ +#define TC_EMR_TRIGSRCB_Pos 4 +#define TC_EMR_TRIGSRCB_Msk (0x3u << TC_EMR_TRIGSRCB_Pos) /**< \brief (TC_EMR) TRIGger SouRCe for input B */ +#define TC_EMR_TRIGSRCB_EXTERNAL_TIOBx (0x0u << 4) /**< \brief (TC_EMR) The trigger/capture input B is driven by external pin TIOBx */ +#define TC_EMR_TRIGSRCB_PWMx (0x1u << 4) /**< \brief (TC_EMR) The trigger/capture input B is driven internally by PWMx */ +#define TC_EMR_NODIVCLK (0x1u << 8) /**< \brief (TC_EMR) NO DIVided CLocK */ +/* -------- TC_BCR : (TC Offset: 0xC0) Block Control Register -------- */ +#define TC_BCR_SYNC (0x1u << 0) /**< \brief (TC_BCR) Synchro Command */ +/* -------- TC_BMR : (TC Offset: 0xC4) Block Mode Register -------- */ +#define TC_BMR_TC0XC0S_Pos 0 +#define TC_BMR_TC0XC0S_Msk (0x3u << TC_BMR_TC0XC0S_Pos) /**< \brief (TC_BMR) External Clock Signal 0 Selection */ +#define TC_BMR_TC0XC0S_TCLK0 (0x0u << 0) /**< \brief (TC_BMR) Signal connected to XC0: TCLK0 */ +#define TC_BMR_TC0XC0S_TIOA1 (0x2u << 0) /**< \brief (TC_BMR) Signal connected to XC0: TIOA1 */ +#define TC_BMR_TC0XC0S_TIOA2 (0x3u << 0) /**< \brief (TC_BMR) Signal connected to XC0: TIOA2 */ +#define TC_BMR_TC1XC1S_Pos 2 +#define TC_BMR_TC1XC1S_Msk (0x3u << TC_BMR_TC1XC1S_Pos) /**< \brief (TC_BMR) External Clock Signal 1 Selection */ +#define TC_BMR_TC1XC1S_TCLK1 (0x0u << 2) /**< \brief (TC_BMR) Signal connected to XC1: TCLK1 */ +#define TC_BMR_TC1XC1S_TIOA0 (0x2u << 2) /**< \brief (TC_BMR) Signal connected to XC1: TIOA0 */ +#define TC_BMR_TC1XC1S_TIOA2 (0x3u << 2) /**< \brief (TC_BMR) Signal connected to XC1: TIOA2 */ +#define TC_BMR_TC2XC2S_Pos 4 +#define TC_BMR_TC2XC2S_Msk (0x3u << TC_BMR_TC2XC2S_Pos) /**< \brief (TC_BMR) External Clock Signal 2 Selection */ +#define TC_BMR_TC2XC2S_TCLK2 (0x0u << 4) /**< \brief (TC_BMR) Signal connected to XC2: TCLK2 */ +#define TC_BMR_TC2XC2S_TIOA0 (0x2u << 4) /**< \brief (TC_BMR) Signal connected to XC2: TIOA0 */ +#define TC_BMR_TC2XC2S_TIOA1 (0x3u << 4) /**< \brief (TC_BMR) Signal connected to XC2: TIOA1 */ +#define TC_BMR_QDEN (0x1u << 8) /**< \brief (TC_BMR) Quadrature Decoder ENabled */ +#define TC_BMR_POSEN (0x1u << 9) /**< \brief (TC_BMR) POSition ENabled */ +#define TC_BMR_SPEEDEN (0x1u << 10) /**< \brief (TC_BMR) SPEED ENabled */ +#define TC_BMR_QDTRANS (0x1u << 11) /**< \brief (TC_BMR) Quadrature Decoding TRANSparent */ +#define TC_BMR_EDGPHA (0x1u << 12) /**< \brief (TC_BMR) EDGe on PHA count mode */ +#define TC_BMR_INVA (0x1u << 13) /**< \brief (TC_BMR) INVerted phA */ +#define TC_BMR_INVB (0x1u << 14) /**< \brief (TC_BMR) INVerted phB */ +#define TC_BMR_INVIDX (0x1u << 15) /**< \brief (TC_BMR) INVerted InDeX */ +#define TC_BMR_SWAP (0x1u << 16) /**< \brief (TC_BMR) SWAP PHA and PHB */ +#define TC_BMR_IDXPHB (0x1u << 17) /**< \brief (TC_BMR) InDeX pin is PHB pin */ +#define TC_BMR_FILTER (0x1u << 19) /**< \brief (TC_BMR) Glitch Filter */ +#define TC_BMR_MAXFILT_Pos 20 +#define TC_BMR_MAXFILT_Msk (0x3fu << TC_BMR_MAXFILT_Pos) /**< \brief (TC_BMR) MAXimum FILTer */ +#define TC_BMR_MAXFILT(value) ((TC_BMR_MAXFILT_Msk & ((value) << TC_BMR_MAXFILT_Pos))) +/* -------- TC_QIER : (TC Offset: 0xC8) QDEC Interrupt Enable Register -------- */ +#define TC_QIER_IDX (0x1u << 0) /**< \brief (TC_QIER) InDeX */ +#define TC_QIER_DIRCHG (0x1u << 1) /**< \brief (TC_QIER) DIRection CHanGe */ +#define TC_QIER_QERR (0x1u << 2) /**< \brief (TC_QIER) Quadrature ERRor */ +/* -------- TC_QIDR : (TC Offset: 0xCC) QDEC Interrupt Disable Register -------- */ +#define TC_QIDR_IDX (0x1u << 0) /**< \brief (TC_QIDR) InDeX */ +#define TC_QIDR_DIRCHG (0x1u << 1) /**< \brief (TC_QIDR) DIRection CHanGe */ +#define TC_QIDR_QERR (0x1u << 2) /**< \brief (TC_QIDR) Quadrature ERRor */ +/* -------- TC_QIMR : (TC Offset: 0xD0) QDEC Interrupt Mask Register -------- */ +#define TC_QIMR_IDX (0x1u << 0) /**< \brief (TC_QIMR) InDeX */ +#define TC_QIMR_DIRCHG (0x1u << 1) /**< \brief (TC_QIMR) DIRection CHanGe */ +#define TC_QIMR_QERR (0x1u << 2) /**< \brief (TC_QIMR) Quadrature ERRor */ +/* -------- TC_QISR : (TC Offset: 0xD4) QDEC Interrupt Status Register -------- */ +#define TC_QISR_IDX (0x1u << 0) /**< \brief (TC_QISR) InDeX */ +#define TC_QISR_DIRCHG (0x1u << 1) /**< \brief (TC_QISR) DIRection CHanGe */ +#define TC_QISR_QERR (0x1u << 2) /**< \brief (TC_QISR) Quadrature ERRor */ +#define TC_QISR_DIR (0x1u << 8) /**< \brief (TC_QISR) DIRection */ +/* -------- TC_FMR : (TC Offset: 0xD8) Fault Mode Register -------- */ +#define TC_FMR_ENCF0 (0x1u << 0) /**< \brief (TC_FMR) ENable Compare Fault Channel 0 */ +#define TC_FMR_ENCF1 (0x1u << 1) /**< \brief (TC_FMR) ENable Compare Fault Channel 1 */ +/* -------- TC_WPMR : (TC Offset: 0xE4) Write Protection Mode Register -------- */ +#define TC_WPMR_WPEN (0x1u << 0) /**< \brief (TC_WPMR) Write Protect Enable */ +#define TC_WPMR_WPKEY_Pos 8 +#define TC_WPMR_WPKEY_Msk (0xffffffu << TC_WPMR_WPKEY_Pos) /**< \brief (TC_WPMR) Write Protect KEY */ +#define TC_WPMR_WPKEY_PASSWD (0x54494Du << 8) /**< \brief (TC_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0. */ +/* -------- TC_RPR : (TC Offset: N/A) Receive Pointer Register -------- */ +#define TC_RPR_RXPTR_Pos 0 +#define TC_RPR_RXPTR_Msk (0xffffffffu << TC_RPR_RXPTR_Pos) /**< \brief (TC_RPR) Receive Pointer Register */ +#define TC_RPR_RXPTR(value) ((TC_RPR_RXPTR_Msk & ((value) << TC_RPR_RXPTR_Pos))) +/* -------- TC_RCR : (TC Offset: N/A) Receive Counter Register -------- */ +#define TC_RCR_RXCTR_Pos 0 +#define TC_RCR_RXCTR_Msk (0xffffu << TC_RCR_RXCTR_Pos) /**< \brief (TC_RCR) Receive Counter Register */ +#define TC_RCR_RXCTR(value) ((TC_RCR_RXCTR_Msk & ((value) << TC_RCR_RXCTR_Pos))) +/* -------- TC_RNPR : (TC Offset: N/A) Receive Next Pointer Register -------- */ +#define TC_RNPR_RXNPTR_Pos 0 +#define TC_RNPR_RXNPTR_Msk (0xffffffffu << TC_RNPR_RXNPTR_Pos) /**< \brief (TC_RNPR) Receive Next Pointer */ +#define TC_RNPR_RXNPTR(value) ((TC_RNPR_RXNPTR_Msk & ((value) << TC_RNPR_RXNPTR_Pos))) +/* -------- TC_RNCR : (TC Offset: N/A) Receive Next Counter Register -------- */ +#define TC_RNCR_RXNCTR_Pos 0 +#define TC_RNCR_RXNCTR_Msk (0xffffu << TC_RNCR_RXNCTR_Pos) /**< \brief (TC_RNCR) Receive Next Counter */ +#define TC_RNCR_RXNCTR(value) ((TC_RNCR_RXNCTR_Msk & ((value) << TC_RNCR_RXNCTR_Pos))) +/* -------- TC_PTCR : (TC Offset: N/A) Transfer Control Register -------- */ +#define TC_PTCR_RXTEN (0x1u << 0) /**< \brief (TC_PTCR) Receiver Transfer Enable */ +#define TC_PTCR_RXTDIS (0x1u << 1) /**< \brief (TC_PTCR) Receiver Transfer Disable */ +#define TC_PTCR_TXTEN (0x1u << 8) /**< \brief (TC_PTCR) Transmitter Transfer Enable */ +#define TC_PTCR_TXTDIS (0x1u << 9) /**< \brief (TC_PTCR) Transmitter Transfer Disable */ +/* -------- TC_PTSR : (TC Offset: N/A) Transfer Status Register -------- */ +#define TC_PTSR_RXTEN (0x1u << 0) /**< \brief (TC_PTSR) Receiver Transfer Enable */ +#define TC_PTSR_TXTEN (0x1u << 8) /**< \brief (TC_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_TC_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/twi.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/twi.h new file mode 100644 index 0000000..e2eefeb --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/twi.h @@ -0,0 +1,244 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TWI_COMPONENT_ +#define _SAM4E_TWI_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Two-wire Interface */ +/* ============================================================================= */ +/** \addtogroup SAM4E_TWI Two-wire Interface */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Twi hardware registers */ +typedef struct { + __O uint32_t TWI_CR; /**< \brief (Twi Offset: 0x00) Control Register */ + __IO uint32_t TWI_MMR; /**< \brief (Twi Offset: 0x04) Master Mode Register */ + __IO uint32_t TWI_SMR; /**< \brief (Twi Offset: 0x08) Slave Mode Register */ + __IO uint32_t TWI_IADR; /**< \brief (Twi Offset: 0x0C) Internal Address Register */ + __IO uint32_t TWI_CWGR; /**< \brief (Twi Offset: 0x10) Clock Waveform Generator Register */ + __I uint32_t Reserved1[3]; + __I uint32_t TWI_SR; /**< \brief (Twi Offset: 0x20) Status Register */ + __O uint32_t TWI_IER; /**< \brief (Twi Offset: 0x24) Interrupt Enable Register */ + __O uint32_t TWI_IDR; /**< \brief (Twi Offset: 0x28) Interrupt Disable Register */ + __I uint32_t TWI_IMR; /**< \brief (Twi Offset: 0x2C) Interrupt Mask Register */ + __I uint32_t TWI_RHR; /**< \brief (Twi Offset: 0x30) Receive Holding Register */ + __O uint32_t TWI_THR; /**< \brief (Twi Offset: 0x34) Transmit Holding Register */ + __I uint32_t Reserved2[43]; + __IO uint32_t TWI_WPMR; /**< \brief (Twi Offset: 0xE4) Write Protection Mode Register */ + __I uint32_t TWI_WPSR; /**< \brief (Twi Offset: 0xE8) Write Protection Status Register */ + __I uint32_t Reserved3[5]; + __IO uint32_t TWI_RPR; /**< \brief (Twi Offset: 0x100) Receive Pointer Register */ + __IO uint32_t TWI_RCR; /**< \brief (Twi Offset: 0x104) Receive Counter Register */ + __IO uint32_t TWI_TPR; /**< \brief (Twi Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t TWI_TCR; /**< \brief (Twi Offset: 0x10C) Transmit Counter Register */ + __IO uint32_t TWI_RNPR; /**< \brief (Twi Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t TWI_RNCR; /**< \brief (Twi Offset: 0x114) Receive Next Counter Register */ + __IO uint32_t TWI_TNPR; /**< \brief (Twi Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t TWI_TNCR; /**< \brief (Twi Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t TWI_PTCR; /**< \brief (Twi Offset: 0x120) Transfer Control Register */ + __I uint32_t TWI_PTSR; /**< \brief (Twi Offset: 0x124) Transfer Status Register */ +} Twi; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- TWI_CR : (TWI Offset: 0x00) Control Register -------- */ +#define TWI_CR_START (0x1u << 0) /**< \brief (TWI_CR) Send a START Condition */ +#define TWI_CR_STOP (0x1u << 1) /**< \brief (TWI_CR) Send a STOP Condition */ +#define TWI_CR_MSEN (0x1u << 2) /**< \brief (TWI_CR) TWI Master Mode Enabled */ +#define TWI_CR_MSDIS (0x1u << 3) /**< \brief (TWI_CR) TWI Master Mode Disabled */ +#define TWI_CR_SVEN (0x1u << 4) /**< \brief (TWI_CR) TWI Slave Mode Enabled */ +#define TWI_CR_SVDIS (0x1u << 5) /**< \brief (TWI_CR) TWI Slave Mode Disabled */ +#define TWI_CR_QUICK (0x1u << 6) /**< \brief (TWI_CR) SMBus Quick Command */ +#define TWI_CR_SWRST (0x1u << 7) /**< \brief (TWI_CR) Software Reset */ +/* -------- TWI_MMR : (TWI Offset: 0x04) Master Mode Register -------- */ +#define TWI_MMR_IADRSZ_Pos 8 +#define TWI_MMR_IADRSZ_Msk (0x3u << TWI_MMR_IADRSZ_Pos) /**< \brief (TWI_MMR) Internal Device Address Size */ +#define TWI_MMR_IADRSZ_NONE (0x0u << 8) /**< \brief (TWI_MMR) No internal device address */ +#define TWI_MMR_IADRSZ_1_BYTE (0x1u << 8) /**< \brief (TWI_MMR) One-byte internal device address */ +#define TWI_MMR_IADRSZ_2_BYTE (0x2u << 8) /**< \brief (TWI_MMR) Two-byte internal device address */ +#define TWI_MMR_IADRSZ_3_BYTE (0x3u << 8) /**< \brief (TWI_MMR) Three-byte internal device address */ +#define TWI_MMR_MREAD (0x1u << 12) /**< \brief (TWI_MMR) Master Read Direction */ +#define TWI_MMR_DADR_Pos 16 +#define TWI_MMR_DADR_Msk (0x7fu << TWI_MMR_DADR_Pos) /**< \brief (TWI_MMR) Device Address */ +#define TWI_MMR_DADR(value) ((TWI_MMR_DADR_Msk & ((value) << TWI_MMR_DADR_Pos))) +/* -------- TWI_SMR : (TWI Offset: 0x08) Slave Mode Register -------- */ +#define TWI_SMR_SADR_Pos 16 +#define TWI_SMR_SADR_Msk (0x7fu << TWI_SMR_SADR_Pos) /**< \brief (TWI_SMR) Slave Address */ +#define TWI_SMR_SADR(value) ((TWI_SMR_SADR_Msk & ((value) << TWI_SMR_SADR_Pos))) +/* -------- TWI_IADR : (TWI Offset: 0x0C) Internal Address Register -------- */ +#define TWI_IADR_IADR_Pos 0 +#define TWI_IADR_IADR_Msk (0xffffffu << TWI_IADR_IADR_Pos) /**< \brief (TWI_IADR) Internal Address */ +#define TWI_IADR_IADR(value) ((TWI_IADR_IADR_Msk & ((value) << TWI_IADR_IADR_Pos))) +/* -------- TWI_CWGR : (TWI Offset: 0x10) Clock Waveform Generator Register -------- */ +#define TWI_CWGR_CLDIV_Pos 0 +#define TWI_CWGR_CLDIV_Msk (0xffu << TWI_CWGR_CLDIV_Pos) /**< \brief (TWI_CWGR) Clock Low Divider */ +#define TWI_CWGR_CLDIV(value) ((TWI_CWGR_CLDIV_Msk & ((value) << TWI_CWGR_CLDIV_Pos))) +#define TWI_CWGR_CHDIV_Pos 8 +#define TWI_CWGR_CHDIV_Msk (0xffu << TWI_CWGR_CHDIV_Pos) /**< \brief (TWI_CWGR) Clock High Divider */ +#define TWI_CWGR_CHDIV(value) ((TWI_CWGR_CHDIV_Msk & ((value) << TWI_CWGR_CHDIV_Pos))) +#define TWI_CWGR_CKDIV_Pos 16 +#define TWI_CWGR_CKDIV_Msk (0x7u << TWI_CWGR_CKDIV_Pos) /**< \brief (TWI_CWGR) Clock Divider */ +#define TWI_CWGR_CKDIV(value) ((TWI_CWGR_CKDIV_Msk & ((value) << TWI_CWGR_CKDIV_Pos))) +/* -------- TWI_SR : (TWI Offset: 0x20) Status Register -------- */ +#define TWI_SR_TXCOMP (0x1u << 0) /**< \brief (TWI_SR) Transmission Completed (automatically set / reset) */ +#define TWI_SR_RXRDY (0x1u << 1) /**< \brief (TWI_SR) Receive Holding Register Ready (automatically set / reset) */ +#define TWI_SR_TXRDY (0x1u << 2) /**< \brief (TWI_SR) Transmit Holding Register Ready (automatically set / reset) */ +#define TWI_SR_SVREAD (0x1u << 3) /**< \brief (TWI_SR) Slave Read (automatically set / reset) */ +#define TWI_SR_SVACC (0x1u << 4) /**< \brief (TWI_SR) Slave Access (automatically set / reset) */ +#define TWI_SR_GACC (0x1u << 5) /**< \brief (TWI_SR) General Call Access (clear on read) */ +#define TWI_SR_OVRE (0x1u << 6) /**< \brief (TWI_SR) Overrun Error (clear on read) */ +#define TWI_SR_NACK (0x1u << 8) /**< \brief (TWI_SR) Not Acknowledged (clear on read) */ +#define TWI_SR_ARBLST (0x1u << 9) /**< \brief (TWI_SR) Arbitration Lost (clear on read) */ +#define TWI_SR_SCLWS (0x1u << 10) /**< \brief (TWI_SR) Clock Wait State (automatically set / reset) */ +#define TWI_SR_EOSACC (0x1u << 11) /**< \brief (TWI_SR) End Of Slave Access (clear on read) */ +#define TWI_SR_ENDRX (0x1u << 12) /**< \brief (TWI_SR) End of RX buffer */ +#define TWI_SR_ENDTX (0x1u << 13) /**< \brief (TWI_SR) End of TX buffer */ +#define TWI_SR_RXBUFF (0x1u << 14) /**< \brief (TWI_SR) RX Buffer Full */ +#define TWI_SR_TXBUFE (0x1u << 15) /**< \brief (TWI_SR) TX Buffer Empty */ +/* -------- TWI_IER : (TWI Offset: 0x24) Interrupt Enable Register -------- */ +#define TWI_IER_TXCOMP (0x1u << 0) /**< \brief (TWI_IER) Transmission Completed Interrupt Enable */ +#define TWI_IER_RXRDY (0x1u << 1) /**< \brief (TWI_IER) Receive Holding Register Ready Interrupt Enable */ +#define TWI_IER_TXRDY (0x1u << 2) /**< \brief (TWI_IER) Transmit Holding Register Ready Interrupt Enable */ +#define TWI_IER_SVACC (0x1u << 4) /**< \brief (TWI_IER) Slave Access Interrupt Enable */ +#define TWI_IER_GACC (0x1u << 5) /**< \brief (TWI_IER) General Call Access Interrupt Enable */ +#define TWI_IER_OVRE (0x1u << 6) /**< \brief (TWI_IER) Overrun Error Interrupt Enable */ +#define TWI_IER_NACK (0x1u << 8) /**< \brief (TWI_IER) Not Acknowledge Interrupt Enable */ +#define TWI_IER_ARBLST (0x1u << 9) /**< \brief (TWI_IER) Arbitration Lost Interrupt Enable */ +#define TWI_IER_SCL_WS (0x1u << 10) /**< \brief (TWI_IER) Clock Wait State Interrupt Enable */ +#define TWI_IER_EOSACC (0x1u << 11) /**< \brief (TWI_IER) End Of Slave Access Interrupt Enable */ +#define TWI_IER_ENDRX (0x1u << 12) /**< \brief (TWI_IER) End of Receive Buffer Interrupt Enable */ +#define TWI_IER_ENDTX (0x1u << 13) /**< \brief (TWI_IER) End of Transmit Buffer Interrupt Enable */ +#define TWI_IER_RXBUFF (0x1u << 14) /**< \brief (TWI_IER) Receive Buffer Full Interrupt Enable */ +#define TWI_IER_TXBUFE (0x1u << 15) /**< \brief (TWI_IER) Transmit Buffer Empty Interrupt Enable */ +/* -------- TWI_IDR : (TWI Offset: 0x28) Interrupt Disable Register -------- */ +#define TWI_IDR_TXCOMP (0x1u << 0) /**< \brief (TWI_IDR) Transmission Completed Interrupt Disable */ +#define TWI_IDR_RXRDY (0x1u << 1) /**< \brief (TWI_IDR) Receive Holding Register Ready Interrupt Disable */ +#define TWI_IDR_TXRDY (0x1u << 2) /**< \brief (TWI_IDR) Transmit Holding Register Ready Interrupt Disable */ +#define TWI_IDR_SVACC (0x1u << 4) /**< \brief (TWI_IDR) Slave Access Interrupt Disable */ +#define TWI_IDR_GACC (0x1u << 5) /**< \brief (TWI_IDR) General Call Access Interrupt Disable */ +#define TWI_IDR_OVRE (0x1u << 6) /**< \brief (TWI_IDR) Overrun Error Interrupt Disable */ +#define TWI_IDR_NACK (0x1u << 8) /**< \brief (TWI_IDR) Not Acknowledge Interrupt Disable */ +#define TWI_IDR_ARBLST (0x1u << 9) /**< \brief (TWI_IDR) Arbitration Lost Interrupt Disable */ +#define TWI_IDR_SCL_WS (0x1u << 10) /**< \brief (TWI_IDR) Clock Wait State Interrupt Disable */ +#define TWI_IDR_EOSACC (0x1u << 11) /**< \brief (TWI_IDR) End Of Slave Access Interrupt Disable */ +#define TWI_IDR_ENDRX (0x1u << 12) /**< \brief (TWI_IDR) End of Receive Buffer Interrupt Disable */ +#define TWI_IDR_ENDTX (0x1u << 13) /**< \brief (TWI_IDR) End of Transmit Buffer Interrupt Disable */ +#define TWI_IDR_RXBUFF (0x1u << 14) /**< \brief (TWI_IDR) Receive Buffer Full Interrupt Disable */ +#define TWI_IDR_TXBUFE (0x1u << 15) /**< \brief (TWI_IDR) Transmit Buffer Empty Interrupt Disable */ +/* -------- TWI_IMR : (TWI Offset: 0x2C) Interrupt Mask Register -------- */ +#define TWI_IMR_TXCOMP (0x1u << 0) /**< \brief (TWI_IMR) Transmission Completed Interrupt Mask */ +#define TWI_IMR_RXRDY (0x1u << 1) /**< \brief (TWI_IMR) Receive Holding Register Ready Interrupt Mask */ +#define TWI_IMR_TXRDY (0x1u << 2) /**< \brief (TWI_IMR) Transmit Holding Register Ready Interrupt Mask */ +#define TWI_IMR_SVACC (0x1u << 4) /**< \brief (TWI_IMR) Slave Access Interrupt Mask */ +#define TWI_IMR_GACC (0x1u << 5) /**< \brief (TWI_IMR) General Call Access Interrupt Mask */ +#define TWI_IMR_OVRE (0x1u << 6) /**< \brief (TWI_IMR) Overrun Error Interrupt Mask */ +#define TWI_IMR_NACK (0x1u << 8) /**< \brief (TWI_IMR) Not Acknowledge Interrupt Mask */ +#define TWI_IMR_ARBLST (0x1u << 9) /**< \brief (TWI_IMR) Arbitration Lost Interrupt Mask */ +#define TWI_IMR_SCL_WS (0x1u << 10) /**< \brief (TWI_IMR) Clock Wait State Interrupt Mask */ +#define TWI_IMR_EOSACC (0x1u << 11) /**< \brief (TWI_IMR) End Of Slave Access Interrupt Mask */ +#define TWI_IMR_ENDRX (0x1u << 12) /**< \brief (TWI_IMR) End of Receive Buffer Interrupt Mask */ +#define TWI_IMR_ENDTX (0x1u << 13) /**< \brief (TWI_IMR) End of Transmit Buffer Interrupt Mask */ +#define TWI_IMR_RXBUFF (0x1u << 14) /**< \brief (TWI_IMR) Receive Buffer Full Interrupt Mask */ +#define TWI_IMR_TXBUFE (0x1u << 15) /**< \brief (TWI_IMR) Transmit Buffer Empty Interrupt Mask */ +/* -------- TWI_RHR : (TWI Offset: 0x30) Receive Holding Register -------- */ +#define TWI_RHR_RXDATA_Pos 0 +#define TWI_RHR_RXDATA_Msk (0xffu << TWI_RHR_RXDATA_Pos) /**< \brief (TWI_RHR) Master or Slave Receive Holding Data */ +/* -------- TWI_THR : (TWI Offset: 0x34) Transmit Holding Register -------- */ +#define TWI_THR_TXDATA_Pos 0 +#define TWI_THR_TXDATA_Msk (0xffu << TWI_THR_TXDATA_Pos) /**< \brief (TWI_THR) Master or Slave Transmit Holding Data */ +#define TWI_THR_TXDATA(value) ((TWI_THR_TXDATA_Msk & ((value) << TWI_THR_TXDATA_Pos))) +/* -------- TWI_WPMR : (TWI Offset: 0xE4) Write Protection Mode Register -------- */ +#define TWI_WPMR_WPEN (0x1u << 0) /**< \brief (TWI_WPMR) Write Protection Enable */ +#define TWI_WPMR_WPKEY_Pos 8 +#define TWI_WPMR_WPKEY_Msk (0xffffffu << TWI_WPMR_WPKEY_Pos) /**< \brief (TWI_WPMR) Write Protection Key */ +#define TWI_WPMR_WPKEY_PASSWD (0x545749u << 8) /**< \brief (TWI_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit.Always reads as 0 */ +/* -------- TWI_WPSR : (TWI Offset: 0xE8) Write Protection Status Register -------- */ +#define TWI_WPSR_WPVS (0x1u << 0) /**< \brief (TWI_WPSR) Write Protection Violation Status */ +#define TWI_WPSR_WPVSRC_Pos 8 +#define TWI_WPSR_WPVSRC_Msk (0xffffffu << TWI_WPSR_WPVSRC_Pos) /**< \brief (TWI_WPSR) Write Protection Violation Source */ +/* -------- TWI_RPR : (TWI Offset: 0x100) Receive Pointer Register -------- */ +#define TWI_RPR_RXPTR_Pos 0 +#define TWI_RPR_RXPTR_Msk (0xffffffffu << TWI_RPR_RXPTR_Pos) /**< \brief (TWI_RPR) Receive Pointer Register */ +#define TWI_RPR_RXPTR(value) ((TWI_RPR_RXPTR_Msk & ((value) << TWI_RPR_RXPTR_Pos))) +/* -------- TWI_RCR : (TWI Offset: 0x104) Receive Counter Register -------- */ +#define TWI_RCR_RXCTR_Pos 0 +#define TWI_RCR_RXCTR_Msk (0xffffu << TWI_RCR_RXCTR_Pos) /**< \brief (TWI_RCR) Receive Counter Register */ +#define TWI_RCR_RXCTR(value) ((TWI_RCR_RXCTR_Msk & ((value) << TWI_RCR_RXCTR_Pos))) +/* -------- TWI_TPR : (TWI Offset: 0x108) Transmit Pointer Register -------- */ +#define TWI_TPR_TXPTR_Pos 0 +#define TWI_TPR_TXPTR_Msk (0xffffffffu << TWI_TPR_TXPTR_Pos) /**< \brief (TWI_TPR) Transmit Counter Register */ +#define TWI_TPR_TXPTR(value) ((TWI_TPR_TXPTR_Msk & ((value) << TWI_TPR_TXPTR_Pos))) +/* -------- TWI_TCR : (TWI Offset: 0x10C) Transmit Counter Register -------- */ +#define TWI_TCR_TXCTR_Pos 0 +#define TWI_TCR_TXCTR_Msk (0xffffu << TWI_TCR_TXCTR_Pos) /**< \brief (TWI_TCR) Transmit Counter Register */ +#define TWI_TCR_TXCTR(value) ((TWI_TCR_TXCTR_Msk & ((value) << TWI_TCR_TXCTR_Pos))) +/* -------- TWI_RNPR : (TWI Offset: 0x110) Receive Next Pointer Register -------- */ +#define TWI_RNPR_RXNPTR_Pos 0 +#define TWI_RNPR_RXNPTR_Msk (0xffffffffu << TWI_RNPR_RXNPTR_Pos) /**< \brief (TWI_RNPR) Receive Next Pointer */ +#define TWI_RNPR_RXNPTR(value) ((TWI_RNPR_RXNPTR_Msk & ((value) << TWI_RNPR_RXNPTR_Pos))) +/* -------- TWI_RNCR : (TWI Offset: 0x114) Receive Next Counter Register -------- */ +#define TWI_RNCR_RXNCTR_Pos 0 +#define TWI_RNCR_RXNCTR_Msk (0xffffu << TWI_RNCR_RXNCTR_Pos) /**< \brief (TWI_RNCR) Receive Next Counter */ +#define TWI_RNCR_RXNCTR(value) ((TWI_RNCR_RXNCTR_Msk & ((value) << TWI_RNCR_RXNCTR_Pos))) +/* -------- TWI_TNPR : (TWI Offset: 0x118) Transmit Next Pointer Register -------- */ +#define TWI_TNPR_TXNPTR_Pos 0 +#define TWI_TNPR_TXNPTR_Msk (0xffffffffu << TWI_TNPR_TXNPTR_Pos) /**< \brief (TWI_TNPR) Transmit Next Pointer */ +#define TWI_TNPR_TXNPTR(value) ((TWI_TNPR_TXNPTR_Msk & ((value) << TWI_TNPR_TXNPTR_Pos))) +/* -------- TWI_TNCR : (TWI Offset: 0x11C) Transmit Next Counter Register -------- */ +#define TWI_TNCR_TXNCTR_Pos 0 +#define TWI_TNCR_TXNCTR_Msk (0xffffu << TWI_TNCR_TXNCTR_Pos) /**< \brief (TWI_TNCR) Transmit Counter Next */ +#define TWI_TNCR_TXNCTR(value) ((TWI_TNCR_TXNCTR_Msk & ((value) << TWI_TNCR_TXNCTR_Pos))) +/* -------- TWI_PTCR : (TWI Offset: 0x120) Transfer Control Register -------- */ +#define TWI_PTCR_RXTEN (0x1u << 0) /**< \brief (TWI_PTCR) Receiver Transfer Enable */ +#define TWI_PTCR_RXTDIS (0x1u << 1) /**< \brief (TWI_PTCR) Receiver Transfer Disable */ +#define TWI_PTCR_TXTEN (0x1u << 8) /**< \brief (TWI_PTCR) Transmitter Transfer Enable */ +#define TWI_PTCR_TXTDIS (0x1u << 9) /**< \brief (TWI_PTCR) Transmitter Transfer Disable */ +/* -------- TWI_PTSR : (TWI Offset: 0x124) Transfer Status Register -------- */ +#define TWI_PTSR_RXTEN (0x1u << 0) /**< \brief (TWI_PTSR) Receiver Transfer Enable */ +#define TWI_PTSR_TXTEN (0x1u << 8) /**< \brief (TWI_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_TWI_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/uart.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/uart.h new file mode 100644 index 0000000..68817de --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/uart.h @@ -0,0 +1,207 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_UART_COMPONENT_ +#define _SAM4E_UART_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Universal Asynchronous Receiver Transmitter */ +/* ============================================================================= */ +/** \addtogroup SAM4E_UART Universal Asynchronous Receiver Transmitter */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Uart hardware registers */ +typedef struct { + __O uint32_t UART_CR; /**< \brief (Uart Offset: 0x0000) Control Register */ + __IO uint32_t UART_MR; /**< \brief (Uart Offset: 0x0004) Mode Register */ + __O uint32_t UART_IER; /**< \brief (Uart Offset: 0x0008) Interrupt Enable Register */ + __O uint32_t UART_IDR; /**< \brief (Uart Offset: 0x000C) Interrupt Disable Register */ + __I uint32_t UART_IMR; /**< \brief (Uart Offset: 0x0010) Interrupt Mask Register */ + __I uint32_t UART_SR; /**< \brief (Uart Offset: 0x0014) Status Register */ + __I uint32_t UART_RHR; /**< \brief (Uart Offset: 0x0018) Receive Holding Register */ + __O uint32_t UART_THR; /**< \brief (Uart Offset: 0x001C) Transmit Holding Register */ + __IO uint32_t UART_BRGR; /**< \brief (Uart Offset: 0x0020) Baud Rate Generator Register */ + __I uint32_t Reserved1[48]; + __IO uint32_t UART_WPMR; /**< \brief (Uart Offset: 0x00E4) Write Protection Mode Register */ + __I uint32_t Reserved2[6]; + __IO uint32_t UART_RPR; /**< \brief (Uart Offset: 0x100) Receive Pointer Register */ + __IO uint32_t UART_RCR; /**< \brief (Uart Offset: 0x104) Receive Counter Register */ + __IO uint32_t UART_TPR; /**< \brief (Uart Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t UART_TCR; /**< \brief (Uart Offset: 0x10C) Transmit Counter Register */ + __IO uint32_t UART_RNPR; /**< \brief (Uart Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t UART_RNCR; /**< \brief (Uart Offset: 0x114) Receive Next Counter Register */ + __IO uint32_t UART_TNPR; /**< \brief (Uart Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t UART_TNCR; /**< \brief (Uart Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t UART_PTCR; /**< \brief (Uart Offset: 0x120) Transfer Control Register */ + __I uint32_t UART_PTSR; /**< \brief (Uart Offset: 0x124) Transfer Status Register */ +} Uart; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- UART_CR : (UART Offset: 0x0000) Control Register -------- */ +#define UART_CR_RSTRX (0x1u << 2) /**< \brief (UART_CR) Reset Receiver */ +#define UART_CR_RSTTX (0x1u << 3) /**< \brief (UART_CR) Reset Transmitter */ +#define UART_CR_RXEN (0x1u << 4) /**< \brief (UART_CR) Receiver Enable */ +#define UART_CR_RXDIS (0x1u << 5) /**< \brief (UART_CR) Receiver Disable */ +#define UART_CR_TXEN (0x1u << 6) /**< \brief (UART_CR) Transmitter Enable */ +#define UART_CR_TXDIS (0x1u << 7) /**< \brief (UART_CR) Transmitter Disable */ +#define UART_CR_RSTSTA (0x1u << 8) /**< \brief (UART_CR) Reset Status */ +/* -------- UART_MR : (UART Offset: 0x0004) Mode Register -------- */ +#define UART_MR_PAR_Pos 9 +#define UART_MR_PAR_Msk (0x7u << UART_MR_PAR_Pos) /**< \brief (UART_MR) Parity Type */ +#define UART_MR_PAR_EVEN (0x0u << 9) /**< \brief (UART_MR) Even Parity */ +#define UART_MR_PAR_ODD (0x1u << 9) /**< \brief (UART_MR) Odd Parity */ +#define UART_MR_PAR_SPACE (0x2u << 9) /**< \brief (UART_MR) Space: parity forced to 0 */ +#define UART_MR_PAR_MARK (0x3u << 9) /**< \brief (UART_MR) Mark: parity forced to 1 */ +#define UART_MR_PAR_NO (0x4u << 9) /**< \brief (UART_MR) No parity */ +#define UART_MR_CHMODE_Pos 14 +#define UART_MR_CHMODE_Msk (0x3u << UART_MR_CHMODE_Pos) /**< \brief (UART_MR) Channel Mode */ +#define UART_MR_CHMODE_NORMAL (0x0u << 14) /**< \brief (UART_MR) Normal mode */ +#define UART_MR_CHMODE_AUTOMATIC (0x1u << 14) /**< \brief (UART_MR) Automatic echo */ +#define UART_MR_CHMODE_LOCAL_LOOPBACK (0x2u << 14) /**< \brief (UART_MR) Local loopback */ +#define UART_MR_CHMODE_REMOTE_LOOPBACK (0x3u << 14) /**< \brief (UART_MR) Remote loopback */ +/* -------- UART_IER : (UART Offset: 0x0008) Interrupt Enable Register -------- */ +#define UART_IER_RXRDY (0x1u << 0) /**< \brief (UART_IER) Enable RXRDY Interrupt */ +#define UART_IER_TXRDY (0x1u << 1) /**< \brief (UART_IER) Enable TXRDY Interrupt */ +#define UART_IER_ENDRX (0x1u << 3) /**< \brief (UART_IER) Enable End of Receive Transfer Interrupt */ +#define UART_IER_ENDTX (0x1u << 4) /**< \brief (UART_IER) Enable End of Transmit Interrupt */ +#define UART_IER_OVRE (0x1u << 5) /**< \brief (UART_IER) Enable Overrun Error Interrupt */ +#define UART_IER_FRAME (0x1u << 6) /**< \brief (UART_IER) Enable Framing Error Interrupt */ +#define UART_IER_PARE (0x1u << 7) /**< \brief (UART_IER) Enable Parity Error Interrupt */ +#define UART_IER_TXEMPTY (0x1u << 9) /**< \brief (UART_IER) Enable TXEMPTY Interrupt */ +#define UART_IER_TXBUFE (0x1u << 11) /**< \brief (UART_IER) Enable Buffer Empty Interrupt */ +#define UART_IER_RXBUFF (0x1u << 12) /**< \brief (UART_IER) Enable Buffer Full Interrupt */ +/* -------- UART_IDR : (UART Offset: 0x000C) Interrupt Disable Register -------- */ +#define UART_IDR_RXRDY (0x1u << 0) /**< \brief (UART_IDR) Disable RXRDY Interrupt */ +#define UART_IDR_TXRDY (0x1u << 1) /**< \brief (UART_IDR) Disable TXRDY Interrupt */ +#define UART_IDR_ENDRX (0x1u << 3) /**< \brief (UART_IDR) Disable End of Receive Transfer Interrupt */ +#define UART_IDR_ENDTX (0x1u << 4) /**< \brief (UART_IDR) Disable End of Transmit Interrupt */ +#define UART_IDR_OVRE (0x1u << 5) /**< \brief (UART_IDR) Disable Overrun Error Interrupt */ +#define UART_IDR_FRAME (0x1u << 6) /**< \brief (UART_IDR) Disable Framing Error Interrupt */ +#define UART_IDR_PARE (0x1u << 7) /**< \brief (UART_IDR) Disable Parity Error Interrupt */ +#define UART_IDR_TXEMPTY (0x1u << 9) /**< \brief (UART_IDR) Disable TXEMPTY Interrupt */ +#define UART_IDR_TXBUFE (0x1u << 11) /**< \brief (UART_IDR) Disable Buffer Empty Interrupt */ +#define UART_IDR_RXBUFF (0x1u << 12) /**< \brief (UART_IDR) Disable Buffer Full Interrupt */ +/* -------- UART_IMR : (UART Offset: 0x0010) Interrupt Mask Register -------- */ +#define UART_IMR_RXRDY (0x1u << 0) /**< \brief (UART_IMR) Mask RXRDY Interrupt */ +#define UART_IMR_TXRDY (0x1u << 1) /**< \brief (UART_IMR) Disable TXRDY Interrupt */ +#define UART_IMR_ENDRX (0x1u << 3) /**< \brief (UART_IMR) Mask End of Receive Transfer Interrupt */ +#define UART_IMR_ENDTX (0x1u << 4) /**< \brief (UART_IMR) Mask End of Transmit Interrupt */ +#define UART_IMR_OVRE (0x1u << 5) /**< \brief (UART_IMR) Mask Overrun Error Interrupt */ +#define UART_IMR_FRAME (0x1u << 6) /**< \brief (UART_IMR) Mask Framing Error Interrupt */ +#define UART_IMR_PARE (0x1u << 7) /**< \brief (UART_IMR) Mask Parity Error Interrupt */ +#define UART_IMR_TXEMPTY (0x1u << 9) /**< \brief (UART_IMR) Mask TXEMPTY Interrupt */ +#define UART_IMR_TXBUFE (0x1u << 11) /**< \brief (UART_IMR) Mask TXBUFE Interrupt */ +#define UART_IMR_RXBUFF (0x1u << 12) /**< \brief (UART_IMR) Mask RXBUFF Interrupt */ +/* -------- UART_SR : (UART Offset: 0x0014) Status Register -------- */ +#define UART_SR_RXRDY (0x1u << 0) /**< \brief (UART_SR) Receiver Ready */ +#define UART_SR_TXRDY (0x1u << 1) /**< \brief (UART_SR) Transmitter Ready */ +#define UART_SR_ENDRX (0x1u << 3) /**< \brief (UART_SR) End of Receiver Transfer */ +#define UART_SR_ENDTX (0x1u << 4) /**< \brief (UART_SR) End of Transmitter Transfer */ +#define UART_SR_OVRE (0x1u << 5) /**< \brief (UART_SR) Overrun Error */ +#define UART_SR_FRAME (0x1u << 6) /**< \brief (UART_SR) Framing Error */ +#define UART_SR_PARE (0x1u << 7) /**< \brief (UART_SR) Parity Error */ +#define UART_SR_TXEMPTY (0x1u << 9) /**< \brief (UART_SR) Transmitter Empty */ +#define UART_SR_TXBUFE (0x1u << 11) /**< \brief (UART_SR) Transmission Buffer Empty */ +#define UART_SR_RXBUFF (0x1u << 12) /**< \brief (UART_SR) Receive Buffer Full */ +/* -------- UART_RHR : (UART Offset: 0x0018) Receive Holding Register -------- */ +#define UART_RHR_RXCHR_Pos 0 +#define UART_RHR_RXCHR_Msk (0xffu << UART_RHR_RXCHR_Pos) /**< \brief (UART_RHR) Received Character */ +/* -------- UART_THR : (UART Offset: 0x001C) Transmit Holding Register -------- */ +#define UART_THR_TXCHR_Pos 0 +#define UART_THR_TXCHR_Msk (0xffu << UART_THR_TXCHR_Pos) /**< \brief (UART_THR) Character to be Transmitted */ +#define UART_THR_TXCHR(value) ((UART_THR_TXCHR_Msk & ((value) << UART_THR_TXCHR_Pos))) +/* -------- UART_BRGR : (UART Offset: 0x0020) Baud Rate Generator Register -------- */ +#define UART_BRGR_CD_Pos 0 +#define UART_BRGR_CD_Msk (0xffffu << UART_BRGR_CD_Pos) /**< \brief (UART_BRGR) Clock Divisor */ +#define UART_BRGR_CD(value) ((UART_BRGR_CD_Msk & ((value) << UART_BRGR_CD_Pos))) +/* -------- UART_WPMR : (UART Offset: 0x00E4) Write Protection Mode Register -------- */ +#define UART_WPMR_WPEN (0x1u << 0) /**< \brief (UART_WPMR) Write Protection Enable */ +#define UART_WPMR_WPKEY_Pos 8 +#define UART_WPMR_WPKEY_Msk (0xffffffu << UART_WPMR_WPKEY_Pos) /**< \brief (UART_WPMR) Write Protection Key */ +#define UART_WPMR_WPKEY_PASSWD (0x554152u << 8) /**< \brief (UART_WPMR) Writing any other value in this field aborts the write operation.Always reads as 0. */ +/* -------- UART_RPR : (UART Offset: 0x100) Receive Pointer Register -------- */ +#define UART_RPR_RXPTR_Pos 0 +#define UART_RPR_RXPTR_Msk (0xffffffffu << UART_RPR_RXPTR_Pos) /**< \brief (UART_RPR) Receive Pointer Register */ +#define UART_RPR_RXPTR(value) ((UART_RPR_RXPTR_Msk & ((value) << UART_RPR_RXPTR_Pos))) +/* -------- UART_RCR : (UART Offset: 0x104) Receive Counter Register -------- */ +#define UART_RCR_RXCTR_Pos 0 +#define UART_RCR_RXCTR_Msk (0xffffu << UART_RCR_RXCTR_Pos) /**< \brief (UART_RCR) Receive Counter Register */ +#define UART_RCR_RXCTR(value) ((UART_RCR_RXCTR_Msk & ((value) << UART_RCR_RXCTR_Pos))) +/* -------- UART_TPR : (UART Offset: 0x108) Transmit Pointer Register -------- */ +#define UART_TPR_TXPTR_Pos 0 +#define UART_TPR_TXPTR_Msk (0xffffffffu << UART_TPR_TXPTR_Pos) /**< \brief (UART_TPR) Transmit Counter Register */ +#define UART_TPR_TXPTR(value) ((UART_TPR_TXPTR_Msk & ((value) << UART_TPR_TXPTR_Pos))) +/* -------- UART_TCR : (UART Offset: 0x10C) Transmit Counter Register -------- */ +#define UART_TCR_TXCTR_Pos 0 +#define UART_TCR_TXCTR_Msk (0xffffu << UART_TCR_TXCTR_Pos) /**< \brief (UART_TCR) Transmit Counter Register */ +#define UART_TCR_TXCTR(value) ((UART_TCR_TXCTR_Msk & ((value) << UART_TCR_TXCTR_Pos))) +/* -------- UART_RNPR : (UART Offset: 0x110) Receive Next Pointer Register -------- */ +#define UART_RNPR_RXNPTR_Pos 0 +#define UART_RNPR_RXNPTR_Msk (0xffffffffu << UART_RNPR_RXNPTR_Pos) /**< \brief (UART_RNPR) Receive Next Pointer */ +#define UART_RNPR_RXNPTR(value) ((UART_RNPR_RXNPTR_Msk & ((value) << UART_RNPR_RXNPTR_Pos))) +/* -------- UART_RNCR : (UART Offset: 0x114) Receive Next Counter Register -------- */ +#define UART_RNCR_RXNCTR_Pos 0 +#define UART_RNCR_RXNCTR_Msk (0xffffu << UART_RNCR_RXNCTR_Pos) /**< \brief (UART_RNCR) Receive Next Counter */ +#define UART_RNCR_RXNCTR(value) ((UART_RNCR_RXNCTR_Msk & ((value) << UART_RNCR_RXNCTR_Pos))) +/* -------- UART_TNPR : (UART Offset: 0x118) Transmit Next Pointer Register -------- */ +#define UART_TNPR_TXNPTR_Pos 0 +#define UART_TNPR_TXNPTR_Msk (0xffffffffu << UART_TNPR_TXNPTR_Pos) /**< \brief (UART_TNPR) Transmit Next Pointer */ +#define UART_TNPR_TXNPTR(value) ((UART_TNPR_TXNPTR_Msk & ((value) << UART_TNPR_TXNPTR_Pos))) +/* -------- UART_TNCR : (UART Offset: 0x11C) Transmit Next Counter Register -------- */ +#define UART_TNCR_TXNCTR_Pos 0 +#define UART_TNCR_TXNCTR_Msk (0xffffu << UART_TNCR_TXNCTR_Pos) /**< \brief (UART_TNCR) Transmit Counter Next */ +#define UART_TNCR_TXNCTR(value) ((UART_TNCR_TXNCTR_Msk & ((value) << UART_TNCR_TXNCTR_Pos))) +/* -------- UART_PTCR : (UART Offset: 0x120) Transfer Control Register -------- */ +#define UART_PTCR_RXTEN (0x1u << 0) /**< \brief (UART_PTCR) Receiver Transfer Enable */ +#define UART_PTCR_RXTDIS (0x1u << 1) /**< \brief (UART_PTCR) Receiver Transfer Disable */ +#define UART_PTCR_TXTEN (0x1u << 8) /**< \brief (UART_PTCR) Transmitter Transfer Enable */ +#define UART_PTCR_TXTDIS (0x1u << 9) /**< \brief (UART_PTCR) Transmitter Transfer Disable */ +/* -------- UART_PTSR : (UART Offset: 0x124) Transfer Status Register -------- */ +#define UART_PTSR_RXTEN (0x1u << 0) /**< \brief (UART_PTSR) Receiver Transfer Enable */ +#define UART_PTSR_TXTEN (0x1u << 8) /**< \brief (UART_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_UART_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/udp.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/udp.h new file mode 100644 index 0000000..24a39e1 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/udp.h @@ -0,0 +1,200 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_UDP_COMPONENT_ +#define _SAM4E_UDP_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR USB Device Port */ +/* ============================================================================= */ +/** \addtogroup SAM4E_UDP USB Device Port */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Udp hardware registers */ +typedef struct { + __I uint32_t UDP_FRM_NUM; /**< \brief (Udp Offset: 0x000) Frame Number Register */ + __IO uint32_t UDP_GLB_STAT; /**< \brief (Udp Offset: 0x004) Global State Register */ + __IO uint32_t UDP_FADDR; /**< \brief (Udp Offset: 0x008) Function Address Register */ + __I uint32_t Reserved1[1]; + __O uint32_t UDP_IER; /**< \brief (Udp Offset: 0x010) Interrupt Enable Register */ + __O uint32_t UDP_IDR; /**< \brief (Udp Offset: 0x014) Interrupt Disable Register */ + __I uint32_t UDP_IMR; /**< \brief (Udp Offset: 0x018) Interrupt Mask Register */ + __I uint32_t UDP_ISR; /**< \brief (Udp Offset: 0x01C) Interrupt Status Register */ + __O uint32_t UDP_ICR; /**< \brief (Udp Offset: 0x020) Interrupt Clear Register */ + __I uint32_t Reserved2[1]; + __IO uint32_t UDP_RST_EP; /**< \brief (Udp Offset: 0x028) Reset Endpoint Register */ + __I uint32_t Reserved3[1]; + __IO uint32_t UDP_CSR[8]; /**< \brief (Udp Offset: 0x030) Endpoint Control and Status Register */ + __IO uint32_t UDP_FDR[8]; /**< \brief (Udp Offset: 0x050) Endpoint FIFO Data Register */ + __I uint32_t Reserved4[1]; + __IO uint32_t UDP_TXVC; /**< \brief (Udp Offset: 0x074) Transceiver Control Register */ +} Udp; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- UDP_FRM_NUM : (UDP Offset: 0x000) Frame Number Register -------- */ +#define UDP_FRM_NUM_FRM_NUM_Pos 0 +#define UDP_FRM_NUM_FRM_NUM_Msk (0x7ffu << UDP_FRM_NUM_FRM_NUM_Pos) /**< \brief (UDP_FRM_NUM) Frame Number as Defined in the Packet Field Formats */ +#define UDP_FRM_NUM_FRM_ERR (0x1u << 16) /**< \brief (UDP_FRM_NUM) Frame Error */ +#define UDP_FRM_NUM_FRM_OK (0x1u << 17) /**< \brief (UDP_FRM_NUM) Frame OK */ +/* -------- UDP_GLB_STAT : (UDP Offset: 0x004) Global State Register -------- */ +#define UDP_GLB_STAT_FADDEN (0x1u << 0) /**< \brief (UDP_GLB_STAT) Function Address Enable */ +#define UDP_GLB_STAT_CONFG (0x1u << 1) /**< \brief (UDP_GLB_STAT) Configured */ +#define UDP_GLB_STAT_ESR (0x1u << 2) /**< \brief (UDP_GLB_STAT) Enable Send Resume */ +#define UDP_GLB_STAT_RSMINPR (0x1u << 3) /**< \brief (UDP_GLB_STAT) */ +#define UDP_GLB_STAT_RMWUPE (0x1u << 4) /**< \brief (UDP_GLB_STAT) Remote Wake Up Enable */ +/* -------- UDP_FADDR : (UDP Offset: 0x008) Function Address Register -------- */ +#define UDP_FADDR_FADD_Pos 0 +#define UDP_FADDR_FADD_Msk (0x7fu << UDP_FADDR_FADD_Pos) /**< \brief (UDP_FADDR) Function Address Value */ +#define UDP_FADDR_FADD(value) ((UDP_FADDR_FADD_Msk & ((value) << UDP_FADDR_FADD_Pos))) +#define UDP_FADDR_FEN (0x1u << 8) /**< \brief (UDP_FADDR) Function Enable */ +/* -------- UDP_IER : (UDP Offset: 0x010) Interrupt Enable Register -------- */ +#define UDP_IER_EP0INT (0x1u << 0) /**< \brief (UDP_IER) Enable Endpoint 0 Interrupt */ +#define UDP_IER_EP1INT (0x1u << 1) /**< \brief (UDP_IER) Enable Endpoint 1 Interrupt */ +#define UDP_IER_EP2INT (0x1u << 2) /**< \brief (UDP_IER) Enable Endpoint 2Interrupt */ +#define UDP_IER_EP3INT (0x1u << 3) /**< \brief (UDP_IER) Enable Endpoint 3 Interrupt */ +#define UDP_IER_EP4INT (0x1u << 4) /**< \brief (UDP_IER) Enable Endpoint 4 Interrupt */ +#define UDP_IER_EP5INT (0x1u << 5) /**< \brief (UDP_IER) Enable Endpoint 5 Interrupt */ +#define UDP_IER_EP6INT (0x1u << 6) /**< \brief (UDP_IER) Enable Endpoint 6 Interrupt */ +#define UDP_IER_EP7INT (0x1u << 7) /**< \brief (UDP_IER) Enable Endpoint 7 Interrupt */ +#define UDP_IER_RXSUSP (0x1u << 8) /**< \brief (UDP_IER) Enable UDP Suspend Interrupt */ +#define UDP_IER_RXRSM (0x1u << 9) /**< \brief (UDP_IER) Enable UDP Resume Interrupt */ +#define UDP_IER_EXTRSM (0x1u << 10) /**< \brief (UDP_IER) */ +#define UDP_IER_SOFINT (0x1u << 11) /**< \brief (UDP_IER) Enable Start Of Frame Interrupt */ +#define UDP_IER_WAKEUP (0x1u << 13) /**< \brief (UDP_IER) Enable UDP bus Wakeup Interrupt */ +/* -------- UDP_IDR : (UDP Offset: 0x014) Interrupt Disable Register -------- */ +#define UDP_IDR_EP0INT (0x1u << 0) /**< \brief (UDP_IDR) Disable Endpoint 0 Interrupt */ +#define UDP_IDR_EP1INT (0x1u << 1) /**< \brief (UDP_IDR) Disable Endpoint 1 Interrupt */ +#define UDP_IDR_EP2INT (0x1u << 2) /**< \brief (UDP_IDR) Disable Endpoint 2 Interrupt */ +#define UDP_IDR_EP3INT (0x1u << 3) /**< \brief (UDP_IDR) Disable Endpoint 3 Interrupt */ +#define UDP_IDR_EP4INT (0x1u << 4) /**< \brief (UDP_IDR) Disable Endpoint 4 Interrupt */ +#define UDP_IDR_EP5INT (0x1u << 5) /**< \brief (UDP_IDR) Disable Endpoint 5 Interrupt */ +#define UDP_IDR_EP6INT (0x1u << 6) /**< \brief (UDP_IDR) Disable Endpoint 6 Interrupt */ +#define UDP_IDR_EP7INT (0x1u << 7) /**< \brief (UDP_IDR) Disable Endpoint 7 Interrupt */ +#define UDP_IDR_RXSUSP (0x1u << 8) /**< \brief (UDP_IDR) Disable UDP Suspend Interrupt */ +#define UDP_IDR_RXRSM (0x1u << 9) /**< \brief (UDP_IDR) Disable UDP Resume Interrupt */ +#define UDP_IDR_EXTRSM (0x1u << 10) /**< \brief (UDP_IDR) */ +#define UDP_IDR_SOFINT (0x1u << 11) /**< \brief (UDP_IDR) Disable Start Of Frame Interrupt */ +#define UDP_IDR_WAKEUP (0x1u << 13) /**< \brief (UDP_IDR) Disable USB Bus Interrupt */ +/* -------- UDP_IMR : (UDP Offset: 0x018) Interrupt Mask Register -------- */ +#define UDP_IMR_EP0INT (0x1u << 0) /**< \brief (UDP_IMR) Mask Endpoint 0 Interrupt */ +#define UDP_IMR_EP1INT (0x1u << 1) /**< \brief (UDP_IMR) Mask Endpoint 1 Interrupt */ +#define UDP_IMR_EP2INT (0x1u << 2) /**< \brief (UDP_IMR) Mask Endpoint 2 Interrupt */ +#define UDP_IMR_EP3INT (0x1u << 3) /**< \brief (UDP_IMR) Mask Endpoint 3 Interrupt */ +#define UDP_IMR_EP4INT (0x1u << 4) /**< \brief (UDP_IMR) Mask Endpoint 4 Interrupt */ +#define UDP_IMR_EP5INT (0x1u << 5) /**< \brief (UDP_IMR) Mask Endpoint 5 Interrupt */ +#define UDP_IMR_EP6INT (0x1u << 6) /**< \brief (UDP_IMR) Mask Endpoint 6 Interrupt */ +#define UDP_IMR_EP7INT (0x1u << 7) /**< \brief (UDP_IMR) Mask Endpoint 7 Interrupt */ +#define UDP_IMR_RXSUSP (0x1u << 8) /**< \brief (UDP_IMR) Mask UDP Suspend Interrupt */ +#define UDP_IMR_RXRSM (0x1u << 9) /**< \brief (UDP_IMR) Mask UDP Resume Interrupt. */ +#define UDP_IMR_EXTRSM (0x1u << 10) /**< \brief (UDP_IMR) */ +#define UDP_IMR_SOFINT (0x1u << 11) /**< \brief (UDP_IMR) Mask Start Of Frame Interrupt */ +#define UDP_IMR_BIT12 (0x1u << 12) /**< \brief (UDP_IMR) UDP_IMR Bit 12 */ +#define UDP_IMR_WAKEUP (0x1u << 13) /**< \brief (UDP_IMR) USB Bus WAKEUP Interrupt */ +/* -------- UDP_ISR : (UDP Offset: 0x01C) Interrupt Status Register -------- */ +#define UDP_ISR_EP0INT (0x1u << 0) /**< \brief (UDP_ISR) Endpoint 0 Interrupt Status */ +#define UDP_ISR_EP1INT (0x1u << 1) /**< \brief (UDP_ISR) Endpoint 1 Interrupt Status */ +#define UDP_ISR_EP2INT (0x1u << 2) /**< \brief (UDP_ISR) Endpoint 2 Interrupt Status */ +#define UDP_ISR_EP3INT (0x1u << 3) /**< \brief (UDP_ISR) Endpoint 3 Interrupt Status */ +#define UDP_ISR_EP4INT (0x1u << 4) /**< \brief (UDP_ISR) Endpoint 4 Interrupt Status */ +#define UDP_ISR_EP5INT (0x1u << 5) /**< \brief (UDP_ISR) Endpoint 5 Interrupt Status */ +#define UDP_ISR_EP6INT (0x1u << 6) /**< \brief (UDP_ISR) Endpoint 6 Interrupt Status */ +#define UDP_ISR_EP7INT (0x1u << 7) /**< \brief (UDP_ISR) Endpoint 7Interrupt Status */ +#define UDP_ISR_RXSUSP (0x1u << 8) /**< \brief (UDP_ISR) UDP Suspend Interrupt Status */ +#define UDP_ISR_RXRSM (0x1u << 9) /**< \brief (UDP_ISR) UDP Resume Interrupt Status */ +#define UDP_ISR_EXTRSM (0x1u << 10) /**< \brief (UDP_ISR) */ +#define UDP_ISR_SOFINT (0x1u << 11) /**< \brief (UDP_ISR) Start of Frame Interrupt Status */ +#define UDP_ISR_ENDBUSRES (0x1u << 12) /**< \brief (UDP_ISR) End of BUS Reset Interrupt Status */ +#define UDP_ISR_WAKEUP (0x1u << 13) /**< \brief (UDP_ISR) UDP Resume Interrupt Status */ +/* -------- UDP_ICR : (UDP Offset: 0x020) Interrupt Clear Register -------- */ +#define UDP_ICR_RXSUSP (0x1u << 8) /**< \brief (UDP_ICR) Clear UDP Suspend Interrupt */ +#define UDP_ICR_RXRSM (0x1u << 9) /**< \brief (UDP_ICR) Clear UDP Resume Interrupt */ +#define UDP_ICR_EXTRSM (0x1u << 10) /**< \brief (UDP_ICR) */ +#define UDP_ICR_SOFINT (0x1u << 11) /**< \brief (UDP_ICR) Clear Start Of Frame Interrupt */ +#define UDP_ICR_ENDBUSRES (0x1u << 12) /**< \brief (UDP_ICR) Clear End of Bus Reset Interrupt */ +#define UDP_ICR_WAKEUP (0x1u << 13) /**< \brief (UDP_ICR) Clear Wakeup Interrupt */ +/* -------- UDP_RST_EP : (UDP Offset: 0x028) Reset Endpoint Register -------- */ +#define UDP_RST_EP_EP0 (0x1u << 0) /**< \brief (UDP_RST_EP) Reset Endpoint 0 */ +#define UDP_RST_EP_EP1 (0x1u << 1) /**< \brief (UDP_RST_EP) Reset Endpoint 1 */ +#define UDP_RST_EP_EP2 (0x1u << 2) /**< \brief (UDP_RST_EP) Reset Endpoint 2 */ +#define UDP_RST_EP_EP3 (0x1u << 3) /**< \brief (UDP_RST_EP) Reset Endpoint 3 */ +#define UDP_RST_EP_EP4 (0x1u << 4) /**< \brief (UDP_RST_EP) Reset Endpoint 4 */ +#define UDP_RST_EP_EP5 (0x1u << 5) /**< \brief (UDP_RST_EP) Reset Endpoint 5 */ +#define UDP_RST_EP_EP6 (0x1u << 6) /**< \brief (UDP_RST_EP) Reset Endpoint 6 */ +#define UDP_RST_EP_EP7 (0x1u << 7) /**< \brief (UDP_RST_EP) Reset Endpoint 7 */ +/* -------- UDP_CSR[8] : (UDP Offset: 0x030) Endpoint Control and Status Register -------- */ +#define UDP_CSR_TXCOMP (0x1u << 0) /**< \brief (UDP_CSR[8]) Generates an IN Packet with Data Previously Written in the DPR */ +#define UDP_CSR_RX_DATA_BK0 (0x1u << 1) /**< \brief (UDP_CSR[8]) Receive Data Bank 0 */ +#define UDP_CSR_RXSETUP (0x1u << 2) /**< \brief (UDP_CSR[8]) Received Setup */ +#define UDP_CSR_STALLSENT (0x1u << 3) /**< \brief (UDP_CSR[8]) Stall Sent */ +#define UDP_CSR_TXPKTRDY (0x1u << 4) /**< \brief (UDP_CSR[8]) Transmit Packet Ready */ +#define UDP_CSR_FORCESTALL (0x1u << 5) /**< \brief (UDP_CSR[8]) Force Stall (used by Control, Bulk and Isochronous Endpoints) */ +#define UDP_CSR_RX_DATA_BK1 (0x1u << 6) /**< \brief (UDP_CSR[8]) Receive Data Bank 1 (only used by endpoints with ping-pong attributes) */ +#define UDP_CSR_DIR (0x1u << 7) /**< \brief (UDP_CSR[8]) Transfer Direction (only available for control endpoints) */ +#define UDP_CSR_EPTYPE_Pos 8 +#define UDP_CSR_EPTYPE_Msk (0x7u << UDP_CSR_EPTYPE_Pos) /**< \brief (UDP_CSR[8]) Endpoint Type */ +#define UDP_CSR_EPTYPE_CTRL (0x0u << 8) /**< \brief (UDP_CSR[8]) Control */ +#define UDP_CSR_EPTYPE_ISO_OUT (0x1u << 8) /**< \brief (UDP_CSR[8]) Isochronous OUT */ +#define UDP_CSR_EPTYPE_BULK_OUT (0x2u << 8) /**< \brief (UDP_CSR[8]) Bulk OUT */ +#define UDP_CSR_EPTYPE_INT_OUT (0x3u << 8) /**< \brief (UDP_CSR[8]) Interrupt OUT */ +#define UDP_CSR_EPTYPE_ISO_IN (0x5u << 8) /**< \brief (UDP_CSR[8]) Isochronous IN */ +#define UDP_CSR_EPTYPE_BULK_IN (0x6u << 8) /**< \brief (UDP_CSR[8]) Bulk IN */ +#define UDP_CSR_EPTYPE_INT_IN (0x7u << 8) /**< \brief (UDP_CSR[8]) Interrupt IN */ +#define UDP_CSR_DTGLE (0x1u << 11) /**< \brief (UDP_CSR[8]) Data Toggle */ +#define UDP_CSR_EPEDS (0x1u << 15) /**< \brief (UDP_CSR[8]) Endpoint Enable Disable */ +#define UDP_CSR_RXBYTECNT_Pos 16 +#define UDP_CSR_RXBYTECNT_Msk (0x7ffu << UDP_CSR_RXBYTECNT_Pos) /**< \brief (UDP_CSR[8]) Number of Bytes Available in the FIFO */ +#define UDP_CSR_RXBYTECNT(value) ((UDP_CSR_RXBYTECNT_Msk & ((value) << UDP_CSR_RXBYTECNT_Pos))) +#define UDP_CSR_ISOERROR (0x1u << 3) /**< \brief (UDP_CSR[8]) A CRC error has been detected in an isochronous transfer */ +/* -------- UDP_FDR[8] : (UDP Offset: 0x050) Endpoint FIFO Data Register -------- */ +#define UDP_FDR_FIFO_DATA_Pos 0 +#define UDP_FDR_FIFO_DATA_Msk (0xffu << UDP_FDR_FIFO_DATA_Pos) /**< \brief (UDP_FDR[8]) FIFO Data Value */ +#define UDP_FDR_FIFO_DATA(value) ((UDP_FDR_FIFO_DATA_Msk & ((value) << UDP_FDR_FIFO_DATA_Pos))) +/* -------- UDP_TXVC : (UDP Offset: 0x074) Transceiver Control Register -------- */ +#define UDP_TXVC_TXVDIS (0x1u << 8) /**< \brief (UDP_TXVC) Transceiver Disable */ +#define UDP_TXVC_PUON (0x1u << 9) /**< \brief (UDP_TXVC) Pull-up On */ + +/*@}*/ + + +#endif /* _SAM4E_UDP_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/usart.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/usart.h new file mode 100644 index 0000000..8470d01 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/usart.h @@ -0,0 +1,371 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_USART_COMPONENT_ +#define _SAM4E_USART_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Universal Synchronous Asynchronous Receiver Transmitter */ +/* ============================================================================= */ +/** \addtogroup SAM4E_USART Universal Synchronous Asynchronous Receiver Transmitter */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Usart hardware registers */ +typedef struct { + __O uint32_t US_CR; /**< \brief (Usart Offset: 0x0000) Control Register */ + __IO uint32_t US_MR; /**< \brief (Usart Offset: 0x0004) Mode Register */ + __O uint32_t US_IER; /**< \brief (Usart Offset: 0x0008) Interrupt Enable Register */ + __O uint32_t US_IDR; /**< \brief (Usart Offset: 0x000C) Interrupt Disable Register */ + __I uint32_t US_IMR; /**< \brief (Usart Offset: 0x0010) Interrupt Mask Register */ + __I uint32_t US_CSR; /**< \brief (Usart Offset: 0x0014) Channel Status Register */ + __I uint32_t US_RHR; /**< \brief (Usart Offset: 0x0018) Receive Holding Register */ + __O uint32_t US_THR; /**< \brief (Usart Offset: 0x001C) Transmit Holding Register */ + __IO uint32_t US_BRGR; /**< \brief (Usart Offset: 0x0020) Baud Rate Generator Register */ + __IO uint32_t US_RTOR; /**< \brief (Usart Offset: 0x0024) Receiver Time-out Register */ + __IO uint32_t US_TTGR; /**< \brief (Usart Offset: 0x0028) Transmitter Timeguard Register */ + __I uint32_t Reserved1[5]; + __IO uint32_t US_FIDI; /**< \brief (Usart Offset: 0x0040) FI DI Ratio Register */ + __I uint32_t US_NER; /**< \brief (Usart Offset: 0x0044) Number of Errors Register */ + __I uint32_t Reserved2[1]; + __IO uint32_t US_IF; /**< \brief (Usart Offset: 0x004C) IrDA Filter Register */ + __IO uint32_t US_MAN; /**< \brief (Usart Offset: 0x0050) Manchester Configuration Register */ + __I uint32_t Reserved3[36]; + __IO uint32_t US_WPMR; /**< \brief (Usart Offset: 0x00E4) Write Protection Mode Register */ + __I uint32_t US_WPSR; /**< \brief (Usart Offset: 0x00E8) Write Protection Status Register */ + __I uint32_t Reserved4[5]; + __IO uint32_t US_RPR; /**< \brief (Usart Offset: 0x100) Receive Pointer Register */ + __IO uint32_t US_RCR; /**< \brief (Usart Offset: 0x104) Receive Counter Register */ + __IO uint32_t US_TPR; /**< \brief (Usart Offset: 0x108) Transmit Pointer Register */ + __IO uint32_t US_TCR; /**< \brief (Usart Offset: 0x10C) Transmit Counter Register */ + __IO uint32_t US_RNPR; /**< \brief (Usart Offset: 0x110) Receive Next Pointer Register */ + __IO uint32_t US_RNCR; /**< \brief (Usart Offset: 0x114) Receive Next Counter Register */ + __IO uint32_t US_TNPR; /**< \brief (Usart Offset: 0x118) Transmit Next Pointer Register */ + __IO uint32_t US_TNCR; /**< \brief (Usart Offset: 0x11C) Transmit Next Counter Register */ + __O uint32_t US_PTCR; /**< \brief (Usart Offset: 0x120) Transfer Control Register */ + __I uint32_t US_PTSR; /**< \brief (Usart Offset: 0x124) Transfer Status Register */ +} Usart; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- US_CR : (USART Offset: 0x0000) Control Register -------- */ +#define US_CR_RSTRX (0x1u << 2) /**< \brief (US_CR) Reset Receiver */ +#define US_CR_RSTTX (0x1u << 3) /**< \brief (US_CR) Reset Transmitter */ +#define US_CR_RXEN (0x1u << 4) /**< \brief (US_CR) Receiver Enable */ +#define US_CR_RXDIS (0x1u << 5) /**< \brief (US_CR) Receiver Disable */ +#define US_CR_TXEN (0x1u << 6) /**< \brief (US_CR) Transmitter Enable */ +#define US_CR_TXDIS (0x1u << 7) /**< \brief (US_CR) Transmitter Disable */ +#define US_CR_RSTSTA (0x1u << 8) /**< \brief (US_CR) Reset Status Bits */ +#define US_CR_STTBRK (0x1u << 9) /**< \brief (US_CR) Start Break */ +#define US_CR_STPBRK (0x1u << 10) /**< \brief (US_CR) Stop Break */ +#define US_CR_STTTO (0x1u << 11) /**< \brief (US_CR) Start Time-out */ +#define US_CR_SENDA (0x1u << 12) /**< \brief (US_CR) Send Address */ +#define US_CR_RSTIT (0x1u << 13) /**< \brief (US_CR) Reset Iterations */ +#define US_CR_RSTNACK (0x1u << 14) /**< \brief (US_CR) Reset Non Acknowledge */ +#define US_CR_RETTO (0x1u << 15) /**< \brief (US_CR) Rearm Time-out */ +#define US_CR_DTREN (0x1u << 16) /**< \brief (US_CR) Data Terminal Ready Enable */ +#define US_CR_DTRDIS (0x1u << 17) /**< \brief (US_CR) Data Terminal Ready Disable */ +#define US_CR_RTSEN (0x1u << 18) /**< \brief (US_CR) Request to Send Enable */ +#define US_CR_RTSDIS (0x1u << 19) /**< \brief (US_CR) Request to Send Disable */ +#define US_CR_FCS (0x1u << 18) /**< \brief (US_CR) Force SPI Chip Select */ +#define US_CR_RCS (0x1u << 19) /**< \brief (US_CR) Release SPI Chip Select */ +/* -------- US_MR : (USART Offset: 0x0004) Mode Register -------- */ +#define US_MR_USART_MODE_Pos 0 +#define US_MR_USART_MODE_Msk (0xfu << US_MR_USART_MODE_Pos) /**< \brief (US_MR) USART Mode of Operation */ +#define US_MR_USART_MODE_NORMAL (0x0u << 0) /**< \brief (US_MR) Normal mode */ +#define US_MR_USART_MODE_RS485 (0x1u << 0) /**< \brief (US_MR) RS485 */ +#define US_MR_USART_MODE_HW_HANDSHAKING (0x2u << 0) /**< \brief (US_MR) Hardware Handshaking */ +#define US_MR_USART_MODE_MODEM (0x3u << 0) /**< \brief (US_MR) Modem */ +#define US_MR_USART_MODE_IS07816_T_0 (0x4u << 0) /**< \brief (US_MR) IS07816 Protocol: T = 0 */ +#define US_MR_USART_MODE_IS07816_T_1 (0x6u << 0) /**< \brief (US_MR) IS07816 Protocol: T = 1 */ +#define US_MR_USART_MODE_IRDA (0x8u << 0) /**< \brief (US_MR) IrDA */ +#define US_MR_USART_MODE_SPI_MASTER (0xEu << 0) /**< \brief (US_MR) SPI master */ +#define US_MR_USART_MODE_SPI_SLAVE (0xFu << 0) /**< \brief (US_MR) SPI Slave */ +#define US_MR_USCLKS_Pos 4 +#define US_MR_USCLKS_Msk (0x3u << US_MR_USCLKS_Pos) /**< \brief (US_MR) Clock Selection */ +#define US_MR_USCLKS_MCK (0x0u << 4) /**< \brief (US_MR) Peripheral clock is selected */ +#define US_MR_USCLKS_DIV (0x1u << 4) /**< \brief (US_MR) Peripheral clock divided (DIV=8) is selected */ +#define US_MR_USCLKS_SCK (0x3u << 4) /**< \brief (US_MR) Serial clock SCK is selected */ +#define US_MR_CHRL_Pos 6 +#define US_MR_CHRL_Msk (0x3u << US_MR_CHRL_Pos) /**< \brief (US_MR) Character Length */ +#define US_MR_CHRL_5_BIT (0x0u << 6) /**< \brief (US_MR) Character length is 5 bits */ +#define US_MR_CHRL_6_BIT (0x1u << 6) /**< \brief (US_MR) Character length is 6 bits */ +#define US_MR_CHRL_7_BIT (0x2u << 6) /**< \brief (US_MR) Character length is 7 bits */ +#define US_MR_CHRL_8_BIT (0x3u << 6) /**< \brief (US_MR) Character length is 8 bits */ +#define US_MR_SYNC (0x1u << 8) /**< \brief (US_MR) Synchronous Mode Select */ +#define US_MR_PAR_Pos 9 +#define US_MR_PAR_Msk (0x7u << US_MR_PAR_Pos) /**< \brief (US_MR) Parity Type */ +#define US_MR_PAR_EVEN (0x0u << 9) /**< \brief (US_MR) Even parity */ +#define US_MR_PAR_ODD (0x1u << 9) /**< \brief (US_MR) Odd parity */ +#define US_MR_PAR_SPACE (0x2u << 9) /**< \brief (US_MR) Parity forced to 0 (Space) */ +#define US_MR_PAR_MARK (0x3u << 9) /**< \brief (US_MR) Parity forced to 1 (Mark) */ +#define US_MR_PAR_NO (0x4u << 9) /**< \brief (US_MR) No parity */ +#define US_MR_PAR_MULTIDROP (0x6u << 9) /**< \brief (US_MR) Multidrop mode */ +#define US_MR_NBSTOP_Pos 12 +#define US_MR_NBSTOP_Msk (0x3u << US_MR_NBSTOP_Pos) /**< \brief (US_MR) Number of Stop Bits */ +#define US_MR_NBSTOP_1_BIT (0x0u << 12) /**< \brief (US_MR) 1 stop bit */ +#define US_MR_NBSTOP_1_5_BIT (0x1u << 12) /**< \brief (US_MR) 1.5 stop bit (SYNC = 0) or reserved (SYNC = 1) */ +#define US_MR_NBSTOP_2_BIT (0x2u << 12) /**< \brief (US_MR) 2 stop bits */ +#define US_MR_CHMODE_Pos 14 +#define US_MR_CHMODE_Msk (0x3u << US_MR_CHMODE_Pos) /**< \brief (US_MR) Channel Mode */ +#define US_MR_CHMODE_NORMAL (0x0u << 14) /**< \brief (US_MR) Normal mode */ +#define US_MR_CHMODE_AUTOMATIC (0x1u << 14) /**< \brief (US_MR) Automatic Echo. Receiver input is connected to the TXD pin. */ +#define US_MR_CHMODE_LOCAL_LOOPBACK (0x2u << 14) /**< \brief (US_MR) Local Loopback. Transmitter output is connected to the Receiver Input. */ +#define US_MR_CHMODE_REMOTE_LOOPBACK (0x3u << 14) /**< \brief (US_MR) Remote Loopback. RXD pin is internally connected to the TXD pin. */ +#define US_MR_MSBF (0x1u << 16) /**< \brief (US_MR) Bit Order */ +#define US_MR_MODE9 (0x1u << 17) /**< \brief (US_MR) 9-bit Character Length */ +#define US_MR_CLKO (0x1u << 18) /**< \brief (US_MR) Clock Output Select */ +#define US_MR_OVER (0x1u << 19) /**< \brief (US_MR) Oversampling Mode */ +#define US_MR_INACK (0x1u << 20) /**< \brief (US_MR) Inhibit Non Acknowledge */ +#define US_MR_DSNACK (0x1u << 21) /**< \brief (US_MR) Disable Successive NACK */ +#define US_MR_VAR_SYNC (0x1u << 22) /**< \brief (US_MR) Variable Synchronization of Command/Data Sync Start Frame Delimiter */ +#define US_MR_INVDATA (0x1u << 23) /**< \brief (US_MR) Inverted Data */ +#define US_MR_MAX_ITERATION_Pos 24 +#define US_MR_MAX_ITERATION_Msk (0x7u << US_MR_MAX_ITERATION_Pos) /**< \brief (US_MR) Maximum Number of Automatic Iteration */ +#define US_MR_MAX_ITERATION(value) ((US_MR_MAX_ITERATION_Msk & ((value) << US_MR_MAX_ITERATION_Pos))) +#define US_MR_FILTER (0x1u << 28) /**< \brief (US_MR) Receive Line Filter */ +#define US_MR_MAN (0x1u << 29) /**< \brief (US_MR) Manchester Encoder/Decoder Enable */ +#define US_MR_MODSYNC (0x1u << 30) /**< \brief (US_MR) Manchester Synchronization Mode */ +#define US_MR_ONEBIT (0x1u << 31) /**< \brief (US_MR) Start Frame Delimiter Selector */ +#define US_MR_CPHA (0x1u << 8) /**< \brief (US_MR) SPI Clock Phase */ +#define US_MR_CPOL (0x1u << 16) /**< \brief (US_MR) SPI Clock Polarity */ +#define US_MR_WRDBT (0x1u << 20) /**< \brief (US_MR) Wait Read Data Before Transfer */ +/* -------- US_IER : (USART Offset: 0x0008) Interrupt Enable Register -------- */ +#define US_IER_RXRDY (0x1u << 0) /**< \brief (US_IER) RXRDY Interrupt Enable */ +#define US_IER_TXRDY (0x1u << 1) /**< \brief (US_IER) TXRDY Interrupt Enable */ +#define US_IER_RXBRK (0x1u << 2) /**< \brief (US_IER) Receiver Break Interrupt Enable */ +#define US_IER_ENDRX (0x1u << 3) /**< \brief (US_IER) End of Receive Transfer Interrupt Enable (available in all USART modes of operation) */ +#define US_IER_ENDTX (0x1u << 4) /**< \brief (US_IER) End of Transmit Interrupt Enable (available in all USART modes of operation) */ +#define US_IER_OVRE (0x1u << 5) /**< \brief (US_IER) Overrun Error Interrupt Enable */ +#define US_IER_FRAME (0x1u << 6) /**< \brief (US_IER) Framing Error Interrupt Enable */ +#define US_IER_PARE (0x1u << 7) /**< \brief (US_IER) Parity Error Interrupt Enable */ +#define US_IER_TIMEOUT (0x1u << 8) /**< \brief (US_IER) Time-out Interrupt Enable */ +#define US_IER_TXEMPTY (0x1u << 9) /**< \brief (US_IER) TXEMPTY Interrupt Enable */ +#define US_IER_ITER (0x1u << 10) /**< \brief (US_IER) Max number of Repetitions Reached Interrupt Enable */ +#define US_IER_TXBUFE (0x1u << 11) /**< \brief (US_IER) Buffer Empty Interrupt Enable (available in all USART modes of operation) */ +#define US_IER_RXBUFF (0x1u << 12) /**< \brief (US_IER) Buffer Full Interrupt Enable (available in all USART modes of operation) */ +#define US_IER_NACK (0x1u << 13) /**< \brief (US_IER) Non Acknowledge Interrupt Enable */ +#define US_IER_RIIC (0x1u << 16) /**< \brief (US_IER) Ring Indicator Input Change Enable */ +#define US_IER_DSRIC (0x1u << 17) /**< \brief (US_IER) Data Set Ready Input Change Enable */ +#define US_IER_DCDIC (0x1u << 18) /**< \brief (US_IER) Data Carrier Detect Input Change Interrupt Enable */ +#define US_IER_CTSIC (0x1u << 19) /**< \brief (US_IER) Clear to Send Input Change Interrupt Enable */ +#define US_IER_MANE (0x1u << 24) /**< \brief (US_IER) Manchester Error Interrupt Enable */ +#define US_IER_UNRE (0x1u << 10) /**< \brief (US_IER) SPI Underrun Error Interrupt Enable */ +/* -------- US_IDR : (USART Offset: 0x000C) Interrupt Disable Register -------- */ +#define US_IDR_RXRDY (0x1u << 0) /**< \brief (US_IDR) RXRDY Interrupt Disable */ +#define US_IDR_TXRDY (0x1u << 1) /**< \brief (US_IDR) TXRDY Interrupt Disable */ +#define US_IDR_RXBRK (0x1u << 2) /**< \brief (US_IDR) Receiver Break Interrupt Disable */ +#define US_IDR_ENDRX (0x1u << 3) /**< \brief (US_IDR) End of Receive Transfer Interrupt Disable (available in all USART modes of operation) */ +#define US_IDR_ENDTX (0x1u << 4) /**< \brief (US_IDR) End of Transmit Interrupt Disable (available in all USART modes of operation) */ +#define US_IDR_OVRE (0x1u << 5) /**< \brief (US_IDR) Overrun Error Interrupt Enable */ +#define US_IDR_FRAME (0x1u << 6) /**< \brief (US_IDR) Framing Error Interrupt Disable */ +#define US_IDR_PARE (0x1u << 7) /**< \brief (US_IDR) Parity Error Interrupt Disable */ +#define US_IDR_TIMEOUT (0x1u << 8) /**< \brief (US_IDR) Time-out Interrupt Disable */ +#define US_IDR_TXEMPTY (0x1u << 9) /**< \brief (US_IDR) TXEMPTY Interrupt Disable */ +#define US_IDR_ITER (0x1u << 10) /**< \brief (US_IDR) Max Number of Repetitions Reached Interrupt Disable */ +#define US_IDR_TXBUFE (0x1u << 11) /**< \brief (US_IDR) Buffer Empty Interrupt Disable (available in all USART modes of operation) */ +#define US_IDR_RXBUFF (0x1u << 12) /**< \brief (US_IDR) Buffer Full Interrupt Disable (available in all USART modes of operation) */ +#define US_IDR_NACK (0x1u << 13) /**< \brief (US_IDR) Non Acknowledge Interrupt Disable */ +#define US_IDR_RIIC (0x1u << 16) /**< \brief (US_IDR) Ring Indicator Input Change Disable */ +#define US_IDR_DSRIC (0x1u << 17) /**< \brief (US_IDR) Data Set Ready Input Change Disable */ +#define US_IDR_DCDIC (0x1u << 18) /**< \brief (US_IDR) Data Carrier Detect Input Change Interrupt Disable */ +#define US_IDR_CTSIC (0x1u << 19) /**< \brief (US_IDR) Clear to Send Input Change Interrupt Disable */ +#define US_IDR_MANE (0x1u << 24) /**< \brief (US_IDR) Manchester Error Interrupt Disable */ +#define US_IDR_UNRE (0x1u << 10) /**< \brief (US_IDR) SPI Underrun Error Interrupt Disable */ +/* -------- US_IMR : (USART Offset: 0x0010) Interrupt Mask Register -------- */ +#define US_IMR_RXRDY (0x1u << 0) /**< \brief (US_IMR) RXRDY Interrupt Mask */ +#define US_IMR_TXRDY (0x1u << 1) /**< \brief (US_IMR) TXRDY Interrupt Mask */ +#define US_IMR_RXBRK (0x1u << 2) /**< \brief (US_IMR) Receiver Break Interrupt Mask */ +#define US_IMR_ENDRX (0x1u << 3) /**< \brief (US_IMR) End of Receive Transfer Interrupt Mask (available in all USART modes of operation) */ +#define US_IMR_ENDTX (0x1u << 4) /**< \brief (US_IMR) End of Transmit Interrupt Mask (available in all USART modes of operation) */ +#define US_IMR_OVRE (0x1u << 5) /**< \brief (US_IMR) Overrun Error Interrupt Mask */ +#define US_IMR_FRAME (0x1u << 6) /**< \brief (US_IMR) Framing Error Interrupt Mask */ +#define US_IMR_PARE (0x1u << 7) /**< \brief (US_IMR) Parity Error Interrupt Mask */ +#define US_IMR_TIMEOUT (0x1u << 8) /**< \brief (US_IMR) Time-out Interrupt Mask */ +#define US_IMR_TXEMPTY (0x1u << 9) /**< \brief (US_IMR) TXEMPTY Interrupt Mask */ +#define US_IMR_ITER (0x1u << 10) /**< \brief (US_IMR) Max Number of Repetitions Reached Interrupt Mask */ +#define US_IMR_TXBUFE (0x1u << 11) /**< \brief (US_IMR) Buffer Empty Interrupt Mask (available in all USART modes of operation) */ +#define US_IMR_RXBUFF (0x1u << 12) /**< \brief (US_IMR) Buffer Full Interrupt Mask (available in all USART modes of operation) */ +#define US_IMR_NACK (0x1u << 13) /**< \brief (US_IMR) Non Acknowledge Interrupt Mask */ +#define US_IMR_RIIC (0x1u << 16) /**< \brief (US_IMR) Ring Indicator Input Change Mask */ +#define US_IMR_DSRIC (0x1u << 17) /**< \brief (US_IMR) Data Set Ready Input Change Mask */ +#define US_IMR_DCDIC (0x1u << 18) /**< \brief (US_IMR) Data Carrier Detect Input Change Interrupt Mask */ +#define US_IMR_CTSIC (0x1u << 19) /**< \brief (US_IMR) Clear to Send Input Change Interrupt Mask */ +#define US_IMR_MANE (0x1u << 24) /**< \brief (US_IMR) Manchester Error Interrupt Mask */ +#define US_IMR_UNRE (0x1u << 10) /**< \brief (US_IMR) SPI Underrun Error Interrupt Mask */ +/* -------- US_CSR : (USART Offset: 0x0014) Channel Status Register -------- */ +#define US_CSR_RXRDY (0x1u << 0) /**< \brief (US_CSR) Receiver Ready */ +#define US_CSR_TXRDY (0x1u << 1) /**< \brief (US_CSR) Transmitter Ready */ +#define US_CSR_RXBRK (0x1u << 2) /**< \brief (US_CSR) Break Received/End of Break */ +#define US_CSR_ENDRX (0x1u << 3) /**< \brief (US_CSR) End of Receiver Transfer */ +#define US_CSR_ENDTX (0x1u << 4) /**< \brief (US_CSR) End of Transmitter Transfer */ +#define US_CSR_OVRE (0x1u << 5) /**< \brief (US_CSR) Overrun Error */ +#define US_CSR_FRAME (0x1u << 6) /**< \brief (US_CSR) Framing Error */ +#define US_CSR_PARE (0x1u << 7) /**< \brief (US_CSR) Parity Error */ +#define US_CSR_TIMEOUT (0x1u << 8) /**< \brief (US_CSR) Receiver Time-out */ +#define US_CSR_TXEMPTY (0x1u << 9) /**< \brief (US_CSR) Transmitter Empty */ +#define US_CSR_ITER (0x1u << 10) /**< \brief (US_CSR) Max Number of Repetitions Reached */ +#define US_CSR_TXBUFE (0x1u << 11) /**< \brief (US_CSR) Transmission Buffer Empty */ +#define US_CSR_RXBUFF (0x1u << 12) /**< \brief (US_CSR) Reception Buffer Full */ +#define US_CSR_NACK (0x1u << 13) /**< \brief (US_CSR) Non Acknowledge Interrupt */ +#define US_CSR_RIIC (0x1u << 16) /**< \brief (US_CSR) Ring Indicator Input Change Flag */ +#define US_CSR_DSRIC (0x1u << 17) /**< \brief (US_CSR) Data Set Ready Input Change Flag */ +#define US_CSR_DCDIC (0x1u << 18) /**< \brief (US_CSR) Data Carrier Detect Input Change Flag */ +#define US_CSR_CTSIC (0x1u << 19) /**< \brief (US_CSR) Clear to Send Input Change Flag */ +#define US_CSR_RI (0x1u << 20) /**< \brief (US_CSR) Image of RI Input */ +#define US_CSR_DSR (0x1u << 21) /**< \brief (US_CSR) Image of DSR Input */ +#define US_CSR_DCD (0x1u << 22) /**< \brief (US_CSR) Image of DCD Input */ +#define US_CSR_CTS (0x1u << 23) /**< \brief (US_CSR) Image of CTS Input */ +#define US_CSR_MANERR (0x1u << 24) /**< \brief (US_CSR) Manchester Error */ +#define US_CSR_UNRE (0x1u << 10) /**< \brief (US_CSR) Underrun Error */ +/* -------- US_RHR : (USART Offset: 0x0018) Receive Holding Register -------- */ +#define US_RHR_RXCHR_Pos 0 +#define US_RHR_RXCHR_Msk (0x1ffu << US_RHR_RXCHR_Pos) /**< \brief (US_RHR) Received Character */ +#define US_RHR_RXSYNH (0x1u << 15) /**< \brief (US_RHR) Received Sync */ +/* -------- US_THR : (USART Offset: 0x001C) Transmit Holding Register -------- */ +#define US_THR_TXCHR_Pos 0 +#define US_THR_TXCHR_Msk (0x1ffu << US_THR_TXCHR_Pos) /**< \brief (US_THR) Character to be Transmitted */ +#define US_THR_TXCHR(value) ((US_THR_TXCHR_Msk & ((value) << US_THR_TXCHR_Pos))) +#define US_THR_TXSYNH (0x1u << 15) /**< \brief (US_THR) Sync Field to be Transmitted */ +/* -------- US_BRGR : (USART Offset: 0x0020) Baud Rate Generator Register -------- */ +#define US_BRGR_CD_Pos 0 +#define US_BRGR_CD_Msk (0xffffu << US_BRGR_CD_Pos) /**< \brief (US_BRGR) Clock Divider */ +#define US_BRGR_CD(value) ((US_BRGR_CD_Msk & ((value) << US_BRGR_CD_Pos))) +#define US_BRGR_FP_Pos 16 +#define US_BRGR_FP_Msk (0x7u << US_BRGR_FP_Pos) /**< \brief (US_BRGR) Fractional Part */ +#define US_BRGR_FP(value) ((US_BRGR_FP_Msk & ((value) << US_BRGR_FP_Pos))) +/* -------- US_RTOR : (USART Offset: 0x0024) Receiver Time-out Register -------- */ +#define US_RTOR_TO_Pos 0 +#define US_RTOR_TO_Msk (0xffffu << US_RTOR_TO_Pos) /**< \brief (US_RTOR) Time-out Value */ +#define US_RTOR_TO(value) ((US_RTOR_TO_Msk & ((value) << US_RTOR_TO_Pos))) +/* -------- US_TTGR : (USART Offset: 0x0028) Transmitter Timeguard Register -------- */ +#define US_TTGR_TG_Pos 0 +#define US_TTGR_TG_Msk (0xffu << US_TTGR_TG_Pos) /**< \brief (US_TTGR) Timeguard Value */ +#define US_TTGR_TG(value) ((US_TTGR_TG_Msk & ((value) << US_TTGR_TG_Pos))) +/* -------- US_FIDI : (USART Offset: 0x0040) FI DI Ratio Register -------- */ +#define US_FIDI_FI_DI_RATIO_Pos 0 +#define US_FIDI_FI_DI_RATIO_Msk (0x7ffu << US_FIDI_FI_DI_RATIO_Pos) /**< \brief (US_FIDI) FI Over DI Ratio Value */ +#define US_FIDI_FI_DI_RATIO(value) ((US_FIDI_FI_DI_RATIO_Msk & ((value) << US_FIDI_FI_DI_RATIO_Pos))) +/* -------- US_NER : (USART Offset: 0x0044) Number of Errors Register -------- */ +#define US_NER_NB_ERRORS_Pos 0 +#define US_NER_NB_ERRORS_Msk (0xffu << US_NER_NB_ERRORS_Pos) /**< \brief (US_NER) Number of Errors */ +/* -------- US_IF : (USART Offset: 0x004C) IrDA Filter Register -------- */ +#define US_IF_IRDA_FILTER_Pos 0 +#define US_IF_IRDA_FILTER_Msk (0xffu << US_IF_IRDA_FILTER_Pos) /**< \brief (US_IF) IrDA Filter */ +#define US_IF_IRDA_FILTER(value) ((US_IF_IRDA_FILTER_Msk & ((value) << US_IF_IRDA_FILTER_Pos))) +/* -------- US_MAN : (USART Offset: 0x0050) Manchester Configuration Register -------- */ +#define US_MAN_TX_PL_Pos 0 +#define US_MAN_TX_PL_Msk (0xfu << US_MAN_TX_PL_Pos) /**< \brief (US_MAN) Transmitter Preamble Length */ +#define US_MAN_TX_PL(value) ((US_MAN_TX_PL_Msk & ((value) << US_MAN_TX_PL_Pos))) +#define US_MAN_TX_PP_Pos 8 +#define US_MAN_TX_PP_Msk (0x3u << US_MAN_TX_PP_Pos) /**< \brief (US_MAN) Transmitter Preamble Pattern */ +#define US_MAN_TX_PP_ALL_ONE (0x0u << 8) /**< \brief (US_MAN) The preamble is composed of '1's */ +#define US_MAN_TX_PP_ALL_ZERO (0x1u << 8) /**< \brief (US_MAN) The preamble is composed of '0's */ +#define US_MAN_TX_PP_ZERO_ONE (0x2u << 8) /**< \brief (US_MAN) The preamble is composed of '01's */ +#define US_MAN_TX_PP_ONE_ZERO (0x3u << 8) /**< \brief (US_MAN) The preamble is composed of '10's */ +#define US_MAN_TX_MPOL (0x1u << 12) /**< \brief (US_MAN) Transmitter Manchester Polarity */ +#define US_MAN_RX_PL_Pos 16 +#define US_MAN_RX_PL_Msk (0xfu << US_MAN_RX_PL_Pos) /**< \brief (US_MAN) Receiver Preamble Length */ +#define US_MAN_RX_PL(value) ((US_MAN_RX_PL_Msk & ((value) << US_MAN_RX_PL_Pos))) +#define US_MAN_RX_PP_Pos 24 +#define US_MAN_RX_PP_Msk (0x3u << US_MAN_RX_PP_Pos) /**< \brief (US_MAN) Receiver Preamble Pattern detected */ +#define US_MAN_RX_PP_ALL_ONE (0x0u << 24) /**< \brief (US_MAN) The preamble is composed of '1's */ +#define US_MAN_RX_PP_ALL_ZERO (0x1u << 24) /**< \brief (US_MAN) The preamble is composed of '0's */ +#define US_MAN_RX_PP_ZERO_ONE (0x2u << 24) /**< \brief (US_MAN) The preamble is composed of '01's */ +#define US_MAN_RX_PP_ONE_ZERO (0x3u << 24) /**< \brief (US_MAN) The preamble is composed of '10's */ +#define US_MAN_RX_MPOL (0x1u << 28) /**< \brief (US_MAN) Receiver Manchester Polarity */ +#define US_MAN_ONE (0x1u << 29) /**< \brief (US_MAN) Must Be Set to 1 */ +#define US_MAN_DRIFT (0x1u << 30) /**< \brief (US_MAN) Drift Compensation */ +/* -------- US_WPMR : (USART Offset: 0x00E4) Write Protection Mode Register -------- */ +#define US_WPMR_WPEN (0x1u << 0) /**< \brief (US_WPMR) Write Protection Enable */ +#define US_WPMR_WPKEY_Pos 8 +#define US_WPMR_WPKEY_Msk (0xffffffu << US_WPMR_WPKEY_Pos) /**< \brief (US_WPMR) Write Protection Key */ +#define US_WPMR_WPKEY_PASSWD (0x555341u << 8) /**< \brief (US_WPMR) Writing any other value in this field aborts the write operation of the WPEN bit. Always reads as 0. */ +/* -------- US_WPSR : (USART Offset: 0x00E8) Write Protection Status Register -------- */ +#define US_WPSR_WPVS (0x1u << 0) /**< \brief (US_WPSR) Write Protection Violation Status */ +#define US_WPSR_WPVSRC_Pos 8 +#define US_WPSR_WPVSRC_Msk (0xffffu << US_WPSR_WPVSRC_Pos) /**< \brief (US_WPSR) Write Protection Violation Source */ +/* -------- US_RPR : (USART Offset: 0x100) Receive Pointer Register -------- */ +#define US_RPR_RXPTR_Pos 0 +#define US_RPR_RXPTR_Msk (0xffffffffu << US_RPR_RXPTR_Pos) /**< \brief (US_RPR) Receive Pointer Register */ +#define US_RPR_RXPTR(value) ((US_RPR_RXPTR_Msk & ((value) << US_RPR_RXPTR_Pos))) +/* -------- US_RCR : (USART Offset: 0x104) Receive Counter Register -------- */ +#define US_RCR_RXCTR_Pos 0 +#define US_RCR_RXCTR_Msk (0xffffu << US_RCR_RXCTR_Pos) /**< \brief (US_RCR) Receive Counter Register */ +#define US_RCR_RXCTR(value) ((US_RCR_RXCTR_Msk & ((value) << US_RCR_RXCTR_Pos))) +/* -------- US_TPR : (USART Offset: 0x108) Transmit Pointer Register -------- */ +#define US_TPR_TXPTR_Pos 0 +#define US_TPR_TXPTR_Msk (0xffffffffu << US_TPR_TXPTR_Pos) /**< \brief (US_TPR) Transmit Counter Register */ +#define US_TPR_TXPTR(value) ((US_TPR_TXPTR_Msk & ((value) << US_TPR_TXPTR_Pos))) +/* -------- US_TCR : (USART Offset: 0x10C) Transmit Counter Register -------- */ +#define US_TCR_TXCTR_Pos 0 +#define US_TCR_TXCTR_Msk (0xffffu << US_TCR_TXCTR_Pos) /**< \brief (US_TCR) Transmit Counter Register */ +#define US_TCR_TXCTR(value) ((US_TCR_TXCTR_Msk & ((value) << US_TCR_TXCTR_Pos))) +/* -------- US_RNPR : (USART Offset: 0x110) Receive Next Pointer Register -------- */ +#define US_RNPR_RXNPTR_Pos 0 +#define US_RNPR_RXNPTR_Msk (0xffffffffu << US_RNPR_RXNPTR_Pos) /**< \brief (US_RNPR) Receive Next Pointer */ +#define US_RNPR_RXNPTR(value) ((US_RNPR_RXNPTR_Msk & ((value) << US_RNPR_RXNPTR_Pos))) +/* -------- US_RNCR : (USART Offset: 0x114) Receive Next Counter Register -------- */ +#define US_RNCR_RXNCTR_Pos 0 +#define US_RNCR_RXNCTR_Msk (0xffffu << US_RNCR_RXNCTR_Pos) /**< \brief (US_RNCR) Receive Next Counter */ +#define US_RNCR_RXNCTR(value) ((US_RNCR_RXNCTR_Msk & ((value) << US_RNCR_RXNCTR_Pos))) +/* -------- US_TNPR : (USART Offset: 0x118) Transmit Next Pointer Register -------- */ +#define US_TNPR_TXNPTR_Pos 0 +#define US_TNPR_TXNPTR_Msk (0xffffffffu << US_TNPR_TXNPTR_Pos) /**< \brief (US_TNPR) Transmit Next Pointer */ +#define US_TNPR_TXNPTR(value) ((US_TNPR_TXNPTR_Msk & ((value) << US_TNPR_TXNPTR_Pos))) +/* -------- US_TNCR : (USART Offset: 0x11C) Transmit Next Counter Register -------- */ +#define US_TNCR_TXNCTR_Pos 0 +#define US_TNCR_TXNCTR_Msk (0xffffu << US_TNCR_TXNCTR_Pos) /**< \brief (US_TNCR) Transmit Counter Next */ +#define US_TNCR_TXNCTR(value) ((US_TNCR_TXNCTR_Msk & ((value) << US_TNCR_TXNCTR_Pos))) +/* -------- US_PTCR : (USART Offset: 0x120) Transfer Control Register -------- */ +#define US_PTCR_RXTEN (0x1u << 0) /**< \brief (US_PTCR) Receiver Transfer Enable */ +#define US_PTCR_RXTDIS (0x1u << 1) /**< \brief (US_PTCR) Receiver Transfer Disable */ +#define US_PTCR_TXTEN (0x1u << 8) /**< \brief (US_PTCR) Transmitter Transfer Enable */ +#define US_PTCR_TXTDIS (0x1u << 9) /**< \brief (US_PTCR) Transmitter Transfer Disable */ +/* -------- US_PTSR : (USART Offset: 0x124) Transfer Status Register -------- */ +#define US_PTSR_RXTEN (0x1u << 0) /**< \brief (US_PTSR) Receiver Transfer Enable */ +#define US_PTSR_TXTEN (0x1u << 8) /**< \brief (US_PTSR) Transmitter Transfer Enable */ + +/*@}*/ + + +#endif /* _SAM4E_USART_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/wdt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/wdt.h new file mode 100644 index 0000000..97d6be3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/component/wdt.h @@ -0,0 +1,87 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_WDT_COMPONENT_ +#define _SAM4E_WDT_COMPONENT_ + +/* ============================================================================= */ +/** SOFTWARE API DEFINITION FOR Watchdog Timer */ +/* ============================================================================= */ +/** \addtogroup SAM4E_WDT Watchdog Timer */ +/*@{*/ + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief Wdt hardware registers */ +typedef struct { + __O uint32_t WDT_CR; /**< \brief (Wdt Offset: 0x00) Control Register */ + __IO uint32_t WDT_MR; /**< \brief (Wdt Offset: 0x04) Mode Register */ + __I uint32_t WDT_SR; /**< \brief (Wdt Offset: 0x08) Status Register */ +} Wdt; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/* -------- WDT_CR : (WDT Offset: 0x00) Control Register -------- */ +#define WDT_CR_WDRSTT (0x1u << 0) /**< \brief (WDT_CR) Watchdog Restart */ +#define WDT_CR_KEY_Pos 24 +#define WDT_CR_KEY_Msk (0xffu << WDT_CR_KEY_Pos) /**< \brief (WDT_CR) Password. */ +#define WDT_CR_KEY_PASSWD (0xA5u << 24) /**< \brief (WDT_CR) Writing any other value in this field aborts the write operation. */ +/* -------- WDT_MR : (WDT Offset: 0x04) Mode Register -------- */ +#define WDT_MR_WDV_Pos 0 +#define WDT_MR_WDV_Msk (0xfffu << WDT_MR_WDV_Pos) /**< \brief (WDT_MR) Watchdog Counter Value */ +#define WDT_MR_WDV(value) ((WDT_MR_WDV_Msk & ((value) << WDT_MR_WDV_Pos))) +#define WDT_MR_WDFIEN (0x1u << 12) /**< \brief (WDT_MR) Watchdog Fault Interrupt Enable */ +#define WDT_MR_WDRSTEN (0x1u << 13) /**< \brief (WDT_MR) Watchdog Reset Enable */ +#define WDT_MR_WDRPROC (0x1u << 14) /**< \brief (WDT_MR) Watchdog Reset Processor */ +#define WDT_MR_WDDIS (0x1u << 15) /**< \brief (WDT_MR) Watchdog Disable */ +#define WDT_MR_WDD_Pos 16 +#define WDT_MR_WDD_Msk (0xfffu << WDT_MR_WDD_Pos) /**< \brief (WDT_MR) Watchdog Delta Value */ +#define WDT_MR_WDD(value) ((WDT_MR_WDD_Msk & ((value) << WDT_MR_WDD_Pos))) +#define WDT_MR_WDDBGHLT (0x1u << 28) /**< \brief (WDT_MR) Watchdog Debug Halt */ +#define WDT_MR_WDIDLEHLT (0x1u << 29) /**< \brief (WDT_MR) Watchdog Idle Halt */ +/* -------- WDT_SR : (WDT Offset: 0x08) Status Register -------- */ +#define WDT_SR_WDUNF (0x1u << 0) /**< \brief (WDT_SR) Watchdog Underflow */ +#define WDT_SR_WDERR (0x1u << 1) /**< \brief (WDT_SR) Watchdog Error */ + +/*@}*/ + + +#endif /* _SAM4E_WDT_COMPONENT_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/acc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/acc.h new file mode 100644 index 0000000..1109dcb --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/acc.h @@ -0,0 +1,71 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_ACC_INSTANCE_ +#define _SAM4E_ACC_INSTANCE_ + +/* ========== Register definition for ACC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_ACC_CR (0x400BC000U) /**< \brief (ACC) Control Register */ + #define REG_ACC_MR (0x400BC004U) /**< \brief (ACC) Mode Register */ + #define REG_ACC_IER (0x400BC024U) /**< \brief (ACC) Interrupt Enable Register */ + #define REG_ACC_IDR (0x400BC028U) /**< \brief (ACC) Interrupt Disable Register */ + #define REG_ACC_IMR (0x400BC02CU) /**< \brief (ACC) Interrupt Mask Register */ + #define REG_ACC_ISR (0x400BC030U) /**< \brief (ACC) Interrupt Status Register */ + #define REG_ACC_ACR (0x400BC094U) /**< \brief (ACC) Analog Control Register */ + #define REG_ACC_WPMR (0x400BC0E4U) /**< \brief (ACC) Write Protection Mode Register */ + #define REG_ACC_WPSR (0x400BC0E8U) /**< \brief (ACC) Write Protection Status Register */ +#else + #define REG_ACC_CR (*(__O uint32_t*)0x400BC000U) /**< \brief (ACC) Control Register */ + #define REG_ACC_MR (*(__IO uint32_t*)0x400BC004U) /**< \brief (ACC) Mode Register */ + #define REG_ACC_IER (*(__O uint32_t*)0x400BC024U) /**< \brief (ACC) Interrupt Enable Register */ + #define REG_ACC_IDR (*(__O uint32_t*)0x400BC028U) /**< \brief (ACC) Interrupt Disable Register */ + #define REG_ACC_IMR (*(__I uint32_t*)0x400BC02CU) /**< \brief (ACC) Interrupt Mask Register */ + #define REG_ACC_ISR (*(__I uint32_t*)0x400BC030U) /**< \brief (ACC) Interrupt Status Register */ + #define REG_ACC_ACR (*(__IO uint32_t*)0x400BC094U) /**< \brief (ACC) Analog Control Register */ + #define REG_ACC_WPMR (*(__IO uint32_t*)0x400BC0E4U) /**< \brief (ACC) Write Protection Mode Register */ + #define REG_ACC_WPSR (*(__I uint32_t*)0x400BC0E8U) /**< \brief (ACC) Write Protection Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_ACC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/aes.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/aes.h new file mode 100644 index 0000000..0cbe687 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/aes.h @@ -0,0 +1,73 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_AES_INSTANCE_ +#define _SAM4E_AES_INSTANCE_ + +/* ========== Register definition for AES peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_AES_CR (0x40004000U) /**< \brief (AES) Control Register */ + #define REG_AES_MR (0x40004004U) /**< \brief (AES) Mode Register */ + #define REG_AES_IER (0x40004010U) /**< \brief (AES) Interrupt Enable Register */ + #define REG_AES_IDR (0x40004014U) /**< \brief (AES) Interrupt Disable Register */ + #define REG_AES_IMR (0x40004018U) /**< \brief (AES) Interrupt Mask Register */ + #define REG_AES_ISR (0x4000401CU) /**< \brief (AES) Interrupt Status Register */ + #define REG_AES_KEYWR (0x40004020U) /**< \brief (AES) Key Word Register */ + #define REG_AES_IDATAR (0x40004040U) /**< \brief (AES) Input Data Register */ + #define REG_AES_ODATAR (0x40004050U) /**< \brief (AES) Output Data Register */ + #define REG_AES_IVR (0x40004060U) /**< \brief (AES) Initialization Vector Register */ +#else + #define REG_AES_CR (*(__O uint32_t*)0x40004000U) /**< \brief (AES) Control Register */ + #define REG_AES_MR (*(__IO uint32_t*)0x40004004U) /**< \brief (AES) Mode Register */ + #define REG_AES_IER (*(__O uint32_t*)0x40004010U) /**< \brief (AES) Interrupt Enable Register */ + #define REG_AES_IDR (*(__O uint32_t*)0x40004014U) /**< \brief (AES) Interrupt Disable Register */ + #define REG_AES_IMR (*(__I uint32_t*)0x40004018U) /**< \brief (AES) Interrupt Mask Register */ + #define REG_AES_ISR (*(__I uint32_t*)0x4000401CU) /**< \brief (AES) Interrupt Status Register */ + #define REG_AES_KEYWR (*(__O uint32_t*)0x40004020U) /**< \brief (AES) Key Word Register */ + #define REG_AES_IDATAR (*(__O uint32_t*)0x40004040U) /**< \brief (AES) Input Data Register */ + #define REG_AES_ODATAR (*(__I uint32_t*)0x40004050U) /**< \brief (AES) Output Data Register */ + #define REG_AES_IVR (*(__O uint32_t*)0x40004060U) /**< \brief (AES) Initialization Vector Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_AES_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec0.h new file mode 100644 index 0000000..db513c7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec0.h @@ -0,0 +1,123 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_AFEC0_INSTANCE_ +#define _SAM4E_AFEC0_INSTANCE_ + +/* ========== Register definition for AFEC0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_AFEC0_CR (0x400B0000U) /**< \brief (AFEC0) AFEC Control Register */ + #define REG_AFEC0_MR (0x400B0004U) /**< \brief (AFEC0) AFEC Mode Register */ + #define REG_AFEC0_EMR (0x400B0008U) /**< \brief (AFEC0) AFEC Extended Mode Register */ + #define REG_AFEC0_SEQ1R (0x400B000CU) /**< \brief (AFEC0) AFEC Channel Sequence 1 Register */ + #define REG_AFEC0_SEQ2R (0x400B0010U) /**< \brief (AFEC0) AFEC Channel Sequence 2 Register */ + #define REG_AFEC0_CHER (0x400B0014U) /**< \brief (AFEC0) AFEC Channel Enable Register */ + #define REG_AFEC0_CHDR (0x400B0018U) /**< \brief (AFEC0) AFEC Channel Disable Register */ + #define REG_AFEC0_CHSR (0x400B001CU) /**< \brief (AFEC0) AFEC Channel Status Register */ + #define REG_AFEC0_LCDR (0x400B0020U) /**< \brief (AFEC0) AFEC Last Converted Data Register */ + #define REG_AFEC0_IER (0x400B0024U) /**< \brief (AFEC0) AFEC Interrupt Enable Register */ + #define REG_AFEC0_IDR (0x400B0028U) /**< \brief (AFEC0) AFEC Interrupt Disable Register */ + #define REG_AFEC0_IMR (0x400B002CU) /**< \brief (AFEC0) AFEC Interrupt Mask Register */ + #define REG_AFEC0_ISR (0x400B0030U) /**< \brief (AFEC0) AFEC Interrupt Status Register */ + #define REG_AFEC0_OVER (0x400B004CU) /**< \brief (AFEC0) AFEC Overrun Status Register */ + #define REG_AFEC0_CWR (0x400B0050U) /**< \brief (AFEC0) AFEC Compare Window Register */ + #define REG_AFEC0_CGR (0x400B0054U) /**< \brief (AFEC0) AFEC Channel Gain Register */ + #define REG_AFEC0_CDOR (0x400B005CU) /**< \brief (AFEC0) AFEC Channel Calibration DC Offset Register */ + #define REG_AFEC0_DIFFR (0x400B0060U) /**< \brief (AFEC0) AFEC Channel Differential Register */ + #define REG_AFEC0_CSELR (0x400B0064U) /**< \brief (AFEC0) AFEC Channel Register Selection */ + #define REG_AFEC0_CDR (0x400B0068U) /**< \brief (AFEC0) AFEC Channel Data Register */ + #define REG_AFEC0_COCR (0x400B006CU) /**< \brief (AFEC0) AFEC Channel Offset Compensation Register */ + #define REG_AFEC0_TEMPMR (0x400B0070U) /**< \brief (AFEC0) AFEC Temperature Sensor Mode Register */ + #define REG_AFEC0_TEMPCWR (0x400B0074U) /**< \brief (AFEC0) AFEC Temperature Compare Window Register */ + #define REG_AFEC0_ACR (0x400B0094U) /**< \brief (AFEC0) AFEC Analog Control Register */ + #define REG_AFEC0_COSR (0x400B00D0U) /**< \brief (AFEC0) AFEC Correction Select Register */ + #define REG_AFEC0_CVR (0x400B00D4U) /**< \brief (AFEC0) AFEC Correction Values Register */ + #define REG_AFEC0_CECR (0x400B00D8U) /**< \brief (AFEC0) AFEC Channel Error Correction Register */ + #define REG_AFEC0_WPMR (0x400B00E4U) /**< \brief (AFEC0) AFEC Write Protection Mode Register */ + #define REG_AFEC0_WPSR (0x400B00E8U) /**< \brief (AFEC0) AFEC Write Protection Status Register */ + #define REG_AFEC0_RPR (0x400B0100U) /**< \brief (AFEC0) Receive Pointer Register */ + #define REG_AFEC0_RCR (0x400B0104U) /**< \brief (AFEC0) Receive Counter Register */ + #define REG_AFEC0_RNPR (0x400B0110U) /**< \brief (AFEC0) Receive Next Pointer Register */ + #define REG_AFEC0_RNCR (0x400B0114U) /**< \brief (AFEC0) Receive Next Counter Register */ + #define REG_AFEC0_PTCR (0x400B0120U) /**< \brief (AFEC0) Transfer Control Register */ + #define REG_AFEC0_PTSR (0x400B0124U) /**< \brief (AFEC0) Transfer Status Register */ +#else + #define REG_AFEC0_CR (*(__O uint32_t*)0x400B0000U) /**< \brief (AFEC0) AFEC Control Register */ + #define REG_AFEC0_MR (*(__IO uint32_t*)0x400B0004U) /**< \brief (AFEC0) AFEC Mode Register */ + #define REG_AFEC0_EMR (*(__IO uint32_t*)0x400B0008U) /**< \brief (AFEC0) AFEC Extended Mode Register */ + #define REG_AFEC0_SEQ1R (*(__IO uint32_t*)0x400B000CU) /**< \brief (AFEC0) AFEC Channel Sequence 1 Register */ + #define REG_AFEC0_SEQ2R (*(__IO uint32_t*)0x400B0010U) /**< \brief (AFEC0) AFEC Channel Sequence 2 Register */ + #define REG_AFEC0_CHER (*(__O uint32_t*)0x400B0014U) /**< \brief (AFEC0) AFEC Channel Enable Register */ + #define REG_AFEC0_CHDR (*(__O uint32_t*)0x400B0018U) /**< \brief (AFEC0) AFEC Channel Disable Register */ + #define REG_AFEC0_CHSR (*(__I uint32_t*)0x400B001CU) /**< \brief (AFEC0) AFEC Channel Status Register */ + #define REG_AFEC0_LCDR (*(__I uint32_t*)0x400B0020U) /**< \brief (AFEC0) AFEC Last Converted Data Register */ + #define REG_AFEC0_IER (*(__O uint32_t*)0x400B0024U) /**< \brief (AFEC0) AFEC Interrupt Enable Register */ + #define REG_AFEC0_IDR (*(__O uint32_t*)0x400B0028U) /**< \brief (AFEC0) AFEC Interrupt Disable Register */ + #define REG_AFEC0_IMR (*(__I uint32_t*)0x400B002CU) /**< \brief (AFEC0) AFEC Interrupt Mask Register */ + #define REG_AFEC0_ISR (*(__I uint32_t*)0x400B0030U) /**< \brief (AFEC0) AFEC Interrupt Status Register */ + #define REG_AFEC0_OVER (*(__I uint32_t*)0x400B004CU) /**< \brief (AFEC0) AFEC Overrun Status Register */ + #define REG_AFEC0_CWR (*(__IO uint32_t*)0x400B0050U) /**< \brief (AFEC0) AFEC Compare Window Register */ + #define REG_AFEC0_CGR (*(__IO uint32_t*)0x400B0054U) /**< \brief (AFEC0) AFEC Channel Gain Register */ + #define REG_AFEC0_CDOR (*(__IO uint32_t*)0x400B005CU) /**< \brief (AFEC0) AFEC Channel Calibration DC Offset Register */ + #define REG_AFEC0_DIFFR (*(__IO uint32_t*)0x400B0060U) /**< \brief (AFEC0) AFEC Channel Differential Register */ + #define REG_AFEC0_CSELR (*(__IO uint32_t*)0x400B0064U) /**< \brief (AFEC0) AFEC Channel Register Selection */ + #define REG_AFEC0_CDR (*(__I uint32_t*)0x400B0068U) /**< \brief (AFEC0) AFEC Channel Data Register */ + #define REG_AFEC0_COCR (*(__IO uint32_t*)0x400B006CU) /**< \brief (AFEC0) AFEC Channel Offset Compensation Register */ + #define REG_AFEC0_TEMPMR (*(__IO uint32_t*)0x400B0070U) /**< \brief (AFEC0) AFEC Temperature Sensor Mode Register */ + #define REG_AFEC0_TEMPCWR (*(__IO uint32_t*)0x400B0074U) /**< \brief (AFEC0) AFEC Temperature Compare Window Register */ + #define REG_AFEC0_ACR (*(__IO uint32_t*)0x400B0094U) /**< \brief (AFEC0) AFEC Analog Control Register */ + #define REG_AFEC0_COSR (*(__IO uint32_t*)0x400B00D0U) /**< \brief (AFEC0) AFEC Correction Select Register */ + #define REG_AFEC0_CVR (*(__IO uint32_t*)0x400B00D4U) /**< \brief (AFEC0) AFEC Correction Values Register */ + #define REG_AFEC0_CECR (*(__IO uint32_t*)0x400B00D8U) /**< \brief (AFEC0) AFEC Channel Error Correction Register */ + #define REG_AFEC0_WPMR (*(__IO uint32_t*)0x400B00E4U) /**< \brief (AFEC0) AFEC Write Protection Mode Register */ + #define REG_AFEC0_WPSR (*(__I uint32_t*)0x400B00E8U) /**< \brief (AFEC0) AFEC Write Protection Status Register */ + #define REG_AFEC0_RPR (*(__IO uint32_t*)0x400B0100U) /**< \brief (AFEC0) Receive Pointer Register */ + #define REG_AFEC0_RCR (*(__IO uint32_t*)0x400B0104U) /**< \brief (AFEC0) Receive Counter Register */ + #define REG_AFEC0_RNPR (*(__IO uint32_t*)0x400B0110U) /**< \brief (AFEC0) Receive Next Pointer Register */ + #define REG_AFEC0_RNCR (*(__IO uint32_t*)0x400B0114U) /**< \brief (AFEC0) Receive Next Counter Register */ + #define REG_AFEC0_PTCR (*(__O uint32_t*)0x400B0120U) /**< \brief (AFEC0) Transfer Control Register */ + #define REG_AFEC0_PTSR (*(__I uint32_t*)0x400B0124U) /**< \brief (AFEC0) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_AFEC0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec1.h new file mode 100644 index 0000000..be1ff76 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/afec1.h @@ -0,0 +1,123 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_AFEC1_INSTANCE_ +#define _SAM4E_AFEC1_INSTANCE_ + +/* ========== Register definition for AFEC1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_AFEC1_CR (0x400B4000U) /**< \brief (AFEC1) AFEC Control Register */ + #define REG_AFEC1_MR (0x400B4004U) /**< \brief (AFEC1) AFEC Mode Register */ + #define REG_AFEC1_EMR (0x400B4008U) /**< \brief (AFEC1) AFEC Extended Mode Register */ + #define REG_AFEC1_SEQ1R (0x400B400CU) /**< \brief (AFEC1) AFEC Channel Sequence 1 Register */ + #define REG_AFEC1_SEQ2R (0x400B4010U) /**< \brief (AFEC1) AFEC Channel Sequence 2 Register */ + #define REG_AFEC1_CHER (0x400B4014U) /**< \brief (AFEC1) AFEC Channel Enable Register */ + #define REG_AFEC1_CHDR (0x400B4018U) /**< \brief (AFEC1) AFEC Channel Disable Register */ + #define REG_AFEC1_CHSR (0x400B401CU) /**< \brief (AFEC1) AFEC Channel Status Register */ + #define REG_AFEC1_LCDR (0x400B4020U) /**< \brief (AFEC1) AFEC Last Converted Data Register */ + #define REG_AFEC1_IER (0x400B4024U) /**< \brief (AFEC1) AFEC Interrupt Enable Register */ + #define REG_AFEC1_IDR (0x400B4028U) /**< \brief (AFEC1) AFEC Interrupt Disable Register */ + #define REG_AFEC1_IMR (0x400B402CU) /**< \brief (AFEC1) AFEC Interrupt Mask Register */ + #define REG_AFEC1_ISR (0x400B4030U) /**< \brief (AFEC1) AFEC Interrupt Status Register */ + #define REG_AFEC1_OVER (0x400B404CU) /**< \brief (AFEC1) AFEC Overrun Status Register */ + #define REG_AFEC1_CWR (0x400B4050U) /**< \brief (AFEC1) AFEC Compare Window Register */ + #define REG_AFEC1_CGR (0x400B4054U) /**< \brief (AFEC1) AFEC Channel Gain Register */ + #define REG_AFEC1_CDOR (0x400B405CU) /**< \brief (AFEC1) AFEC Channel Calibration DC Offset Register */ + #define REG_AFEC1_DIFFR (0x400B4060U) /**< \brief (AFEC1) AFEC Channel Differential Register */ + #define REG_AFEC1_CSELR (0x400B4064U) /**< \brief (AFEC1) AFEC Channel Register Selection */ + #define REG_AFEC1_CDR (0x400B4068U) /**< \brief (AFEC1) AFEC Channel Data Register */ + #define REG_AFEC1_COCR (0x400B406CU) /**< \brief (AFEC1) AFEC Channel Offset Compensation Register */ + #define REG_AFEC1_TEMPMR (0x400B4070U) /**< \brief (AFEC1) AFEC Temperature Sensor Mode Register */ + #define REG_AFEC1_TEMPCWR (0x400B4074U) /**< \brief (AFEC1) AFEC Temperature Compare Window Register */ + #define REG_AFEC1_ACR (0x400B4094U) /**< \brief (AFEC1) AFEC Analog Control Register */ + #define REG_AFEC1_COSR (0x400B40D0U) /**< \brief (AFEC1) AFEC Correction Select Register */ + #define REG_AFEC1_CVR (0x400B40D4U) /**< \brief (AFEC1) AFEC Correction Values Register */ + #define REG_AFEC1_CECR (0x400B40D8U) /**< \brief (AFEC1) AFEC Channel Error Correction Register */ + #define REG_AFEC1_WPMR (0x400B40E4U) /**< \brief (AFEC1) AFEC Write Protection Mode Register */ + #define REG_AFEC1_WPSR (0x400B40E8U) /**< \brief (AFEC1) AFEC Write Protection Status Register */ + #define REG_AFEC1_RPR (0x400B4100U) /**< \brief (AFEC1) Receive Pointer Register */ + #define REG_AFEC1_RCR (0x400B4104U) /**< \brief (AFEC1) Receive Counter Register */ + #define REG_AFEC1_RNPR (0x400B4110U) /**< \brief (AFEC1) Receive Next Pointer Register */ + #define REG_AFEC1_RNCR (0x400B4114U) /**< \brief (AFEC1) Receive Next Counter Register */ + #define REG_AFEC1_PTCR (0x400B4120U) /**< \brief (AFEC1) Transfer Control Register */ + #define REG_AFEC1_PTSR (0x400B4124U) /**< \brief (AFEC1) Transfer Status Register */ +#else + #define REG_AFEC1_CR (*(__O uint32_t*)0x400B4000U) /**< \brief (AFEC1) AFEC Control Register */ + #define REG_AFEC1_MR (*(__IO uint32_t*)0x400B4004U) /**< \brief (AFEC1) AFEC Mode Register */ + #define REG_AFEC1_EMR (*(__IO uint32_t*)0x400B4008U) /**< \brief (AFEC1) AFEC Extended Mode Register */ + #define REG_AFEC1_SEQ1R (*(__IO uint32_t*)0x400B400CU) /**< \brief (AFEC1) AFEC Channel Sequence 1 Register */ + #define REG_AFEC1_SEQ2R (*(__IO uint32_t*)0x400B4010U) /**< \brief (AFEC1) AFEC Channel Sequence 2 Register */ + #define REG_AFEC1_CHER (*(__O uint32_t*)0x400B4014U) /**< \brief (AFEC1) AFEC Channel Enable Register */ + #define REG_AFEC1_CHDR (*(__O uint32_t*)0x400B4018U) /**< \brief (AFEC1) AFEC Channel Disable Register */ + #define REG_AFEC1_CHSR (*(__I uint32_t*)0x400B401CU) /**< \brief (AFEC1) AFEC Channel Status Register */ + #define REG_AFEC1_LCDR (*(__I uint32_t*)0x400B4020U) /**< \brief (AFEC1) AFEC Last Converted Data Register */ + #define REG_AFEC1_IER (*(__O uint32_t*)0x400B4024U) /**< \brief (AFEC1) AFEC Interrupt Enable Register */ + #define REG_AFEC1_IDR (*(__O uint32_t*)0x400B4028U) /**< \brief (AFEC1) AFEC Interrupt Disable Register */ + #define REG_AFEC1_IMR (*(__I uint32_t*)0x400B402CU) /**< \brief (AFEC1) AFEC Interrupt Mask Register */ + #define REG_AFEC1_ISR (*(__I uint32_t*)0x400B4030U) /**< \brief (AFEC1) AFEC Interrupt Status Register */ + #define REG_AFEC1_OVER (*(__I uint32_t*)0x400B404CU) /**< \brief (AFEC1) AFEC Overrun Status Register */ + #define REG_AFEC1_CWR (*(__IO uint32_t*)0x400B4050U) /**< \brief (AFEC1) AFEC Compare Window Register */ + #define REG_AFEC1_CGR (*(__IO uint32_t*)0x400B4054U) /**< \brief (AFEC1) AFEC Channel Gain Register */ + #define REG_AFEC1_CDOR (*(__IO uint32_t*)0x400B405CU) /**< \brief (AFEC1) AFEC Channel Calibration DC Offset Register */ + #define REG_AFEC1_DIFFR (*(__IO uint32_t*)0x400B4060U) /**< \brief (AFEC1) AFEC Channel Differential Register */ + #define REG_AFEC1_CSELR (*(__IO uint32_t*)0x400B4064U) /**< \brief (AFEC1) AFEC Channel Register Selection */ + #define REG_AFEC1_CDR (*(__I uint32_t*)0x400B4068U) /**< \brief (AFEC1) AFEC Channel Data Register */ + #define REG_AFEC1_COCR (*(__IO uint32_t*)0x400B406CU) /**< \brief (AFEC1) AFEC Channel Offset Compensation Register */ + #define REG_AFEC1_TEMPMR (*(__IO uint32_t*)0x400B4070U) /**< \brief (AFEC1) AFEC Temperature Sensor Mode Register */ + #define REG_AFEC1_TEMPCWR (*(__IO uint32_t*)0x400B4074U) /**< \brief (AFEC1) AFEC Temperature Compare Window Register */ + #define REG_AFEC1_ACR (*(__IO uint32_t*)0x400B4094U) /**< \brief (AFEC1) AFEC Analog Control Register */ + #define REG_AFEC1_COSR (*(__IO uint32_t*)0x400B40D0U) /**< \brief (AFEC1) AFEC Correction Select Register */ + #define REG_AFEC1_CVR (*(__IO uint32_t*)0x400B40D4U) /**< \brief (AFEC1) AFEC Correction Values Register */ + #define REG_AFEC1_CECR (*(__IO uint32_t*)0x400B40D8U) /**< \brief (AFEC1) AFEC Channel Error Correction Register */ + #define REG_AFEC1_WPMR (*(__IO uint32_t*)0x400B40E4U) /**< \brief (AFEC1) AFEC Write Protection Mode Register */ + #define REG_AFEC1_WPSR (*(__I uint32_t*)0x400B40E8U) /**< \brief (AFEC1) AFEC Write Protection Status Register */ + #define REG_AFEC1_RPR (*(__IO uint32_t*)0x400B4100U) /**< \brief (AFEC1) Receive Pointer Register */ + #define REG_AFEC1_RCR (*(__IO uint32_t*)0x400B4104U) /**< \brief (AFEC1) Receive Counter Register */ + #define REG_AFEC1_RNPR (*(__IO uint32_t*)0x400B4110U) /**< \brief (AFEC1) Receive Next Pointer Register */ + #define REG_AFEC1_RNCR (*(__IO uint32_t*)0x400B4114U) /**< \brief (AFEC1) Receive Next Counter Register */ + #define REG_AFEC1_PTCR (*(__O uint32_t*)0x400B4120U) /**< \brief (AFEC1) Transfer Control Register */ + #define REG_AFEC1_PTSR (*(__I uint32_t*)0x400B4124U) /**< \brief (AFEC1) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_AFEC1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can0.h new file mode 100644 index 0000000..07c768d --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can0.h @@ -0,0 +1,207 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CAN0_INSTANCE_ +#define _SAM4E_CAN0_INSTANCE_ + +/* ========== Register definition for CAN0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_CAN0_MR (0x40010000U) /**< \brief (CAN0) Mode Register */ + #define REG_CAN0_IER (0x40010004U) /**< \brief (CAN0) Interrupt Enable Register */ + #define REG_CAN0_IDR (0x40010008U) /**< \brief (CAN0) Interrupt Disable Register */ + #define REG_CAN0_IMR (0x4001000CU) /**< \brief (CAN0) Interrupt Mask Register */ + #define REG_CAN0_SR (0x40010010U) /**< \brief (CAN0) Status Register */ + #define REG_CAN0_BR (0x40010014U) /**< \brief (CAN0) Baudrate Register */ + #define REG_CAN0_TIM (0x40010018U) /**< \brief (CAN0) Timer Register */ + #define REG_CAN0_TIMESTP (0x4001001CU) /**< \brief (CAN0) Timestamp Register */ + #define REG_CAN0_ECR (0x40010020U) /**< \brief (CAN0) Error Counter Register */ + #define REG_CAN0_TCR (0x40010024U) /**< \brief (CAN0) Transfer Command Register */ + #define REG_CAN0_ACR (0x40010028U) /**< \brief (CAN0) Abort Command Register */ + #define REG_CAN0_WPMR (0x400100E4U) /**< \brief (CAN0) Write Protect Mode Register */ + #define REG_CAN0_WPSR (0x400100E8U) /**< \brief (CAN0) Write Protect Status Register */ + #define REG_CAN0_MMR0 (0x40010200U) /**< \brief (CAN0) Mailbox Mode Register (MB = 0) */ + #define REG_CAN0_MAM0 (0x40010204U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 0) */ + #define REG_CAN0_MID0 (0x40010208U) /**< \brief (CAN0) Mailbox ID Register (MB = 0) */ + #define REG_CAN0_MFID0 (0x4001020CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 0) */ + #define REG_CAN0_MSR0 (0x40010210U) /**< \brief (CAN0) Mailbox Status Register (MB = 0) */ + #define REG_CAN0_MDL0 (0x40010214U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 0) */ + #define REG_CAN0_MDH0 (0x40010218U) /**< \brief (CAN0) Mailbox Data High Register (MB = 0) */ + #define REG_CAN0_MCR0 (0x4001021CU) /**< \brief (CAN0) Mailbox Control Register (MB = 0) */ + #define REG_CAN0_MMR1 (0x40010220U) /**< \brief (CAN0) Mailbox Mode Register (MB = 1) */ + #define REG_CAN0_MAM1 (0x40010224U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 1) */ + #define REG_CAN0_MID1 (0x40010228U) /**< \brief (CAN0) Mailbox ID Register (MB = 1) */ + #define REG_CAN0_MFID1 (0x4001022CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 1) */ + #define REG_CAN0_MSR1 (0x40010230U) /**< \brief (CAN0) Mailbox Status Register (MB = 1) */ + #define REG_CAN0_MDL1 (0x40010234U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 1) */ + #define REG_CAN0_MDH1 (0x40010238U) /**< \brief (CAN0) Mailbox Data High Register (MB = 1) */ + #define REG_CAN0_MCR1 (0x4001023CU) /**< \brief (CAN0) Mailbox Control Register (MB = 1) */ + #define REG_CAN0_MMR2 (0x40010240U) /**< \brief (CAN0) Mailbox Mode Register (MB = 2) */ + #define REG_CAN0_MAM2 (0x40010244U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 2) */ + #define REG_CAN0_MID2 (0x40010248U) /**< \brief (CAN0) Mailbox ID Register (MB = 2) */ + #define REG_CAN0_MFID2 (0x4001024CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 2) */ + #define REG_CAN0_MSR2 (0x40010250U) /**< \brief (CAN0) Mailbox Status Register (MB = 2) */ + #define REG_CAN0_MDL2 (0x40010254U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 2) */ + #define REG_CAN0_MDH2 (0x40010258U) /**< \brief (CAN0) Mailbox Data High Register (MB = 2) */ + #define REG_CAN0_MCR2 (0x4001025CU) /**< \brief (CAN0) Mailbox Control Register (MB = 2) */ + #define REG_CAN0_MMR3 (0x40010260U) /**< \brief (CAN0) Mailbox Mode Register (MB = 3) */ + #define REG_CAN0_MAM3 (0x40010264U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 3) */ + #define REG_CAN0_MID3 (0x40010268U) /**< \brief (CAN0) Mailbox ID Register (MB = 3) */ + #define REG_CAN0_MFID3 (0x4001026CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 3) */ + #define REG_CAN0_MSR3 (0x40010270U) /**< \brief (CAN0) Mailbox Status Register (MB = 3) */ + #define REG_CAN0_MDL3 (0x40010274U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 3) */ + #define REG_CAN0_MDH3 (0x40010278U) /**< \brief (CAN0) Mailbox Data High Register (MB = 3) */ + #define REG_CAN0_MCR3 (0x4001027CU) /**< \brief (CAN0) Mailbox Control Register (MB = 3) */ + #define REG_CAN0_MMR4 (0x40010280U) /**< \brief (CAN0) Mailbox Mode Register (MB = 4) */ + #define REG_CAN0_MAM4 (0x40010284U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 4) */ + #define REG_CAN0_MID4 (0x40010288U) /**< \brief (CAN0) Mailbox ID Register (MB = 4) */ + #define REG_CAN0_MFID4 (0x4001028CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 4) */ + #define REG_CAN0_MSR4 (0x40010290U) /**< \brief (CAN0) Mailbox Status Register (MB = 4) */ + #define REG_CAN0_MDL4 (0x40010294U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 4) */ + #define REG_CAN0_MDH4 (0x40010298U) /**< \brief (CAN0) Mailbox Data High Register (MB = 4) */ + #define REG_CAN0_MCR4 (0x4001029CU) /**< \brief (CAN0) Mailbox Control Register (MB = 4) */ + #define REG_CAN0_MMR5 (0x400102A0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 5) */ + #define REG_CAN0_MAM5 (0x400102A4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 5) */ + #define REG_CAN0_MID5 (0x400102A8U) /**< \brief (CAN0) Mailbox ID Register (MB = 5) */ + #define REG_CAN0_MFID5 (0x400102ACU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 5) */ + #define REG_CAN0_MSR5 (0x400102B0U) /**< \brief (CAN0) Mailbox Status Register (MB = 5) */ + #define REG_CAN0_MDL5 (0x400102B4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 5) */ + #define REG_CAN0_MDH5 (0x400102B8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 5) */ + #define REG_CAN0_MCR5 (0x400102BCU) /**< \brief (CAN0) Mailbox Control Register (MB = 5) */ + #define REG_CAN0_MMR6 (0x400102C0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 6) */ + #define REG_CAN0_MAM6 (0x400102C4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 6) */ + #define REG_CAN0_MID6 (0x400102C8U) /**< \brief (CAN0) Mailbox ID Register (MB = 6) */ + #define REG_CAN0_MFID6 (0x400102CCU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 6) */ + #define REG_CAN0_MSR6 (0x400102D0U) /**< \brief (CAN0) Mailbox Status Register (MB = 6) */ + #define REG_CAN0_MDL6 (0x400102D4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 6) */ + #define REG_CAN0_MDH6 (0x400102D8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 6) */ + #define REG_CAN0_MCR6 (0x400102DCU) /**< \brief (CAN0) Mailbox Control Register (MB = 6) */ + #define REG_CAN0_MMR7 (0x400102E0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 7) */ + #define REG_CAN0_MAM7 (0x400102E4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 7) */ + #define REG_CAN0_MID7 (0x400102E8U) /**< \brief (CAN0) Mailbox ID Register (MB = 7) */ + #define REG_CAN0_MFID7 (0x400102ECU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 7) */ + #define REG_CAN0_MSR7 (0x400102F0U) /**< \brief (CAN0) Mailbox Status Register (MB = 7) */ + #define REG_CAN0_MDL7 (0x400102F4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 7) */ + #define REG_CAN0_MDH7 (0x400102F8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 7) */ + #define REG_CAN0_MCR7 (0x400102FCU) /**< \brief (CAN0) Mailbox Control Register (MB = 7) */ +#else + #define REG_CAN0_MR (*(__IO uint32_t*)0x40010000U) /**< \brief (CAN0) Mode Register */ + #define REG_CAN0_IER (*(__O uint32_t*)0x40010004U) /**< \brief (CAN0) Interrupt Enable Register */ + #define REG_CAN0_IDR (*(__O uint32_t*)0x40010008U) /**< \brief (CAN0) Interrupt Disable Register */ + #define REG_CAN0_IMR (*(__I uint32_t*)0x4001000CU) /**< \brief (CAN0) Interrupt Mask Register */ + #define REG_CAN0_SR (*(__I uint32_t*)0x40010010U) /**< \brief (CAN0) Status Register */ + #define REG_CAN0_BR (*(__IO uint32_t*)0x40010014U) /**< \brief (CAN0) Baudrate Register */ + #define REG_CAN0_TIM (*(__I uint32_t*)0x40010018U) /**< \brief (CAN0) Timer Register */ + #define REG_CAN0_TIMESTP (*(__I uint32_t*)0x4001001CU) /**< \brief (CAN0) Timestamp Register */ + #define REG_CAN0_ECR (*(__I uint32_t*)0x40010020U) /**< \brief (CAN0) Error Counter Register */ + #define REG_CAN0_TCR (*(__O uint32_t*)0x40010024U) /**< \brief (CAN0) Transfer Command Register */ + #define REG_CAN0_ACR (*(__O uint32_t*)0x40010028U) /**< \brief (CAN0) Abort Command Register */ + #define REG_CAN0_WPMR (*(__IO uint32_t*)0x400100E4U) /**< \brief (CAN0) Write Protect Mode Register */ + #define REG_CAN0_WPSR (*(__I uint32_t*)0x400100E8U) /**< \brief (CAN0) Write Protect Status Register */ + #define REG_CAN0_MMR0 (*(__IO uint32_t*)0x40010200U) /**< \brief (CAN0) Mailbox Mode Register (MB = 0) */ + #define REG_CAN0_MAM0 (*(__IO uint32_t*)0x40010204U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 0) */ + #define REG_CAN0_MID0 (*(__IO uint32_t*)0x40010208U) /**< \brief (CAN0) Mailbox ID Register (MB = 0) */ + #define REG_CAN0_MFID0 (*(__I uint32_t*)0x4001020CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 0) */ + #define REG_CAN0_MSR0 (*(__I uint32_t*)0x40010210U) /**< \brief (CAN0) Mailbox Status Register (MB = 0) */ + #define REG_CAN0_MDL0 (*(__IO uint32_t*)0x40010214U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 0) */ + #define REG_CAN0_MDH0 (*(__IO uint32_t*)0x40010218U) /**< \brief (CAN0) Mailbox Data High Register (MB = 0) */ + #define REG_CAN0_MCR0 (*(__O uint32_t*)0x4001021CU) /**< \brief (CAN0) Mailbox Control Register (MB = 0) */ + #define REG_CAN0_MMR1 (*(__IO uint32_t*)0x40010220U) /**< \brief (CAN0) Mailbox Mode Register (MB = 1) */ + #define REG_CAN0_MAM1 (*(__IO uint32_t*)0x40010224U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 1) */ + #define REG_CAN0_MID1 (*(__IO uint32_t*)0x40010228U) /**< \brief (CAN0) Mailbox ID Register (MB = 1) */ + #define REG_CAN0_MFID1 (*(__I uint32_t*)0x4001022CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 1) */ + #define REG_CAN0_MSR1 (*(__I uint32_t*)0x40010230U) /**< \brief (CAN0) Mailbox Status Register (MB = 1) */ + #define REG_CAN0_MDL1 (*(__IO uint32_t*)0x40010234U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 1) */ + #define REG_CAN0_MDH1 (*(__IO uint32_t*)0x40010238U) /**< \brief (CAN0) Mailbox Data High Register (MB = 1) */ + #define REG_CAN0_MCR1 (*(__O uint32_t*)0x4001023CU) /**< \brief (CAN0) Mailbox Control Register (MB = 1) */ + #define REG_CAN0_MMR2 (*(__IO uint32_t*)0x40010240U) /**< \brief (CAN0) Mailbox Mode Register (MB = 2) */ + #define REG_CAN0_MAM2 (*(__IO uint32_t*)0x40010244U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 2) */ + #define REG_CAN0_MID2 (*(__IO uint32_t*)0x40010248U) /**< \brief (CAN0) Mailbox ID Register (MB = 2) */ + #define REG_CAN0_MFID2 (*(__I uint32_t*)0x4001024CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 2) */ + #define REG_CAN0_MSR2 (*(__I uint32_t*)0x40010250U) /**< \brief (CAN0) Mailbox Status Register (MB = 2) */ + #define REG_CAN0_MDL2 (*(__IO uint32_t*)0x40010254U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 2) */ + #define REG_CAN0_MDH2 (*(__IO uint32_t*)0x40010258U) /**< \brief (CAN0) Mailbox Data High Register (MB = 2) */ + #define REG_CAN0_MCR2 (*(__O uint32_t*)0x4001025CU) /**< \brief (CAN0) Mailbox Control Register (MB = 2) */ + #define REG_CAN0_MMR3 (*(__IO uint32_t*)0x40010260U) /**< \brief (CAN0) Mailbox Mode Register (MB = 3) */ + #define REG_CAN0_MAM3 (*(__IO uint32_t*)0x40010264U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 3) */ + #define REG_CAN0_MID3 (*(__IO uint32_t*)0x40010268U) /**< \brief (CAN0) Mailbox ID Register (MB = 3) */ + #define REG_CAN0_MFID3 (*(__I uint32_t*)0x4001026CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 3) */ + #define REG_CAN0_MSR3 (*(__I uint32_t*)0x40010270U) /**< \brief (CAN0) Mailbox Status Register (MB = 3) */ + #define REG_CAN0_MDL3 (*(__IO uint32_t*)0x40010274U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 3) */ + #define REG_CAN0_MDH3 (*(__IO uint32_t*)0x40010278U) /**< \brief (CAN0) Mailbox Data High Register (MB = 3) */ + #define REG_CAN0_MCR3 (*(__O uint32_t*)0x4001027CU) /**< \brief (CAN0) Mailbox Control Register (MB = 3) */ + #define REG_CAN0_MMR4 (*(__IO uint32_t*)0x40010280U) /**< \brief (CAN0) Mailbox Mode Register (MB = 4) */ + #define REG_CAN0_MAM4 (*(__IO uint32_t*)0x40010284U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 4) */ + #define REG_CAN0_MID4 (*(__IO uint32_t*)0x40010288U) /**< \brief (CAN0) Mailbox ID Register (MB = 4) */ + #define REG_CAN0_MFID4 (*(__I uint32_t*)0x4001028CU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 4) */ + #define REG_CAN0_MSR4 (*(__I uint32_t*)0x40010290U) /**< \brief (CAN0) Mailbox Status Register (MB = 4) */ + #define REG_CAN0_MDL4 (*(__IO uint32_t*)0x40010294U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 4) */ + #define REG_CAN0_MDH4 (*(__IO uint32_t*)0x40010298U) /**< \brief (CAN0) Mailbox Data High Register (MB = 4) */ + #define REG_CAN0_MCR4 (*(__O uint32_t*)0x4001029CU) /**< \brief (CAN0) Mailbox Control Register (MB = 4) */ + #define REG_CAN0_MMR5 (*(__IO uint32_t*)0x400102A0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 5) */ + #define REG_CAN0_MAM5 (*(__IO uint32_t*)0x400102A4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 5) */ + #define REG_CAN0_MID5 (*(__IO uint32_t*)0x400102A8U) /**< \brief (CAN0) Mailbox ID Register (MB = 5) */ + #define REG_CAN0_MFID5 (*(__I uint32_t*)0x400102ACU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 5) */ + #define REG_CAN0_MSR5 (*(__I uint32_t*)0x400102B0U) /**< \brief (CAN0) Mailbox Status Register (MB = 5) */ + #define REG_CAN0_MDL5 (*(__IO uint32_t*)0x400102B4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 5) */ + #define REG_CAN0_MDH5 (*(__IO uint32_t*)0x400102B8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 5) */ + #define REG_CAN0_MCR5 (*(__O uint32_t*)0x400102BCU) /**< \brief (CAN0) Mailbox Control Register (MB = 5) */ + #define REG_CAN0_MMR6 (*(__IO uint32_t*)0x400102C0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 6) */ + #define REG_CAN0_MAM6 (*(__IO uint32_t*)0x400102C4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 6) */ + #define REG_CAN0_MID6 (*(__IO uint32_t*)0x400102C8U) /**< \brief (CAN0) Mailbox ID Register (MB = 6) */ + #define REG_CAN0_MFID6 (*(__I uint32_t*)0x400102CCU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 6) */ + #define REG_CAN0_MSR6 (*(__I uint32_t*)0x400102D0U) /**< \brief (CAN0) Mailbox Status Register (MB = 6) */ + #define REG_CAN0_MDL6 (*(__IO uint32_t*)0x400102D4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 6) */ + #define REG_CAN0_MDH6 (*(__IO uint32_t*)0x400102D8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 6) */ + #define REG_CAN0_MCR6 (*(__O uint32_t*)0x400102DCU) /**< \brief (CAN0) Mailbox Control Register (MB = 6) */ + #define REG_CAN0_MMR7 (*(__IO uint32_t*)0x400102E0U) /**< \brief (CAN0) Mailbox Mode Register (MB = 7) */ + #define REG_CAN0_MAM7 (*(__IO uint32_t*)0x400102E4U) /**< \brief (CAN0) Mailbox Acceptance Mask Register (MB = 7) */ + #define REG_CAN0_MID7 (*(__IO uint32_t*)0x400102E8U) /**< \brief (CAN0) Mailbox ID Register (MB = 7) */ + #define REG_CAN0_MFID7 (*(__I uint32_t*)0x400102ECU) /**< \brief (CAN0) Mailbox Family ID Register (MB = 7) */ + #define REG_CAN0_MSR7 (*(__I uint32_t*)0x400102F0U) /**< \brief (CAN0) Mailbox Status Register (MB = 7) */ + #define REG_CAN0_MDL7 (*(__IO uint32_t*)0x400102F4U) /**< \brief (CAN0) Mailbox Data Low Register (MB = 7) */ + #define REG_CAN0_MDH7 (*(__IO uint32_t*)0x400102F8U) /**< \brief (CAN0) Mailbox Data High Register (MB = 7) */ + #define REG_CAN0_MCR7 (*(__O uint32_t*)0x400102FCU) /**< \brief (CAN0) Mailbox Control Register (MB = 7) */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_CAN0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can1.h new file mode 100644 index 0000000..5b0cf60 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/can1.h @@ -0,0 +1,207 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CAN1_INSTANCE_ +#define _SAM4E_CAN1_INSTANCE_ + +/* ========== Register definition for CAN1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_CAN1_MR (0x40014000U) /**< \brief (CAN1) Mode Register */ + #define REG_CAN1_IER (0x40014004U) /**< \brief (CAN1) Interrupt Enable Register */ + #define REG_CAN1_IDR (0x40014008U) /**< \brief (CAN1) Interrupt Disable Register */ + #define REG_CAN1_IMR (0x4001400CU) /**< \brief (CAN1) Interrupt Mask Register */ + #define REG_CAN1_SR (0x40014010U) /**< \brief (CAN1) Status Register */ + #define REG_CAN1_BR (0x40014014U) /**< \brief (CAN1) Baudrate Register */ + #define REG_CAN1_TIM (0x40014018U) /**< \brief (CAN1) Timer Register */ + #define REG_CAN1_TIMESTP (0x4001401CU) /**< \brief (CAN1) Timestamp Register */ + #define REG_CAN1_ECR (0x40014020U) /**< \brief (CAN1) Error Counter Register */ + #define REG_CAN1_TCR (0x40014024U) /**< \brief (CAN1) Transfer Command Register */ + #define REG_CAN1_ACR (0x40014028U) /**< \brief (CAN1) Abort Command Register */ + #define REG_CAN1_WPMR (0x400140E4U) /**< \brief (CAN1) Write Protect Mode Register */ + #define REG_CAN1_WPSR (0x400140E8U) /**< \brief (CAN1) Write Protect Status Register */ + #define REG_CAN1_MMR0 (0x40014200U) /**< \brief (CAN1) Mailbox Mode Register (MB = 0) */ + #define REG_CAN1_MAM0 (0x40014204U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 0) */ + #define REG_CAN1_MID0 (0x40014208U) /**< \brief (CAN1) Mailbox ID Register (MB = 0) */ + #define REG_CAN1_MFID0 (0x4001420CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 0) */ + #define REG_CAN1_MSR0 (0x40014210U) /**< \brief (CAN1) Mailbox Status Register (MB = 0) */ + #define REG_CAN1_MDL0 (0x40014214U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 0) */ + #define REG_CAN1_MDH0 (0x40014218U) /**< \brief (CAN1) Mailbox Data High Register (MB = 0) */ + #define REG_CAN1_MCR0 (0x4001421CU) /**< \brief (CAN1) Mailbox Control Register (MB = 0) */ + #define REG_CAN1_MMR1 (0x40014220U) /**< \brief (CAN1) Mailbox Mode Register (MB = 1) */ + #define REG_CAN1_MAM1 (0x40014224U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 1) */ + #define REG_CAN1_MID1 (0x40014228U) /**< \brief (CAN1) Mailbox ID Register (MB = 1) */ + #define REG_CAN1_MFID1 (0x4001422CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 1) */ + #define REG_CAN1_MSR1 (0x40014230U) /**< \brief (CAN1) Mailbox Status Register (MB = 1) */ + #define REG_CAN1_MDL1 (0x40014234U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 1) */ + #define REG_CAN1_MDH1 (0x40014238U) /**< \brief (CAN1) Mailbox Data High Register (MB = 1) */ + #define REG_CAN1_MCR1 (0x4001423CU) /**< \brief (CAN1) Mailbox Control Register (MB = 1) */ + #define REG_CAN1_MMR2 (0x40014240U) /**< \brief (CAN1) Mailbox Mode Register (MB = 2) */ + #define REG_CAN1_MAM2 (0x40014244U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 2) */ + #define REG_CAN1_MID2 (0x40014248U) /**< \brief (CAN1) Mailbox ID Register (MB = 2) */ + #define REG_CAN1_MFID2 (0x4001424CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 2) */ + #define REG_CAN1_MSR2 (0x40014250U) /**< \brief (CAN1) Mailbox Status Register (MB = 2) */ + #define REG_CAN1_MDL2 (0x40014254U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 2) */ + #define REG_CAN1_MDH2 (0x40014258U) /**< \brief (CAN1) Mailbox Data High Register (MB = 2) */ + #define REG_CAN1_MCR2 (0x4001425CU) /**< \brief (CAN1) Mailbox Control Register (MB = 2) */ + #define REG_CAN1_MMR3 (0x40014260U) /**< \brief (CAN1) Mailbox Mode Register (MB = 3) */ + #define REG_CAN1_MAM3 (0x40014264U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 3) */ + #define REG_CAN1_MID3 (0x40014268U) /**< \brief (CAN1) Mailbox ID Register (MB = 3) */ + #define REG_CAN1_MFID3 (0x4001426CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 3) */ + #define REG_CAN1_MSR3 (0x40014270U) /**< \brief (CAN1) Mailbox Status Register (MB = 3) */ + #define REG_CAN1_MDL3 (0x40014274U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 3) */ + #define REG_CAN1_MDH3 (0x40014278U) /**< \brief (CAN1) Mailbox Data High Register (MB = 3) */ + #define REG_CAN1_MCR3 (0x4001427CU) /**< \brief (CAN1) Mailbox Control Register (MB = 3) */ + #define REG_CAN1_MMR4 (0x40014280U) /**< \brief (CAN1) Mailbox Mode Register (MB = 4) */ + #define REG_CAN1_MAM4 (0x40014284U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 4) */ + #define REG_CAN1_MID4 (0x40014288U) /**< \brief (CAN1) Mailbox ID Register (MB = 4) */ + #define REG_CAN1_MFID4 (0x4001428CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 4) */ + #define REG_CAN1_MSR4 (0x40014290U) /**< \brief (CAN1) Mailbox Status Register (MB = 4) */ + #define REG_CAN1_MDL4 (0x40014294U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 4) */ + #define REG_CAN1_MDH4 (0x40014298U) /**< \brief (CAN1) Mailbox Data High Register (MB = 4) */ + #define REG_CAN1_MCR4 (0x4001429CU) /**< \brief (CAN1) Mailbox Control Register (MB = 4) */ + #define REG_CAN1_MMR5 (0x400142A0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 5) */ + #define REG_CAN1_MAM5 (0x400142A4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 5) */ + #define REG_CAN1_MID5 (0x400142A8U) /**< \brief (CAN1) Mailbox ID Register (MB = 5) */ + #define REG_CAN1_MFID5 (0x400142ACU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 5) */ + #define REG_CAN1_MSR5 (0x400142B0U) /**< \brief (CAN1) Mailbox Status Register (MB = 5) */ + #define REG_CAN1_MDL5 (0x400142B4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 5) */ + #define REG_CAN1_MDH5 (0x400142B8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 5) */ + #define REG_CAN1_MCR5 (0x400142BCU) /**< \brief (CAN1) Mailbox Control Register (MB = 5) */ + #define REG_CAN1_MMR6 (0x400142C0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 6) */ + #define REG_CAN1_MAM6 (0x400142C4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 6) */ + #define REG_CAN1_MID6 (0x400142C8U) /**< \brief (CAN1) Mailbox ID Register (MB = 6) */ + #define REG_CAN1_MFID6 (0x400142CCU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 6) */ + #define REG_CAN1_MSR6 (0x400142D0U) /**< \brief (CAN1) Mailbox Status Register (MB = 6) */ + #define REG_CAN1_MDL6 (0x400142D4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 6) */ + #define REG_CAN1_MDH6 (0x400142D8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 6) */ + #define REG_CAN1_MCR6 (0x400142DCU) /**< \brief (CAN1) Mailbox Control Register (MB = 6) */ + #define REG_CAN1_MMR7 (0x400142E0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 7) */ + #define REG_CAN1_MAM7 (0x400142E4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 7) */ + #define REG_CAN1_MID7 (0x400142E8U) /**< \brief (CAN1) Mailbox ID Register (MB = 7) */ + #define REG_CAN1_MFID7 (0x400142ECU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 7) */ + #define REG_CAN1_MSR7 (0x400142F0U) /**< \brief (CAN1) Mailbox Status Register (MB = 7) */ + #define REG_CAN1_MDL7 (0x400142F4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 7) */ + #define REG_CAN1_MDH7 (0x400142F8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 7) */ + #define REG_CAN1_MCR7 (0x400142FCU) /**< \brief (CAN1) Mailbox Control Register (MB = 7) */ +#else + #define REG_CAN1_MR (*(__IO uint32_t*)0x40014000U) /**< \brief (CAN1) Mode Register */ + #define REG_CAN1_IER (*(__O uint32_t*)0x40014004U) /**< \brief (CAN1) Interrupt Enable Register */ + #define REG_CAN1_IDR (*(__O uint32_t*)0x40014008U) /**< \brief (CAN1) Interrupt Disable Register */ + #define REG_CAN1_IMR (*(__I uint32_t*)0x4001400CU) /**< \brief (CAN1) Interrupt Mask Register */ + #define REG_CAN1_SR (*(__I uint32_t*)0x40014010U) /**< \brief (CAN1) Status Register */ + #define REG_CAN1_BR (*(__IO uint32_t*)0x40014014U) /**< \brief (CAN1) Baudrate Register */ + #define REG_CAN1_TIM (*(__I uint32_t*)0x40014018U) /**< \brief (CAN1) Timer Register */ + #define REG_CAN1_TIMESTP (*(__I uint32_t*)0x4001401CU) /**< \brief (CAN1) Timestamp Register */ + #define REG_CAN1_ECR (*(__I uint32_t*)0x40014020U) /**< \brief (CAN1) Error Counter Register */ + #define REG_CAN1_TCR (*(__O uint32_t*)0x40014024U) /**< \brief (CAN1) Transfer Command Register */ + #define REG_CAN1_ACR (*(__O uint32_t*)0x40014028U) /**< \brief (CAN1) Abort Command Register */ + #define REG_CAN1_WPMR (*(__IO uint32_t*)0x400140E4U) /**< \brief (CAN1) Write Protect Mode Register */ + #define REG_CAN1_WPSR (*(__I uint32_t*)0x400140E8U) /**< \brief (CAN1) Write Protect Status Register */ + #define REG_CAN1_MMR0 (*(__IO uint32_t*)0x40014200U) /**< \brief (CAN1) Mailbox Mode Register (MB = 0) */ + #define REG_CAN1_MAM0 (*(__IO uint32_t*)0x40014204U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 0) */ + #define REG_CAN1_MID0 (*(__IO uint32_t*)0x40014208U) /**< \brief (CAN1) Mailbox ID Register (MB = 0) */ + #define REG_CAN1_MFID0 (*(__I uint32_t*)0x4001420CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 0) */ + #define REG_CAN1_MSR0 (*(__I uint32_t*)0x40014210U) /**< \brief (CAN1) Mailbox Status Register (MB = 0) */ + #define REG_CAN1_MDL0 (*(__IO uint32_t*)0x40014214U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 0) */ + #define REG_CAN1_MDH0 (*(__IO uint32_t*)0x40014218U) /**< \brief (CAN1) Mailbox Data High Register (MB = 0) */ + #define REG_CAN1_MCR0 (*(__O uint32_t*)0x4001421CU) /**< \brief (CAN1) Mailbox Control Register (MB = 0) */ + #define REG_CAN1_MMR1 (*(__IO uint32_t*)0x40014220U) /**< \brief (CAN1) Mailbox Mode Register (MB = 1) */ + #define REG_CAN1_MAM1 (*(__IO uint32_t*)0x40014224U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 1) */ + #define REG_CAN1_MID1 (*(__IO uint32_t*)0x40014228U) /**< \brief (CAN1) Mailbox ID Register (MB = 1) */ + #define REG_CAN1_MFID1 (*(__I uint32_t*)0x4001422CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 1) */ + #define REG_CAN1_MSR1 (*(__I uint32_t*)0x40014230U) /**< \brief (CAN1) Mailbox Status Register (MB = 1) */ + #define REG_CAN1_MDL1 (*(__IO uint32_t*)0x40014234U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 1) */ + #define REG_CAN1_MDH1 (*(__IO uint32_t*)0x40014238U) /**< \brief (CAN1) Mailbox Data High Register (MB = 1) */ + #define REG_CAN1_MCR1 (*(__O uint32_t*)0x4001423CU) /**< \brief (CAN1) Mailbox Control Register (MB = 1) */ + #define REG_CAN1_MMR2 (*(__IO uint32_t*)0x40014240U) /**< \brief (CAN1) Mailbox Mode Register (MB = 2) */ + #define REG_CAN1_MAM2 (*(__IO uint32_t*)0x40014244U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 2) */ + #define REG_CAN1_MID2 (*(__IO uint32_t*)0x40014248U) /**< \brief (CAN1) Mailbox ID Register (MB = 2) */ + #define REG_CAN1_MFID2 (*(__I uint32_t*)0x4001424CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 2) */ + #define REG_CAN1_MSR2 (*(__I uint32_t*)0x40014250U) /**< \brief (CAN1) Mailbox Status Register (MB = 2) */ + #define REG_CAN1_MDL2 (*(__IO uint32_t*)0x40014254U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 2) */ + #define REG_CAN1_MDH2 (*(__IO uint32_t*)0x40014258U) /**< \brief (CAN1) Mailbox Data High Register (MB = 2) */ + #define REG_CAN1_MCR2 (*(__O uint32_t*)0x4001425CU) /**< \brief (CAN1) Mailbox Control Register (MB = 2) */ + #define REG_CAN1_MMR3 (*(__IO uint32_t*)0x40014260U) /**< \brief (CAN1) Mailbox Mode Register (MB = 3) */ + #define REG_CAN1_MAM3 (*(__IO uint32_t*)0x40014264U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 3) */ + #define REG_CAN1_MID3 (*(__IO uint32_t*)0x40014268U) /**< \brief (CAN1) Mailbox ID Register (MB = 3) */ + #define REG_CAN1_MFID3 (*(__I uint32_t*)0x4001426CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 3) */ + #define REG_CAN1_MSR3 (*(__I uint32_t*)0x40014270U) /**< \brief (CAN1) Mailbox Status Register (MB = 3) */ + #define REG_CAN1_MDL3 (*(__IO uint32_t*)0x40014274U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 3) */ + #define REG_CAN1_MDH3 (*(__IO uint32_t*)0x40014278U) /**< \brief (CAN1) Mailbox Data High Register (MB = 3) */ + #define REG_CAN1_MCR3 (*(__O uint32_t*)0x4001427CU) /**< \brief (CAN1) Mailbox Control Register (MB = 3) */ + #define REG_CAN1_MMR4 (*(__IO uint32_t*)0x40014280U) /**< \brief (CAN1) Mailbox Mode Register (MB = 4) */ + #define REG_CAN1_MAM4 (*(__IO uint32_t*)0x40014284U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 4) */ + #define REG_CAN1_MID4 (*(__IO uint32_t*)0x40014288U) /**< \brief (CAN1) Mailbox ID Register (MB = 4) */ + #define REG_CAN1_MFID4 (*(__I uint32_t*)0x4001428CU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 4) */ + #define REG_CAN1_MSR4 (*(__I uint32_t*)0x40014290U) /**< \brief (CAN1) Mailbox Status Register (MB = 4) */ + #define REG_CAN1_MDL4 (*(__IO uint32_t*)0x40014294U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 4) */ + #define REG_CAN1_MDH4 (*(__IO uint32_t*)0x40014298U) /**< \brief (CAN1) Mailbox Data High Register (MB = 4) */ + #define REG_CAN1_MCR4 (*(__O uint32_t*)0x4001429CU) /**< \brief (CAN1) Mailbox Control Register (MB = 4) */ + #define REG_CAN1_MMR5 (*(__IO uint32_t*)0x400142A0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 5) */ + #define REG_CAN1_MAM5 (*(__IO uint32_t*)0x400142A4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 5) */ + #define REG_CAN1_MID5 (*(__IO uint32_t*)0x400142A8U) /**< \brief (CAN1) Mailbox ID Register (MB = 5) */ + #define REG_CAN1_MFID5 (*(__I uint32_t*)0x400142ACU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 5) */ + #define REG_CAN1_MSR5 (*(__I uint32_t*)0x400142B0U) /**< \brief (CAN1) Mailbox Status Register (MB = 5) */ + #define REG_CAN1_MDL5 (*(__IO uint32_t*)0x400142B4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 5) */ + #define REG_CAN1_MDH5 (*(__IO uint32_t*)0x400142B8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 5) */ + #define REG_CAN1_MCR5 (*(__O uint32_t*)0x400142BCU) /**< \brief (CAN1) Mailbox Control Register (MB = 5) */ + #define REG_CAN1_MMR6 (*(__IO uint32_t*)0x400142C0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 6) */ + #define REG_CAN1_MAM6 (*(__IO uint32_t*)0x400142C4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 6) */ + #define REG_CAN1_MID6 (*(__IO uint32_t*)0x400142C8U) /**< \brief (CAN1) Mailbox ID Register (MB = 6) */ + #define REG_CAN1_MFID6 (*(__I uint32_t*)0x400142CCU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 6) */ + #define REG_CAN1_MSR6 (*(__I uint32_t*)0x400142D0U) /**< \brief (CAN1) Mailbox Status Register (MB = 6) */ + #define REG_CAN1_MDL6 (*(__IO uint32_t*)0x400142D4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 6) */ + #define REG_CAN1_MDH6 (*(__IO uint32_t*)0x400142D8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 6) */ + #define REG_CAN1_MCR6 (*(__O uint32_t*)0x400142DCU) /**< \brief (CAN1) Mailbox Control Register (MB = 6) */ + #define REG_CAN1_MMR7 (*(__IO uint32_t*)0x400142E0U) /**< \brief (CAN1) Mailbox Mode Register (MB = 7) */ + #define REG_CAN1_MAM7 (*(__IO uint32_t*)0x400142E4U) /**< \brief (CAN1) Mailbox Acceptance Mask Register (MB = 7) */ + #define REG_CAN1_MID7 (*(__IO uint32_t*)0x400142E8U) /**< \brief (CAN1) Mailbox ID Register (MB = 7) */ + #define REG_CAN1_MFID7 (*(__I uint32_t*)0x400142ECU) /**< \brief (CAN1) Mailbox Family ID Register (MB = 7) */ + #define REG_CAN1_MSR7 (*(__I uint32_t*)0x400142F0U) /**< \brief (CAN1) Mailbox Status Register (MB = 7) */ + #define REG_CAN1_MDL7 (*(__IO uint32_t*)0x400142F4U) /**< \brief (CAN1) Mailbox Data Low Register (MB = 7) */ + #define REG_CAN1_MDH7 (*(__IO uint32_t*)0x400142F8U) /**< \brief (CAN1) Mailbox Data High Register (MB = 7) */ + #define REG_CAN1_MCR7 (*(__O uint32_t*)0x400142FCU) /**< \brief (CAN1) Mailbox Control Register (MB = 7) */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_CAN1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/chipid.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/chipid.h new file mode 100644 index 0000000..92c402c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/chipid.h @@ -0,0 +1,57 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CHIPID_INSTANCE_ +#define _SAM4E_CHIPID_INSTANCE_ + +/* ========== Register definition for CHIPID peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_CHIPID_CIDR (0x400E0740U) /**< \brief (CHIPID) Chip ID Register */ + #define REG_CHIPID_EXID (0x400E0744U) /**< \brief (CHIPID) Chip ID Extension Register */ +#else + #define REG_CHIPID_CIDR (*(__I uint32_t*)0x400E0740U) /**< \brief (CHIPID) Chip ID Register */ + #define REG_CHIPID_EXID (*(__I uint32_t*)0x400E0744U) /**< \brief (CHIPID) Chip ID Extension Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_CHIPID_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/cmcc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/cmcc.h new file mode 100644 index 0000000..a82a945 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/cmcc.h @@ -0,0 +1,73 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_CMCC_INSTANCE_ +#define _SAM4E_CMCC_INSTANCE_ + +/* ========== Register definition for CMCC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_CMCC_TYPE (0x400C4000U) /**< \brief (CMCC) Cache Type Register */ + #define REG_CMCC_CFG (0x400C4004U) /**< \brief (CMCC) Cache Configuration Register */ + #define REG_CMCC_CTRL (0x400C4008U) /**< \brief (CMCC) Cache Control Register */ + #define REG_CMCC_SR (0x400C400CU) /**< \brief (CMCC) Cache Status Register */ + #define REG_CMCC_MAINT0 (0x400C4020U) /**< \brief (CMCC) Cache Maintenance Register 0 */ + #define REG_CMCC_MAINT1 (0x400C4024U) /**< \brief (CMCC) Cache Maintenance Register 1 */ + #define REG_CMCC_MCFG (0x400C4028U) /**< \brief (CMCC) Cache Monitor Configuration Register */ + #define REG_CMCC_MEN (0x400C402CU) /**< \brief (CMCC) Cache Monitor Enable Register */ + #define REG_CMCC_MCTRL (0x400C4030U) /**< \brief (CMCC) Cache Monitor Control Register */ + #define REG_CMCC_MSR (0x400C4034U) /**< \brief (CMCC) Cache Monitor Status Register */ +#else + #define REG_CMCC_TYPE (*(__I uint32_t*)0x400C4000U) /**< \brief (CMCC) Cache Type Register */ + #define REG_CMCC_CFG (*(__IO uint32_t*)0x400C4004U) /**< \brief (CMCC) Cache Configuration Register */ + #define REG_CMCC_CTRL (*(__O uint32_t*)0x400C4008U) /**< \brief (CMCC) Cache Control Register */ + #define REG_CMCC_SR (*(__I uint32_t*)0x400C400CU) /**< \brief (CMCC) Cache Status Register */ + #define REG_CMCC_MAINT0 (*(__O uint32_t*)0x400C4020U) /**< \brief (CMCC) Cache Maintenance Register 0 */ + #define REG_CMCC_MAINT1 (*(__O uint32_t*)0x400C4024U) /**< \brief (CMCC) Cache Maintenance Register 1 */ + #define REG_CMCC_MCFG (*(__IO uint32_t*)0x400C4028U) /**< \brief (CMCC) Cache Monitor Configuration Register */ + #define REG_CMCC_MEN (*(__IO uint32_t*)0x400C402CU) /**< \brief (CMCC) Cache Monitor Enable Register */ + #define REG_CMCC_MCTRL (*(__O uint32_t*)0x400C4030U) /**< \brief (CMCC) Cache Monitor Control Register */ + #define REG_CMCC_MSR (*(__I uint32_t*)0x400C4034U) /**< \brief (CMCC) Cache Monitor Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_CMCC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dacc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dacc.h new file mode 100644 index 0000000..ed726b2 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dacc.h @@ -0,0 +1,91 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_DACC_INSTANCE_ +#define _SAM4E_DACC_INSTANCE_ + +/* ========== Register definition for DACC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_DACC_CR (0x400B8000U) /**< \brief (DACC) Control Register */ + #define REG_DACC_MR (0x400B8004U) /**< \brief (DACC) Mode Register */ + #define REG_DACC_CHER (0x400B8010U) /**< \brief (DACC) Channel Enable Register */ + #define REG_DACC_CHDR (0x400B8014U) /**< \brief (DACC) Channel Disable Register */ + #define REG_DACC_CHSR (0x400B8018U) /**< \brief (DACC) Channel Status Register */ + #define REG_DACC_CDR (0x400B8020U) /**< \brief (DACC) Conversion Data Register */ + #define REG_DACC_IER (0x400B8024U) /**< \brief (DACC) Interrupt Enable Register */ + #define REG_DACC_IDR (0x400B8028U) /**< \brief (DACC) Interrupt Disable Register */ + #define REG_DACC_IMR (0x400B802CU) /**< \brief (DACC) Interrupt Mask Register */ + #define REG_DACC_ISR (0x400B8030U) /**< \brief (DACC) Interrupt Status Register */ + #define REG_DACC_ACR (0x400B8094U) /**< \brief (DACC) Analog Current Register */ + #define REG_DACC_WPMR (0x400B80E4U) /**< \brief (DACC) Write Protection Mode Register */ + #define REG_DACC_WPSR (0x400B80E8U) /**< \brief (DACC) Write Protection Status Register */ + #define REG_DACC_TPR (0x400B8108U) /**< \brief (DACC) Transmit Pointer Register */ + #define REG_DACC_TCR (0x400B810CU) /**< \brief (DACC) Transmit Counter Register */ + #define REG_DACC_TNPR (0x400B8118U) /**< \brief (DACC) Transmit Next Pointer Register */ + #define REG_DACC_TNCR (0x400B811CU) /**< \brief (DACC) Transmit Next Counter Register */ + #define REG_DACC_PTCR (0x400B8120U) /**< \brief (DACC) Transfer Control Register */ + #define REG_DACC_PTSR (0x400B8124U) /**< \brief (DACC) Transfer Status Register */ +#else + #define REG_DACC_CR (*(__O uint32_t*)0x400B8000U) /**< \brief (DACC) Control Register */ + #define REG_DACC_MR (*(__IO uint32_t*)0x400B8004U) /**< \brief (DACC) Mode Register */ + #define REG_DACC_CHER (*(__O uint32_t*)0x400B8010U) /**< \brief (DACC) Channel Enable Register */ + #define REG_DACC_CHDR (*(__O uint32_t*)0x400B8014U) /**< \brief (DACC) Channel Disable Register */ + #define REG_DACC_CHSR (*(__I uint32_t*)0x400B8018U) /**< \brief (DACC) Channel Status Register */ + #define REG_DACC_CDR (*(__O uint32_t*)0x400B8020U) /**< \brief (DACC) Conversion Data Register */ + #define REG_DACC_IER (*(__O uint32_t*)0x400B8024U) /**< \brief (DACC) Interrupt Enable Register */ + #define REG_DACC_IDR (*(__O uint32_t*)0x400B8028U) /**< \brief (DACC) Interrupt Disable Register */ + #define REG_DACC_IMR (*(__I uint32_t*)0x400B802CU) /**< \brief (DACC) Interrupt Mask Register */ + #define REG_DACC_ISR (*(__I uint32_t*)0x400B8030U) /**< \brief (DACC) Interrupt Status Register */ + #define REG_DACC_ACR (*(__IO uint32_t*)0x400B8094U) /**< \brief (DACC) Analog Current Register */ + #define REG_DACC_WPMR (*(__IO uint32_t*)0x400B80E4U) /**< \brief (DACC) Write Protection Mode Register */ + #define REG_DACC_WPSR (*(__I uint32_t*)0x400B80E8U) /**< \brief (DACC) Write Protection Status Register */ + #define REG_DACC_TPR (*(__IO uint32_t*)0x400B8108U) /**< \brief (DACC) Transmit Pointer Register */ + #define REG_DACC_TCR (*(__IO uint32_t*)0x400B810CU) /**< \brief (DACC) Transmit Counter Register */ + #define REG_DACC_TNPR (*(__IO uint32_t*)0x400B8118U) /**< \brief (DACC) Transmit Next Pointer Register */ + #define REG_DACC_TNCR (*(__IO uint32_t*)0x400B811CU) /**< \brief (DACC) Transmit Next Counter Register */ + #define REG_DACC_PTCR (*(__O uint32_t*)0x400B8120U) /**< \brief (DACC) Transfer Control Register */ + #define REG_DACC_PTSR (*(__I uint32_t*)0x400B8124U) /**< \brief (DACC) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_DACC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dmac.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dmac.h new file mode 100644 index 0000000..2479ef8 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/dmac.h @@ -0,0 +1,129 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_DMAC_INSTANCE_ +#define _SAM4E_DMAC_INSTANCE_ + +/* ========== Register definition for DMAC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_DMAC_GCFG (0x400C0000U) /**< \brief (DMAC) DMAC Global Configuration Register */ + #define REG_DMAC_EN (0x400C0004U) /**< \brief (DMAC) DMAC Enable Register */ + #define REG_DMAC_SREQ (0x400C0008U) /**< \brief (DMAC) DMAC Software Single Request Register */ + #define REG_DMAC_CREQ (0x400C000CU) /**< \brief (DMAC) DMAC Software Chunk Transfer Request Register */ + #define REG_DMAC_LAST (0x400C0010U) /**< \brief (DMAC) DMAC Software Last Transfer Flag Register */ + #define REG_DMAC_EBCIER (0x400C0018U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. */ + #define REG_DMAC_EBCIDR (0x400C001CU) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. */ + #define REG_DMAC_EBCIMR (0x400C0020U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. */ + #define REG_DMAC_EBCISR (0x400C0024U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. */ + #define REG_DMAC_CHER (0x400C0028U) /**< \brief (DMAC) DMAC Channel Handler Enable Register */ + #define REG_DMAC_CHDR (0x400C002CU) /**< \brief (DMAC) DMAC Channel Handler Disable Register */ + #define REG_DMAC_CHSR (0x400C0030U) /**< \brief (DMAC) DMAC Channel Handler Status Register */ + #define REG_DMAC_SADDR0 (0x400C003CU) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 0) */ + #define REG_DMAC_DADDR0 (0x400C0040U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 0) */ + #define REG_DMAC_DSCR0 (0x400C0044U) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 0) */ + #define REG_DMAC_CTRLA0 (0x400C0048U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 0) */ + #define REG_DMAC_CTRLB0 (0x400C004CU) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 0) */ + #define REG_DMAC_CFG0 (0x400C0050U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 0) */ + #define REG_DMAC_SADDR1 (0x400C0064U) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 1) */ + #define REG_DMAC_DADDR1 (0x400C0068U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 1) */ + #define REG_DMAC_DSCR1 (0x400C006CU) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 1) */ + #define REG_DMAC_CTRLA1 (0x400C0070U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 1) */ + #define REG_DMAC_CTRLB1 (0x400C0074U) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 1) */ + #define REG_DMAC_CFG1 (0x400C0078U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 1) */ + #define REG_DMAC_SADDR2 (0x400C008CU) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 2) */ + #define REG_DMAC_DADDR2 (0x400C0090U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 2) */ + #define REG_DMAC_DSCR2 (0x400C0094U) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 2) */ + #define REG_DMAC_CTRLA2 (0x400C0098U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 2) */ + #define REG_DMAC_CTRLB2 (0x400C009CU) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 2) */ + #define REG_DMAC_CFG2 (0x400C00A0U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 2) */ + #define REG_DMAC_SADDR3 (0x400C00B4U) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 3) */ + #define REG_DMAC_DADDR3 (0x400C00B8U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 3) */ + #define REG_DMAC_DSCR3 (0x400C00BCU) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 3) */ + #define REG_DMAC_CTRLA3 (0x400C00C0U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 3) */ + #define REG_DMAC_CTRLB3 (0x400C00C4U) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 3) */ + #define REG_DMAC_CFG3 (0x400C00C8U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 3) */ + #define REG_DMAC_WPMR (0x400C01E4U) /**< \brief (DMAC) DMAC Write Protect Mode Register */ + #define REG_DMAC_WPSR (0x400C01E8U) /**< \brief (DMAC) DMAC Write Protect Status Register */ +#else + #define REG_DMAC_GCFG (*(__IO uint32_t*)0x400C0000U) /**< \brief (DMAC) DMAC Global Configuration Register */ + #define REG_DMAC_EN (*(__IO uint32_t*)0x400C0004U) /**< \brief (DMAC) DMAC Enable Register */ + #define REG_DMAC_SREQ (*(__IO uint32_t*)0x400C0008U) /**< \brief (DMAC) DMAC Software Single Request Register */ + #define REG_DMAC_CREQ (*(__IO uint32_t*)0x400C000CU) /**< \brief (DMAC) DMAC Software Chunk Transfer Request Register */ + #define REG_DMAC_LAST (*(__IO uint32_t*)0x400C0010U) /**< \brief (DMAC) DMAC Software Last Transfer Flag Register */ + #define REG_DMAC_EBCIER (*(__O uint32_t*)0x400C0018U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Enable register. */ + #define REG_DMAC_EBCIDR (*(__O uint32_t*)0x400C001CU) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer Transfer Completed Interrupt Disable register. */ + #define REG_DMAC_EBCIMR (*(__I uint32_t*)0x400C0020U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Mask Register. */ + #define REG_DMAC_EBCISR (*(__I uint32_t*)0x400C0024U) /**< \brief (DMAC) DMAC Error, Chained Buffer Transfer Completed Interrupt and Buffer transfer completed Status Register. */ + #define REG_DMAC_CHER (*(__O uint32_t*)0x400C0028U) /**< \brief (DMAC) DMAC Channel Handler Enable Register */ + #define REG_DMAC_CHDR (*(__O uint32_t*)0x400C002CU) /**< \brief (DMAC) DMAC Channel Handler Disable Register */ + #define REG_DMAC_CHSR (*(__I uint32_t*)0x400C0030U) /**< \brief (DMAC) DMAC Channel Handler Status Register */ + #define REG_DMAC_SADDR0 (*(__IO uint32_t*)0x400C003CU) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 0) */ + #define REG_DMAC_DADDR0 (*(__IO uint32_t*)0x400C0040U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 0) */ + #define REG_DMAC_DSCR0 (*(__IO uint32_t*)0x400C0044U) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 0) */ + #define REG_DMAC_CTRLA0 (*(__IO uint32_t*)0x400C0048U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 0) */ + #define REG_DMAC_CTRLB0 (*(__IO uint32_t*)0x400C004CU) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 0) */ + #define REG_DMAC_CFG0 (*(__IO uint32_t*)0x400C0050U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 0) */ + #define REG_DMAC_SADDR1 (*(__IO uint32_t*)0x400C0064U) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 1) */ + #define REG_DMAC_DADDR1 (*(__IO uint32_t*)0x400C0068U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 1) */ + #define REG_DMAC_DSCR1 (*(__IO uint32_t*)0x400C006CU) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 1) */ + #define REG_DMAC_CTRLA1 (*(__IO uint32_t*)0x400C0070U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 1) */ + #define REG_DMAC_CTRLB1 (*(__IO uint32_t*)0x400C0074U) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 1) */ + #define REG_DMAC_CFG1 (*(__IO uint32_t*)0x400C0078U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 1) */ + #define REG_DMAC_SADDR2 (*(__IO uint32_t*)0x400C008CU) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 2) */ + #define REG_DMAC_DADDR2 (*(__IO uint32_t*)0x400C0090U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 2) */ + #define REG_DMAC_DSCR2 (*(__IO uint32_t*)0x400C0094U) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 2) */ + #define REG_DMAC_CTRLA2 (*(__IO uint32_t*)0x400C0098U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 2) */ + #define REG_DMAC_CTRLB2 (*(__IO uint32_t*)0x400C009CU) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 2) */ + #define REG_DMAC_CFG2 (*(__IO uint32_t*)0x400C00A0U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 2) */ + #define REG_DMAC_SADDR3 (*(__IO uint32_t*)0x400C00B4U) /**< \brief (DMAC) DMAC Channel Source Address Register (ch_num = 3) */ + #define REG_DMAC_DADDR3 (*(__IO uint32_t*)0x400C00B8U) /**< \brief (DMAC) DMAC Channel Destination Address Register (ch_num = 3) */ + #define REG_DMAC_DSCR3 (*(__IO uint32_t*)0x400C00BCU) /**< \brief (DMAC) DMAC Channel Descriptor Address Register (ch_num = 3) */ + #define REG_DMAC_CTRLA3 (*(__IO uint32_t*)0x400C00C0U) /**< \brief (DMAC) DMAC Channel Control A Register (ch_num = 3) */ + #define REG_DMAC_CTRLB3 (*(__IO uint32_t*)0x400C00C4U) /**< \brief (DMAC) DMAC Channel Control B Register (ch_num = 3) */ + #define REG_DMAC_CFG3 (*(__IO uint32_t*)0x400C00C8U) /**< \brief (DMAC) DMAC Channel Configuration Register (ch_num = 3) */ + #define REG_DMAC_WPMR (*(__IO uint32_t*)0x400C01E4U) /**< \brief (DMAC) DMAC Write Protect Mode Register */ + #define REG_DMAC_WPSR (*(__I uint32_t*)0x400C01E8U) /**< \brief (DMAC) DMAC Write Protect Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_DMAC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/efc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/efc.h new file mode 100644 index 0000000..5f84c4e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/efc.h @@ -0,0 +1,61 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_EFC_INSTANCE_ +#define _SAM4E_EFC_INSTANCE_ + +/* ========== Register definition for EFC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_EFC_FMR (0x400E0A00U) /**< \brief (EFC) EEFC Flash Mode Register */ + #define REG_EFC_FCR (0x400E0A04U) /**< \brief (EFC) EEFC Flash Command Register */ + #define REG_EFC_FSR (0x400E0A08U) /**< \brief (EFC) EEFC Flash Status Register */ + #define REG_EFC_FRR (0x400E0A0CU) /**< \brief (EFC) EEFC Flash Result Register */ +#else + #define REG_EFC_FMR (*(__IO uint32_t*)0x400E0A00U) /**< \brief (EFC) EEFC Flash Mode Register */ + #define REG_EFC_FCR (*(__O uint32_t*)0x400E0A04U) /**< \brief (EFC) EEFC Flash Command Register */ + #define REG_EFC_FSR (*(__I uint32_t*)0x400E0A08U) /**< \brief (EFC) EEFC Flash Status Register */ + #define REG_EFC_FRR (*(__I uint32_t*)0x400E0A0CU) /**< \brief (EFC) EEFC Flash Result Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_EFC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gmac.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gmac.h new file mode 100644 index 0000000..298121e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gmac.h @@ -0,0 +1,235 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_GMAC_INSTANCE_ +#define _SAM4E_GMAC_INSTANCE_ + +/* ========== Register definition for GMAC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_GMAC_NCR (0x40034000U) /**< \brief (GMAC) Network Control Register */ + #define REG_GMAC_NCFGR (0x40034004U) /**< \brief (GMAC) Network Configuration Register */ + #define REG_GMAC_NSR (0x40034008U) /**< \brief (GMAC) Network Status Register */ + #define REG_GMAC_UR (0x4003400CU) /**< \brief (GMAC) User Register */ + #define REG_GMAC_DCFGR (0x40034010U) /**< \brief (GMAC) DMA Configuration Register */ + #define REG_GMAC_TSR (0x40034014U) /**< \brief (GMAC) Transmit Status Register */ + #define REG_GMAC_RBQB (0x40034018U) /**< \brief (GMAC) Receive Buffer Queue Base Address */ + #define REG_GMAC_TBQB (0x4003401CU) /**< \brief (GMAC) Transmit Buffer Queue Base Address */ + #define REG_GMAC_RSR (0x40034020U) /**< \brief (GMAC) Receive Status Register */ + #define REG_GMAC_ISR (0x40034024U) /**< \brief (GMAC) Interrupt Status Register */ + #define REG_GMAC_IER (0x40034028U) /**< \brief (GMAC) Interrupt Enable Register */ + #define REG_GMAC_IDR (0x4003402CU) /**< \brief (GMAC) Interrupt Disable Register */ + #define REG_GMAC_IMR (0x40034030U) /**< \brief (GMAC) Interrupt Mask Register */ + #define REG_GMAC_MAN (0x40034034U) /**< \brief (GMAC) PHY Maintenance Register */ + #define REG_GMAC_RPQ (0x40034038U) /**< \brief (GMAC) Received Pause Quantum Register */ + #define REG_GMAC_TPQ (0x4003403CU) /**< \brief (GMAC) Transmit Pause Quantum Register */ + #define REG_GMAC_HRB (0x40034080U) /**< \brief (GMAC) Hash Register Bottom [31:0] */ + #define REG_GMAC_HRT (0x40034084U) /**< \brief (GMAC) Hash Register Top [63:32] */ + #define REG_GMAC_SAB1 (0x40034088U) /**< \brief (GMAC) Specific Address 1 Bottom [31:0] Register */ + #define REG_GMAC_SAT1 (0x4003408CU) /**< \brief (GMAC) Specific Address 1 Top [47:32] Register */ + #define REG_GMAC_SAB2 (0x40034090U) /**< \brief (GMAC) Specific Address 2 Bottom [31:0] Register */ + #define REG_GMAC_SAT2 (0x40034094U) /**< \brief (GMAC) Specific Address 2 Top [47:32] Register */ + #define REG_GMAC_SAB3 (0x40034098U) /**< \brief (GMAC) Specific Address 3 Bottom [31:0] Register */ + #define REG_GMAC_SAT3 (0x4003409CU) /**< \brief (GMAC) Specific Address 3 Top [47:32] Register */ + #define REG_GMAC_SAB4 (0x400340A0U) /**< \brief (GMAC) Specific Address 4 Bottom [31:0] Register */ + #define REG_GMAC_SAT4 (0x400340A4U) /**< \brief (GMAC) Specific Address 4 Top [47:32] Register */ + #define REG_GMAC_TIDM (0x400340A8U) /**< \brief (GMAC) Type ID Match 1 Register */ + #define REG_GMAC_IPGS (0x400340BCU) /**< \brief (GMAC) IPG Stretch Register */ + #define REG_GMAC_SVLAN (0x400340C0U) /**< \brief (GMAC) Stacked VLAN Register */ + #define REG_GMAC_TPFCP (0x400340C4U) /**< \brief (GMAC) Transmit PFC Pause Register */ + #define REG_GMAC_SAMB1 (0x400340C8U) /**< \brief (GMAC) Specific Address 1 Mask Bottom [31:0] Register */ + #define REG_GMAC_SAMT1 (0x400340CCU) /**< \brief (GMAC) Specific Address 1 Mask Top [47:32] Register */ + #define REG_GMAC_OTLO (0x40034100U) /**< \brief (GMAC) Octets Transmitted [31:0] Register */ + #define REG_GMAC_OTHI (0x40034104U) /**< \brief (GMAC) Octets Transmitted [47:32] Register */ + #define REG_GMAC_FT (0x40034108U) /**< \brief (GMAC) Frames Transmitted Register */ + #define REG_GMAC_BCFT (0x4003410CU) /**< \brief (GMAC) Broadcast Frames Transmitted Register */ + #define REG_GMAC_MFT (0x40034110U) /**< \brief (GMAC) Multicast Frames Transmitted Register */ + #define REG_GMAC_PFT (0x40034114U) /**< \brief (GMAC) Pause Frames Transmitted Register */ + #define REG_GMAC_BFT64 (0x40034118U) /**< \brief (GMAC) 64 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT127 (0x4003411CU) /**< \brief (GMAC) 65 to 127 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT255 (0x40034120U) /**< \brief (GMAC) 128 to 255 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT511 (0x40034124U) /**< \brief (GMAC) 256 to 511 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT1023 (0x40034128U) /**< \brief (GMAC) 512 to 1023 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT1518 (0x4003412CU) /**< \brief (GMAC) 1024 to 1518 Byte Frames Transmitted Register */ + #define REG_GMAC_GTBFT1518 (0x40034130U) /**< \brief (GMAC) Greater Than 1518 Byte Frames Transmitted Register */ + #define REG_GMAC_TUR (0x40034134U) /**< \brief (GMAC) Transmit Underruns Register */ + #define REG_GMAC_SCF (0x40034138U) /**< \brief (GMAC) Single Collision Frames Register */ + #define REG_GMAC_MCF (0x4003413CU) /**< \brief (GMAC) Multiple Collision Frames Register */ + #define REG_GMAC_EC (0x40034140U) /**< \brief (GMAC) Excessive Collisions Register */ + #define REG_GMAC_LC (0x40034144U) /**< \brief (GMAC) Late Collisions Register */ + #define REG_GMAC_DTF (0x40034148U) /**< \brief (GMAC) Deferred Transmission Frames Register */ + #define REG_GMAC_CSE (0x4003414CU) /**< \brief (GMAC) Carrier Sense Errors Register */ + #define REG_GMAC_ORLO (0x40034150U) /**< \brief (GMAC) Octets Received [31:0] Received */ + #define REG_GMAC_ORHI (0x40034154U) /**< \brief (GMAC) Octets Received [47:32] Received */ + #define REG_GMAC_FR (0x40034158U) /**< \brief (GMAC) Frames Received Register */ + #define REG_GMAC_BCFR (0x4003415CU) /**< \brief (GMAC) Broadcast Frames Received Register */ + #define REG_GMAC_MFR (0x40034160U) /**< \brief (GMAC) Multicast Frames Received Register */ + #define REG_GMAC_PFR (0x40034164U) /**< \brief (GMAC) Pause Frames Received Register */ + #define REG_GMAC_BFR64 (0x40034168U) /**< \brief (GMAC) 64 Byte Frames Received Register */ + #define REG_GMAC_TBFR127 (0x4003416CU) /**< \brief (GMAC) 65 to 127 Byte Frames Received Register */ + #define REG_GMAC_TBFR255 (0x40034170U) /**< \brief (GMAC) 128 to 255 Byte Frames Received Register */ + #define REG_GMAC_TBFR511 (0x40034174U) /**< \brief (GMAC) 256 to 511Byte Frames Received Register */ + #define REG_GMAC_TBFR1023 (0x40034178U) /**< \brief (GMAC) 512 to 1023 Byte Frames Received Register */ + #define REG_GMAC_TBFR1518 (0x4003417CU) /**< \brief (GMAC) 1024 to 1518 Byte Frames Received Register */ + #define REG_GMAC_TMXBFR (0x40034180U) /**< \brief (GMAC) 1519 to Maximum Byte Frames Received Register */ + #define REG_GMAC_UFR (0x40034184U) /**< \brief (GMAC) Undersize Frames Received Register */ + #define REG_GMAC_OFR (0x40034188U) /**< \brief (GMAC) Oversize Frames Received Register */ + #define REG_GMAC_JR (0x4003418CU) /**< \brief (GMAC) Jabbers Received Register */ + #define REG_GMAC_FCSE (0x40034190U) /**< \brief (GMAC) Frame Check Sequence Errors Register */ + #define REG_GMAC_LFFE (0x40034194U) /**< \brief (GMAC) Length Field Frame Errors Register */ + #define REG_GMAC_RSE (0x40034198U) /**< \brief (GMAC) Receive Symbol Errors Register */ + #define REG_GMAC_AE (0x4003419CU) /**< \brief (GMAC) Alignment Errors Register */ + #define REG_GMAC_RRE (0x400341A0U) /**< \brief (GMAC) Receive Resource Errors Register */ + #define REG_GMAC_ROE (0x400341A4U) /**< \brief (GMAC) Receive Overrun Register */ + #define REG_GMAC_IHCE (0x400341A8U) /**< \brief (GMAC) IP Header Checksum Errors Register */ + #define REG_GMAC_TCE (0x400341ACU) /**< \brief (GMAC) TCP Checksum Errors Register */ + #define REG_GMAC_UCE (0x400341B0U) /**< \brief (GMAC) UDP Checksum Errors Register */ + #define REG_GMAC_TSSSL (0x400341C8U) /**< \brief (GMAC) 1588 Timer Sync Strobe Seconds [31:0] Register */ + #define REG_GMAC_TSSN (0x400341CCU) /**< \brief (GMAC) 1588 Timer Sync Strobe Nanoseconds Register */ + #define REG_GMAC_TSL (0x400341D0U) /**< \brief (GMAC) 1588 Timer Seconds [31:0] Register */ + #define REG_GMAC_TN (0x400341D4U) /**< \brief (GMAC) 1588 Timer Nanoseconds Register */ + #define REG_GMAC_TA (0x400341D8U) /**< \brief (GMAC) 1588 Timer Adjust Register */ + #define REG_GMAC_TI (0x400341DCU) /**< \brief (GMAC) 1588 Timer Increment Register */ + #define REG_GMAC_EFTS (0x400341E0U) /**< \brief (GMAC) PTP Event Frame Transmitted Seconds */ + #define REG_GMAC_EFTN (0x400341E4U) /**< \brief (GMAC) PTP Event Frame Transmitted Nanoseconds */ + #define REG_GMAC_EFRS (0x400341E8U) /**< \brief (GMAC) PTP Event Frame Received Seconds */ + #define REG_GMAC_EFRN (0x400341ECU) /**< \brief (GMAC) PTP Event Frame Received Nanoseconds */ + #define REG_GMAC_PEFTS (0x400341F0U) /**< \brief (GMAC) PTP Peer Event Frame Transmitted Seconds */ + #define REG_GMAC_PEFTN (0x400341F4U) /**< \brief (GMAC) PTP Peer Event Frame Transmitted Nanoseconds */ + #define REG_GMAC_PEFRS (0x400341F8U) /**< \brief (GMAC) PTP Peer Event Frame Received Seconds */ + #define REG_GMAC_PEFRN (0x400341FCU) /**< \brief (GMAC) PTP Peer Event Frame Received Nanoseconds */ +#else + #define REG_GMAC_NCR (*(__IO uint32_t*)0x40034000U) /**< \brief (GMAC) Network Control Register */ + #define REG_GMAC_NCFGR (*(__IO uint32_t*)0x40034004U) /**< \brief (GMAC) Network Configuration Register */ + #define REG_GMAC_NSR (*(__I uint32_t*)0x40034008U) /**< \brief (GMAC) Network Status Register */ + #define REG_GMAC_UR (*(__IO uint32_t*)0x4003400CU) /**< \brief (GMAC) User Register */ + #define REG_GMAC_DCFGR (*(__IO uint32_t*)0x40034010U) /**< \brief (GMAC) DMA Configuration Register */ + #define REG_GMAC_TSR (*(__IO uint32_t*)0x40034014U) /**< \brief (GMAC) Transmit Status Register */ + #define REG_GMAC_RBQB (*(__IO uint32_t*)0x40034018U) /**< \brief (GMAC) Receive Buffer Queue Base Address */ + #define REG_GMAC_TBQB (*(__IO uint32_t*)0x4003401CU) /**< \brief (GMAC) Transmit Buffer Queue Base Address */ + #define REG_GMAC_RSR (*(__IO uint32_t*)0x40034020U) /**< \brief (GMAC) Receive Status Register */ + #define REG_GMAC_ISR (*(__I uint32_t*)0x40034024U) /**< \brief (GMAC) Interrupt Status Register */ + #define REG_GMAC_IER (*(__O uint32_t*)0x40034028U) /**< \brief (GMAC) Interrupt Enable Register */ + #define REG_GMAC_IDR (*(__O uint32_t*)0x4003402CU) /**< \brief (GMAC) Interrupt Disable Register */ + #define REG_GMAC_IMR (*(__I uint32_t*)0x40034030U) /**< \brief (GMAC) Interrupt Mask Register */ + #define REG_GMAC_MAN (*(__IO uint32_t*)0x40034034U) /**< \brief (GMAC) PHY Maintenance Register */ + #define REG_GMAC_RPQ (*(__I uint32_t*)0x40034038U) /**< \brief (GMAC) Received Pause Quantum Register */ + #define REG_GMAC_TPQ (*(__IO uint32_t*)0x4003403CU) /**< \brief (GMAC) Transmit Pause Quantum Register */ + #define REG_GMAC_HRB (*(__IO uint32_t*)0x40034080U) /**< \brief (GMAC) Hash Register Bottom [31:0] */ + #define REG_GMAC_HRT (*(__IO uint32_t*)0x40034084U) /**< \brief (GMAC) Hash Register Top [63:32] */ + #define REG_GMAC_SAB1 (*(__IO uint32_t*)0x40034088U) /**< \brief (GMAC) Specific Address 1 Bottom [31:0] Register */ + #define REG_GMAC_SAT1 (*(__IO uint32_t*)0x4003408CU) /**< \brief (GMAC) Specific Address 1 Top [47:32] Register */ + #define REG_GMAC_SAB2 (*(__IO uint32_t*)0x40034090U) /**< \brief (GMAC) Specific Address 2 Bottom [31:0] Register */ + #define REG_GMAC_SAT2 (*(__IO uint32_t*)0x40034094U) /**< \brief (GMAC) Specific Address 2 Top [47:32] Register */ + #define REG_GMAC_SAB3 (*(__IO uint32_t*)0x40034098U) /**< \brief (GMAC) Specific Address 3 Bottom [31:0] Register */ + #define REG_GMAC_SAT3 (*(__IO uint32_t*)0x4003409CU) /**< \brief (GMAC) Specific Address 3 Top [47:32] Register */ + #define REG_GMAC_SAB4 (*(__IO uint32_t*)0x400340A0U) /**< \brief (GMAC) Specific Address 4 Bottom [31:0] Register */ + #define REG_GMAC_SAT4 (*(__IO uint32_t*)0x400340A4U) /**< \brief (GMAC) Specific Address 4 Top [47:32] Register */ + #define REG_GMAC_TIDM (*(__IO uint32_t*)0x400340A8U) /**< \brief (GMAC) Type ID Match 1 Register */ + #define REG_GMAC_IPGS (*(__IO uint32_t*)0x400340BCU) /**< \brief (GMAC) IPG Stretch Register */ + #define REG_GMAC_SVLAN (*(__IO uint32_t*)0x400340C0U) /**< \brief (GMAC) Stacked VLAN Register */ + #define REG_GMAC_TPFCP (*(__IO uint32_t*)0x400340C4U) /**< \brief (GMAC) Transmit PFC Pause Register */ + #define REG_GMAC_SAMB1 (*(__IO uint32_t*)0x400340C8U) /**< \brief (GMAC) Specific Address 1 Mask Bottom [31:0] Register */ + #define REG_GMAC_SAMT1 (*(__IO uint32_t*)0x400340CCU) /**< \brief (GMAC) Specific Address 1 Mask Top [47:32] Register */ + #define REG_GMAC_OTLO (*(__I uint32_t*)0x40034100U) /**< \brief (GMAC) Octets Transmitted [31:0] Register */ + #define REG_GMAC_OTHI (*(__I uint32_t*)0x40034104U) /**< \brief (GMAC) Octets Transmitted [47:32] Register */ + #define REG_GMAC_FT (*(__I uint32_t*)0x40034108U) /**< \brief (GMAC) Frames Transmitted Register */ + #define REG_GMAC_BCFT (*(__I uint32_t*)0x4003410CU) /**< \brief (GMAC) Broadcast Frames Transmitted Register */ + #define REG_GMAC_MFT (*(__I uint32_t*)0x40034110U) /**< \brief (GMAC) Multicast Frames Transmitted Register */ + #define REG_GMAC_PFT (*(__I uint32_t*)0x40034114U) /**< \brief (GMAC) Pause Frames Transmitted Register */ + #define REG_GMAC_BFT64 (*(__I uint32_t*)0x40034118U) /**< \brief (GMAC) 64 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT127 (*(__I uint32_t*)0x4003411CU) /**< \brief (GMAC) 65 to 127 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT255 (*(__I uint32_t*)0x40034120U) /**< \brief (GMAC) 128 to 255 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT511 (*(__I uint32_t*)0x40034124U) /**< \brief (GMAC) 256 to 511 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT1023 (*(__I uint32_t*)0x40034128U) /**< \brief (GMAC) 512 to 1023 Byte Frames Transmitted Register */ + #define REG_GMAC_TBFT1518 (*(__I uint32_t*)0x4003412CU) /**< \brief (GMAC) 1024 to 1518 Byte Frames Transmitted Register */ + #define REG_GMAC_GTBFT1518 (*(__I uint32_t*)0x40034130U) /**< \brief (GMAC) Greater Than 1518 Byte Frames Transmitted Register */ + #define REG_GMAC_TUR (*(__I uint32_t*)0x40034134U) /**< \brief (GMAC) Transmit Underruns Register */ + #define REG_GMAC_SCF (*(__I uint32_t*)0x40034138U) /**< \brief (GMAC) Single Collision Frames Register */ + #define REG_GMAC_MCF (*(__I uint32_t*)0x4003413CU) /**< \brief (GMAC) Multiple Collision Frames Register */ + #define REG_GMAC_EC (*(__I uint32_t*)0x40034140U) /**< \brief (GMAC) Excessive Collisions Register */ + #define REG_GMAC_LC (*(__I uint32_t*)0x40034144U) /**< \brief (GMAC) Late Collisions Register */ + #define REG_GMAC_DTF (*(__I uint32_t*)0x40034148U) /**< \brief (GMAC) Deferred Transmission Frames Register */ + #define REG_GMAC_CSE (*(__I uint32_t*)0x4003414CU) /**< \brief (GMAC) Carrier Sense Errors Register */ + #define REG_GMAC_ORLO (*(__I uint32_t*)0x40034150U) /**< \brief (GMAC) Octets Received [31:0] Received */ + #define REG_GMAC_ORHI (*(__I uint32_t*)0x40034154U) /**< \brief (GMAC) Octets Received [47:32] Received */ + #define REG_GMAC_FR (*(__I uint32_t*)0x40034158U) /**< \brief (GMAC) Frames Received Register */ + #define REG_GMAC_BCFR (*(__I uint32_t*)0x4003415CU) /**< \brief (GMAC) Broadcast Frames Received Register */ + #define REG_GMAC_MFR (*(__I uint32_t*)0x40034160U) /**< \brief (GMAC) Multicast Frames Received Register */ + #define REG_GMAC_PFR (*(__I uint32_t*)0x40034164U) /**< \brief (GMAC) Pause Frames Received Register */ + #define REG_GMAC_BFR64 (*(__I uint32_t*)0x40034168U) /**< \brief (GMAC) 64 Byte Frames Received Register */ + #define REG_GMAC_TBFR127 (*(__I uint32_t*)0x4003416CU) /**< \brief (GMAC) 65 to 127 Byte Frames Received Register */ + #define REG_GMAC_TBFR255 (*(__I uint32_t*)0x40034170U) /**< \brief (GMAC) 128 to 255 Byte Frames Received Register */ + #define REG_GMAC_TBFR511 (*(__I uint32_t*)0x40034174U) /**< \brief (GMAC) 256 to 511Byte Frames Received Register */ + #define REG_GMAC_TBFR1023 (*(__I uint32_t*)0x40034178U) /**< \brief (GMAC) 512 to 1023 Byte Frames Received Register */ + #define REG_GMAC_TBFR1518 (*(__I uint32_t*)0x4003417CU) /**< \brief (GMAC) 1024 to 1518 Byte Frames Received Register */ + #define REG_GMAC_TMXBFR (*(__I uint32_t*)0x40034180U) /**< \brief (GMAC) 1519 to Maximum Byte Frames Received Register */ + #define REG_GMAC_UFR (*(__I uint32_t*)0x40034184U) /**< \brief (GMAC) Undersize Frames Received Register */ + #define REG_GMAC_OFR (*(__I uint32_t*)0x40034188U) /**< \brief (GMAC) Oversize Frames Received Register */ + #define REG_GMAC_JR (*(__I uint32_t*)0x4003418CU) /**< \brief (GMAC) Jabbers Received Register */ + #define REG_GMAC_FCSE (*(__I uint32_t*)0x40034190U) /**< \brief (GMAC) Frame Check Sequence Errors Register */ + #define REG_GMAC_LFFE (*(__I uint32_t*)0x40034194U) /**< \brief (GMAC) Length Field Frame Errors Register */ + #define REG_GMAC_RSE (*(__I uint32_t*)0x40034198U) /**< \brief (GMAC) Receive Symbol Errors Register */ + #define REG_GMAC_AE (*(__I uint32_t*)0x4003419CU) /**< \brief (GMAC) Alignment Errors Register */ + #define REG_GMAC_RRE (*(__I uint32_t*)0x400341A0U) /**< \brief (GMAC) Receive Resource Errors Register */ + #define REG_GMAC_ROE (*(__I uint32_t*)0x400341A4U) /**< \brief (GMAC) Receive Overrun Register */ + #define REG_GMAC_IHCE (*(__I uint32_t*)0x400341A8U) /**< \brief (GMAC) IP Header Checksum Errors Register */ + #define REG_GMAC_TCE (*(__I uint32_t*)0x400341ACU) /**< \brief (GMAC) TCP Checksum Errors Register */ + #define REG_GMAC_UCE (*(__I uint32_t*)0x400341B0U) /**< \brief (GMAC) UDP Checksum Errors Register */ + #define REG_GMAC_TSSSL (*(__IO uint32_t*)0x400341C8U) /**< \brief (GMAC) 1588 Timer Sync Strobe Seconds [31:0] Register */ + #define REG_GMAC_TSSN (*(__IO uint32_t*)0x400341CCU) /**< \brief (GMAC) 1588 Timer Sync Strobe Nanoseconds Register */ + #define REG_GMAC_TSL (*(__IO uint32_t*)0x400341D0U) /**< \brief (GMAC) 1588 Timer Seconds [31:0] Register */ + #define REG_GMAC_TN (*(__IO uint32_t*)0x400341D4U) /**< \brief (GMAC) 1588 Timer Nanoseconds Register */ + #define REG_GMAC_TA (*(__O uint32_t*)0x400341D8U) /**< \brief (GMAC) 1588 Timer Adjust Register */ + #define REG_GMAC_TI (*(__IO uint32_t*)0x400341DCU) /**< \brief (GMAC) 1588 Timer Increment Register */ + #define REG_GMAC_EFTS (*(__I uint32_t*)0x400341E0U) /**< \brief (GMAC) PTP Event Frame Transmitted Seconds */ + #define REG_GMAC_EFTN (*(__I uint32_t*)0x400341E4U) /**< \brief (GMAC) PTP Event Frame Transmitted Nanoseconds */ + #define REG_GMAC_EFRS (*(__I uint32_t*)0x400341E8U) /**< \brief (GMAC) PTP Event Frame Received Seconds */ + #define REG_GMAC_EFRN (*(__I uint32_t*)0x400341ECU) /**< \brief (GMAC) PTP Event Frame Received Nanoseconds */ + #define REG_GMAC_PEFTS (*(__I uint32_t*)0x400341F0U) /**< \brief (GMAC) PTP Peer Event Frame Transmitted Seconds */ + #define REG_GMAC_PEFTN (*(__I uint32_t*)0x400341F4U) /**< \brief (GMAC) PTP Peer Event Frame Transmitted Nanoseconds */ + #define REG_GMAC_PEFRS (*(__I uint32_t*)0x400341F8U) /**< \brief (GMAC) PTP Peer Event Frame Received Seconds */ + #define REG_GMAC_PEFRN (*(__I uint32_t*)0x400341FCU) /**< \brief (GMAC) PTP Peer Event Frame Received Nanoseconds */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_GMAC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gpbr.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gpbr.h new file mode 100644 index 0000000..e8b41df --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/gpbr.h @@ -0,0 +1,55 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_GPBR_INSTANCE_ +#define _SAM4E_GPBR_INSTANCE_ + +/* ========== Register definition for GPBR peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_GPBR_GPBR (0x400E1890U) /**< \brief (GPBR) General Purpose Backup Register */ +#else + #define REG_GPBR_GPBR (*(__IO uint32_t*)0x400E1890U) /**< \brief (GPBR) General Purpose Backup Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_GPBR_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/hsmci.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/hsmci.h new file mode 100644 index 0000000..a87e336 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/hsmci.h @@ -0,0 +1,111 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_HSMCI_INSTANCE_ +#define _SAM4E_HSMCI_INSTANCE_ + +/* ========== Register definition for HSMCI peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_HSMCI_CR (0x40080000U) /**< \brief (HSMCI) Control Register */ + #define REG_HSMCI_MR (0x40080004U) /**< \brief (HSMCI) Mode Register */ + #define REG_HSMCI_DTOR (0x40080008U) /**< \brief (HSMCI) Data Timeout Register */ + #define REG_HSMCI_SDCR (0x4008000CU) /**< \brief (HSMCI) SD/SDIO Card Register */ + #define REG_HSMCI_ARGR (0x40080010U) /**< \brief (HSMCI) Argument Register */ + #define REG_HSMCI_CMDR (0x40080014U) /**< \brief (HSMCI) Command Register */ + #define REG_HSMCI_BLKR (0x40080018U) /**< \brief (HSMCI) Block Register */ + #define REG_HSMCI_CSTOR (0x4008001CU) /**< \brief (HSMCI) Completion Signal Timeout Register */ + #define REG_HSMCI_RSPR (0x40080020U) /**< \brief (HSMCI) Response Register */ + #define REG_HSMCI_RDR (0x40080030U) /**< \brief (HSMCI) Receive Data Register */ + #define REG_HSMCI_TDR (0x40080034U) /**< \brief (HSMCI) Transmit Data Register */ + #define REG_HSMCI_SR (0x40080040U) /**< \brief (HSMCI) Status Register */ + #define REG_HSMCI_IER (0x40080044U) /**< \brief (HSMCI) Interrupt Enable Register */ + #define REG_HSMCI_IDR (0x40080048U) /**< \brief (HSMCI) Interrupt Disable Register */ + #define REG_HSMCI_IMR (0x4008004CU) /**< \brief (HSMCI) Interrupt Mask Register */ + #define REG_HSMCI_CFG (0x40080054U) /**< \brief (HSMCI) Configuration Register */ + #define REG_HSMCI_WPMR (0x400800E4U) /**< \brief (HSMCI) Write Protection Mode Register */ + #define REG_HSMCI_WPSR (0x400800E8U) /**< \brief (HSMCI) Write Protection Status Register */ + #define REG_HSMCI_RPR (0x40080100U) /**< \brief (HSMCI) Receive Pointer Register */ + #define REG_HSMCI_RCR (0x40080104U) /**< \brief (HSMCI) Receive Counter Register */ + #define REG_HSMCI_TPR (0x40080108U) /**< \brief (HSMCI) Transmit Pointer Register */ + #define REG_HSMCI_TCR (0x4008010CU) /**< \brief (HSMCI) Transmit Counter Register */ + #define REG_HSMCI_RNPR (0x40080110U) /**< \brief (HSMCI) Receive Next Pointer Register */ + #define REG_HSMCI_RNCR (0x40080114U) /**< \brief (HSMCI) Receive Next Counter Register */ + #define REG_HSMCI_TNPR (0x40080118U) /**< \brief (HSMCI) Transmit Next Pointer Register */ + #define REG_HSMCI_TNCR (0x4008011CU) /**< \brief (HSMCI) Transmit Next Counter Register */ + #define REG_HSMCI_PTCR (0x40080120U) /**< \brief (HSMCI) Transfer Control Register */ + #define REG_HSMCI_PTSR (0x40080124U) /**< \brief (HSMCI) Transfer Status Register */ + #define REG_HSMCI_FIFO (0x40080200U) /**< \brief (HSMCI) FIFO Memory Aperture0 */ +#else + #define REG_HSMCI_CR (*(__O uint32_t*)0x40080000U) /**< \brief (HSMCI) Control Register */ + #define REG_HSMCI_MR (*(__IO uint32_t*)0x40080004U) /**< \brief (HSMCI) Mode Register */ + #define REG_HSMCI_DTOR (*(__IO uint32_t*)0x40080008U) /**< \brief (HSMCI) Data Timeout Register */ + #define REG_HSMCI_SDCR (*(__IO uint32_t*)0x4008000CU) /**< \brief (HSMCI) SD/SDIO Card Register */ + #define REG_HSMCI_ARGR (*(__IO uint32_t*)0x40080010U) /**< \brief (HSMCI) Argument Register */ + #define REG_HSMCI_CMDR (*(__O uint32_t*)0x40080014U) /**< \brief (HSMCI) Command Register */ + #define REG_HSMCI_BLKR (*(__IO uint32_t*)0x40080018U) /**< \brief (HSMCI) Block Register */ + #define REG_HSMCI_CSTOR (*(__IO uint32_t*)0x4008001CU) /**< \brief (HSMCI) Completion Signal Timeout Register */ + #define REG_HSMCI_RSPR (*(__I uint32_t*)0x40080020U) /**< \brief (HSMCI) Response Register */ + #define REG_HSMCI_RDR (*(__I uint32_t*)0x40080030U) /**< \brief (HSMCI) Receive Data Register */ + #define REG_HSMCI_TDR (*(__O uint32_t*)0x40080034U) /**< \brief (HSMCI) Transmit Data Register */ + #define REG_HSMCI_SR (*(__I uint32_t*)0x40080040U) /**< \brief (HSMCI) Status Register */ + #define REG_HSMCI_IER (*(__O uint32_t*)0x40080044U) /**< \brief (HSMCI) Interrupt Enable Register */ + #define REG_HSMCI_IDR (*(__O uint32_t*)0x40080048U) /**< \brief (HSMCI) Interrupt Disable Register */ + #define REG_HSMCI_IMR (*(__I uint32_t*)0x4008004CU) /**< \brief (HSMCI) Interrupt Mask Register */ + #define REG_HSMCI_CFG (*(__IO uint32_t*)0x40080054U) /**< \brief (HSMCI) Configuration Register */ + #define REG_HSMCI_WPMR (*(__IO uint32_t*)0x400800E4U) /**< \brief (HSMCI) Write Protection Mode Register */ + #define REG_HSMCI_WPSR (*(__I uint32_t*)0x400800E8U) /**< \brief (HSMCI) Write Protection Status Register */ + #define REG_HSMCI_RPR (*(__IO uint32_t*)0x40080100U) /**< \brief (HSMCI) Receive Pointer Register */ + #define REG_HSMCI_RCR (*(__IO uint32_t*)0x40080104U) /**< \brief (HSMCI) Receive Counter Register */ + #define REG_HSMCI_TPR (*(__IO uint32_t*)0x40080108U) /**< \brief (HSMCI) Transmit Pointer Register */ + #define REG_HSMCI_TCR (*(__IO uint32_t*)0x4008010CU) /**< \brief (HSMCI) Transmit Counter Register */ + #define REG_HSMCI_RNPR (*(__IO uint32_t*)0x40080110U) /**< \brief (HSMCI) Receive Next Pointer Register */ + #define REG_HSMCI_RNCR (*(__IO uint32_t*)0x40080114U) /**< \brief (HSMCI) Receive Next Counter Register */ + #define REG_HSMCI_TNPR (*(__IO uint32_t*)0x40080118U) /**< \brief (HSMCI) Transmit Next Pointer Register */ + #define REG_HSMCI_TNCR (*(__IO uint32_t*)0x4008011CU) /**< \brief (HSMCI) Transmit Next Counter Register */ + #define REG_HSMCI_PTCR (*(__O uint32_t*)0x40080120U) /**< \brief (HSMCI) Transfer Control Register */ + #define REG_HSMCI_PTSR (*(__I uint32_t*)0x40080124U) /**< \brief (HSMCI) Transfer Status Register */ + #define REG_HSMCI_FIFO (*(__IO uint32_t*)0x40080200U) /**< \brief (HSMCI) FIFO Memory Aperture0 */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_HSMCI_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/matrix.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/matrix.h new file mode 100644 index 0000000..3f74ec5 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/matrix.h @@ -0,0 +1,79 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_MATRIX_INSTANCE_ +#define _SAM4E_MATRIX_INSTANCE_ + +/* ========== Register definition for MATRIX peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_MATRIX_MCFG (0x400E0200U) /**< \brief (MATRIX) Master Configuration Register */ + #define REG_MATRIX_SCFG (0x400E0240U) /**< \brief (MATRIX) Slave Configuration Register */ + #define REG_MATRIX_PRAS0 (0x400E0280U) /**< \brief (MATRIX) Priority Register A for Slave 0 */ + #define REG_MATRIX_PRAS1 (0x400E0288U) /**< \brief (MATRIX) Priority Register A for Slave 1 */ + #define REG_MATRIX_PRAS2 (0x400E0290U) /**< \brief (MATRIX) Priority Register A for Slave 2 */ + #define REG_MATRIX_PRAS3 (0x400E0298U) /**< \brief (MATRIX) Priority Register A for Slave 3 */ + #define REG_MATRIX_PRAS4 (0x400E02A0U) /**< \brief (MATRIX) Priority Register A for Slave 4 */ + #define REG_MATRIX_PRAS5 (0x400E02A8U) /**< \brief (MATRIX) Priority Register A for Slave 5 */ + #define REG_MATRIX_MRCR (0x400E0300U) /**< \brief (MATRIX) Master Remap Control Register */ + #define REG_CCFG_SYSIO (0x400E0314U) /**< \brief (MATRIX) System I/O Configuration Register */ + #define REG_CCFG_SMCNFCS (0x400E0324U) /**< \brief (MATRIX) SMC NAND Flash Chip Select Configuration Register */ + #define REG_MATRIX_WPMR (0x400E03E4U) /**< \brief (MATRIX) Write Protect Mode Register */ + #define REG_MATRIX_WPSR (0x400E03E8U) /**< \brief (MATRIX) Write Protect Status Register */ +#else + #define REG_MATRIX_MCFG (*(__IO uint32_t*)0x400E0200U) /**< \brief (MATRIX) Master Configuration Register */ + #define REG_MATRIX_SCFG (*(__IO uint32_t*)0x400E0240U) /**< \brief (MATRIX) Slave Configuration Register */ + #define REG_MATRIX_PRAS0 (*(__IO uint32_t*)0x400E0280U) /**< \brief (MATRIX) Priority Register A for Slave 0 */ + #define REG_MATRIX_PRAS1 (*(__IO uint32_t*)0x400E0288U) /**< \brief (MATRIX) Priority Register A for Slave 1 */ + #define REG_MATRIX_PRAS2 (*(__IO uint32_t*)0x400E0290U) /**< \brief (MATRIX) Priority Register A for Slave 2 */ + #define REG_MATRIX_PRAS3 (*(__IO uint32_t*)0x400E0298U) /**< \brief (MATRIX) Priority Register A for Slave 3 */ + #define REG_MATRIX_PRAS4 (*(__IO uint32_t*)0x400E02A0U) /**< \brief (MATRIX) Priority Register A for Slave 4 */ + #define REG_MATRIX_PRAS5 (*(__IO uint32_t*)0x400E02A8U) /**< \brief (MATRIX) Priority Register A for Slave 5 */ + #define REG_MATRIX_MRCR (*(__IO uint32_t*)0x400E0300U) /**< \brief (MATRIX) Master Remap Control Register */ + #define REG_CCFG_SYSIO (*(__IO uint32_t*)0x400E0314U) /**< \brief (MATRIX) System I/O Configuration Register */ + #define REG_CCFG_SMCNFCS (*(__IO uint32_t*)0x400E0324U) /**< \brief (MATRIX) SMC NAND Flash Chip Select Configuration Register */ + #define REG_MATRIX_WPMR (*(__IO uint32_t*)0x400E03E4U) /**< \brief (MATRIX) Write Protect Mode Register */ + #define REG_MATRIX_WPSR (*(__I uint32_t*)0x400E03E8U) /**< \brief (MATRIX) Write Protect Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_MATRIX_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioa.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioa.h new file mode 100644 index 0000000..3dbf8fb --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioa.h @@ -0,0 +1,173 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIOA_INSTANCE_ +#define _SAM4E_PIOA_INSTANCE_ + +/* ========== Register definition for PIOA peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PIOA_PER (0x400E0E00U) /**< \brief (PIOA) PIO Enable Register */ + #define REG_PIOA_PDR (0x400E0E04U) /**< \brief (PIOA) PIO Disable Register */ + #define REG_PIOA_PSR (0x400E0E08U) /**< \brief (PIOA) PIO Status Register */ + #define REG_PIOA_OER (0x400E0E10U) /**< \brief (PIOA) Output Enable Register */ + #define REG_PIOA_ODR (0x400E0E14U) /**< \brief (PIOA) Output Disable Register */ + #define REG_PIOA_OSR (0x400E0E18U) /**< \brief (PIOA) Output Status Register */ + #define REG_PIOA_IFER (0x400E0E20U) /**< \brief (PIOA) Glitch Input Filter Enable Register */ + #define REG_PIOA_IFDR (0x400E0E24U) /**< \brief (PIOA) Glitch Input Filter Disable Register */ + #define REG_PIOA_IFSR (0x400E0E28U) /**< \brief (PIOA) Glitch Input Filter Status Register */ + #define REG_PIOA_SODR (0x400E0E30U) /**< \brief (PIOA) Set Output Data Register */ + #define REG_PIOA_CODR (0x400E0E34U) /**< \brief (PIOA) Clear Output Data Register */ + #define REG_PIOA_ODSR (0x400E0E38U) /**< \brief (PIOA) Output Data Status Register */ + #define REG_PIOA_PDSR (0x400E0E3CU) /**< \brief (PIOA) Pin Data Status Register */ + #define REG_PIOA_IER (0x400E0E40U) /**< \brief (PIOA) Interrupt Enable Register */ + #define REG_PIOA_IDR (0x400E0E44U) /**< \brief (PIOA) Interrupt Disable Register */ + #define REG_PIOA_IMR (0x400E0E48U) /**< \brief (PIOA) Interrupt Mask Register */ + #define REG_PIOA_ISR (0x400E0E4CU) /**< \brief (PIOA) Interrupt Status Register */ + #define REG_PIOA_MDER (0x400E0E50U) /**< \brief (PIOA) Multi-driver Enable Register */ + #define REG_PIOA_MDDR (0x400E0E54U) /**< \brief (PIOA) Multi-driver Disable Register */ + #define REG_PIOA_MDSR (0x400E0E58U) /**< \brief (PIOA) Multi-driver Status Register */ + #define REG_PIOA_PUDR (0x400E0E60U) /**< \brief (PIOA) Pull-up Disable Register */ + #define REG_PIOA_PUER (0x400E0E64U) /**< \brief (PIOA) Pull-up Enable Register */ + #define REG_PIOA_PUSR (0x400E0E68U) /**< \brief (PIOA) Pad Pull-up Status Register */ + #define REG_PIOA_ABCDSR (0x400E0E70U) /**< \brief (PIOA) Peripheral Select Register */ + #define REG_PIOA_IFSCDR (0x400E0E80U) /**< \brief (PIOA) Input Filter Slow Clock Disable Register */ + #define REG_PIOA_IFSCER (0x400E0E84U) /**< \brief (PIOA) Input Filter Slow Clock Enable Register */ + #define REG_PIOA_IFSCSR (0x400E0E88U) /**< \brief (PIOA) Input Filter Slow Clock Status Register */ + #define REG_PIOA_SCDR (0x400E0E8CU) /**< \brief (PIOA) Slow Clock Divider Debouncing Register */ + #define REG_PIOA_PPDDR (0x400E0E90U) /**< \brief (PIOA) Pad Pull-down Disable Register */ + #define REG_PIOA_PPDER (0x400E0E94U) /**< \brief (PIOA) Pad Pull-down Enable Register */ + #define REG_PIOA_PPDSR (0x400E0E98U) /**< \brief (PIOA) Pad Pull-down Status Register */ + #define REG_PIOA_OWER (0x400E0EA0U) /**< \brief (PIOA) Output Write Enable */ + #define REG_PIOA_OWDR (0x400E0EA4U) /**< \brief (PIOA) Output Write Disable */ + #define REG_PIOA_OWSR (0x400E0EA8U) /**< \brief (PIOA) Output Write Status Register */ + #define REG_PIOA_AIMER (0x400E0EB0U) /**< \brief (PIOA) Additional Interrupt Modes Enable Register */ + #define REG_PIOA_AIMDR (0x400E0EB4U) /**< \brief (PIOA) Additional Interrupt Modes Disable Register */ + #define REG_PIOA_AIMMR (0x400E0EB8U) /**< \brief (PIOA) Additional Interrupt Modes Mask Register */ + #define REG_PIOA_ESR (0x400E0EC0U) /**< \brief (PIOA) Edge Select Register */ + #define REG_PIOA_LSR (0x400E0EC4U) /**< \brief (PIOA) Level Select Register */ + #define REG_PIOA_ELSR (0x400E0EC8U) /**< \brief (PIOA) Edge/Level Status Register */ + #define REG_PIOA_FELLSR (0x400E0ED0U) /**< \brief (PIOA) Falling Edge/Low-Level Select Register */ + #define REG_PIOA_REHLSR (0x400E0ED4U) /**< \brief (PIOA) Rising Edge/High-Level Select Register */ + #define REG_PIOA_FRLHSR (0x400E0ED8U) /**< \brief (PIOA) Fall/Rise - Low/High Status Register */ + #define REG_PIOA_LOCKSR (0x400E0EE0U) /**< \brief (PIOA) Lock Status */ + #define REG_PIOA_WPMR (0x400E0EE4U) /**< \brief (PIOA) Write Protection Mode Register */ + #define REG_PIOA_WPSR (0x400E0EE8U) /**< \brief (PIOA) Write Protection Status Register */ + #define REG_PIOA_SCHMITT (0x400E0F00U) /**< \brief (PIOA) Schmitt Trigger Register */ + #define REG_PIOA_DELAYR (0x400E0F10U) /**< \brief (PIOA) I/O Delay Register */ + #define REG_PIOA_PCMR (0x400E0F50U) /**< \brief (PIOA) Parallel Capture Mode Register */ + #define REG_PIOA_PCIER (0x400E0F54U) /**< \brief (PIOA) Parallel Capture Interrupt Enable Register */ + #define REG_PIOA_PCIDR (0x400E0F58U) /**< \brief (PIOA) Parallel Capture Interrupt Disable Register */ + #define REG_PIOA_PCIMR (0x400E0F5CU) /**< \brief (PIOA) Parallel Capture Interrupt Mask Register */ + #define REG_PIOA_PCISR (0x400E0F60U) /**< \brief (PIOA) Parallel Capture Interrupt Status Register */ + #define REG_PIOA_PCRHR (0x400E0F64U) /**< \brief (PIOA) Parallel Capture Reception Holding Register */ + #define REG_PIOA_RPR (0x400E0F68U) /**< \brief (PIOA) Receive Pointer Register */ + #define REG_PIOA_RCR (0x400E0F6CU) /**< \brief (PIOA) Receive Counter Register */ + #define REG_PIOA_RNPR (0x400E0F78U) /**< \brief (PIOA) Receive Next Pointer Register */ + #define REG_PIOA_RNCR (0x400E0F7CU) /**< \brief (PIOA) Receive Next Counter Register */ + #define REG_PIOA_PTCR (0x400E0F88U) /**< \brief (PIOA) Transfer Control Register */ + #define REG_PIOA_PTSR (0x400E0F8CU) /**< \brief (PIOA) Transfer Status Register */ +#else + #define REG_PIOA_PER (*(__O uint32_t*)0x400E0E00U) /**< \brief (PIOA) PIO Enable Register */ + #define REG_PIOA_PDR (*(__O uint32_t*)0x400E0E04U) /**< \brief (PIOA) PIO Disable Register */ + #define REG_PIOA_PSR (*(__I uint32_t*)0x400E0E08U) /**< \brief (PIOA) PIO Status Register */ + #define REG_PIOA_OER (*(__O uint32_t*)0x400E0E10U) /**< \brief (PIOA) Output Enable Register */ + #define REG_PIOA_ODR (*(__O uint32_t*)0x400E0E14U) /**< \brief (PIOA) Output Disable Register */ + #define REG_PIOA_OSR (*(__I uint32_t*)0x400E0E18U) /**< \brief (PIOA) Output Status Register */ + #define REG_PIOA_IFER (*(__O uint32_t*)0x400E0E20U) /**< \brief (PIOA) Glitch Input Filter Enable Register */ + #define REG_PIOA_IFDR (*(__O uint32_t*)0x400E0E24U) /**< \brief (PIOA) Glitch Input Filter Disable Register */ + #define REG_PIOA_IFSR (*(__I uint32_t*)0x400E0E28U) /**< \brief (PIOA) Glitch Input Filter Status Register */ + #define REG_PIOA_SODR (*(__O uint32_t*)0x400E0E30U) /**< \brief (PIOA) Set Output Data Register */ + #define REG_PIOA_CODR (*(__O uint32_t*)0x400E0E34U) /**< \brief (PIOA) Clear Output Data Register */ + #define REG_PIOA_ODSR (*(__IO uint32_t*)0x400E0E38U) /**< \brief (PIOA) Output Data Status Register */ + #define REG_PIOA_PDSR (*(__I uint32_t*)0x400E0E3CU) /**< \brief (PIOA) Pin Data Status Register */ + #define REG_PIOA_IER (*(__O uint32_t*)0x400E0E40U) /**< \brief (PIOA) Interrupt Enable Register */ + #define REG_PIOA_IDR (*(__O uint32_t*)0x400E0E44U) /**< \brief (PIOA) Interrupt Disable Register */ + #define REG_PIOA_IMR (*(__I uint32_t*)0x400E0E48U) /**< \brief (PIOA) Interrupt Mask Register */ + #define REG_PIOA_ISR (*(__I uint32_t*)0x400E0E4CU) /**< \brief (PIOA) Interrupt Status Register */ + #define REG_PIOA_MDER (*(__O uint32_t*)0x400E0E50U) /**< \brief (PIOA) Multi-driver Enable Register */ + #define REG_PIOA_MDDR (*(__O uint32_t*)0x400E0E54U) /**< \brief (PIOA) Multi-driver Disable Register */ + #define REG_PIOA_MDSR (*(__I uint32_t*)0x400E0E58U) /**< \brief (PIOA) Multi-driver Status Register */ + #define REG_PIOA_PUDR (*(__O uint32_t*)0x400E0E60U) /**< \brief (PIOA) Pull-up Disable Register */ + #define REG_PIOA_PUER (*(__O uint32_t*)0x400E0E64U) /**< \brief (PIOA) Pull-up Enable Register */ + #define REG_PIOA_PUSR (*(__I uint32_t*)0x400E0E68U) /**< \brief (PIOA) Pad Pull-up Status Register */ + #define REG_PIOA_ABCDSR (*(__IO uint32_t*)0x400E0E70U) /**< \brief (PIOA) Peripheral Select Register */ + #define REG_PIOA_IFSCDR (*(__O uint32_t*)0x400E0E80U) /**< \brief (PIOA) Input Filter Slow Clock Disable Register */ + #define REG_PIOA_IFSCER (*(__O uint32_t*)0x400E0E84U) /**< \brief (PIOA) Input Filter Slow Clock Enable Register */ + #define REG_PIOA_IFSCSR (*(__I uint32_t*)0x400E0E88U) /**< \brief (PIOA) Input Filter Slow Clock Status Register */ + #define REG_PIOA_SCDR (*(__IO uint32_t*)0x400E0E8CU) /**< \brief (PIOA) Slow Clock Divider Debouncing Register */ + #define REG_PIOA_PPDDR (*(__O uint32_t*)0x400E0E90U) /**< \brief (PIOA) Pad Pull-down Disable Register */ + #define REG_PIOA_PPDER (*(__O uint32_t*)0x400E0E94U) /**< \brief (PIOA) Pad Pull-down Enable Register */ + #define REG_PIOA_PPDSR (*(__I uint32_t*)0x400E0E98U) /**< \brief (PIOA) Pad Pull-down Status Register */ + #define REG_PIOA_OWER (*(__O uint32_t*)0x400E0EA0U) /**< \brief (PIOA) Output Write Enable */ + #define REG_PIOA_OWDR (*(__O uint32_t*)0x400E0EA4U) /**< \brief (PIOA) Output Write Disable */ + #define REG_PIOA_OWSR (*(__I uint32_t*)0x400E0EA8U) /**< \brief (PIOA) Output Write Status Register */ + #define REG_PIOA_AIMER (*(__O uint32_t*)0x400E0EB0U) /**< \brief (PIOA) Additional Interrupt Modes Enable Register */ + #define REG_PIOA_AIMDR (*(__O uint32_t*)0x400E0EB4U) /**< \brief (PIOA) Additional Interrupt Modes Disable Register */ + #define REG_PIOA_AIMMR (*(__I uint32_t*)0x400E0EB8U) /**< \brief (PIOA) Additional Interrupt Modes Mask Register */ + #define REG_PIOA_ESR (*(__O uint32_t*)0x400E0EC0U) /**< \brief (PIOA) Edge Select Register */ + #define REG_PIOA_LSR (*(__O uint32_t*)0x400E0EC4U) /**< \brief (PIOA) Level Select Register */ + #define REG_PIOA_ELSR (*(__I uint32_t*)0x400E0EC8U) /**< \brief (PIOA) Edge/Level Status Register */ + #define REG_PIOA_FELLSR (*(__O uint32_t*)0x400E0ED0U) /**< \brief (PIOA) Falling Edge/Low-Level Select Register */ + #define REG_PIOA_REHLSR (*(__O uint32_t*)0x400E0ED4U) /**< \brief (PIOA) Rising Edge/High-Level Select Register */ + #define REG_PIOA_FRLHSR (*(__I uint32_t*)0x400E0ED8U) /**< \brief (PIOA) Fall/Rise - Low/High Status Register */ + #define REG_PIOA_LOCKSR (*(__I uint32_t*)0x400E0EE0U) /**< \brief (PIOA) Lock Status */ + #define REG_PIOA_WPMR (*(__IO uint32_t*)0x400E0EE4U) /**< \brief (PIOA) Write Protection Mode Register */ + #define REG_PIOA_WPSR (*(__I uint32_t*)0x400E0EE8U) /**< \brief (PIOA) Write Protection Status Register */ + #define REG_PIOA_SCHMITT (*(__IO uint32_t*)0x400E0F00U) /**< \brief (PIOA) Schmitt Trigger Register */ + #define REG_PIOA_DELAYR (*(__IO uint32_t*)0x400E0F10U) /**< \brief (PIOA) I/O Delay Register */ + #define REG_PIOA_PCMR (*(__IO uint32_t*)0x400E0F50U) /**< \brief (PIOA) Parallel Capture Mode Register */ + #define REG_PIOA_PCIER (*(__O uint32_t*)0x400E0F54U) /**< \brief (PIOA) Parallel Capture Interrupt Enable Register */ + #define REG_PIOA_PCIDR (*(__O uint32_t*)0x400E0F58U) /**< \brief (PIOA) Parallel Capture Interrupt Disable Register */ + #define REG_PIOA_PCIMR (*(__I uint32_t*)0x400E0F5CU) /**< \brief (PIOA) Parallel Capture Interrupt Mask Register */ + #define REG_PIOA_PCISR (*(__I uint32_t*)0x400E0F60U) /**< \brief (PIOA) Parallel Capture Interrupt Status Register */ + #define REG_PIOA_PCRHR (*(__I uint32_t*)0x400E0F64U) /**< \brief (PIOA) Parallel Capture Reception Holding Register */ + #define REG_PIOA_RPR (*(__IO uint32_t*)0x400E0F68U) /**< \brief (PIOA) Receive Pointer Register */ + #define REG_PIOA_RCR (*(__IO uint32_t*)0x400E0F6CU) /**< \brief (PIOA) Receive Counter Register */ + #define REG_PIOA_RNPR (*(__IO uint32_t*)0x400E0F78U) /**< \brief (PIOA) Receive Next Pointer Register */ + #define REG_PIOA_RNCR (*(__IO uint32_t*)0x400E0F7CU) /**< \brief (PIOA) Receive Next Counter Register */ + #define REG_PIOA_PTCR (*(__O uint32_t*)0x400E0F88U) /**< \brief (PIOA) Transfer Control Register */ + #define REG_PIOA_PTSR (*(__I uint32_t*)0x400E0F8CU) /**< \brief (PIOA) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PIOA_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piob.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piob.h new file mode 100644 index 0000000..8f0b755 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piob.h @@ -0,0 +1,161 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIOB_INSTANCE_ +#define _SAM4E_PIOB_INSTANCE_ + +/* ========== Register definition for PIOB peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PIOB_PER (0x400E1000U) /**< \brief (PIOB) PIO Enable Register */ + #define REG_PIOB_PDR (0x400E1004U) /**< \brief (PIOB) PIO Disable Register */ + #define REG_PIOB_PSR (0x400E1008U) /**< \brief (PIOB) PIO Status Register */ + #define REG_PIOB_OER (0x400E1010U) /**< \brief (PIOB) Output Enable Register */ + #define REG_PIOB_ODR (0x400E1014U) /**< \brief (PIOB) Output Disable Register */ + #define REG_PIOB_OSR (0x400E1018U) /**< \brief (PIOB) Output Status Register */ + #define REG_PIOB_IFER (0x400E1020U) /**< \brief (PIOB) Glitch Input Filter Enable Register */ + #define REG_PIOB_IFDR (0x400E1024U) /**< \brief (PIOB) Glitch Input Filter Disable Register */ + #define REG_PIOB_IFSR (0x400E1028U) /**< \brief (PIOB) Glitch Input Filter Status Register */ + #define REG_PIOB_SODR (0x400E1030U) /**< \brief (PIOB) Set Output Data Register */ + #define REG_PIOB_CODR (0x400E1034U) /**< \brief (PIOB) Clear Output Data Register */ + #define REG_PIOB_ODSR (0x400E1038U) /**< \brief (PIOB) Output Data Status Register */ + #define REG_PIOB_PDSR (0x400E103CU) /**< \brief (PIOB) Pin Data Status Register */ + #define REG_PIOB_IER (0x400E1040U) /**< \brief (PIOB) Interrupt Enable Register */ + #define REG_PIOB_IDR (0x400E1044U) /**< \brief (PIOB) Interrupt Disable Register */ + #define REG_PIOB_IMR (0x400E1048U) /**< \brief (PIOB) Interrupt Mask Register */ + #define REG_PIOB_ISR (0x400E104CU) /**< \brief (PIOB) Interrupt Status Register */ + #define REG_PIOB_MDER (0x400E1050U) /**< \brief (PIOB) Multi-driver Enable Register */ + #define REG_PIOB_MDDR (0x400E1054U) /**< \brief (PIOB) Multi-driver Disable Register */ + #define REG_PIOB_MDSR (0x400E1058U) /**< \brief (PIOB) Multi-driver Status Register */ + #define REG_PIOB_PUDR (0x400E1060U) /**< \brief (PIOB) Pull-up Disable Register */ + #define REG_PIOB_PUER (0x400E1064U) /**< \brief (PIOB) Pull-up Enable Register */ + #define REG_PIOB_PUSR (0x400E1068U) /**< \brief (PIOB) Pad Pull-up Status Register */ + #define REG_PIOB_ABCDSR (0x400E1070U) /**< \brief (PIOB) Peripheral Select Register */ + #define REG_PIOB_IFSCDR (0x400E1080U) /**< \brief (PIOB) Input Filter Slow Clock Disable Register */ + #define REG_PIOB_IFSCER (0x400E1084U) /**< \brief (PIOB) Input Filter Slow Clock Enable Register */ + #define REG_PIOB_IFSCSR (0x400E1088U) /**< \brief (PIOB) Input Filter Slow Clock Status Register */ + #define REG_PIOB_SCDR (0x400E108CU) /**< \brief (PIOB) Slow Clock Divider Debouncing Register */ + #define REG_PIOB_PPDDR (0x400E1090U) /**< \brief (PIOB) Pad Pull-down Disable Register */ + #define REG_PIOB_PPDER (0x400E1094U) /**< \brief (PIOB) Pad Pull-down Enable Register */ + #define REG_PIOB_PPDSR (0x400E1098U) /**< \brief (PIOB) Pad Pull-down Status Register */ + #define REG_PIOB_OWER (0x400E10A0U) /**< \brief (PIOB) Output Write Enable */ + #define REG_PIOB_OWDR (0x400E10A4U) /**< \brief (PIOB) Output Write Disable */ + #define REG_PIOB_OWSR (0x400E10A8U) /**< \brief (PIOB) Output Write Status Register */ + #define REG_PIOB_AIMER (0x400E10B0U) /**< \brief (PIOB) Additional Interrupt Modes Enable Register */ + #define REG_PIOB_AIMDR (0x400E10B4U) /**< \brief (PIOB) Additional Interrupt Modes Disable Register */ + #define REG_PIOB_AIMMR (0x400E10B8U) /**< \brief (PIOB) Additional Interrupt Modes Mask Register */ + #define REG_PIOB_ESR (0x400E10C0U) /**< \brief (PIOB) Edge Select Register */ + #define REG_PIOB_LSR (0x400E10C4U) /**< \brief (PIOB) Level Select Register */ + #define REG_PIOB_ELSR (0x400E10C8U) /**< \brief (PIOB) Edge/Level Status Register */ + #define REG_PIOB_FELLSR (0x400E10D0U) /**< \brief (PIOB) Falling Edge/Low-Level Select Register */ + #define REG_PIOB_REHLSR (0x400E10D4U) /**< \brief (PIOB) Rising Edge/High-Level Select Register */ + #define REG_PIOB_FRLHSR (0x400E10D8U) /**< \brief (PIOB) Fall/Rise - Low/High Status Register */ + #define REG_PIOB_LOCKSR (0x400E10E0U) /**< \brief (PIOB) Lock Status */ + #define REG_PIOB_WPMR (0x400E10E4U) /**< \brief (PIOB) Write Protection Mode Register */ + #define REG_PIOB_WPSR (0x400E10E8U) /**< \brief (PIOB) Write Protection Status Register */ + #define REG_PIOB_SCHMITT (0x400E1100U) /**< \brief (PIOB) Schmitt Trigger Register */ + #define REG_PIOB_DELAYR (0x400E1110U) /**< \brief (PIOB) I/O Delay Register */ + #define REG_PIOB_PCMR (0x400E1150U) /**< \brief (PIOB) Parallel Capture Mode Register */ + #define REG_PIOB_PCIER (0x400E1154U) /**< \brief (PIOB) Parallel Capture Interrupt Enable Register */ + #define REG_PIOB_PCIDR (0x400E1158U) /**< \brief (PIOB) Parallel Capture Interrupt Disable Register */ + #define REG_PIOB_PCIMR (0x400E115CU) /**< \brief (PIOB) Parallel Capture Interrupt Mask Register */ + #define REG_PIOB_PCISR (0x400E1160U) /**< \brief (PIOB) Parallel Capture Interrupt Status Register */ + #define REG_PIOB_PCRHR (0x400E1164U) /**< \brief (PIOB) Parallel Capture Reception Holding Register */ +#else + #define REG_PIOB_PER (*(__O uint32_t*)0x400E1000U) /**< \brief (PIOB) PIO Enable Register */ + #define REG_PIOB_PDR (*(__O uint32_t*)0x400E1004U) /**< \brief (PIOB) PIO Disable Register */ + #define REG_PIOB_PSR (*(__I uint32_t*)0x400E1008U) /**< \brief (PIOB) PIO Status Register */ + #define REG_PIOB_OER (*(__O uint32_t*)0x400E1010U) /**< \brief (PIOB) Output Enable Register */ + #define REG_PIOB_ODR (*(__O uint32_t*)0x400E1014U) /**< \brief (PIOB) Output Disable Register */ + #define REG_PIOB_OSR (*(__I uint32_t*)0x400E1018U) /**< \brief (PIOB) Output Status Register */ + #define REG_PIOB_IFER (*(__O uint32_t*)0x400E1020U) /**< \brief (PIOB) Glitch Input Filter Enable Register */ + #define REG_PIOB_IFDR (*(__O uint32_t*)0x400E1024U) /**< \brief (PIOB) Glitch Input Filter Disable Register */ + #define REG_PIOB_IFSR (*(__I uint32_t*)0x400E1028U) /**< \brief (PIOB) Glitch Input Filter Status Register */ + #define REG_PIOB_SODR (*(__O uint32_t*)0x400E1030U) /**< \brief (PIOB) Set Output Data Register */ + #define REG_PIOB_CODR (*(__O uint32_t*)0x400E1034U) /**< \brief (PIOB) Clear Output Data Register */ + #define REG_PIOB_ODSR (*(__IO uint32_t*)0x400E1038U) /**< \brief (PIOB) Output Data Status Register */ + #define REG_PIOB_PDSR (*(__I uint32_t*)0x400E103CU) /**< \brief (PIOB) Pin Data Status Register */ + #define REG_PIOB_IER (*(__O uint32_t*)0x400E1040U) /**< \brief (PIOB) Interrupt Enable Register */ + #define REG_PIOB_IDR (*(__O uint32_t*)0x400E1044U) /**< \brief (PIOB) Interrupt Disable Register */ + #define REG_PIOB_IMR (*(__I uint32_t*)0x400E1048U) /**< \brief (PIOB) Interrupt Mask Register */ + #define REG_PIOB_ISR (*(__I uint32_t*)0x400E104CU) /**< \brief (PIOB) Interrupt Status Register */ + #define REG_PIOB_MDER (*(__O uint32_t*)0x400E1050U) /**< \brief (PIOB) Multi-driver Enable Register */ + #define REG_PIOB_MDDR (*(__O uint32_t*)0x400E1054U) /**< \brief (PIOB) Multi-driver Disable Register */ + #define REG_PIOB_MDSR (*(__I uint32_t*)0x400E1058U) /**< \brief (PIOB) Multi-driver Status Register */ + #define REG_PIOB_PUDR (*(__O uint32_t*)0x400E1060U) /**< \brief (PIOB) Pull-up Disable Register */ + #define REG_PIOB_PUER (*(__O uint32_t*)0x400E1064U) /**< \brief (PIOB) Pull-up Enable Register */ + #define REG_PIOB_PUSR (*(__I uint32_t*)0x400E1068U) /**< \brief (PIOB) Pad Pull-up Status Register */ + #define REG_PIOB_ABCDSR (*(__IO uint32_t*)0x400E1070U) /**< \brief (PIOB) Peripheral Select Register */ + #define REG_PIOB_IFSCDR (*(__O uint32_t*)0x400E1080U) /**< \brief (PIOB) Input Filter Slow Clock Disable Register */ + #define REG_PIOB_IFSCER (*(__O uint32_t*)0x400E1084U) /**< \brief (PIOB) Input Filter Slow Clock Enable Register */ + #define REG_PIOB_IFSCSR (*(__I uint32_t*)0x400E1088U) /**< \brief (PIOB) Input Filter Slow Clock Status Register */ + #define REG_PIOB_SCDR (*(__IO uint32_t*)0x400E108CU) /**< \brief (PIOB) Slow Clock Divider Debouncing Register */ + #define REG_PIOB_PPDDR (*(__O uint32_t*)0x400E1090U) /**< \brief (PIOB) Pad Pull-down Disable Register */ + #define REG_PIOB_PPDER (*(__O uint32_t*)0x400E1094U) /**< \brief (PIOB) Pad Pull-down Enable Register */ + #define REG_PIOB_PPDSR (*(__I uint32_t*)0x400E1098U) /**< \brief (PIOB) Pad Pull-down Status Register */ + #define REG_PIOB_OWER (*(__O uint32_t*)0x400E10A0U) /**< \brief (PIOB) Output Write Enable */ + #define REG_PIOB_OWDR (*(__O uint32_t*)0x400E10A4U) /**< \brief (PIOB) Output Write Disable */ + #define REG_PIOB_OWSR (*(__I uint32_t*)0x400E10A8U) /**< \brief (PIOB) Output Write Status Register */ + #define REG_PIOB_AIMER (*(__O uint32_t*)0x400E10B0U) /**< \brief (PIOB) Additional Interrupt Modes Enable Register */ + #define REG_PIOB_AIMDR (*(__O uint32_t*)0x400E10B4U) /**< \brief (PIOB) Additional Interrupt Modes Disable Register */ + #define REG_PIOB_AIMMR (*(__I uint32_t*)0x400E10B8U) /**< \brief (PIOB) Additional Interrupt Modes Mask Register */ + #define REG_PIOB_ESR (*(__O uint32_t*)0x400E10C0U) /**< \brief (PIOB) Edge Select Register */ + #define REG_PIOB_LSR (*(__O uint32_t*)0x400E10C4U) /**< \brief (PIOB) Level Select Register */ + #define REG_PIOB_ELSR (*(__I uint32_t*)0x400E10C8U) /**< \brief (PIOB) Edge/Level Status Register */ + #define REG_PIOB_FELLSR (*(__O uint32_t*)0x400E10D0U) /**< \brief (PIOB) Falling Edge/Low-Level Select Register */ + #define REG_PIOB_REHLSR (*(__O uint32_t*)0x400E10D4U) /**< \brief (PIOB) Rising Edge/High-Level Select Register */ + #define REG_PIOB_FRLHSR (*(__I uint32_t*)0x400E10D8U) /**< \brief (PIOB) Fall/Rise - Low/High Status Register */ + #define REG_PIOB_LOCKSR (*(__I uint32_t*)0x400E10E0U) /**< \brief (PIOB) Lock Status */ + #define REG_PIOB_WPMR (*(__IO uint32_t*)0x400E10E4U) /**< \brief (PIOB) Write Protection Mode Register */ + #define REG_PIOB_WPSR (*(__I uint32_t*)0x400E10E8U) /**< \brief (PIOB) Write Protection Status Register */ + #define REG_PIOB_SCHMITT (*(__IO uint32_t*)0x400E1100U) /**< \brief (PIOB) Schmitt Trigger Register */ + #define REG_PIOB_DELAYR (*(__IO uint32_t*)0x400E1110U) /**< \brief (PIOB) I/O Delay Register */ + #define REG_PIOB_PCMR (*(__IO uint32_t*)0x400E1150U) /**< \brief (PIOB) Parallel Capture Mode Register */ + #define REG_PIOB_PCIER (*(__O uint32_t*)0x400E1154U) /**< \brief (PIOB) Parallel Capture Interrupt Enable Register */ + #define REG_PIOB_PCIDR (*(__O uint32_t*)0x400E1158U) /**< \brief (PIOB) Parallel Capture Interrupt Disable Register */ + #define REG_PIOB_PCIMR (*(__I uint32_t*)0x400E115CU) /**< \brief (PIOB) Parallel Capture Interrupt Mask Register */ + #define REG_PIOB_PCISR (*(__I uint32_t*)0x400E1160U) /**< \brief (PIOB) Parallel Capture Interrupt Status Register */ + #define REG_PIOB_PCRHR (*(__I uint32_t*)0x400E1164U) /**< \brief (PIOB) Parallel Capture Reception Holding Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PIOB_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioc.h new file mode 100644 index 0000000..468322e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioc.h @@ -0,0 +1,161 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIOC_INSTANCE_ +#define _SAM4E_PIOC_INSTANCE_ + +/* ========== Register definition for PIOC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PIOC_PER (0x400E1200U) /**< \brief (PIOC) PIO Enable Register */ + #define REG_PIOC_PDR (0x400E1204U) /**< \brief (PIOC) PIO Disable Register */ + #define REG_PIOC_PSR (0x400E1208U) /**< \brief (PIOC) PIO Status Register */ + #define REG_PIOC_OER (0x400E1210U) /**< \brief (PIOC) Output Enable Register */ + #define REG_PIOC_ODR (0x400E1214U) /**< \brief (PIOC) Output Disable Register */ + #define REG_PIOC_OSR (0x400E1218U) /**< \brief (PIOC) Output Status Register */ + #define REG_PIOC_IFER (0x400E1220U) /**< \brief (PIOC) Glitch Input Filter Enable Register */ + #define REG_PIOC_IFDR (0x400E1224U) /**< \brief (PIOC) Glitch Input Filter Disable Register */ + #define REG_PIOC_IFSR (0x400E1228U) /**< \brief (PIOC) Glitch Input Filter Status Register */ + #define REG_PIOC_SODR (0x400E1230U) /**< \brief (PIOC) Set Output Data Register */ + #define REG_PIOC_CODR (0x400E1234U) /**< \brief (PIOC) Clear Output Data Register */ + #define REG_PIOC_ODSR (0x400E1238U) /**< \brief (PIOC) Output Data Status Register */ + #define REG_PIOC_PDSR (0x400E123CU) /**< \brief (PIOC) Pin Data Status Register */ + #define REG_PIOC_IER (0x400E1240U) /**< \brief (PIOC) Interrupt Enable Register */ + #define REG_PIOC_IDR (0x400E1244U) /**< \brief (PIOC) Interrupt Disable Register */ + #define REG_PIOC_IMR (0x400E1248U) /**< \brief (PIOC) Interrupt Mask Register */ + #define REG_PIOC_ISR (0x400E124CU) /**< \brief (PIOC) Interrupt Status Register */ + #define REG_PIOC_MDER (0x400E1250U) /**< \brief (PIOC) Multi-driver Enable Register */ + #define REG_PIOC_MDDR (0x400E1254U) /**< \brief (PIOC) Multi-driver Disable Register */ + #define REG_PIOC_MDSR (0x400E1258U) /**< \brief (PIOC) Multi-driver Status Register */ + #define REG_PIOC_PUDR (0x400E1260U) /**< \brief (PIOC) Pull-up Disable Register */ + #define REG_PIOC_PUER (0x400E1264U) /**< \brief (PIOC) Pull-up Enable Register */ + #define REG_PIOC_PUSR (0x400E1268U) /**< \brief (PIOC) Pad Pull-up Status Register */ + #define REG_PIOC_ABCDSR (0x400E1270U) /**< \brief (PIOC) Peripheral Select Register */ + #define REG_PIOC_IFSCDR (0x400E1280U) /**< \brief (PIOC) Input Filter Slow Clock Disable Register */ + #define REG_PIOC_IFSCER (0x400E1284U) /**< \brief (PIOC) Input Filter Slow Clock Enable Register */ + #define REG_PIOC_IFSCSR (0x400E1288U) /**< \brief (PIOC) Input Filter Slow Clock Status Register */ + #define REG_PIOC_SCDR (0x400E128CU) /**< \brief (PIOC) Slow Clock Divider Debouncing Register */ + #define REG_PIOC_PPDDR (0x400E1290U) /**< \brief (PIOC) Pad Pull-down Disable Register */ + #define REG_PIOC_PPDER (0x400E1294U) /**< \brief (PIOC) Pad Pull-down Enable Register */ + #define REG_PIOC_PPDSR (0x400E1298U) /**< \brief (PIOC) Pad Pull-down Status Register */ + #define REG_PIOC_OWER (0x400E12A0U) /**< \brief (PIOC) Output Write Enable */ + #define REG_PIOC_OWDR (0x400E12A4U) /**< \brief (PIOC) Output Write Disable */ + #define REG_PIOC_OWSR (0x400E12A8U) /**< \brief (PIOC) Output Write Status Register */ + #define REG_PIOC_AIMER (0x400E12B0U) /**< \brief (PIOC) Additional Interrupt Modes Enable Register */ + #define REG_PIOC_AIMDR (0x400E12B4U) /**< \brief (PIOC) Additional Interrupt Modes Disable Register */ + #define REG_PIOC_AIMMR (0x400E12B8U) /**< \brief (PIOC) Additional Interrupt Modes Mask Register */ + #define REG_PIOC_ESR (0x400E12C0U) /**< \brief (PIOC) Edge Select Register */ + #define REG_PIOC_LSR (0x400E12C4U) /**< \brief (PIOC) Level Select Register */ + #define REG_PIOC_ELSR (0x400E12C8U) /**< \brief (PIOC) Edge/Level Status Register */ + #define REG_PIOC_FELLSR (0x400E12D0U) /**< \brief (PIOC) Falling Edge/Low-Level Select Register */ + #define REG_PIOC_REHLSR (0x400E12D4U) /**< \brief (PIOC) Rising Edge/High-Level Select Register */ + #define REG_PIOC_FRLHSR (0x400E12D8U) /**< \brief (PIOC) Fall/Rise - Low/High Status Register */ + #define REG_PIOC_LOCKSR (0x400E12E0U) /**< \brief (PIOC) Lock Status */ + #define REG_PIOC_WPMR (0x400E12E4U) /**< \brief (PIOC) Write Protection Mode Register */ + #define REG_PIOC_WPSR (0x400E12E8U) /**< \brief (PIOC) Write Protection Status Register */ + #define REG_PIOC_SCHMITT (0x400E1300U) /**< \brief (PIOC) Schmitt Trigger Register */ + #define REG_PIOC_DELAYR (0x400E1310U) /**< \brief (PIOC) I/O Delay Register */ + #define REG_PIOC_PCMR (0x400E1350U) /**< \brief (PIOC) Parallel Capture Mode Register */ + #define REG_PIOC_PCIER (0x400E1354U) /**< \brief (PIOC) Parallel Capture Interrupt Enable Register */ + #define REG_PIOC_PCIDR (0x400E1358U) /**< \brief (PIOC) Parallel Capture Interrupt Disable Register */ + #define REG_PIOC_PCIMR (0x400E135CU) /**< \brief (PIOC) Parallel Capture Interrupt Mask Register */ + #define REG_PIOC_PCISR (0x400E1360U) /**< \brief (PIOC) Parallel Capture Interrupt Status Register */ + #define REG_PIOC_PCRHR (0x400E1364U) /**< \brief (PIOC) Parallel Capture Reception Holding Register */ +#else + #define REG_PIOC_PER (*(__O uint32_t*)0x400E1200U) /**< \brief (PIOC) PIO Enable Register */ + #define REG_PIOC_PDR (*(__O uint32_t*)0x400E1204U) /**< \brief (PIOC) PIO Disable Register */ + #define REG_PIOC_PSR (*(__I uint32_t*)0x400E1208U) /**< \brief (PIOC) PIO Status Register */ + #define REG_PIOC_OER (*(__O uint32_t*)0x400E1210U) /**< \brief (PIOC) Output Enable Register */ + #define REG_PIOC_ODR (*(__O uint32_t*)0x400E1214U) /**< \brief (PIOC) Output Disable Register */ + #define REG_PIOC_OSR (*(__I uint32_t*)0x400E1218U) /**< \brief (PIOC) Output Status Register */ + #define REG_PIOC_IFER (*(__O uint32_t*)0x400E1220U) /**< \brief (PIOC) Glitch Input Filter Enable Register */ + #define REG_PIOC_IFDR (*(__O uint32_t*)0x400E1224U) /**< \brief (PIOC) Glitch Input Filter Disable Register */ + #define REG_PIOC_IFSR (*(__I uint32_t*)0x400E1228U) /**< \brief (PIOC) Glitch Input Filter Status Register */ + #define REG_PIOC_SODR (*(__O uint32_t*)0x400E1230U) /**< \brief (PIOC) Set Output Data Register */ + #define REG_PIOC_CODR (*(__O uint32_t*)0x400E1234U) /**< \brief (PIOC) Clear Output Data Register */ + #define REG_PIOC_ODSR (*(__IO uint32_t*)0x400E1238U) /**< \brief (PIOC) Output Data Status Register */ + #define REG_PIOC_PDSR (*(__I uint32_t*)0x400E123CU) /**< \brief (PIOC) Pin Data Status Register */ + #define REG_PIOC_IER (*(__O uint32_t*)0x400E1240U) /**< \brief (PIOC) Interrupt Enable Register */ + #define REG_PIOC_IDR (*(__O uint32_t*)0x400E1244U) /**< \brief (PIOC) Interrupt Disable Register */ + #define REG_PIOC_IMR (*(__I uint32_t*)0x400E1248U) /**< \brief (PIOC) Interrupt Mask Register */ + #define REG_PIOC_ISR (*(__I uint32_t*)0x400E124CU) /**< \brief (PIOC) Interrupt Status Register */ + #define REG_PIOC_MDER (*(__O uint32_t*)0x400E1250U) /**< \brief (PIOC) Multi-driver Enable Register */ + #define REG_PIOC_MDDR (*(__O uint32_t*)0x400E1254U) /**< \brief (PIOC) Multi-driver Disable Register */ + #define REG_PIOC_MDSR (*(__I uint32_t*)0x400E1258U) /**< \brief (PIOC) Multi-driver Status Register */ + #define REG_PIOC_PUDR (*(__O uint32_t*)0x400E1260U) /**< \brief (PIOC) Pull-up Disable Register */ + #define REG_PIOC_PUER (*(__O uint32_t*)0x400E1264U) /**< \brief (PIOC) Pull-up Enable Register */ + #define REG_PIOC_PUSR (*(__I uint32_t*)0x400E1268U) /**< \brief (PIOC) Pad Pull-up Status Register */ + #define REG_PIOC_ABCDSR (*(__IO uint32_t*)0x400E1270U) /**< \brief (PIOC) Peripheral Select Register */ + #define REG_PIOC_IFSCDR (*(__O uint32_t*)0x400E1280U) /**< \brief (PIOC) Input Filter Slow Clock Disable Register */ + #define REG_PIOC_IFSCER (*(__O uint32_t*)0x400E1284U) /**< \brief (PIOC) Input Filter Slow Clock Enable Register */ + #define REG_PIOC_IFSCSR (*(__I uint32_t*)0x400E1288U) /**< \brief (PIOC) Input Filter Slow Clock Status Register */ + #define REG_PIOC_SCDR (*(__IO uint32_t*)0x400E128CU) /**< \brief (PIOC) Slow Clock Divider Debouncing Register */ + #define REG_PIOC_PPDDR (*(__O uint32_t*)0x400E1290U) /**< \brief (PIOC) Pad Pull-down Disable Register */ + #define REG_PIOC_PPDER (*(__O uint32_t*)0x400E1294U) /**< \brief (PIOC) Pad Pull-down Enable Register */ + #define REG_PIOC_PPDSR (*(__I uint32_t*)0x400E1298U) /**< \brief (PIOC) Pad Pull-down Status Register */ + #define REG_PIOC_OWER (*(__O uint32_t*)0x400E12A0U) /**< \brief (PIOC) Output Write Enable */ + #define REG_PIOC_OWDR (*(__O uint32_t*)0x400E12A4U) /**< \brief (PIOC) Output Write Disable */ + #define REG_PIOC_OWSR (*(__I uint32_t*)0x400E12A8U) /**< \brief (PIOC) Output Write Status Register */ + #define REG_PIOC_AIMER (*(__O uint32_t*)0x400E12B0U) /**< \brief (PIOC) Additional Interrupt Modes Enable Register */ + #define REG_PIOC_AIMDR (*(__O uint32_t*)0x400E12B4U) /**< \brief (PIOC) Additional Interrupt Modes Disable Register */ + #define REG_PIOC_AIMMR (*(__I uint32_t*)0x400E12B8U) /**< \brief (PIOC) Additional Interrupt Modes Mask Register */ + #define REG_PIOC_ESR (*(__O uint32_t*)0x400E12C0U) /**< \brief (PIOC) Edge Select Register */ + #define REG_PIOC_LSR (*(__O uint32_t*)0x400E12C4U) /**< \brief (PIOC) Level Select Register */ + #define REG_PIOC_ELSR (*(__I uint32_t*)0x400E12C8U) /**< \brief (PIOC) Edge/Level Status Register */ + #define REG_PIOC_FELLSR (*(__O uint32_t*)0x400E12D0U) /**< \brief (PIOC) Falling Edge/Low-Level Select Register */ + #define REG_PIOC_REHLSR (*(__O uint32_t*)0x400E12D4U) /**< \brief (PIOC) Rising Edge/High-Level Select Register */ + #define REG_PIOC_FRLHSR (*(__I uint32_t*)0x400E12D8U) /**< \brief (PIOC) Fall/Rise - Low/High Status Register */ + #define REG_PIOC_LOCKSR (*(__I uint32_t*)0x400E12E0U) /**< \brief (PIOC) Lock Status */ + #define REG_PIOC_WPMR (*(__IO uint32_t*)0x400E12E4U) /**< \brief (PIOC) Write Protection Mode Register */ + #define REG_PIOC_WPSR (*(__I uint32_t*)0x400E12E8U) /**< \brief (PIOC) Write Protection Status Register */ + #define REG_PIOC_SCHMITT (*(__IO uint32_t*)0x400E1300U) /**< \brief (PIOC) Schmitt Trigger Register */ + #define REG_PIOC_DELAYR (*(__IO uint32_t*)0x400E1310U) /**< \brief (PIOC) I/O Delay Register */ + #define REG_PIOC_PCMR (*(__IO uint32_t*)0x400E1350U) /**< \brief (PIOC) Parallel Capture Mode Register */ + #define REG_PIOC_PCIER (*(__O uint32_t*)0x400E1354U) /**< \brief (PIOC) Parallel Capture Interrupt Enable Register */ + #define REG_PIOC_PCIDR (*(__O uint32_t*)0x400E1358U) /**< \brief (PIOC) Parallel Capture Interrupt Disable Register */ + #define REG_PIOC_PCIMR (*(__I uint32_t*)0x400E135CU) /**< \brief (PIOC) Parallel Capture Interrupt Mask Register */ + #define REG_PIOC_PCISR (*(__I uint32_t*)0x400E1360U) /**< \brief (PIOC) Parallel Capture Interrupt Status Register */ + #define REG_PIOC_PCRHR (*(__I uint32_t*)0x400E1364U) /**< \brief (PIOC) Parallel Capture Reception Holding Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PIOC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piod.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piod.h new file mode 100644 index 0000000..d29e4d9 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/piod.h @@ -0,0 +1,161 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIOD_INSTANCE_ +#define _SAM4E_PIOD_INSTANCE_ + +/* ========== Register definition for PIOD peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PIOD_PER (0x400E1400U) /**< \brief (PIOD) PIO Enable Register */ + #define REG_PIOD_PDR (0x400E1404U) /**< \brief (PIOD) PIO Disable Register */ + #define REG_PIOD_PSR (0x400E1408U) /**< \brief (PIOD) PIO Status Register */ + #define REG_PIOD_OER (0x400E1410U) /**< \brief (PIOD) Output Enable Register */ + #define REG_PIOD_ODR (0x400E1414U) /**< \brief (PIOD) Output Disable Register */ + #define REG_PIOD_OSR (0x400E1418U) /**< \brief (PIOD) Output Status Register */ + #define REG_PIOD_IFER (0x400E1420U) /**< \brief (PIOD) Glitch Input Filter Enable Register */ + #define REG_PIOD_IFDR (0x400E1424U) /**< \brief (PIOD) Glitch Input Filter Disable Register */ + #define REG_PIOD_IFSR (0x400E1428U) /**< \brief (PIOD) Glitch Input Filter Status Register */ + #define REG_PIOD_SODR (0x400E1430U) /**< \brief (PIOD) Set Output Data Register */ + #define REG_PIOD_CODR (0x400E1434U) /**< \brief (PIOD) Clear Output Data Register */ + #define REG_PIOD_ODSR (0x400E1438U) /**< \brief (PIOD) Output Data Status Register */ + #define REG_PIOD_PDSR (0x400E143CU) /**< \brief (PIOD) Pin Data Status Register */ + #define REG_PIOD_IER (0x400E1440U) /**< \brief (PIOD) Interrupt Enable Register */ + #define REG_PIOD_IDR (0x400E1444U) /**< \brief (PIOD) Interrupt Disable Register */ + #define REG_PIOD_IMR (0x400E1448U) /**< \brief (PIOD) Interrupt Mask Register */ + #define REG_PIOD_ISR (0x400E144CU) /**< \brief (PIOD) Interrupt Status Register */ + #define REG_PIOD_MDER (0x400E1450U) /**< \brief (PIOD) Multi-driver Enable Register */ + #define REG_PIOD_MDDR (0x400E1454U) /**< \brief (PIOD) Multi-driver Disable Register */ + #define REG_PIOD_MDSR (0x400E1458U) /**< \brief (PIOD) Multi-driver Status Register */ + #define REG_PIOD_PUDR (0x400E1460U) /**< \brief (PIOD) Pull-up Disable Register */ + #define REG_PIOD_PUER (0x400E1464U) /**< \brief (PIOD) Pull-up Enable Register */ + #define REG_PIOD_PUSR (0x400E1468U) /**< \brief (PIOD) Pad Pull-up Status Register */ + #define REG_PIOD_ABCDSR (0x400E1470U) /**< \brief (PIOD) Peripheral Select Register */ + #define REG_PIOD_IFSCDR (0x400E1480U) /**< \brief (PIOD) Input Filter Slow Clock Disable Register */ + #define REG_PIOD_IFSCER (0x400E1484U) /**< \brief (PIOD) Input Filter Slow Clock Enable Register */ + #define REG_PIOD_IFSCSR (0x400E1488U) /**< \brief (PIOD) Input Filter Slow Clock Status Register */ + #define REG_PIOD_SCDR (0x400E148CU) /**< \brief (PIOD) Slow Clock Divider Debouncing Register */ + #define REG_PIOD_PPDDR (0x400E1490U) /**< \brief (PIOD) Pad Pull-down Disable Register */ + #define REG_PIOD_PPDER (0x400E1494U) /**< \brief (PIOD) Pad Pull-down Enable Register */ + #define REG_PIOD_PPDSR (0x400E1498U) /**< \brief (PIOD) Pad Pull-down Status Register */ + #define REG_PIOD_OWER (0x400E14A0U) /**< \brief (PIOD) Output Write Enable */ + #define REG_PIOD_OWDR (0x400E14A4U) /**< \brief (PIOD) Output Write Disable */ + #define REG_PIOD_OWSR (0x400E14A8U) /**< \brief (PIOD) Output Write Status Register */ + #define REG_PIOD_AIMER (0x400E14B0U) /**< \brief (PIOD) Additional Interrupt Modes Enable Register */ + #define REG_PIOD_AIMDR (0x400E14B4U) /**< \brief (PIOD) Additional Interrupt Modes Disable Register */ + #define REG_PIOD_AIMMR (0x400E14B8U) /**< \brief (PIOD) Additional Interrupt Modes Mask Register */ + #define REG_PIOD_ESR (0x400E14C0U) /**< \brief (PIOD) Edge Select Register */ + #define REG_PIOD_LSR (0x400E14C4U) /**< \brief (PIOD) Level Select Register */ + #define REG_PIOD_ELSR (0x400E14C8U) /**< \brief (PIOD) Edge/Level Status Register */ + #define REG_PIOD_FELLSR (0x400E14D0U) /**< \brief (PIOD) Falling Edge/Low-Level Select Register */ + #define REG_PIOD_REHLSR (0x400E14D4U) /**< \brief (PIOD) Rising Edge/High-Level Select Register */ + #define REG_PIOD_FRLHSR (0x400E14D8U) /**< \brief (PIOD) Fall/Rise - Low/High Status Register */ + #define REG_PIOD_LOCKSR (0x400E14E0U) /**< \brief (PIOD) Lock Status */ + #define REG_PIOD_WPMR (0x400E14E4U) /**< \brief (PIOD) Write Protection Mode Register */ + #define REG_PIOD_WPSR (0x400E14E8U) /**< \brief (PIOD) Write Protection Status Register */ + #define REG_PIOD_SCHMITT (0x400E1500U) /**< \brief (PIOD) Schmitt Trigger Register */ + #define REG_PIOD_DELAYR (0x400E1510U) /**< \brief (PIOD) I/O Delay Register */ + #define REG_PIOD_PCMR (0x400E1550U) /**< \brief (PIOD) Parallel Capture Mode Register */ + #define REG_PIOD_PCIER (0x400E1554U) /**< \brief (PIOD) Parallel Capture Interrupt Enable Register */ + #define REG_PIOD_PCIDR (0x400E1558U) /**< \brief (PIOD) Parallel Capture Interrupt Disable Register */ + #define REG_PIOD_PCIMR (0x400E155CU) /**< \brief (PIOD) Parallel Capture Interrupt Mask Register */ + #define REG_PIOD_PCISR (0x400E1560U) /**< \brief (PIOD) Parallel Capture Interrupt Status Register */ + #define REG_PIOD_PCRHR (0x400E1564U) /**< \brief (PIOD) Parallel Capture Reception Holding Register */ +#else + #define REG_PIOD_PER (*(__O uint32_t*)0x400E1400U) /**< \brief (PIOD) PIO Enable Register */ + #define REG_PIOD_PDR (*(__O uint32_t*)0x400E1404U) /**< \brief (PIOD) PIO Disable Register */ + #define REG_PIOD_PSR (*(__I uint32_t*)0x400E1408U) /**< \brief (PIOD) PIO Status Register */ + #define REG_PIOD_OER (*(__O uint32_t*)0x400E1410U) /**< \brief (PIOD) Output Enable Register */ + #define REG_PIOD_ODR (*(__O uint32_t*)0x400E1414U) /**< \brief (PIOD) Output Disable Register */ + #define REG_PIOD_OSR (*(__I uint32_t*)0x400E1418U) /**< \brief (PIOD) Output Status Register */ + #define REG_PIOD_IFER (*(__O uint32_t*)0x400E1420U) /**< \brief (PIOD) Glitch Input Filter Enable Register */ + #define REG_PIOD_IFDR (*(__O uint32_t*)0x400E1424U) /**< \brief (PIOD) Glitch Input Filter Disable Register */ + #define REG_PIOD_IFSR (*(__I uint32_t*)0x400E1428U) /**< \brief (PIOD) Glitch Input Filter Status Register */ + #define REG_PIOD_SODR (*(__O uint32_t*)0x400E1430U) /**< \brief (PIOD) Set Output Data Register */ + #define REG_PIOD_CODR (*(__O uint32_t*)0x400E1434U) /**< \brief (PIOD) Clear Output Data Register */ + #define REG_PIOD_ODSR (*(__IO uint32_t*)0x400E1438U) /**< \brief (PIOD) Output Data Status Register */ + #define REG_PIOD_PDSR (*(__I uint32_t*)0x400E143CU) /**< \brief (PIOD) Pin Data Status Register */ + #define REG_PIOD_IER (*(__O uint32_t*)0x400E1440U) /**< \brief (PIOD) Interrupt Enable Register */ + #define REG_PIOD_IDR (*(__O uint32_t*)0x400E1444U) /**< \brief (PIOD) Interrupt Disable Register */ + #define REG_PIOD_IMR (*(__I uint32_t*)0x400E1448U) /**< \brief (PIOD) Interrupt Mask Register */ + #define REG_PIOD_ISR (*(__I uint32_t*)0x400E144CU) /**< \brief (PIOD) Interrupt Status Register */ + #define REG_PIOD_MDER (*(__O uint32_t*)0x400E1450U) /**< \brief (PIOD) Multi-driver Enable Register */ + #define REG_PIOD_MDDR (*(__O uint32_t*)0x400E1454U) /**< \brief (PIOD) Multi-driver Disable Register */ + #define REG_PIOD_MDSR (*(__I uint32_t*)0x400E1458U) /**< \brief (PIOD) Multi-driver Status Register */ + #define REG_PIOD_PUDR (*(__O uint32_t*)0x400E1460U) /**< \brief (PIOD) Pull-up Disable Register */ + #define REG_PIOD_PUER (*(__O uint32_t*)0x400E1464U) /**< \brief (PIOD) Pull-up Enable Register */ + #define REG_PIOD_PUSR (*(__I uint32_t*)0x400E1468U) /**< \brief (PIOD) Pad Pull-up Status Register */ + #define REG_PIOD_ABCDSR (*(__IO uint32_t*)0x400E1470U) /**< \brief (PIOD) Peripheral Select Register */ + #define REG_PIOD_IFSCDR (*(__O uint32_t*)0x400E1480U) /**< \brief (PIOD) Input Filter Slow Clock Disable Register */ + #define REG_PIOD_IFSCER (*(__O uint32_t*)0x400E1484U) /**< \brief (PIOD) Input Filter Slow Clock Enable Register */ + #define REG_PIOD_IFSCSR (*(__I uint32_t*)0x400E1488U) /**< \brief (PIOD) Input Filter Slow Clock Status Register */ + #define REG_PIOD_SCDR (*(__IO uint32_t*)0x400E148CU) /**< \brief (PIOD) Slow Clock Divider Debouncing Register */ + #define REG_PIOD_PPDDR (*(__O uint32_t*)0x400E1490U) /**< \brief (PIOD) Pad Pull-down Disable Register */ + #define REG_PIOD_PPDER (*(__O uint32_t*)0x400E1494U) /**< \brief (PIOD) Pad Pull-down Enable Register */ + #define REG_PIOD_PPDSR (*(__I uint32_t*)0x400E1498U) /**< \brief (PIOD) Pad Pull-down Status Register */ + #define REG_PIOD_OWER (*(__O uint32_t*)0x400E14A0U) /**< \brief (PIOD) Output Write Enable */ + #define REG_PIOD_OWDR (*(__O uint32_t*)0x400E14A4U) /**< \brief (PIOD) Output Write Disable */ + #define REG_PIOD_OWSR (*(__I uint32_t*)0x400E14A8U) /**< \brief (PIOD) Output Write Status Register */ + #define REG_PIOD_AIMER (*(__O uint32_t*)0x400E14B0U) /**< \brief (PIOD) Additional Interrupt Modes Enable Register */ + #define REG_PIOD_AIMDR (*(__O uint32_t*)0x400E14B4U) /**< \brief (PIOD) Additional Interrupt Modes Disable Register */ + #define REG_PIOD_AIMMR (*(__I uint32_t*)0x400E14B8U) /**< \brief (PIOD) Additional Interrupt Modes Mask Register */ + #define REG_PIOD_ESR (*(__O uint32_t*)0x400E14C0U) /**< \brief (PIOD) Edge Select Register */ + #define REG_PIOD_LSR (*(__O uint32_t*)0x400E14C4U) /**< \brief (PIOD) Level Select Register */ + #define REG_PIOD_ELSR (*(__I uint32_t*)0x400E14C8U) /**< \brief (PIOD) Edge/Level Status Register */ + #define REG_PIOD_FELLSR (*(__O uint32_t*)0x400E14D0U) /**< \brief (PIOD) Falling Edge/Low-Level Select Register */ + #define REG_PIOD_REHLSR (*(__O uint32_t*)0x400E14D4U) /**< \brief (PIOD) Rising Edge/High-Level Select Register */ + #define REG_PIOD_FRLHSR (*(__I uint32_t*)0x400E14D8U) /**< \brief (PIOD) Fall/Rise - Low/High Status Register */ + #define REG_PIOD_LOCKSR (*(__I uint32_t*)0x400E14E0U) /**< \brief (PIOD) Lock Status */ + #define REG_PIOD_WPMR (*(__IO uint32_t*)0x400E14E4U) /**< \brief (PIOD) Write Protection Mode Register */ + #define REG_PIOD_WPSR (*(__I uint32_t*)0x400E14E8U) /**< \brief (PIOD) Write Protection Status Register */ + #define REG_PIOD_SCHMITT (*(__IO uint32_t*)0x400E1500U) /**< \brief (PIOD) Schmitt Trigger Register */ + #define REG_PIOD_DELAYR (*(__IO uint32_t*)0x400E1510U) /**< \brief (PIOD) I/O Delay Register */ + #define REG_PIOD_PCMR (*(__IO uint32_t*)0x400E1550U) /**< \brief (PIOD) Parallel Capture Mode Register */ + #define REG_PIOD_PCIER (*(__O uint32_t*)0x400E1554U) /**< \brief (PIOD) Parallel Capture Interrupt Enable Register */ + #define REG_PIOD_PCIDR (*(__O uint32_t*)0x400E1558U) /**< \brief (PIOD) Parallel Capture Interrupt Disable Register */ + #define REG_PIOD_PCIMR (*(__I uint32_t*)0x400E155CU) /**< \brief (PIOD) Parallel Capture Interrupt Mask Register */ + #define REG_PIOD_PCISR (*(__I uint32_t*)0x400E1560U) /**< \brief (PIOD) Parallel Capture Interrupt Status Register */ + #define REG_PIOD_PCRHR (*(__I uint32_t*)0x400E1564U) /**< \brief (PIOD) Parallel Capture Reception Holding Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PIOD_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioe.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioe.h new file mode 100644 index 0000000..7ab1eec --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pioe.h @@ -0,0 +1,161 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PIOE_INSTANCE_ +#define _SAM4E_PIOE_INSTANCE_ + +/* ========== Register definition for PIOE peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PIOE_PER (0x400E1600U) /**< \brief (PIOE) PIO Enable Register */ + #define REG_PIOE_PDR (0x400E1604U) /**< \brief (PIOE) PIO Disable Register */ + #define REG_PIOE_PSR (0x400E1608U) /**< \brief (PIOE) PIO Status Register */ + #define REG_PIOE_OER (0x400E1610U) /**< \brief (PIOE) Output Enable Register */ + #define REG_PIOE_ODR (0x400E1614U) /**< \brief (PIOE) Output Disable Register */ + #define REG_PIOE_OSR (0x400E1618U) /**< \brief (PIOE) Output Status Register */ + #define REG_PIOE_IFER (0x400E1620U) /**< \brief (PIOE) Glitch Input Filter Enable Register */ + #define REG_PIOE_IFDR (0x400E1624U) /**< \brief (PIOE) Glitch Input Filter Disable Register */ + #define REG_PIOE_IFSR (0x400E1628U) /**< \brief (PIOE) Glitch Input Filter Status Register */ + #define REG_PIOE_SODR (0x400E1630U) /**< \brief (PIOE) Set Output Data Register */ + #define REG_PIOE_CODR (0x400E1634U) /**< \brief (PIOE) Clear Output Data Register */ + #define REG_PIOE_ODSR (0x400E1638U) /**< \brief (PIOE) Output Data Status Register */ + #define REG_PIOE_PDSR (0x400E163CU) /**< \brief (PIOE) Pin Data Status Register */ + #define REG_PIOE_IER (0x400E1640U) /**< \brief (PIOE) Interrupt Enable Register */ + #define REG_PIOE_IDR (0x400E1644U) /**< \brief (PIOE) Interrupt Disable Register */ + #define REG_PIOE_IMR (0x400E1648U) /**< \brief (PIOE) Interrupt Mask Register */ + #define REG_PIOE_ISR (0x400E164CU) /**< \brief (PIOE) Interrupt Status Register */ + #define REG_PIOE_MDER (0x400E1650U) /**< \brief (PIOE) Multi-driver Enable Register */ + #define REG_PIOE_MDDR (0x400E1654U) /**< \brief (PIOE) Multi-driver Disable Register */ + #define REG_PIOE_MDSR (0x400E1658U) /**< \brief (PIOE) Multi-driver Status Register */ + #define REG_PIOE_PUDR (0x400E1660U) /**< \brief (PIOE) Pull-up Disable Register */ + #define REG_PIOE_PUER (0x400E1664U) /**< \brief (PIOE) Pull-up Enable Register */ + #define REG_PIOE_PUSR (0x400E1668U) /**< \brief (PIOE) Pad Pull-up Status Register */ + #define REG_PIOE_ABCDSR (0x400E1670U) /**< \brief (PIOE) Peripheral Select Register */ + #define REG_PIOE_IFSCDR (0x400E1680U) /**< \brief (PIOE) Input Filter Slow Clock Disable Register */ + #define REG_PIOE_IFSCER (0x400E1684U) /**< \brief (PIOE) Input Filter Slow Clock Enable Register */ + #define REG_PIOE_IFSCSR (0x400E1688U) /**< \brief (PIOE) Input Filter Slow Clock Status Register */ + #define REG_PIOE_SCDR (0x400E168CU) /**< \brief (PIOE) Slow Clock Divider Debouncing Register */ + #define REG_PIOE_PPDDR (0x400E1690U) /**< \brief (PIOE) Pad Pull-down Disable Register */ + #define REG_PIOE_PPDER (0x400E1694U) /**< \brief (PIOE) Pad Pull-down Enable Register */ + #define REG_PIOE_PPDSR (0x400E1698U) /**< \brief (PIOE) Pad Pull-down Status Register */ + #define REG_PIOE_OWER (0x400E16A0U) /**< \brief (PIOE) Output Write Enable */ + #define REG_PIOE_OWDR (0x400E16A4U) /**< \brief (PIOE) Output Write Disable */ + #define REG_PIOE_OWSR (0x400E16A8U) /**< \brief (PIOE) Output Write Status Register */ + #define REG_PIOE_AIMER (0x400E16B0U) /**< \brief (PIOE) Additional Interrupt Modes Enable Register */ + #define REG_PIOE_AIMDR (0x400E16B4U) /**< \brief (PIOE) Additional Interrupt Modes Disable Register */ + #define REG_PIOE_AIMMR (0x400E16B8U) /**< \brief (PIOE) Additional Interrupt Modes Mask Register */ + #define REG_PIOE_ESR (0x400E16C0U) /**< \brief (PIOE) Edge Select Register */ + #define REG_PIOE_LSR (0x400E16C4U) /**< \brief (PIOE) Level Select Register */ + #define REG_PIOE_ELSR (0x400E16C8U) /**< \brief (PIOE) Edge/Level Status Register */ + #define REG_PIOE_FELLSR (0x400E16D0U) /**< \brief (PIOE) Falling Edge/Low-Level Select Register */ + #define REG_PIOE_REHLSR (0x400E16D4U) /**< \brief (PIOE) Rising Edge/High-Level Select Register */ + #define REG_PIOE_FRLHSR (0x400E16D8U) /**< \brief (PIOE) Fall/Rise - Low/High Status Register */ + #define REG_PIOE_LOCKSR (0x400E16E0U) /**< \brief (PIOE) Lock Status */ + #define REG_PIOE_WPMR (0x400E16E4U) /**< \brief (PIOE) Write Protection Mode Register */ + #define REG_PIOE_WPSR (0x400E16E8U) /**< \brief (PIOE) Write Protection Status Register */ + #define REG_PIOE_SCHMITT (0x400E1700U) /**< \brief (PIOE) Schmitt Trigger Register */ + #define REG_PIOE_DELAYR (0x400E1710U) /**< \brief (PIOE) I/O Delay Register */ + #define REG_PIOE_PCMR (0x400E1750U) /**< \brief (PIOE) Parallel Capture Mode Register */ + #define REG_PIOE_PCIER (0x400E1754U) /**< \brief (PIOE) Parallel Capture Interrupt Enable Register */ + #define REG_PIOE_PCIDR (0x400E1758U) /**< \brief (PIOE) Parallel Capture Interrupt Disable Register */ + #define REG_PIOE_PCIMR (0x400E175CU) /**< \brief (PIOE) Parallel Capture Interrupt Mask Register */ + #define REG_PIOE_PCISR (0x400E1760U) /**< \brief (PIOE) Parallel Capture Interrupt Status Register */ + #define REG_PIOE_PCRHR (0x400E1764U) /**< \brief (PIOE) Parallel Capture Reception Holding Register */ +#else + #define REG_PIOE_PER (*(__O uint32_t*)0x400E1600U) /**< \brief (PIOE) PIO Enable Register */ + #define REG_PIOE_PDR (*(__O uint32_t*)0x400E1604U) /**< \brief (PIOE) PIO Disable Register */ + #define REG_PIOE_PSR (*(__I uint32_t*)0x400E1608U) /**< \brief (PIOE) PIO Status Register */ + #define REG_PIOE_OER (*(__O uint32_t*)0x400E1610U) /**< \brief (PIOE) Output Enable Register */ + #define REG_PIOE_ODR (*(__O uint32_t*)0x400E1614U) /**< \brief (PIOE) Output Disable Register */ + #define REG_PIOE_OSR (*(__I uint32_t*)0x400E1618U) /**< \brief (PIOE) Output Status Register */ + #define REG_PIOE_IFER (*(__O uint32_t*)0x400E1620U) /**< \brief (PIOE) Glitch Input Filter Enable Register */ + #define REG_PIOE_IFDR (*(__O uint32_t*)0x400E1624U) /**< \brief (PIOE) Glitch Input Filter Disable Register */ + #define REG_PIOE_IFSR (*(__I uint32_t*)0x400E1628U) /**< \brief (PIOE) Glitch Input Filter Status Register */ + #define REG_PIOE_SODR (*(__O uint32_t*)0x400E1630U) /**< \brief (PIOE) Set Output Data Register */ + #define REG_PIOE_CODR (*(__O uint32_t*)0x400E1634U) /**< \brief (PIOE) Clear Output Data Register */ + #define REG_PIOE_ODSR (*(__IO uint32_t*)0x400E1638U) /**< \brief (PIOE) Output Data Status Register */ + #define REG_PIOE_PDSR (*(__I uint32_t*)0x400E163CU) /**< \brief (PIOE) Pin Data Status Register */ + #define REG_PIOE_IER (*(__O uint32_t*)0x400E1640U) /**< \brief (PIOE) Interrupt Enable Register */ + #define REG_PIOE_IDR (*(__O uint32_t*)0x400E1644U) /**< \brief (PIOE) Interrupt Disable Register */ + #define REG_PIOE_IMR (*(__I uint32_t*)0x400E1648U) /**< \brief (PIOE) Interrupt Mask Register */ + #define REG_PIOE_ISR (*(__I uint32_t*)0x400E164CU) /**< \brief (PIOE) Interrupt Status Register */ + #define REG_PIOE_MDER (*(__O uint32_t*)0x400E1650U) /**< \brief (PIOE) Multi-driver Enable Register */ + #define REG_PIOE_MDDR (*(__O uint32_t*)0x400E1654U) /**< \brief (PIOE) Multi-driver Disable Register */ + #define REG_PIOE_MDSR (*(__I uint32_t*)0x400E1658U) /**< \brief (PIOE) Multi-driver Status Register */ + #define REG_PIOE_PUDR (*(__O uint32_t*)0x400E1660U) /**< \brief (PIOE) Pull-up Disable Register */ + #define REG_PIOE_PUER (*(__O uint32_t*)0x400E1664U) /**< \brief (PIOE) Pull-up Enable Register */ + #define REG_PIOE_PUSR (*(__I uint32_t*)0x400E1668U) /**< \brief (PIOE) Pad Pull-up Status Register */ + #define REG_PIOE_ABCDSR (*(__IO uint32_t*)0x400E1670U) /**< \brief (PIOE) Peripheral Select Register */ + #define REG_PIOE_IFSCDR (*(__O uint32_t*)0x400E1680U) /**< \brief (PIOE) Input Filter Slow Clock Disable Register */ + #define REG_PIOE_IFSCER (*(__O uint32_t*)0x400E1684U) /**< \brief (PIOE) Input Filter Slow Clock Enable Register */ + #define REG_PIOE_IFSCSR (*(__I uint32_t*)0x400E1688U) /**< \brief (PIOE) Input Filter Slow Clock Status Register */ + #define REG_PIOE_SCDR (*(__IO uint32_t*)0x400E168CU) /**< \brief (PIOE) Slow Clock Divider Debouncing Register */ + #define REG_PIOE_PPDDR (*(__O uint32_t*)0x400E1690U) /**< \brief (PIOE) Pad Pull-down Disable Register */ + #define REG_PIOE_PPDER (*(__O uint32_t*)0x400E1694U) /**< \brief (PIOE) Pad Pull-down Enable Register */ + #define REG_PIOE_PPDSR (*(__I uint32_t*)0x400E1698U) /**< \brief (PIOE) Pad Pull-down Status Register */ + #define REG_PIOE_OWER (*(__O uint32_t*)0x400E16A0U) /**< \brief (PIOE) Output Write Enable */ + #define REG_PIOE_OWDR (*(__O uint32_t*)0x400E16A4U) /**< \brief (PIOE) Output Write Disable */ + #define REG_PIOE_OWSR (*(__I uint32_t*)0x400E16A8U) /**< \brief (PIOE) Output Write Status Register */ + #define REG_PIOE_AIMER (*(__O uint32_t*)0x400E16B0U) /**< \brief (PIOE) Additional Interrupt Modes Enable Register */ + #define REG_PIOE_AIMDR (*(__O uint32_t*)0x400E16B4U) /**< \brief (PIOE) Additional Interrupt Modes Disable Register */ + #define REG_PIOE_AIMMR (*(__I uint32_t*)0x400E16B8U) /**< \brief (PIOE) Additional Interrupt Modes Mask Register */ + #define REG_PIOE_ESR (*(__O uint32_t*)0x400E16C0U) /**< \brief (PIOE) Edge Select Register */ + #define REG_PIOE_LSR (*(__O uint32_t*)0x400E16C4U) /**< \brief (PIOE) Level Select Register */ + #define REG_PIOE_ELSR (*(__I uint32_t*)0x400E16C8U) /**< \brief (PIOE) Edge/Level Status Register */ + #define REG_PIOE_FELLSR (*(__O uint32_t*)0x400E16D0U) /**< \brief (PIOE) Falling Edge/Low-Level Select Register */ + #define REG_PIOE_REHLSR (*(__O uint32_t*)0x400E16D4U) /**< \brief (PIOE) Rising Edge/High-Level Select Register */ + #define REG_PIOE_FRLHSR (*(__I uint32_t*)0x400E16D8U) /**< \brief (PIOE) Fall/Rise - Low/High Status Register */ + #define REG_PIOE_LOCKSR (*(__I uint32_t*)0x400E16E0U) /**< \brief (PIOE) Lock Status */ + #define REG_PIOE_WPMR (*(__IO uint32_t*)0x400E16E4U) /**< \brief (PIOE) Write Protection Mode Register */ + #define REG_PIOE_WPSR (*(__I uint32_t*)0x400E16E8U) /**< \brief (PIOE) Write Protection Status Register */ + #define REG_PIOE_SCHMITT (*(__IO uint32_t*)0x400E1700U) /**< \brief (PIOE) Schmitt Trigger Register */ + #define REG_PIOE_DELAYR (*(__IO uint32_t*)0x400E1710U) /**< \brief (PIOE) I/O Delay Register */ + #define REG_PIOE_PCMR (*(__IO uint32_t*)0x400E1750U) /**< \brief (PIOE) Parallel Capture Mode Register */ + #define REG_PIOE_PCIER (*(__O uint32_t*)0x400E1754U) /**< \brief (PIOE) Parallel Capture Interrupt Enable Register */ + #define REG_PIOE_PCIDR (*(__O uint32_t*)0x400E1758U) /**< \brief (PIOE) Parallel Capture Interrupt Disable Register */ + #define REG_PIOE_PCIMR (*(__I uint32_t*)0x400E175CU) /**< \brief (PIOE) Parallel Capture Interrupt Mask Register */ + #define REG_PIOE_PCISR (*(__I uint32_t*)0x400E1760U) /**< \brief (PIOE) Parallel Capture Interrupt Status Register */ + #define REG_PIOE_PCRHR (*(__I uint32_t*)0x400E1764U) /**< \brief (PIOE) Parallel Capture Reception Holding Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PIOE_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pmc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pmc.h new file mode 100644 index 0000000..33b69ce --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pmc.h @@ -0,0 +1,105 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PMC_INSTANCE_ +#define _SAM4E_PMC_INSTANCE_ + +/* ========== Register definition for PMC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PMC_SCER (0x400E0400U) /**< \brief (PMC) System Clock Enable Register */ + #define REG_PMC_SCDR (0x400E0404U) /**< \brief (PMC) System Clock Disable Register */ + #define REG_PMC_SCSR (0x400E0408U) /**< \brief (PMC) System Clock Status Register */ + #define REG_PMC_PCER0 (0x400E0410U) /**< \brief (PMC) Peripheral Clock Enable Register 0 */ + #define REG_PMC_PCDR0 (0x400E0414U) /**< \brief (PMC) Peripheral Clock Disable Register 0 */ + #define REG_PMC_PCSR0 (0x400E0418U) /**< \brief (PMC) Peripheral Clock Status Register 0 */ + #define REG_CKGR_MOR (0x400E0420U) /**< \brief (PMC) Main Oscillator Register */ + #define REG_CKGR_MCFR (0x400E0424U) /**< \brief (PMC) Main Clock Frequency Register */ + #define REG_CKGR_PLLAR (0x400E0428U) /**< \brief (PMC) PLLA Register */ + #define REG_PMC_MCKR (0x400E0430U) /**< \brief (PMC) Master Clock Register */ + #define REG_PMC_USB (0x400E0438U) /**< \brief (PMC) USB Clock Register */ + #define REG_PMC_PCK (0x400E0440U) /**< \brief (PMC) Programmable Clock 0 Register */ + #define REG_PMC_IER (0x400E0460U) /**< \brief (PMC) Interrupt Enable Register */ + #define REG_PMC_IDR (0x400E0464U) /**< \brief (PMC) Interrupt Disable Register */ + #define REG_PMC_SR (0x400E0468U) /**< \brief (PMC) Status Register */ + #define REG_PMC_IMR (0x400E046CU) /**< \brief (PMC) Interrupt Mask Register */ + #define REG_PMC_FSMR (0x400E0470U) /**< \brief (PMC) Fast Startup Mode Register */ + #define REG_PMC_FSPR (0x400E0474U) /**< \brief (PMC) Fast Startup Polarity Register */ + #define REG_PMC_FOCR (0x400E0478U) /**< \brief (PMC) Fault Output Clear Register */ + #define REG_PMC_WPMR (0x400E04E4U) /**< \brief (PMC) Write Protection Mode Register */ + #define REG_PMC_WPSR (0x400E04E8U) /**< \brief (PMC) Write Protection Status Register */ + #define REG_PMC_PCER1 (0x400E0500U) /**< \brief (PMC) Peripheral Clock Enable Register 1 */ + #define REG_PMC_PCDR1 (0x400E0504U) /**< \brief (PMC) Peripheral Clock Disable Register 1 */ + #define REG_PMC_PCSR1 (0x400E0508U) /**< \brief (PMC) Peripheral Clock Status Register 1 */ + #define REG_PMC_OCR (0x400E0510U) /**< \brief (PMC) Oscillator Calibration Register */ + #define REG_PMC_PMMR (0x400E0530U) /**< \brief (PMC) PLL Maximum Multiplier Value Register */ +#else + #define REG_PMC_SCER (*(__O uint32_t*)0x400E0400U) /**< \brief (PMC) System Clock Enable Register */ + #define REG_PMC_SCDR (*(__O uint32_t*)0x400E0404U) /**< \brief (PMC) System Clock Disable Register */ + #define REG_PMC_SCSR (*(__I uint32_t*)0x400E0408U) /**< \brief (PMC) System Clock Status Register */ + #define REG_PMC_PCER0 (*(__O uint32_t*)0x400E0410U) /**< \brief (PMC) Peripheral Clock Enable Register 0 */ + #define REG_PMC_PCDR0 (*(__O uint32_t*)0x400E0414U) /**< \brief (PMC) Peripheral Clock Disable Register 0 */ + #define REG_PMC_PCSR0 (*(__I uint32_t*)0x400E0418U) /**< \brief (PMC) Peripheral Clock Status Register 0 */ + #define REG_CKGR_MOR (*(__IO uint32_t*)0x400E0420U) /**< \brief (PMC) Main Oscillator Register */ + #define REG_CKGR_MCFR (*(__IO uint32_t*)0x400E0424U) /**< \brief (PMC) Main Clock Frequency Register */ + #define REG_CKGR_PLLAR (*(__IO uint32_t*)0x400E0428U) /**< \brief (PMC) PLLA Register */ + #define REG_PMC_MCKR (*(__IO uint32_t*)0x400E0430U) /**< \brief (PMC) Master Clock Register */ + #define REG_PMC_USB (*(__IO uint32_t*)0x400E0438U) /**< \brief (PMC) USB Clock Register */ + #define REG_PMC_PCK (*(__IO uint32_t*)0x400E0440U) /**< \brief (PMC) Programmable Clock 0 Register */ + #define REG_PMC_IER (*(__O uint32_t*)0x400E0460U) /**< \brief (PMC) Interrupt Enable Register */ + #define REG_PMC_IDR (*(__O uint32_t*)0x400E0464U) /**< \brief (PMC) Interrupt Disable Register */ + #define REG_PMC_SR (*(__I uint32_t*)0x400E0468U) /**< \brief (PMC) Status Register */ + #define REG_PMC_IMR (*(__I uint32_t*)0x400E046CU) /**< \brief (PMC) Interrupt Mask Register */ + #define REG_PMC_FSMR (*(__IO uint32_t*)0x400E0470U) /**< \brief (PMC) Fast Startup Mode Register */ + #define REG_PMC_FSPR (*(__IO uint32_t*)0x400E0474U) /**< \brief (PMC) Fast Startup Polarity Register */ + #define REG_PMC_FOCR (*(__O uint32_t*)0x400E0478U) /**< \brief (PMC) Fault Output Clear Register */ + #define REG_PMC_WPMR (*(__IO uint32_t*)0x400E04E4U) /**< \brief (PMC) Write Protection Mode Register */ + #define REG_PMC_WPSR (*(__I uint32_t*)0x400E04E8U) /**< \brief (PMC) Write Protection Status Register */ + #define REG_PMC_PCER1 (*(__O uint32_t*)0x400E0500U) /**< \brief (PMC) Peripheral Clock Enable Register 1 */ + #define REG_PMC_PCDR1 (*(__O uint32_t*)0x400E0504U) /**< \brief (PMC) Peripheral Clock Disable Register 1 */ + #define REG_PMC_PCSR1 (*(__I uint32_t*)0x400E0508U) /**< \brief (PMC) Peripheral Clock Status Register 1 */ + #define REG_PMC_OCR (*(__IO uint32_t*)0x400E0510U) /**< \brief (PMC) Oscillator Calibration Register */ + #define REG_PMC_PMMR (*(__IO uint32_t*)0x400E0530U) /**< \brief (PMC) PLL Maximum Multiplier Value Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PMC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pwm.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pwm.h new file mode 100644 index 0000000..7386960 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/pwm.h @@ -0,0 +1,263 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_PWM_INSTANCE_ +#define _SAM4E_PWM_INSTANCE_ + +/* ========== Register definition for PWM peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_PWM_CLK (0x40000000U) /**< \brief (PWM) PWM Clock Register */ + #define REG_PWM_ENA (0x40000004U) /**< \brief (PWM) PWM Enable Register */ + #define REG_PWM_DIS (0x40000008U) /**< \brief (PWM) PWM Disable Register */ + #define REG_PWM_SR (0x4000000CU) /**< \brief (PWM) PWM Status Register */ + #define REG_PWM_IER1 (0x40000010U) /**< \brief (PWM) PWM Interrupt Enable Register 1 */ + #define REG_PWM_IDR1 (0x40000014U) /**< \brief (PWM) PWM Interrupt Disable Register 1 */ + #define REG_PWM_IMR1 (0x40000018U) /**< \brief (PWM) PWM Interrupt Mask Register 1 */ + #define REG_PWM_ISR1 (0x4000001CU) /**< \brief (PWM) PWM Interrupt Status Register 1 */ + #define REG_PWM_SCM (0x40000020U) /**< \brief (PWM) PWM Sync Channels Mode Register */ + #define REG_PWM_DMAR (0x40000024U) /**< \brief (PWM) PWM DMA Register */ + #define REG_PWM_SCUC (0x40000028U) /**< \brief (PWM) PWM Sync Channels Update Control Register */ + #define REG_PWM_SCUP (0x4000002CU) /**< \brief (PWM) PWM Sync Channels Update Period Register */ + #define REG_PWM_SCUPUPD (0x40000030U) /**< \brief (PWM) PWM Sync Channels Update Period Update Register */ + #define REG_PWM_IER2 (0x40000034U) /**< \brief (PWM) PWM Interrupt Enable Register 2 */ + #define REG_PWM_IDR2 (0x40000038U) /**< \brief (PWM) PWM Interrupt Disable Register 2 */ + #define REG_PWM_IMR2 (0x4000003CU) /**< \brief (PWM) PWM Interrupt Mask Register 2 */ + #define REG_PWM_ISR2 (0x40000040U) /**< \brief (PWM) PWM Interrupt Status Register 2 */ + #define REG_PWM_OOV (0x40000044U) /**< \brief (PWM) PWM Output Override Value Register */ + #define REG_PWM_OS (0x40000048U) /**< \brief (PWM) PWM Output Selection Register */ + #define REG_PWM_OSS (0x4000004CU) /**< \brief (PWM) PWM Output Selection Set Register */ + #define REG_PWM_OSC (0x40000050U) /**< \brief (PWM) PWM Output Selection Clear Register */ + #define REG_PWM_OSSUPD (0x40000054U) /**< \brief (PWM) PWM Output Selection Set Update Register */ + #define REG_PWM_OSCUPD (0x40000058U) /**< \brief (PWM) PWM Output Selection Clear Update Register */ + #define REG_PWM_FMR (0x4000005CU) /**< \brief (PWM) PWM Fault Mode Register */ + #define REG_PWM_FSR (0x40000060U) /**< \brief (PWM) PWM Fault Status Register */ + #define REG_PWM_FCR (0x40000064U) /**< \brief (PWM) PWM Fault Clear Register */ +#define REG_PWM_FPV1 (0x40000068U) /**< \brief (PWM) PWM Fault Protection Value Register 1 */ + #define REG_PWM_FPE (0x4000006CU) /**< \brief (PWM) PWM Fault Protection Enable Register */ + #define REG_PWM_ELMR (0x4000007CU) /**< \brief (PWM) PWM Event Line 0 Mode Register */ + #define REG_PWM_SSPR (0x400000A0U) /**< \brief (PWM) PWM Spread Spectrum Register */ + #define REG_PWM_SSPUP (0x400000A4U) /**< \brief (PWM) PWM Spread Spectrum Update Register */ + #define REG_PWM_SMMR (0x400000B0U) /**< \brief (PWM) PWM Stepper Motor Mode Register */ + #define REG_PWM_FPV2 (0x400000C0U) /**< \brief (PWM) PWM Fault Protection Value 2 Register */ + #define REG_PWM_WPCR (0x400000E4U) /**< \brief (PWM) PWM Write Protection Control Register */ + #define REG_PWM_WPSR (0x400000E8U) /**< \brief (PWM) PWM Write Protection Status Register */ + #define REG_PWM_TPR (0x40000108U) /**< \brief (PWM) Transmit Pointer Register */ + #define REG_PWM_TCR (0x4000010CU) /**< \brief (PWM) Transmit Counter Register */ + #define REG_PWM_TNPR (0x40000118U) /**< \brief (PWM) Transmit Next Pointer Register */ + #define REG_PWM_TNCR (0x4000011CU) /**< \brief (PWM) Transmit Next Counter Register */ + #define REG_PWM_PTCR (0x40000120U) /**< \brief (PWM) Transfer Control Register */ + #define REG_PWM_PTSR (0x40000124U) /**< \brief (PWM) Transfer Status Register */ + #define REG_PWM_CMPV0 (0x40000130U) /**< \brief (PWM) PWM Comparison 0 Value Register */ + #define REG_PWM_CMPVUPD0 (0x40000134U) /**< \brief (PWM) PWM Comparison 0 Value Update Register */ + #define REG_PWM_CMPM0 (0x40000138U) /**< \brief (PWM) PWM Comparison 0 Mode Register */ + #define REG_PWM_CMPMUPD0 (0x4000013CU) /**< \brief (PWM) PWM Comparison 0 Mode Update Register */ + #define REG_PWM_CMPV1 (0x40000140U) /**< \brief (PWM) PWM Comparison 1 Value Register */ + #define REG_PWM_CMPVUPD1 (0x40000144U) /**< \brief (PWM) PWM Comparison 1 Value Update Register */ + #define REG_PWM_CMPM1 (0x40000148U) /**< \brief (PWM) PWM Comparison 1 Mode Register */ + #define REG_PWM_CMPMUPD1 (0x4000014CU) /**< \brief (PWM) PWM Comparison 1 Mode Update Register */ + #define REG_PWM_CMPV2 (0x40000150U) /**< \brief (PWM) PWM Comparison 2 Value Register */ + #define REG_PWM_CMPVUPD2 (0x40000154U) /**< \brief (PWM) PWM Comparison 2 Value Update Register */ + #define REG_PWM_CMPM2 (0x40000158U) /**< \brief (PWM) PWM Comparison 2 Mode Register */ + #define REG_PWM_CMPMUPD2 (0x4000015CU) /**< \brief (PWM) PWM Comparison 2 Mode Update Register */ + #define REG_PWM_CMPV3 (0x40000160U) /**< \brief (PWM) PWM Comparison 3 Value Register */ + #define REG_PWM_CMPVUPD3 (0x40000164U) /**< \brief (PWM) PWM Comparison 3 Value Update Register */ + #define REG_PWM_CMPM3 (0x40000168U) /**< \brief (PWM) PWM Comparison 3 Mode Register */ + #define REG_PWM_CMPMUPD3 (0x4000016CU) /**< \brief (PWM) PWM Comparison 3 Mode Update Register */ + #define REG_PWM_CMPV4 (0x40000170U) /**< \brief (PWM) PWM Comparison 4 Value Register */ + #define REG_PWM_CMPVUPD4 (0x40000174U) /**< \brief (PWM) PWM Comparison 4 Value Update Register */ + #define REG_PWM_CMPM4 (0x40000178U) /**< \brief (PWM) PWM Comparison 4 Mode Register */ + #define REG_PWM_CMPMUPD4 (0x4000017CU) /**< \brief (PWM) PWM Comparison 4 Mode Update Register */ + #define REG_PWM_CMPV5 (0x40000180U) /**< \brief (PWM) PWM Comparison 5 Value Register */ + #define REG_PWM_CMPVUPD5 (0x40000184U) /**< \brief (PWM) PWM Comparison 5 Value Update Register */ + #define REG_PWM_CMPM5 (0x40000188U) /**< \brief (PWM) PWM Comparison 5 Mode Register */ + #define REG_PWM_CMPMUPD5 (0x4000018CU) /**< \brief (PWM) PWM Comparison 5 Mode Update Register */ + #define REG_PWM_CMPV6 (0x40000190U) /**< \brief (PWM) PWM Comparison 6 Value Register */ + #define REG_PWM_CMPVUPD6 (0x40000194U) /**< \brief (PWM) PWM Comparison 6 Value Update Register */ + #define REG_PWM_CMPM6 (0x40000198U) /**< \brief (PWM) PWM Comparison 6 Mode Register */ + #define REG_PWM_CMPMUPD6 (0x4000019CU) /**< \brief (PWM) PWM Comparison 6 Mode Update Register */ + #define REG_PWM_CMPV7 (0x400001A0U) /**< \brief (PWM) PWM Comparison 7 Value Register */ + #define REG_PWM_CMPVUPD7 (0x400001A4U) /**< \brief (PWM) PWM Comparison 7 Value Update Register */ + #define REG_PWM_CMPM7 (0x400001A8U) /**< \brief (PWM) PWM Comparison 7 Mode Register */ + #define REG_PWM_CMPMUPD7 (0x400001ACU) /**< \brief (PWM) PWM Comparison 7 Mode Update Register */ + #define REG_PWM_CMR0 (0x40000200U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 0) */ + #define REG_PWM_CDTY0 (0x40000204U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 0) */ + #define REG_PWM_CDTYUPD0 (0x40000208U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 0) */ + #define REG_PWM_CPRD0 (0x4000020CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 0) */ + #define REG_PWM_CPRDUPD0 (0x40000210U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 0) */ + #define REG_PWM_CCNT0 (0x40000214U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 0) */ + #define REG_PWM_DT0 (0x40000218U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 0) */ + #define REG_PWM_DTUPD0 (0x4000021CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 0) */ + #define REG_PWM_CMR1 (0x40000220U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 1) */ + #define REG_PWM_CDTY1 (0x40000224U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 1) */ + #define REG_PWM_CDTYUPD1 (0x40000228U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 1) */ + #define REG_PWM_CPRD1 (0x4000022CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 1) */ + #define REG_PWM_CPRDUPD1 (0x40000230U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 1) */ + #define REG_PWM_CCNT1 (0x40000234U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 1) */ + #define REG_PWM_DT1 (0x40000238U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 1) */ + #define REG_PWM_DTUPD1 (0x4000023CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 1) */ + #define REG_PWM_CMR2 (0x40000240U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 2) */ + #define REG_PWM_CDTY2 (0x40000244U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 2) */ + #define REG_PWM_CDTYUPD2 (0x40000248U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 2) */ + #define REG_PWM_CPRD2 (0x4000024CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 2) */ + #define REG_PWM_CPRDUPD2 (0x40000250U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 2) */ + #define REG_PWM_CCNT2 (0x40000254U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 2) */ + #define REG_PWM_DT2 (0x40000258U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 2) */ + #define REG_PWM_DTUPD2 (0x4000025CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 2) */ + #define REG_PWM_CMR3 (0x40000260U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 3) */ + #define REG_PWM_CDTY3 (0x40000264U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 3) */ + #define REG_PWM_CDTYUPD3 (0x40000268U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 3) */ + #define REG_PWM_CPRD3 (0x4000026CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 3) */ + #define REG_PWM_CPRDUPD3 (0x40000270U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 3) */ + #define REG_PWM_CCNT3 (0x40000274U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 3) */ + #define REG_PWM_DT3 (0x40000278U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 3) */ + #define REG_PWM_DTUPD3 (0x4000027CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 3) */ +#else + #define REG_PWM_CLK (*(__IO uint32_t*)0x40000000U) /**< \brief (PWM) PWM Clock Register */ + #define REG_PWM_ENA (*(__O uint32_t*)0x40000004U) /**< \brief (PWM) PWM Enable Register */ + #define REG_PWM_DIS (*(__O uint32_t*)0x40000008U) /**< \brief (PWM) PWM Disable Register */ + #define REG_PWM_SR (*(__I uint32_t*)0x4000000CU) /**< \brief (PWM) PWM Status Register */ + #define REG_PWM_IER1 (*(__O uint32_t*)0x40000010U) /**< \brief (PWM) PWM Interrupt Enable Register 1 */ + #define REG_PWM_IDR1 (*(__O uint32_t*)0x40000014U) /**< \brief (PWM) PWM Interrupt Disable Register 1 */ + #define REG_PWM_IMR1 (*(__I uint32_t*)0x40000018U) /**< \brief (PWM) PWM Interrupt Mask Register 1 */ + #define REG_PWM_ISR1 (*(__I uint32_t*)0x4000001CU) /**< \brief (PWM) PWM Interrupt Status Register 1 */ + #define REG_PWM_SCM (*(__IO uint32_t*)0x40000020U) /**< \brief (PWM) PWM Sync Channels Mode Register */ + #define REG_PWM_DMAR (*(__O uint32_t*)0x40000024U) /**< \brief (PWM) PWM DMA Register */ + #define REG_PWM_SCUC (*(__IO uint32_t*)0x40000028U) /**< \brief (PWM) PWM Sync Channels Update Control Register */ + #define REG_PWM_SCUP (*(__IO uint32_t*)0x4000002CU) /**< \brief (PWM) PWM Sync Channels Update Period Register */ + #define REG_PWM_SCUPUPD (*(__O uint32_t*)0x40000030U) /**< \brief (PWM) PWM Sync Channels Update Period Update Register */ + #define REG_PWM_IER2 (*(__O uint32_t*)0x40000034U) /**< \brief (PWM) PWM Interrupt Enable Register 2 */ + #define REG_PWM_IDR2 (*(__O uint32_t*)0x40000038U) /**< \brief (PWM) PWM Interrupt Disable Register 2 */ + #define REG_PWM_IMR2 (*(__I uint32_t*)0x4000003CU) /**< \brief (PWM) PWM Interrupt Mask Register 2 */ + #define REG_PWM_ISR2 (*(__I uint32_t*)0x40000040U) /**< \brief (PWM) PWM Interrupt Status Register 2 */ + #define REG_PWM_OOV (*(__IO uint32_t*)0x40000044U) /**< \brief (PWM) PWM Output Override Value Register */ + #define REG_PWM_OS (*(__IO uint32_t*)0x40000048U) /**< \brief (PWM) PWM Output Selection Register */ + #define REG_PWM_OSS (*(__O uint32_t*)0x4000004CU) /**< \brief (PWM) PWM Output Selection Set Register */ + #define REG_PWM_OSC (*(__O uint32_t*)0x40000050U) /**< \brief (PWM) PWM Output Selection Clear Register */ + #define REG_PWM_OSSUPD (*(__O uint32_t*)0x40000054U) /**< \brief (PWM) PWM Output Selection Set Update Register */ + #define REG_PWM_OSCUPD (*(__O uint32_t*)0x40000058U) /**< \brief (PWM) PWM Output Selection Clear Update Register */ + #define REG_PWM_FMR (*(__IO uint32_t*)0x4000005CU) /**< \brief (PWM) PWM Fault Mode Register */ + #define REG_PWM_FSR (*(__I uint32_t*)0x40000060U) /**< \brief (PWM) PWM Fault Status Register */ + #define REG_PWM_FCR (*(__O uint32_t*)0x40000064U) /**< \brief (PWM) PWM Fault Clear Register */ +#define REG_PWM_FPV1 (*(RwReg*)0x40000068U) /**< \brief (PWM) PWM Fault Protection Value Register 1 */ + #define REG_PWM_FPE (*(__IO uint32_t*)0x4000006CU) /**< \brief (PWM) PWM Fault Protection Enable Register */ + #define REG_PWM_ELMR (*(__IO uint32_t*)0x4000007CU) /**< \brief (PWM) PWM Event Line 0 Mode Register */ + #define REG_PWM_SSPR (*(__IO uint32_t*)0x400000A0U) /**< \brief (PWM) PWM Spread Spectrum Register */ + #define REG_PWM_SSPUP (*(__O uint32_t*)0x400000A4U) /**< \brief (PWM) PWM Spread Spectrum Update Register */ + #define REG_PWM_SMMR (*(__IO uint32_t*)0x400000B0U) /**< \brief (PWM) PWM Stepper Motor Mode Register */ + #define REG_PWM_FPV2 (*(__IO uint32_t*)0x400000C0U) /**< \brief (PWM) PWM Fault Protection Value 2 Register */ + #define REG_PWM_WPCR (*(__O uint32_t*)0x400000E4U) /**< \brief (PWM) PWM Write Protection Control Register */ + #define REG_PWM_WPSR (*(__I uint32_t*)0x400000E8U) /**< \brief (PWM) PWM Write Protection Status Register */ + #define REG_PWM_TPR (*(__IO uint32_t*)0x40000108U) /**< \brief (PWM) Transmit Pointer Register */ + #define REG_PWM_TCR (*(__IO uint32_t*)0x4000010CU) /**< \brief (PWM) Transmit Counter Register */ + #define REG_PWM_TNPR (*(__IO uint32_t*)0x40000118U) /**< \brief (PWM) Transmit Next Pointer Register */ + #define REG_PWM_TNCR (*(__IO uint32_t*)0x4000011CU) /**< \brief (PWM) Transmit Next Counter Register */ + #define REG_PWM_PTCR (*(__O uint32_t*)0x40000120U) /**< \brief (PWM) Transfer Control Register */ + #define REG_PWM_PTSR (*(__I uint32_t*)0x40000124U) /**< \brief (PWM) Transfer Status Register */ + #define REG_PWM_CMPV0 (*(__IO uint32_t*)0x40000130U) /**< \brief (PWM) PWM Comparison 0 Value Register */ + #define REG_PWM_CMPVUPD0 (*(__O uint32_t*)0x40000134U) /**< \brief (PWM) PWM Comparison 0 Value Update Register */ + #define REG_PWM_CMPM0 (*(__IO uint32_t*)0x40000138U) /**< \brief (PWM) PWM Comparison 0 Mode Register */ + #define REG_PWM_CMPMUPD0 (*(__O uint32_t*)0x4000013CU) /**< \brief (PWM) PWM Comparison 0 Mode Update Register */ + #define REG_PWM_CMPV1 (*(__IO uint32_t*)0x40000140U) /**< \brief (PWM) PWM Comparison 1 Value Register */ + #define REG_PWM_CMPVUPD1 (*(__O uint32_t*)0x40000144U) /**< \brief (PWM) PWM Comparison 1 Value Update Register */ + #define REG_PWM_CMPM1 (*(__IO uint32_t*)0x40000148U) /**< \brief (PWM) PWM Comparison 1 Mode Register */ + #define REG_PWM_CMPMUPD1 (*(__O uint32_t*)0x4000014CU) /**< \brief (PWM) PWM Comparison 1 Mode Update Register */ + #define REG_PWM_CMPV2 (*(__IO uint32_t*)0x40000150U) /**< \brief (PWM) PWM Comparison 2 Value Register */ + #define REG_PWM_CMPVUPD2 (*(__O uint32_t*)0x40000154U) /**< \brief (PWM) PWM Comparison 2 Value Update Register */ + #define REG_PWM_CMPM2 (*(__IO uint32_t*)0x40000158U) /**< \brief (PWM) PWM Comparison 2 Mode Register */ + #define REG_PWM_CMPMUPD2 (*(__O uint32_t*)0x4000015CU) /**< \brief (PWM) PWM Comparison 2 Mode Update Register */ + #define REG_PWM_CMPV3 (*(__IO uint32_t*)0x40000160U) /**< \brief (PWM) PWM Comparison 3 Value Register */ + #define REG_PWM_CMPVUPD3 (*(__O uint32_t*)0x40000164U) /**< \brief (PWM) PWM Comparison 3 Value Update Register */ + #define REG_PWM_CMPM3 (*(__IO uint32_t*)0x40000168U) /**< \brief (PWM) PWM Comparison 3 Mode Register */ + #define REG_PWM_CMPMUPD3 (*(__O uint32_t*)0x4000016CU) /**< \brief (PWM) PWM Comparison 3 Mode Update Register */ + #define REG_PWM_CMPV4 (*(__IO uint32_t*)0x40000170U) /**< \brief (PWM) PWM Comparison 4 Value Register */ + #define REG_PWM_CMPVUPD4 (*(__O uint32_t*)0x40000174U) /**< \brief (PWM) PWM Comparison 4 Value Update Register */ + #define REG_PWM_CMPM4 (*(__IO uint32_t*)0x40000178U) /**< \brief (PWM) PWM Comparison 4 Mode Register */ + #define REG_PWM_CMPMUPD4 (*(__O uint32_t*)0x4000017CU) /**< \brief (PWM) PWM Comparison 4 Mode Update Register */ + #define REG_PWM_CMPV5 (*(__IO uint32_t*)0x40000180U) /**< \brief (PWM) PWM Comparison 5 Value Register */ + #define REG_PWM_CMPVUPD5 (*(__O uint32_t*)0x40000184U) /**< \brief (PWM) PWM Comparison 5 Value Update Register */ + #define REG_PWM_CMPM5 (*(__IO uint32_t*)0x40000188U) /**< \brief (PWM) PWM Comparison 5 Mode Register */ + #define REG_PWM_CMPMUPD5 (*(__O uint32_t*)0x4000018CU) /**< \brief (PWM) PWM Comparison 5 Mode Update Register */ + #define REG_PWM_CMPV6 (*(__IO uint32_t*)0x40000190U) /**< \brief (PWM) PWM Comparison 6 Value Register */ + #define REG_PWM_CMPVUPD6 (*(__O uint32_t*)0x40000194U) /**< \brief (PWM) PWM Comparison 6 Value Update Register */ + #define REG_PWM_CMPM6 (*(__IO uint32_t*)0x40000198U) /**< \brief (PWM) PWM Comparison 6 Mode Register */ + #define REG_PWM_CMPMUPD6 (*(__O uint32_t*)0x4000019CU) /**< \brief (PWM) PWM Comparison 6 Mode Update Register */ + #define REG_PWM_CMPV7 (*(__IO uint32_t*)0x400001A0U) /**< \brief (PWM) PWM Comparison 7 Value Register */ + #define REG_PWM_CMPVUPD7 (*(__O uint32_t*)0x400001A4U) /**< \brief (PWM) PWM Comparison 7 Value Update Register */ + #define REG_PWM_CMPM7 (*(__IO uint32_t*)0x400001A8U) /**< \brief (PWM) PWM Comparison 7 Mode Register */ + #define REG_PWM_CMPMUPD7 (*(__O uint32_t*)0x400001ACU) /**< \brief (PWM) PWM Comparison 7 Mode Update Register */ + #define REG_PWM_CMR0 (*(__IO uint32_t*)0x40000200U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 0) */ + #define REG_PWM_CDTY0 (*(__IO uint32_t*)0x40000204U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 0) */ + #define REG_PWM_CDTYUPD0 (*(__O uint32_t*)0x40000208U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 0) */ + #define REG_PWM_CPRD0 (*(__IO uint32_t*)0x4000020CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 0) */ + #define REG_PWM_CPRDUPD0 (*(__O uint32_t*)0x40000210U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 0) */ + #define REG_PWM_CCNT0 (*(__I uint32_t*)0x40000214U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 0) */ + #define REG_PWM_DT0 (*(__IO uint32_t*)0x40000218U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 0) */ + #define REG_PWM_DTUPD0 (*(__O uint32_t*)0x4000021CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 0) */ + #define REG_PWM_CMR1 (*(__IO uint32_t*)0x40000220U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 1) */ + #define REG_PWM_CDTY1 (*(__IO uint32_t*)0x40000224U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 1) */ + #define REG_PWM_CDTYUPD1 (*(__O uint32_t*)0x40000228U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 1) */ + #define REG_PWM_CPRD1 (*(__IO uint32_t*)0x4000022CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 1) */ + #define REG_PWM_CPRDUPD1 (*(__O uint32_t*)0x40000230U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 1) */ + #define REG_PWM_CCNT1 (*(__I uint32_t*)0x40000234U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 1) */ + #define REG_PWM_DT1 (*(__IO uint32_t*)0x40000238U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 1) */ + #define REG_PWM_DTUPD1 (*(__O uint32_t*)0x4000023CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 1) */ + #define REG_PWM_CMR2 (*(__IO uint32_t*)0x40000240U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 2) */ + #define REG_PWM_CDTY2 (*(__IO uint32_t*)0x40000244U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 2) */ + #define REG_PWM_CDTYUPD2 (*(__O uint32_t*)0x40000248U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 2) */ + #define REG_PWM_CPRD2 (*(__IO uint32_t*)0x4000024CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 2) */ + #define REG_PWM_CPRDUPD2 (*(__O uint32_t*)0x40000250U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 2) */ + #define REG_PWM_CCNT2 (*(__I uint32_t*)0x40000254U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 2) */ + #define REG_PWM_DT2 (*(__IO uint32_t*)0x40000258U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 2) */ + #define REG_PWM_DTUPD2 (*(__O uint32_t*)0x4000025CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 2) */ + #define REG_PWM_CMR3 (*(__IO uint32_t*)0x40000260U) /**< \brief (PWM) PWM Channel Mode Register (ch_num = 3) */ + #define REG_PWM_CDTY3 (*(__IO uint32_t*)0x40000264U) /**< \brief (PWM) PWM Channel Duty Cycle Register (ch_num = 3) */ + #define REG_PWM_CDTYUPD3 (*(__O uint32_t*)0x40000268U) /**< \brief (PWM) PWM Channel Duty Cycle Update Register (ch_num = 3) */ + #define REG_PWM_CPRD3 (*(__IO uint32_t*)0x4000026CU) /**< \brief (PWM) PWM Channel Period Register (ch_num = 3) */ + #define REG_PWM_CPRDUPD3 (*(__O uint32_t*)0x40000270U) /**< \brief (PWM) PWM Channel Period Update Register (ch_num = 3) */ + #define REG_PWM_CCNT3 (*(__I uint32_t*)0x40000274U) /**< \brief (PWM) PWM Channel Counter Register (ch_num = 3) */ + #define REG_PWM_DT3 (*(__IO uint32_t*)0x40000278U) /**< \brief (PWM) PWM Channel Dead Time Register (ch_num = 3) */ + #define REG_PWM_DTUPD3 (*(__O uint32_t*)0x4000027CU) /**< \brief (PWM) PWM Channel Dead Time Update Register (ch_num = 3) */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_PWM_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rstc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rstc.h new file mode 100644 index 0000000..e5da9f3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rstc.h @@ -0,0 +1,59 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RSTC_INSTANCE_ +#define _SAM4E_RSTC_INSTANCE_ + +/* ========== Register definition for RSTC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_RSTC_CR (0x400E1800U) /**< \brief (RSTC) Control Register */ + #define REG_RSTC_SR (0x400E1804U) /**< \brief (RSTC) Status Register */ + #define REG_RSTC_MR (0x400E1808U) /**< \brief (RSTC) Mode Register */ +#else + #define REG_RSTC_CR (*(__O uint32_t*)0x400E1800U) /**< \brief (RSTC) Control Register */ + #define REG_RSTC_SR (*(__I uint32_t*)0x400E1804U) /**< \brief (RSTC) Status Register */ + #define REG_RSTC_MR (*(__IO uint32_t*)0x400E1808U) /**< \brief (RSTC) Mode Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_RSTC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rswdt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rswdt.h new file mode 100644 index 0000000..86d61d9 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rswdt.h @@ -0,0 +1,59 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RSWDT_INSTANCE_ +#define _SAM4E_RSWDT_INSTANCE_ + +/* ========== Register definition for RSWDT peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_RSWDT_CR (0x400E1900U) /**< \brief (RSWDT) Control Register */ + #define REG_RSWDT_MR (0x400E1904U) /**< \brief (RSWDT) Mode Register */ + #define REG_RSWDT_SR (0x400E1908U) /**< \brief (RSWDT) Status Register */ +#else + #define REG_RSWDT_CR (*(__O uint32_t*)0x400E1900U) /**< \brief (RSWDT) Control Register */ + #define REG_RSWDT_MR (*(__IO uint32_t*)0x400E1904U) /**< \brief (RSWDT) Mode Register */ + #define REG_RSWDT_SR (*(__I uint32_t*)0x400E1908U) /**< \brief (RSWDT) Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_RSWDT_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtc.h new file mode 100644 index 0000000..587176c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtc.h @@ -0,0 +1,77 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RTC_INSTANCE_ +#define _SAM4E_RTC_INSTANCE_ + +/* ========== Register definition for RTC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_RTC_CR (0x400E1860U) /**< \brief (RTC) Control Register */ + #define REG_RTC_MR (0x400E1864U) /**< \brief (RTC) Mode Register */ + #define REG_RTC_TIMR (0x400E1868U) /**< \brief (RTC) Time Register */ + #define REG_RTC_CALR (0x400E186CU) /**< \brief (RTC) Calendar Register */ + #define REG_RTC_TIMALR (0x400E1870U) /**< \brief (RTC) Time Alarm Register */ + #define REG_RTC_CALALR (0x400E1874U) /**< \brief (RTC) Calendar Alarm Register */ + #define REG_RTC_SR (0x400E1878U) /**< \brief (RTC) Status Register */ + #define REG_RTC_SCCR (0x400E187CU) /**< \brief (RTC) Status Clear Command Register */ + #define REG_RTC_IER (0x400E1880U) /**< \brief (RTC) Interrupt Enable Register */ + #define REG_RTC_IDR (0x400E1884U) /**< \brief (RTC) Interrupt Disable Register */ + #define REG_RTC_IMR (0x400E1888U) /**< \brief (RTC) Interrupt Mask Register */ + #define REG_RTC_VER (0x400E188CU) /**< \brief (RTC) Valid Entry Register */ +#else + #define REG_RTC_CR (*(__IO uint32_t*)0x400E1860U) /**< \brief (RTC) Control Register */ + #define REG_RTC_MR (*(__IO uint32_t*)0x400E1864U) /**< \brief (RTC) Mode Register */ + #define REG_RTC_TIMR (*(__IO uint32_t*)0x400E1868U) /**< \brief (RTC) Time Register */ + #define REG_RTC_CALR (*(__IO uint32_t*)0x400E186CU) /**< \brief (RTC) Calendar Register */ + #define REG_RTC_TIMALR (*(__IO uint32_t*)0x400E1870U) /**< \brief (RTC) Time Alarm Register */ + #define REG_RTC_CALALR (*(__IO uint32_t*)0x400E1874U) /**< \brief (RTC) Calendar Alarm Register */ + #define REG_RTC_SR (*(__I uint32_t*)0x400E1878U) /**< \brief (RTC) Status Register */ + #define REG_RTC_SCCR (*(__O uint32_t*)0x400E187CU) /**< \brief (RTC) Status Clear Command Register */ + #define REG_RTC_IER (*(__O uint32_t*)0x400E1880U) /**< \brief (RTC) Interrupt Enable Register */ + #define REG_RTC_IDR (*(__O uint32_t*)0x400E1884U) /**< \brief (RTC) Interrupt Disable Register */ + #define REG_RTC_IMR (*(__I uint32_t*)0x400E1888U) /**< \brief (RTC) Interrupt Mask Register */ + #define REG_RTC_VER (*(__I uint32_t*)0x400E188CU) /**< \brief (RTC) Valid Entry Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_RTC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtt.h new file mode 100644 index 0000000..29dc074 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/rtt.h @@ -0,0 +1,61 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_RTT_INSTANCE_ +#define _SAM4E_RTT_INSTANCE_ + +/* ========== Register definition for RTT peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_RTT_MR (0x400E1830U) /**< \brief (RTT) Mode Register */ + #define REG_RTT_AR (0x400E1834U) /**< \brief (RTT) Alarm Register */ + #define REG_RTT_VR (0x400E1838U) /**< \brief (RTT) Value Register */ + #define REG_RTT_SR (0x400E183CU) /**< \brief (RTT) Status Register */ +#else + #define REG_RTT_MR (*(__IO uint32_t*)0x400E1830U) /**< \brief (RTT) Mode Register */ + #define REG_RTT_AR (*(__IO uint32_t*)0x400E1834U) /**< \brief (RTT) Alarm Register */ + #define REG_RTT_VR (*(__I uint32_t*)0x400E1838U) /**< \brief (RTT) Value Register */ + #define REG_RTT_SR (*(__I uint32_t*)0x400E183CU) /**< \brief (RTT) Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_RTT_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/smc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/smc.h new file mode 100644 index 0000000..6cf749b --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/smc.h @@ -0,0 +1,95 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SMC_INSTANCE_ +#define _SAM4E_SMC_INSTANCE_ + +/* ========== Register definition for SMC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_SMC_SETUP0 (0x40060000U) /**< \brief (SMC) SMC Setup Register (CS_number = 0) */ + #define REG_SMC_PULSE0 (0x40060004U) /**< \brief (SMC) SMC Pulse Register (CS_number = 0) */ + #define REG_SMC_CYCLE0 (0x40060008U) /**< \brief (SMC) SMC Cycle Register (CS_number = 0) */ + #define REG_SMC_MODE0 (0x4006000CU) /**< \brief (SMC) SMC Mode Register (CS_number = 0) */ + #define REG_SMC_SETUP1 (0x40060010U) /**< \brief (SMC) SMC Setup Register (CS_number = 1) */ + #define REG_SMC_PULSE1 (0x40060014U) /**< \brief (SMC) SMC Pulse Register (CS_number = 1) */ + #define REG_SMC_CYCLE1 (0x40060018U) /**< \brief (SMC) SMC Cycle Register (CS_number = 1) */ + #define REG_SMC_MODE1 (0x4006001CU) /**< \brief (SMC) SMC Mode Register (CS_number = 1) */ + #define REG_SMC_SETUP2 (0x40060020U) /**< \brief (SMC) SMC Setup Register (CS_number = 2) */ + #define REG_SMC_PULSE2 (0x40060024U) /**< \brief (SMC) SMC Pulse Register (CS_number = 2) */ + #define REG_SMC_CYCLE2 (0x40060028U) /**< \brief (SMC) SMC Cycle Register (CS_number = 2) */ + #define REG_SMC_MODE2 (0x4006002CU) /**< \brief (SMC) SMC Mode Register (CS_number = 2) */ + #define REG_SMC_SETUP3 (0x40060030U) /**< \brief (SMC) SMC Setup Register (CS_number = 3) */ + #define REG_SMC_PULSE3 (0x40060034U) /**< \brief (SMC) SMC Pulse Register (CS_number = 3) */ + #define REG_SMC_CYCLE3 (0x40060038U) /**< \brief (SMC) SMC Cycle Register (CS_number = 3) */ + #define REG_SMC_MODE3 (0x4006003CU) /**< \brief (SMC) SMC Mode Register (CS_number = 3) */ + #define REG_SMC_OCMS (0x40060080U) /**< \brief (SMC) SMC OCMS MODE Register */ + #define REG_SMC_KEY1 (0x40060084U) /**< \brief (SMC) SMC OCMS KEY1 Register */ + #define REG_SMC_KEY2 (0x40060088U) /**< \brief (SMC) SMC OCMS KEY2 Register */ + #define REG_SMC_WPMR (0x400600E4U) /**< \brief (SMC) SMC Write Protect Mode Register */ + #define REG_SMC_WPSR (0x400600E8U) /**< \brief (SMC) SMC Write Protect Status Register */ +#else + #define REG_SMC_SETUP0 (*(__IO uint32_t*)0x40060000U) /**< \brief (SMC) SMC Setup Register (CS_number = 0) */ + #define REG_SMC_PULSE0 (*(__IO uint32_t*)0x40060004U) /**< \brief (SMC) SMC Pulse Register (CS_number = 0) */ + #define REG_SMC_CYCLE0 (*(__IO uint32_t*)0x40060008U) /**< \brief (SMC) SMC Cycle Register (CS_number = 0) */ + #define REG_SMC_MODE0 (*(__IO uint32_t*)0x4006000CU) /**< \brief (SMC) SMC Mode Register (CS_number = 0) */ + #define REG_SMC_SETUP1 (*(__IO uint32_t*)0x40060010U) /**< \brief (SMC) SMC Setup Register (CS_number = 1) */ + #define REG_SMC_PULSE1 (*(__IO uint32_t*)0x40060014U) /**< \brief (SMC) SMC Pulse Register (CS_number = 1) */ + #define REG_SMC_CYCLE1 (*(__IO uint32_t*)0x40060018U) /**< \brief (SMC) SMC Cycle Register (CS_number = 1) */ + #define REG_SMC_MODE1 (*(__IO uint32_t*)0x4006001CU) /**< \brief (SMC) SMC Mode Register (CS_number = 1) */ + #define REG_SMC_SETUP2 (*(__IO uint32_t*)0x40060020U) /**< \brief (SMC) SMC Setup Register (CS_number = 2) */ + #define REG_SMC_PULSE2 (*(__IO uint32_t*)0x40060024U) /**< \brief (SMC) SMC Pulse Register (CS_number = 2) */ + #define REG_SMC_CYCLE2 (*(__IO uint32_t*)0x40060028U) /**< \brief (SMC) SMC Cycle Register (CS_number = 2) */ + #define REG_SMC_MODE2 (*(__IO uint32_t*)0x4006002CU) /**< \brief (SMC) SMC Mode Register (CS_number = 2) */ + #define REG_SMC_SETUP3 (*(__IO uint32_t*)0x40060030U) /**< \brief (SMC) SMC Setup Register (CS_number = 3) */ + #define REG_SMC_PULSE3 (*(__IO uint32_t*)0x40060034U) /**< \brief (SMC) SMC Pulse Register (CS_number = 3) */ + #define REG_SMC_CYCLE3 (*(__IO uint32_t*)0x40060038U) /**< \brief (SMC) SMC Cycle Register (CS_number = 3) */ + #define REG_SMC_MODE3 (*(__IO uint32_t*)0x4006003CU) /**< \brief (SMC) SMC Mode Register (CS_number = 3) */ + #define REG_SMC_OCMS (*(__IO uint32_t*)0x40060080U) /**< \brief (SMC) SMC OCMS MODE Register */ + #define REG_SMC_KEY1 (*(__O uint32_t*)0x40060084U) /**< \brief (SMC) SMC OCMS KEY1 Register */ + #define REG_SMC_KEY2 (*(__O uint32_t*)0x40060088U) /**< \brief (SMC) SMC OCMS KEY2 Register */ + #define REG_SMC_WPMR (*(__IO uint32_t*)0x400600E4U) /**< \brief (SMC) SMC Write Protect Mode Register */ + #define REG_SMC_WPSR (*(__I uint32_t*)0x400600E8U) /**< \brief (SMC) SMC Write Protect Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_SMC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/spi.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/spi.h new file mode 100644 index 0000000..8eb3cf3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/spi.h @@ -0,0 +1,95 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SPI_INSTANCE_ +#define _SAM4E_SPI_INSTANCE_ + +/* ========== Register definition for SPI peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_SPI_CR (0x40088000U) /**< \brief (SPI) Control Register */ + #define REG_SPI_MR (0x40088004U) /**< \brief (SPI) Mode Register */ + #define REG_SPI_RDR (0x40088008U) /**< \brief (SPI) Receive Data Register */ + #define REG_SPI_TDR (0x4008800CU) /**< \brief (SPI) Transmit Data Register */ + #define REG_SPI_SR (0x40088010U) /**< \brief (SPI) Status Register */ + #define REG_SPI_IER (0x40088014U) /**< \brief (SPI) Interrupt Enable Register */ + #define REG_SPI_IDR (0x40088018U) /**< \brief (SPI) Interrupt Disable Register */ + #define REG_SPI_IMR (0x4008801CU) /**< \brief (SPI) Interrupt Mask Register */ + #define REG_SPI_CSR (0x40088030U) /**< \brief (SPI) Chip Select Register */ + #define REG_SPI_WPMR (0x400880E4U) /**< \brief (SPI) Write Protection Mode Register */ + #define REG_SPI_WPSR (0x400880E8U) /**< \brief (SPI) Write Protection Status Register */ + #define REG_SPI_RPR (0x40088100U) /**< \brief (SPI) Receive Pointer Register */ + #define REG_SPI_RCR (0x40088104U) /**< \brief (SPI) Receive Counter Register */ + #define REG_SPI_TPR (0x40088108U) /**< \brief (SPI) Transmit Pointer Register */ + #define REG_SPI_TCR (0x4008810CU) /**< \brief (SPI) Transmit Counter Register */ + #define REG_SPI_RNPR (0x40088110U) /**< \brief (SPI) Receive Next Pointer Register */ + #define REG_SPI_RNCR (0x40088114U) /**< \brief (SPI) Receive Next Counter Register */ + #define REG_SPI_TNPR (0x40088118U) /**< \brief (SPI) Transmit Next Pointer Register */ + #define REG_SPI_TNCR (0x4008811CU) /**< \brief (SPI) Transmit Next Counter Register */ + #define REG_SPI_PTCR (0x40088120U) /**< \brief (SPI) Transfer Control Register */ + #define REG_SPI_PTSR (0x40088124U) /**< \brief (SPI) Transfer Status Register */ +#else + #define REG_SPI_CR (*(__O uint32_t*)0x40088000U) /**< \brief (SPI) Control Register */ + #define REG_SPI_MR (*(__IO uint32_t*)0x40088004U) /**< \brief (SPI) Mode Register */ + #define REG_SPI_RDR (*(__I uint32_t*)0x40088008U) /**< \brief (SPI) Receive Data Register */ + #define REG_SPI_TDR (*(__O uint32_t*)0x4008800CU) /**< \brief (SPI) Transmit Data Register */ + #define REG_SPI_SR (*(__I uint32_t*)0x40088010U) /**< \brief (SPI) Status Register */ + #define REG_SPI_IER (*(__O uint32_t*)0x40088014U) /**< \brief (SPI) Interrupt Enable Register */ + #define REG_SPI_IDR (*(__O uint32_t*)0x40088018U) /**< \brief (SPI) Interrupt Disable Register */ + #define REG_SPI_IMR (*(__I uint32_t*)0x4008801CU) /**< \brief (SPI) Interrupt Mask Register */ + #define REG_SPI_CSR (*(__IO uint32_t*)0x40088030U) /**< \brief (SPI) Chip Select Register */ + #define REG_SPI_WPMR (*(__IO uint32_t*)0x400880E4U) /**< \brief (SPI) Write Protection Mode Register */ + #define REG_SPI_WPSR (*(__I uint32_t*)0x400880E8U) /**< \brief (SPI) Write Protection Status Register */ + #define REG_SPI_RPR (*(__IO uint32_t*)0x40088100U) /**< \brief (SPI) Receive Pointer Register */ + #define REG_SPI_RCR (*(__IO uint32_t*)0x40088104U) /**< \brief (SPI) Receive Counter Register */ + #define REG_SPI_TPR (*(__IO uint32_t*)0x40088108U) /**< \brief (SPI) Transmit Pointer Register */ + #define REG_SPI_TCR (*(__IO uint32_t*)0x4008810CU) /**< \brief (SPI) Transmit Counter Register */ + #define REG_SPI_RNPR (*(__IO uint32_t*)0x40088110U) /**< \brief (SPI) Receive Next Pointer Register */ + #define REG_SPI_RNCR (*(__IO uint32_t*)0x40088114U) /**< \brief (SPI) Receive Next Counter Register */ + #define REG_SPI_TNPR (*(__IO uint32_t*)0x40088118U) /**< \brief (SPI) Transmit Next Pointer Register */ + #define REG_SPI_TNCR (*(__IO uint32_t*)0x4008811CU) /**< \brief (SPI) Transmit Next Counter Register */ + #define REG_SPI_PTCR (*(__O uint32_t*)0x40088120U) /**< \brief (SPI) Transfer Control Register */ + #define REG_SPI_PTSR (*(__I uint32_t*)0x40088124U) /**< \brief (SPI) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_SPI_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/supc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/supc.h new file mode 100644 index 0000000..9116ae3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/supc.h @@ -0,0 +1,65 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_SUPC_INSTANCE_ +#define _SAM4E_SUPC_INSTANCE_ + +/* ========== Register definition for SUPC peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_SUPC_CR (0x400E1810U) /**< \brief (SUPC) Supply Controller Control Register */ + #define REG_SUPC_SMMR (0x400E1814U) /**< \brief (SUPC) Supply Controller Supply Monitor Mode Register */ + #define REG_SUPC_MR (0x400E1818U) /**< \brief (SUPC) Supply Controller Mode Register */ + #define REG_SUPC_WUMR (0x400E181CU) /**< \brief (SUPC) Supply Controller Wake-up Mode Register */ + #define REG_SUPC_WUIR (0x400E1820U) /**< \brief (SUPC) Supply Controller Wake-up Inputs Register */ + #define REG_SUPC_SR (0x400E1824U) /**< \brief (SUPC) Supply Controller Status Register */ +#else + #define REG_SUPC_CR (*(__O uint32_t*)0x400E1810U) /**< \brief (SUPC) Supply Controller Control Register */ + #define REG_SUPC_SMMR (*(__IO uint32_t*)0x400E1814U) /**< \brief (SUPC) Supply Controller Supply Monitor Mode Register */ + #define REG_SUPC_MR (*(__IO uint32_t*)0x400E1818U) /**< \brief (SUPC) Supply Controller Mode Register */ + #define REG_SUPC_WUMR (*(__IO uint32_t*)0x400E181CU) /**< \brief (SUPC) Supply Controller Wake-up Mode Register */ + #define REG_SUPC_WUIR (*(__IO uint32_t*)0x400E1820U) /**< \brief (SUPC) Supply Controller Wake-up Inputs Register */ + #define REG_SUPC_SR (*(__I uint32_t*)0x400E1824U) /**< \brief (SUPC) Supply Controller Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_SUPC_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc0.h new file mode 100644 index 0000000..2c250d0 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc0.h @@ -0,0 +1,183 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TC0_INSTANCE_ +#define _SAM4E_TC0_INSTANCE_ + +/* ========== Register definition for TC0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_TC0_CCR0 (0x40090000U) /**< \brief (TC0) Channel Control Register (channel = 0) */ + #define REG_TC0_CMR0 (0x40090004U) /**< \brief (TC0) Channel Mode Register (channel = 0) */ + #define REG_TC0_SMMR0 (0x40090008U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC0_RAB0 (0x4009000CU) /**< \brief (TC0) Register AB (channel = 0) */ + #define REG_TC0_CV0 (0x40090010U) /**< \brief (TC0) Counter Value (channel = 0) */ + #define REG_TC0_RA0 (0x40090014U) /**< \brief (TC0) Register A (channel = 0) */ + #define REG_TC0_RB0 (0x40090018U) /**< \brief (TC0) Register B (channel = 0) */ + #define REG_TC0_RC0 (0x4009001CU) /**< \brief (TC0) Register C (channel = 0) */ + #define REG_TC0_SR0 (0x40090020U) /**< \brief (TC0) Status Register (channel = 0) */ + #define REG_TC0_IER0 (0x40090024U) /**< \brief (TC0) Interrupt Enable Register (channel = 0) */ + #define REG_TC0_IDR0 (0x40090028U) /**< \brief (TC0) Interrupt Disable Register (channel = 0) */ + #define REG_TC0_IMR0 (0x4009002CU) /**< \brief (TC0) Interrupt Mask Register (channel = 0) */ + #define REG_TC0_EMR0 (0x40090030U) /**< \brief (TC0) Extended Mode Register (channel = 0) */ + #define REG_TC0_CCR1 (0x40090040U) /**< \brief (TC0) Channel Control Register (channel = 1) */ + #define REG_TC0_CMR1 (0x40090044U) /**< \brief (TC0) Channel Mode Register (channel = 1) */ + #define REG_TC0_SMMR1 (0x40090048U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC0_RAB1 (0x4009004CU) /**< \brief (TC0) Register AB (channel = 1) */ + #define REG_TC0_CV1 (0x40090050U) /**< \brief (TC0) Counter Value (channel = 1) */ + #define REG_TC0_RA1 (0x40090054U) /**< \brief (TC0) Register A (channel = 1) */ + #define REG_TC0_RB1 (0x40090058U) /**< \brief (TC0) Register B (channel = 1) */ + #define REG_TC0_RC1 (0x4009005CU) /**< \brief (TC0) Register C (channel = 1) */ + #define REG_TC0_SR1 (0x40090060U) /**< \brief (TC0) Status Register (channel = 1) */ + #define REG_TC0_IER1 (0x40090064U) /**< \brief (TC0) Interrupt Enable Register (channel = 1) */ + #define REG_TC0_IDR1 (0x40090068U) /**< \brief (TC0) Interrupt Disable Register (channel = 1) */ + #define REG_TC0_IMR1 (0x4009006CU) /**< \brief (TC0) Interrupt Mask Register (channel = 1) */ + #define REG_TC0_EMR1 (0x40090070U) /**< \brief (TC0) Extended Mode Register (channel = 1) */ + #define REG_TC0_CCR2 (0x40090080U) /**< \brief (TC0) Channel Control Register (channel = 2) */ + #define REG_TC0_CMR2 (0x40090084U) /**< \brief (TC0) Channel Mode Register (channel = 2) */ + #define REG_TC0_SMMR2 (0x40090088U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC0_RAB2 (0x4009008CU) /**< \brief (TC0) Register AB (channel = 2) */ + #define REG_TC0_CV2 (0x40090090U) /**< \brief (TC0) Counter Value (channel = 2) */ + #define REG_TC0_RA2 (0x40090094U) /**< \brief (TC0) Register A (channel = 2) */ + #define REG_TC0_RB2 (0x40090098U) /**< \brief (TC0) Register B (channel = 2) */ + #define REG_TC0_RC2 (0x4009009CU) /**< \brief (TC0) Register C (channel = 2) */ + #define REG_TC0_SR2 (0x400900A0U) /**< \brief (TC0) Status Register (channel = 2) */ + #define REG_TC0_IER2 (0x400900A4U) /**< \brief (TC0) Interrupt Enable Register (channel = 2) */ + #define REG_TC0_IDR2 (0x400900A8U) /**< \brief (TC0) Interrupt Disable Register (channel = 2) */ + #define REG_TC0_IMR2 (0x400900ACU) /**< \brief (TC0) Interrupt Mask Register (channel = 2) */ + #define REG_TC0_EMR2 (0x400900B0U) /**< \brief (TC0) Extended Mode Register (channel = 2) */ + #define REG_TC0_BCR (0x400900C0U) /**< \brief (TC0) Block Control Register */ + #define REG_TC0_BMR (0x400900C4U) /**< \brief (TC0) Block Mode Register */ + #define REG_TC0_QIER (0x400900C8U) /**< \brief (TC0) QDEC Interrupt Enable Register */ + #define REG_TC0_QIDR (0x400900CCU) /**< \brief (TC0) QDEC Interrupt Disable Register */ + #define REG_TC0_QIMR (0x400900D0U) /**< \brief (TC0) QDEC Interrupt Mask Register */ + #define REG_TC0_QISR (0x400900D4U) /**< \brief (TC0) QDEC Interrupt Status Register */ + #define REG_TC0_FMR (0x400900D8U) /**< \brief (TC0) Fault Mode Register */ + #define REG_TC0_WPMR (0x400900E4U) /**< \brief (TC0) Write Protection Mode Register */ + #define REG_TC0_RPR0 (0x40090100U) /**< \brief (TC0) Receive Pointer Register (pdc = 0) */ + #define REG_TC0_RCR0 (0x40090104U) /**< \brief (TC0) Receive Counter Register (pdc = 0) */ + #define REG_TC0_RNPR0 (0x40090110U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 0) */ + #define REG_TC0_RNCR0 (0x40090114U) /**< \brief (TC0) Receive Next Counter Register (pdc = 0) */ + #define REG_TC0_PTCR0 (0x40090120U) /**< \brief (TC0) Transfer Control Register (pdc = 0) */ + #define REG_TC0_PTSR0 (0x40090124U) /**< \brief (TC0) Transfer Status Register (pdc = 0) */ + #define REG_TC0_RPR1 (0x40090140U) /**< \brief (TC0) Receive Pointer Register (pdc = 1) */ + #define REG_TC0_RCR1 (0x40090144U) /**< \brief (TC0) Receive Counter Register (pdc = 1) */ + #define REG_TC0_RNPR1 (0x40090150U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 1) */ + #define REG_TC0_RNCR1 (0x40090154U) /**< \brief (TC0) Receive Next Counter Register (pdc = 1) */ + #define REG_TC0_PTCR1 (0x40090160U) /**< \brief (TC0) Transfer Control Register (pdc = 1) */ + #define REG_TC0_PTSR1 (0x40090164U) /**< \brief (TC0) Transfer Status Register (pdc = 1) */ + #define REG_TC0_RPR2 (0x40090180U) /**< \brief (TC0) Receive Pointer Register (pdc = 2) */ + #define REG_TC0_RCR2 (0x40090184U) /**< \brief (TC0) Receive Counter Register (pdc = 2) */ + #define REG_TC0_RNPR2 (0x40090190U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 2) */ + #define REG_TC0_RNCR2 (0x40090194U) /**< \brief (TC0) Receive Next Counter Register (pdc = 2) */ + #define REG_TC0_PTCR2 (0x400901A0U) /**< \brief (TC0) Transfer Control Register (pdc = 2) */ + #define REG_TC0_PTSR2 (0x400901A4U) /**< \brief (TC0) Transfer Status Register (pdc = 2) */ +#else + #define REG_TC0_CCR0 (*(__O uint32_t*)0x40090000U) /**< \brief (TC0) Channel Control Register (channel = 0) */ + #define REG_TC0_CMR0 (*(__IO uint32_t*)0x40090004U) /**< \brief (TC0) Channel Mode Register (channel = 0) */ + #define REG_TC0_SMMR0 (*(__IO uint32_t*)0x40090008U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC0_RAB0 (*(__I uint32_t*)0x4009000CU) /**< \brief (TC0) Register AB (channel = 0) */ + #define REG_TC0_CV0 (*(__I uint32_t*)0x40090010U) /**< \brief (TC0) Counter Value (channel = 0) */ + #define REG_TC0_RA0 (*(__IO uint32_t*)0x40090014U) /**< \brief (TC0) Register A (channel = 0) */ + #define REG_TC0_RB0 (*(__IO uint32_t*)0x40090018U) /**< \brief (TC0) Register B (channel = 0) */ + #define REG_TC0_RC0 (*(__IO uint32_t*)0x4009001CU) /**< \brief (TC0) Register C (channel = 0) */ + #define REG_TC0_SR0 (*(__I uint32_t*)0x40090020U) /**< \brief (TC0) Status Register (channel = 0) */ + #define REG_TC0_IER0 (*(__O uint32_t*)0x40090024U) /**< \brief (TC0) Interrupt Enable Register (channel = 0) */ + #define REG_TC0_IDR0 (*(__O uint32_t*)0x40090028U) /**< \brief (TC0) Interrupt Disable Register (channel = 0) */ + #define REG_TC0_IMR0 (*(__I uint32_t*)0x4009002CU) /**< \brief (TC0) Interrupt Mask Register (channel = 0) */ + #define REG_TC0_EMR0 (*(__IO uint32_t*)0x40090030U) /**< \brief (TC0) Extended Mode Register (channel = 0) */ + #define REG_TC0_CCR1 (*(__O uint32_t*)0x40090040U) /**< \brief (TC0) Channel Control Register (channel = 1) */ + #define REG_TC0_CMR1 (*(__IO uint32_t*)0x40090044U) /**< \brief (TC0) Channel Mode Register (channel = 1) */ + #define REG_TC0_SMMR1 (*(__IO uint32_t*)0x40090048U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC0_RAB1 (*(__I uint32_t*)0x4009004CU) /**< \brief (TC0) Register AB (channel = 1) */ + #define REG_TC0_CV1 (*(__I uint32_t*)0x40090050U) /**< \brief (TC0) Counter Value (channel = 1) */ + #define REG_TC0_RA1 (*(__IO uint32_t*)0x40090054U) /**< \brief (TC0) Register A (channel = 1) */ + #define REG_TC0_RB1 (*(__IO uint32_t*)0x40090058U) /**< \brief (TC0) Register B (channel = 1) */ + #define REG_TC0_RC1 (*(__IO uint32_t*)0x4009005CU) /**< \brief (TC0) Register C (channel = 1) */ + #define REG_TC0_SR1 (*(__I uint32_t*)0x40090060U) /**< \brief (TC0) Status Register (channel = 1) */ + #define REG_TC0_IER1 (*(__O uint32_t*)0x40090064U) /**< \brief (TC0) Interrupt Enable Register (channel = 1) */ + #define REG_TC0_IDR1 (*(__O uint32_t*)0x40090068U) /**< \brief (TC0) Interrupt Disable Register (channel = 1) */ + #define REG_TC0_IMR1 (*(__I uint32_t*)0x4009006CU) /**< \brief (TC0) Interrupt Mask Register (channel = 1) */ + #define REG_TC0_EMR1 (*(__IO uint32_t*)0x40090070U) /**< \brief (TC0) Extended Mode Register (channel = 1) */ + #define REG_TC0_CCR2 (*(__O uint32_t*)0x40090080U) /**< \brief (TC0) Channel Control Register (channel = 2) */ + #define REG_TC0_CMR2 (*(__IO uint32_t*)0x40090084U) /**< \brief (TC0) Channel Mode Register (channel = 2) */ + #define REG_TC0_SMMR2 (*(__IO uint32_t*)0x40090088U) /**< \brief (TC0) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC0_RAB2 (*(__I uint32_t*)0x4009008CU) /**< \brief (TC0) Register AB (channel = 2) */ + #define REG_TC0_CV2 (*(__I uint32_t*)0x40090090U) /**< \brief (TC0) Counter Value (channel = 2) */ + #define REG_TC0_RA2 (*(__IO uint32_t*)0x40090094U) /**< \brief (TC0) Register A (channel = 2) */ + #define REG_TC0_RB2 (*(__IO uint32_t*)0x40090098U) /**< \brief (TC0) Register B (channel = 2) */ + #define REG_TC0_RC2 (*(__IO uint32_t*)0x4009009CU) /**< \brief (TC0) Register C (channel = 2) */ + #define REG_TC0_SR2 (*(__I uint32_t*)0x400900A0U) /**< \brief (TC0) Status Register (channel = 2) */ + #define REG_TC0_IER2 (*(__O uint32_t*)0x400900A4U) /**< \brief (TC0) Interrupt Enable Register (channel = 2) */ + #define REG_TC0_IDR2 (*(__O uint32_t*)0x400900A8U) /**< \brief (TC0) Interrupt Disable Register (channel = 2) */ + #define REG_TC0_IMR2 (*(__I uint32_t*)0x400900ACU) /**< \brief (TC0) Interrupt Mask Register (channel = 2) */ + #define REG_TC0_EMR2 (*(__IO uint32_t*)0x400900B0U) /**< \brief (TC0) Extended Mode Register (channel = 2) */ + #define REG_TC0_BCR (*(__O uint32_t*)0x400900C0U) /**< \brief (TC0) Block Control Register */ + #define REG_TC0_BMR (*(__IO uint32_t*)0x400900C4U) /**< \brief (TC0) Block Mode Register */ + #define REG_TC0_QIER (*(__O uint32_t*)0x400900C8U) /**< \brief (TC0) QDEC Interrupt Enable Register */ + #define REG_TC0_QIDR (*(__O uint32_t*)0x400900CCU) /**< \brief (TC0) QDEC Interrupt Disable Register */ + #define REG_TC0_QIMR (*(__I uint32_t*)0x400900D0U) /**< \brief (TC0) QDEC Interrupt Mask Register */ + #define REG_TC0_QISR (*(__I uint32_t*)0x400900D4U) /**< \brief (TC0) QDEC Interrupt Status Register */ + #define REG_TC0_FMR (*(__IO uint32_t*)0x400900D8U) /**< \brief (TC0) Fault Mode Register */ + #define REG_TC0_WPMR (*(__IO uint32_t*)0x400900E4U) /**< \brief (TC0) Write Protection Mode Register */ + #define REG_TC0_RPR0 (*(__IO uint32_t*)0x40090100U) /**< \brief (TC0) Receive Pointer Register (pdc = 0) */ + #define REG_TC0_RCR0 (*(__IO uint32_t*)0x40090104U) /**< \brief (TC0) Receive Counter Register (pdc = 0) */ + #define REG_TC0_RNPR0 (*(__IO uint32_t*)0x40090110U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 0) */ + #define REG_TC0_RNCR0 (*(__IO uint32_t*)0x40090114U) /**< \brief (TC0) Receive Next Counter Register (pdc = 0) */ + #define REG_TC0_PTCR0 (*(__O uint32_t*)0x40090120U) /**< \brief (TC0) Transfer Control Register (pdc = 0) */ + #define REG_TC0_PTSR0 (*(__I uint32_t*)0x40090124U) /**< \brief (TC0) Transfer Status Register (pdc = 0) */ + #define REG_TC0_RPR1 (*(__IO uint32_t*)0x40090140U) /**< \brief (TC0) Receive Pointer Register (pdc = 1) */ + #define REG_TC0_RCR1 (*(__IO uint32_t*)0x40090144U) /**< \brief (TC0) Receive Counter Register (pdc = 1) */ + #define REG_TC0_RNPR1 (*(__IO uint32_t*)0x40090150U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 1) */ + #define REG_TC0_RNCR1 (*(__IO uint32_t*)0x40090154U) /**< \brief (TC0) Receive Next Counter Register (pdc = 1) */ + #define REG_TC0_PTCR1 (*(__O uint32_t*)0x40090160U) /**< \brief (TC0) Transfer Control Register (pdc = 1) */ + #define REG_TC0_PTSR1 (*(__I uint32_t*)0x40090164U) /**< \brief (TC0) Transfer Status Register (pdc = 1) */ + #define REG_TC0_RPR2 (*(__IO uint32_t*)0x40090180U) /**< \brief (TC0) Receive Pointer Register (pdc = 2) */ + #define REG_TC0_RCR2 (*(__IO uint32_t*)0x40090184U) /**< \brief (TC0) Receive Counter Register (pdc = 2) */ + #define REG_TC0_RNPR2 (*(__IO uint32_t*)0x40090190U) /**< \brief (TC0) Receive Next Pointer Register (pdc = 2) */ + #define REG_TC0_RNCR2 (*(__IO uint32_t*)0x40090194U) /**< \brief (TC0) Receive Next Counter Register (pdc = 2) */ + #define REG_TC0_PTCR2 (*(__O uint32_t*)0x400901A0U) /**< \brief (TC0) Transfer Control Register (pdc = 2) */ + #define REG_TC0_PTSR2 (*(__I uint32_t*)0x400901A4U) /**< \brief (TC0) Transfer Status Register (pdc = 2) */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_TC0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc1.h new file mode 100644 index 0000000..a402e7c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc1.h @@ -0,0 +1,183 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TC1_INSTANCE_ +#define _SAM4E_TC1_INSTANCE_ + +/* ========== Register definition for TC1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_TC1_CCR0 (0x40094000U) /**< \brief (TC1) Channel Control Register (channel = 0) */ + #define REG_TC1_CMR0 (0x40094004U) /**< \brief (TC1) Channel Mode Register (channel = 0) */ + #define REG_TC1_SMMR0 (0x40094008U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC1_RAB0 (0x4009400CU) /**< \brief (TC1) Register AB (channel = 0) */ + #define REG_TC1_CV0 (0x40094010U) /**< \brief (TC1) Counter Value (channel = 0) */ + #define REG_TC1_RA0 (0x40094014U) /**< \brief (TC1) Register A (channel = 0) */ + #define REG_TC1_RB0 (0x40094018U) /**< \brief (TC1) Register B (channel = 0) */ + #define REG_TC1_RC0 (0x4009401CU) /**< \brief (TC1) Register C (channel = 0) */ + #define REG_TC1_SR0 (0x40094020U) /**< \brief (TC1) Status Register (channel = 0) */ + #define REG_TC1_IER0 (0x40094024U) /**< \brief (TC1) Interrupt Enable Register (channel = 0) */ + #define REG_TC1_IDR0 (0x40094028U) /**< \brief (TC1) Interrupt Disable Register (channel = 0) */ + #define REG_TC1_IMR0 (0x4009402CU) /**< \brief (TC1) Interrupt Mask Register (channel = 0) */ + #define REG_TC1_EMR0 (0x40094030U) /**< \brief (TC1) Extended Mode Register (channel = 0) */ + #define REG_TC1_CCR1 (0x40094040U) /**< \brief (TC1) Channel Control Register (channel = 1) */ + #define REG_TC1_CMR1 (0x40094044U) /**< \brief (TC1) Channel Mode Register (channel = 1) */ + #define REG_TC1_SMMR1 (0x40094048U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC1_RAB1 (0x4009404CU) /**< \brief (TC1) Register AB (channel = 1) */ + #define REG_TC1_CV1 (0x40094050U) /**< \brief (TC1) Counter Value (channel = 1) */ + #define REG_TC1_RA1 (0x40094054U) /**< \brief (TC1) Register A (channel = 1) */ + #define REG_TC1_RB1 (0x40094058U) /**< \brief (TC1) Register B (channel = 1) */ + #define REG_TC1_RC1 (0x4009405CU) /**< \brief (TC1) Register C (channel = 1) */ + #define REG_TC1_SR1 (0x40094060U) /**< \brief (TC1) Status Register (channel = 1) */ + #define REG_TC1_IER1 (0x40094064U) /**< \brief (TC1) Interrupt Enable Register (channel = 1) */ + #define REG_TC1_IDR1 (0x40094068U) /**< \brief (TC1) Interrupt Disable Register (channel = 1) */ + #define REG_TC1_IMR1 (0x4009406CU) /**< \brief (TC1) Interrupt Mask Register (channel = 1) */ + #define REG_TC1_EMR1 (0x40094070U) /**< \brief (TC1) Extended Mode Register (channel = 1) */ + #define REG_TC1_CCR2 (0x40094080U) /**< \brief (TC1) Channel Control Register (channel = 2) */ + #define REG_TC1_CMR2 (0x40094084U) /**< \brief (TC1) Channel Mode Register (channel = 2) */ + #define REG_TC1_SMMR2 (0x40094088U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC1_RAB2 (0x4009408CU) /**< \brief (TC1) Register AB (channel = 2) */ + #define REG_TC1_CV2 (0x40094090U) /**< \brief (TC1) Counter Value (channel = 2) */ + #define REG_TC1_RA2 (0x40094094U) /**< \brief (TC1) Register A (channel = 2) */ + #define REG_TC1_RB2 (0x40094098U) /**< \brief (TC1) Register B (channel = 2) */ + #define REG_TC1_RC2 (0x4009409CU) /**< \brief (TC1) Register C (channel = 2) */ + #define REG_TC1_SR2 (0x400940A0U) /**< \brief (TC1) Status Register (channel = 2) */ + #define REG_TC1_IER2 (0x400940A4U) /**< \brief (TC1) Interrupt Enable Register (channel = 2) */ + #define REG_TC1_IDR2 (0x400940A8U) /**< \brief (TC1) Interrupt Disable Register (channel = 2) */ + #define REG_TC1_IMR2 (0x400940ACU) /**< \brief (TC1) Interrupt Mask Register (channel = 2) */ + #define REG_TC1_EMR2 (0x400940B0U) /**< \brief (TC1) Extended Mode Register (channel = 2) */ + #define REG_TC1_BCR (0x400940C0U) /**< \brief (TC1) Block Control Register */ + #define REG_TC1_BMR (0x400940C4U) /**< \brief (TC1) Block Mode Register */ + #define REG_TC1_QIER (0x400940C8U) /**< \brief (TC1) QDEC Interrupt Enable Register */ + #define REG_TC1_QIDR (0x400940CCU) /**< \brief (TC1) QDEC Interrupt Disable Register */ + #define REG_TC1_QIMR (0x400940D0U) /**< \brief (TC1) QDEC Interrupt Mask Register */ + #define REG_TC1_QISR (0x400940D4U) /**< \brief (TC1) QDEC Interrupt Status Register */ + #define REG_TC1_FMR (0x400940D8U) /**< \brief (TC1) Fault Mode Register */ + #define REG_TC1_WPMR (0x400940E4U) /**< \brief (TC1) Write Protection Mode Register */ + #define REG_TC1_RPR0 (0x40094100U) /**< \brief (TC1) Receive Pointer Register (pdc = 0) */ + #define REG_TC1_RCR0 (0x40094104U) /**< \brief (TC1) Receive Counter Register (pdc = 0) */ + #define REG_TC1_RNPR0 (0x40094110U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 0) */ + #define REG_TC1_RNCR0 (0x40094114U) /**< \brief (TC1) Receive Next Counter Register (pdc = 0) */ + #define REG_TC1_PTCR0 (0x40094120U) /**< \brief (TC1) Transfer Control Register (pdc = 0) */ + #define REG_TC1_PTSR0 (0x40094124U) /**< \brief (TC1) Transfer Status Register (pdc = 0) */ + #define REG_TC1_RPR1 (0x40094140U) /**< \brief (TC1) Receive Pointer Register (pdc = 1) */ + #define REG_TC1_RCR1 (0x40094144U) /**< \brief (TC1) Receive Counter Register (pdc = 1) */ + #define REG_TC1_RNPR1 (0x40094150U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 1) */ + #define REG_TC1_RNCR1 (0x40094154U) /**< \brief (TC1) Receive Next Counter Register (pdc = 1) */ + #define REG_TC1_PTCR1 (0x40094160U) /**< \brief (TC1) Transfer Control Register (pdc = 1) */ + #define REG_TC1_PTSR1 (0x40094164U) /**< \brief (TC1) Transfer Status Register (pdc = 1) */ + #define REG_TC1_RPR2 (0x40094180U) /**< \brief (TC1) Receive Pointer Register (pdc = 2) */ + #define REG_TC1_RCR2 (0x40094184U) /**< \brief (TC1) Receive Counter Register (pdc = 2) */ + #define REG_TC1_RNPR2 (0x40094190U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 2) */ + #define REG_TC1_RNCR2 (0x40094194U) /**< \brief (TC1) Receive Next Counter Register (pdc = 2) */ + #define REG_TC1_PTCR2 (0x400941A0U) /**< \brief (TC1) Transfer Control Register (pdc = 2) */ + #define REG_TC1_PTSR2 (0x400941A4U) /**< \brief (TC1) Transfer Status Register (pdc = 2) */ +#else + #define REG_TC1_CCR0 (*(__O uint32_t*)0x40094000U) /**< \brief (TC1) Channel Control Register (channel = 0) */ + #define REG_TC1_CMR0 (*(__IO uint32_t*)0x40094004U) /**< \brief (TC1) Channel Mode Register (channel = 0) */ + #define REG_TC1_SMMR0 (*(__IO uint32_t*)0x40094008U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC1_RAB0 (*(__I uint32_t*)0x4009400CU) /**< \brief (TC1) Register AB (channel = 0) */ + #define REG_TC1_CV0 (*(__I uint32_t*)0x40094010U) /**< \brief (TC1) Counter Value (channel = 0) */ + #define REG_TC1_RA0 (*(__IO uint32_t*)0x40094014U) /**< \brief (TC1) Register A (channel = 0) */ + #define REG_TC1_RB0 (*(__IO uint32_t*)0x40094018U) /**< \brief (TC1) Register B (channel = 0) */ + #define REG_TC1_RC0 (*(__IO uint32_t*)0x4009401CU) /**< \brief (TC1) Register C (channel = 0) */ + #define REG_TC1_SR0 (*(__I uint32_t*)0x40094020U) /**< \brief (TC1) Status Register (channel = 0) */ + #define REG_TC1_IER0 (*(__O uint32_t*)0x40094024U) /**< \brief (TC1) Interrupt Enable Register (channel = 0) */ + #define REG_TC1_IDR0 (*(__O uint32_t*)0x40094028U) /**< \brief (TC1) Interrupt Disable Register (channel = 0) */ + #define REG_TC1_IMR0 (*(__I uint32_t*)0x4009402CU) /**< \brief (TC1) Interrupt Mask Register (channel = 0) */ + #define REG_TC1_EMR0 (*(__IO uint32_t*)0x40094030U) /**< \brief (TC1) Extended Mode Register (channel = 0) */ + #define REG_TC1_CCR1 (*(__O uint32_t*)0x40094040U) /**< \brief (TC1) Channel Control Register (channel = 1) */ + #define REG_TC1_CMR1 (*(__IO uint32_t*)0x40094044U) /**< \brief (TC1) Channel Mode Register (channel = 1) */ + #define REG_TC1_SMMR1 (*(__IO uint32_t*)0x40094048U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC1_RAB1 (*(__I uint32_t*)0x4009404CU) /**< \brief (TC1) Register AB (channel = 1) */ + #define REG_TC1_CV1 (*(__I uint32_t*)0x40094050U) /**< \brief (TC1) Counter Value (channel = 1) */ + #define REG_TC1_RA1 (*(__IO uint32_t*)0x40094054U) /**< \brief (TC1) Register A (channel = 1) */ + #define REG_TC1_RB1 (*(__IO uint32_t*)0x40094058U) /**< \brief (TC1) Register B (channel = 1) */ + #define REG_TC1_RC1 (*(__IO uint32_t*)0x4009405CU) /**< \brief (TC1) Register C (channel = 1) */ + #define REG_TC1_SR1 (*(__I uint32_t*)0x40094060U) /**< \brief (TC1) Status Register (channel = 1) */ + #define REG_TC1_IER1 (*(__O uint32_t*)0x40094064U) /**< \brief (TC1) Interrupt Enable Register (channel = 1) */ + #define REG_TC1_IDR1 (*(__O uint32_t*)0x40094068U) /**< \brief (TC1) Interrupt Disable Register (channel = 1) */ + #define REG_TC1_IMR1 (*(__I uint32_t*)0x4009406CU) /**< \brief (TC1) Interrupt Mask Register (channel = 1) */ + #define REG_TC1_EMR1 (*(__IO uint32_t*)0x40094070U) /**< \brief (TC1) Extended Mode Register (channel = 1) */ + #define REG_TC1_CCR2 (*(__O uint32_t*)0x40094080U) /**< \brief (TC1) Channel Control Register (channel = 2) */ + #define REG_TC1_CMR2 (*(__IO uint32_t*)0x40094084U) /**< \brief (TC1) Channel Mode Register (channel = 2) */ + #define REG_TC1_SMMR2 (*(__IO uint32_t*)0x40094088U) /**< \brief (TC1) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC1_RAB2 (*(__I uint32_t*)0x4009408CU) /**< \brief (TC1) Register AB (channel = 2) */ + #define REG_TC1_CV2 (*(__I uint32_t*)0x40094090U) /**< \brief (TC1) Counter Value (channel = 2) */ + #define REG_TC1_RA2 (*(__IO uint32_t*)0x40094094U) /**< \brief (TC1) Register A (channel = 2) */ + #define REG_TC1_RB2 (*(__IO uint32_t*)0x40094098U) /**< \brief (TC1) Register B (channel = 2) */ + #define REG_TC1_RC2 (*(__IO uint32_t*)0x4009409CU) /**< \brief (TC1) Register C (channel = 2) */ + #define REG_TC1_SR2 (*(__I uint32_t*)0x400940A0U) /**< \brief (TC1) Status Register (channel = 2) */ + #define REG_TC1_IER2 (*(__O uint32_t*)0x400940A4U) /**< \brief (TC1) Interrupt Enable Register (channel = 2) */ + #define REG_TC1_IDR2 (*(__O uint32_t*)0x400940A8U) /**< \brief (TC1) Interrupt Disable Register (channel = 2) */ + #define REG_TC1_IMR2 (*(__I uint32_t*)0x400940ACU) /**< \brief (TC1) Interrupt Mask Register (channel = 2) */ + #define REG_TC1_EMR2 (*(__IO uint32_t*)0x400940B0U) /**< \brief (TC1) Extended Mode Register (channel = 2) */ + #define REG_TC1_BCR (*(__O uint32_t*)0x400940C0U) /**< \brief (TC1) Block Control Register */ + #define REG_TC1_BMR (*(__IO uint32_t*)0x400940C4U) /**< \brief (TC1) Block Mode Register */ + #define REG_TC1_QIER (*(__O uint32_t*)0x400940C8U) /**< \brief (TC1) QDEC Interrupt Enable Register */ + #define REG_TC1_QIDR (*(__O uint32_t*)0x400940CCU) /**< \brief (TC1) QDEC Interrupt Disable Register */ + #define REG_TC1_QIMR (*(__I uint32_t*)0x400940D0U) /**< \brief (TC1) QDEC Interrupt Mask Register */ + #define REG_TC1_QISR (*(__I uint32_t*)0x400940D4U) /**< \brief (TC1) QDEC Interrupt Status Register */ + #define REG_TC1_FMR (*(__IO uint32_t*)0x400940D8U) /**< \brief (TC1) Fault Mode Register */ + #define REG_TC1_WPMR (*(__IO uint32_t*)0x400940E4U) /**< \brief (TC1) Write Protection Mode Register */ + #define REG_TC1_RPR0 (*(__IO uint32_t*)0x40094100U) /**< \brief (TC1) Receive Pointer Register (pdc = 0) */ + #define REG_TC1_RCR0 (*(__IO uint32_t*)0x40094104U) /**< \brief (TC1) Receive Counter Register (pdc = 0) */ + #define REG_TC1_RNPR0 (*(__IO uint32_t*)0x40094110U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 0) */ + #define REG_TC1_RNCR0 (*(__IO uint32_t*)0x40094114U) /**< \brief (TC1) Receive Next Counter Register (pdc = 0) */ + #define REG_TC1_PTCR0 (*(__O uint32_t*)0x40094120U) /**< \brief (TC1) Transfer Control Register (pdc = 0) */ + #define REG_TC1_PTSR0 (*(__I uint32_t*)0x40094124U) /**< \brief (TC1) Transfer Status Register (pdc = 0) */ + #define REG_TC1_RPR1 (*(__IO uint32_t*)0x40094140U) /**< \brief (TC1) Receive Pointer Register (pdc = 1) */ + #define REG_TC1_RCR1 (*(__IO uint32_t*)0x40094144U) /**< \brief (TC1) Receive Counter Register (pdc = 1) */ + #define REG_TC1_RNPR1 (*(__IO uint32_t*)0x40094150U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 1) */ + #define REG_TC1_RNCR1 (*(__IO uint32_t*)0x40094154U) /**< \brief (TC1) Receive Next Counter Register (pdc = 1) */ + #define REG_TC1_PTCR1 (*(__O uint32_t*)0x40094160U) /**< \brief (TC1) Transfer Control Register (pdc = 1) */ + #define REG_TC1_PTSR1 (*(__I uint32_t*)0x40094164U) /**< \brief (TC1) Transfer Status Register (pdc = 1) */ + #define REG_TC1_RPR2 (*(__IO uint32_t*)0x40094180U) /**< \brief (TC1) Receive Pointer Register (pdc = 2) */ + #define REG_TC1_RCR2 (*(__IO uint32_t*)0x40094184U) /**< \brief (TC1) Receive Counter Register (pdc = 2) */ + #define REG_TC1_RNPR2 (*(__IO uint32_t*)0x40094190U) /**< \brief (TC1) Receive Next Pointer Register (pdc = 2) */ + #define REG_TC1_RNCR2 (*(__IO uint32_t*)0x40094194U) /**< \brief (TC1) Receive Next Counter Register (pdc = 2) */ + #define REG_TC1_PTCR2 (*(__O uint32_t*)0x400941A0U) /**< \brief (TC1) Transfer Control Register (pdc = 2) */ + #define REG_TC1_PTSR2 (*(__I uint32_t*)0x400941A4U) /**< \brief (TC1) Transfer Status Register (pdc = 2) */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_TC1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc2.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc2.h new file mode 100644 index 0000000..a3b506c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/tc2.h @@ -0,0 +1,147 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TC2_INSTANCE_ +#define _SAM4E_TC2_INSTANCE_ + +/* ========== Register definition for TC2 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_TC2_CCR0 (0x40098000U) /**< \brief (TC2) Channel Control Register (channel = 0) */ + #define REG_TC2_CMR0 (0x40098004U) /**< \brief (TC2) Channel Mode Register (channel = 0) */ + #define REG_TC2_SMMR0 (0x40098008U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC2_RAB0 (0x4009800CU) /**< \brief (TC2) Register AB (channel = 0) */ + #define REG_TC2_CV0 (0x40098010U) /**< \brief (TC2) Counter Value (channel = 0) */ + #define REG_TC2_RA0 (0x40098014U) /**< \brief (TC2) Register A (channel = 0) */ + #define REG_TC2_RB0 (0x40098018U) /**< \brief (TC2) Register B (channel = 0) */ + #define REG_TC2_RC0 (0x4009801CU) /**< \brief (TC2) Register C (channel = 0) */ + #define REG_TC2_SR0 (0x40098020U) /**< \brief (TC2) Status Register (channel = 0) */ + #define REG_TC2_IER0 (0x40098024U) /**< \brief (TC2) Interrupt Enable Register (channel = 0) */ + #define REG_TC2_IDR0 (0x40098028U) /**< \brief (TC2) Interrupt Disable Register (channel = 0) */ + #define REG_TC2_IMR0 (0x4009802CU) /**< \brief (TC2) Interrupt Mask Register (channel = 0) */ + #define REG_TC2_EMR0 (0x40098030U) /**< \brief (TC2) Extended Mode Register (channel = 0) */ + #define REG_TC2_CCR1 (0x40098040U) /**< \brief (TC2) Channel Control Register (channel = 1) */ + #define REG_TC2_CMR1 (0x40098044U) /**< \brief (TC2) Channel Mode Register (channel = 1) */ + #define REG_TC2_SMMR1 (0x40098048U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC2_RAB1 (0x4009804CU) /**< \brief (TC2) Register AB (channel = 1) */ + #define REG_TC2_CV1 (0x40098050U) /**< \brief (TC2) Counter Value (channel = 1) */ + #define REG_TC2_RA1 (0x40098054U) /**< \brief (TC2) Register A (channel = 1) */ + #define REG_TC2_RB1 (0x40098058U) /**< \brief (TC2) Register B (channel = 1) */ + #define REG_TC2_RC1 (0x4009805CU) /**< \brief (TC2) Register C (channel = 1) */ + #define REG_TC2_SR1 (0x40098060U) /**< \brief (TC2) Status Register (channel = 1) */ + #define REG_TC2_IER1 (0x40098064U) /**< \brief (TC2) Interrupt Enable Register (channel = 1) */ + #define REG_TC2_IDR1 (0x40098068U) /**< \brief (TC2) Interrupt Disable Register (channel = 1) */ + #define REG_TC2_IMR1 (0x4009806CU) /**< \brief (TC2) Interrupt Mask Register (channel = 1) */ + #define REG_TC2_EMR1 (0x40098070U) /**< \brief (TC2) Extended Mode Register (channel = 1) */ + #define REG_TC2_CCR2 (0x40098080U) /**< \brief (TC2) Channel Control Register (channel = 2) */ + #define REG_TC2_CMR2 (0x40098084U) /**< \brief (TC2) Channel Mode Register (channel = 2) */ + #define REG_TC2_SMMR2 (0x40098088U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC2_RAB2 (0x4009808CU) /**< \brief (TC2) Register AB (channel = 2) */ + #define REG_TC2_CV2 (0x40098090U) /**< \brief (TC2) Counter Value (channel = 2) */ + #define REG_TC2_RA2 (0x40098094U) /**< \brief (TC2) Register A (channel = 2) */ + #define REG_TC2_RB2 (0x40098098U) /**< \brief (TC2) Register B (channel = 2) */ + #define REG_TC2_RC2 (0x4009809CU) /**< \brief (TC2) Register C (channel = 2) */ + #define REG_TC2_SR2 (0x400980A0U) /**< \brief (TC2) Status Register (channel = 2) */ + #define REG_TC2_IER2 (0x400980A4U) /**< \brief (TC2) Interrupt Enable Register (channel = 2) */ + #define REG_TC2_IDR2 (0x400980A8U) /**< \brief (TC2) Interrupt Disable Register (channel = 2) */ + #define REG_TC2_IMR2 (0x400980ACU) /**< \brief (TC2) Interrupt Mask Register (channel = 2) */ + #define REG_TC2_EMR2 (0x400980B0U) /**< \brief (TC2) Extended Mode Register (channel = 2) */ + #define REG_TC2_BCR (0x400980C0U) /**< \brief (TC2) Block Control Register */ + #define REG_TC2_BMR (0x400980C4U) /**< \brief (TC2) Block Mode Register */ + #define REG_TC2_QIER (0x400980C8U) /**< \brief (TC2) QDEC Interrupt Enable Register */ + #define REG_TC2_QIDR (0x400980CCU) /**< \brief (TC2) QDEC Interrupt Disable Register */ + #define REG_TC2_QIMR (0x400980D0U) /**< \brief (TC2) QDEC Interrupt Mask Register */ + #define REG_TC2_QISR (0x400980D4U) /**< \brief (TC2) QDEC Interrupt Status Register */ + #define REG_TC2_FMR (0x400980D8U) /**< \brief (TC2) Fault Mode Register */ + #define REG_TC2_WPMR (0x400980E4U) /**< \brief (TC2) Write Protection Mode Register */ +#else + #define REG_TC2_CCR0 (*(__O uint32_t*)0x40098000U) /**< \brief (TC2) Channel Control Register (channel = 0) */ + #define REG_TC2_CMR0 (*(__IO uint32_t*)0x40098004U) /**< \brief (TC2) Channel Mode Register (channel = 0) */ + #define REG_TC2_SMMR0 (*(__IO uint32_t*)0x40098008U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 0) */ + #define REG_TC2_RAB0 (*(__I uint32_t*)0x4009800CU) /**< \brief (TC2) Register AB (channel = 0) */ + #define REG_TC2_CV0 (*(__I uint32_t*)0x40098010U) /**< \brief (TC2) Counter Value (channel = 0) */ + #define REG_TC2_RA0 (*(__IO uint32_t*)0x40098014U) /**< \brief (TC2) Register A (channel = 0) */ + #define REG_TC2_RB0 (*(__IO uint32_t*)0x40098018U) /**< \brief (TC2) Register B (channel = 0) */ + #define REG_TC2_RC0 (*(__IO uint32_t*)0x4009801CU) /**< \brief (TC2) Register C (channel = 0) */ + #define REG_TC2_SR0 (*(__I uint32_t*)0x40098020U) /**< \brief (TC2) Status Register (channel = 0) */ + #define REG_TC2_IER0 (*(__O uint32_t*)0x40098024U) /**< \brief (TC2) Interrupt Enable Register (channel = 0) */ + #define REG_TC2_IDR0 (*(__O uint32_t*)0x40098028U) /**< \brief (TC2) Interrupt Disable Register (channel = 0) */ + #define REG_TC2_IMR0 (*(__I uint32_t*)0x4009802CU) /**< \brief (TC2) Interrupt Mask Register (channel = 0) */ + #define REG_TC2_EMR0 (*(__IO uint32_t*)0x40098030U) /**< \brief (TC2) Extended Mode Register (channel = 0) */ + #define REG_TC2_CCR1 (*(__O uint32_t*)0x40098040U) /**< \brief (TC2) Channel Control Register (channel = 1) */ + #define REG_TC2_CMR1 (*(__IO uint32_t*)0x40098044U) /**< \brief (TC2) Channel Mode Register (channel = 1) */ + #define REG_TC2_SMMR1 (*(__IO uint32_t*)0x40098048U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 1) */ + #define REG_TC2_RAB1 (*(__I uint32_t*)0x4009804CU) /**< \brief (TC2) Register AB (channel = 1) */ + #define REG_TC2_CV1 (*(__I uint32_t*)0x40098050U) /**< \brief (TC2) Counter Value (channel = 1) */ + #define REG_TC2_RA1 (*(__IO uint32_t*)0x40098054U) /**< \brief (TC2) Register A (channel = 1) */ + #define REG_TC2_RB1 (*(__IO uint32_t*)0x40098058U) /**< \brief (TC2) Register B (channel = 1) */ + #define REG_TC2_RC1 (*(__IO uint32_t*)0x4009805CU) /**< \brief (TC2) Register C (channel = 1) */ + #define REG_TC2_SR1 (*(__I uint32_t*)0x40098060U) /**< \brief (TC2) Status Register (channel = 1) */ + #define REG_TC2_IER1 (*(__O uint32_t*)0x40098064U) /**< \brief (TC2) Interrupt Enable Register (channel = 1) */ + #define REG_TC2_IDR1 (*(__O uint32_t*)0x40098068U) /**< \brief (TC2) Interrupt Disable Register (channel = 1) */ + #define REG_TC2_IMR1 (*(__I uint32_t*)0x4009806CU) /**< \brief (TC2) Interrupt Mask Register (channel = 1) */ + #define REG_TC2_EMR1 (*(__IO uint32_t*)0x40098070U) /**< \brief (TC2) Extended Mode Register (channel = 1) */ + #define REG_TC2_CCR2 (*(__O uint32_t*)0x40098080U) /**< \brief (TC2) Channel Control Register (channel = 2) */ + #define REG_TC2_CMR2 (*(__IO uint32_t*)0x40098084U) /**< \brief (TC2) Channel Mode Register (channel = 2) */ + #define REG_TC2_SMMR2 (*(__IO uint32_t*)0x40098088U) /**< \brief (TC2) Stepper Motor Mode Register (channel = 2) */ + #define REG_TC2_RAB2 (*(__I uint32_t*)0x4009808CU) /**< \brief (TC2) Register AB (channel = 2) */ + #define REG_TC2_CV2 (*(__I uint32_t*)0x40098090U) /**< \brief (TC2) Counter Value (channel = 2) */ + #define REG_TC2_RA2 (*(__IO uint32_t*)0x40098094U) /**< \brief (TC2) Register A (channel = 2) */ + #define REG_TC2_RB2 (*(__IO uint32_t*)0x40098098U) /**< \brief (TC2) Register B (channel = 2) */ + #define REG_TC2_RC2 (*(__IO uint32_t*)0x4009809CU) /**< \brief (TC2) Register C (channel = 2) */ + #define REG_TC2_SR2 (*(__I uint32_t*)0x400980A0U) /**< \brief (TC2) Status Register (channel = 2) */ + #define REG_TC2_IER2 (*(__O uint32_t*)0x400980A4U) /**< \brief (TC2) Interrupt Enable Register (channel = 2) */ + #define REG_TC2_IDR2 (*(__O uint32_t*)0x400980A8U) /**< \brief (TC2) Interrupt Disable Register (channel = 2) */ + #define REG_TC2_IMR2 (*(__I uint32_t*)0x400980ACU) /**< \brief (TC2) Interrupt Mask Register (channel = 2) */ + #define REG_TC2_EMR2 (*(__IO uint32_t*)0x400980B0U) /**< \brief (TC2) Extended Mode Register (channel = 2) */ + #define REG_TC2_BCR (*(__O uint32_t*)0x400980C0U) /**< \brief (TC2) Block Control Register */ + #define REG_TC2_BMR (*(__IO uint32_t*)0x400980C4U) /**< \brief (TC2) Block Mode Register */ + #define REG_TC2_QIER (*(__O uint32_t*)0x400980C8U) /**< \brief (TC2) QDEC Interrupt Enable Register */ + #define REG_TC2_QIDR (*(__O uint32_t*)0x400980CCU) /**< \brief (TC2) QDEC Interrupt Disable Register */ + #define REG_TC2_QIMR (*(__I uint32_t*)0x400980D0U) /**< \brief (TC2) QDEC Interrupt Mask Register */ + #define REG_TC2_QISR (*(__I uint32_t*)0x400980D4U) /**< \brief (TC2) QDEC Interrupt Status Register */ + #define REG_TC2_FMR (*(__IO uint32_t*)0x400980D8U) /**< \brief (TC2) Fault Mode Register */ + #define REG_TC2_WPMR (*(__IO uint32_t*)0x400980E4U) /**< \brief (TC2) Write Protection Mode Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_TC2_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi0.h new file mode 100644 index 0000000..c2ba95c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi0.h @@ -0,0 +1,99 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TWI0_INSTANCE_ +#define _SAM4E_TWI0_INSTANCE_ + +/* ========== Register definition for TWI0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_TWI0_CR (0x400A8000U) /**< \brief (TWI0) Control Register */ + #define REG_TWI0_MMR (0x400A8004U) /**< \brief (TWI0) Master Mode Register */ + #define REG_TWI0_SMR (0x400A8008U) /**< \brief (TWI0) Slave Mode Register */ + #define REG_TWI0_IADR (0x400A800CU) /**< \brief (TWI0) Internal Address Register */ + #define REG_TWI0_CWGR (0x400A8010U) /**< \brief (TWI0) Clock Waveform Generator Register */ + #define REG_TWI0_SR (0x400A8020U) /**< \brief (TWI0) Status Register */ + #define REG_TWI0_IER (0x400A8024U) /**< \brief (TWI0) Interrupt Enable Register */ + #define REG_TWI0_IDR (0x400A8028U) /**< \brief (TWI0) Interrupt Disable Register */ + #define REG_TWI0_IMR (0x400A802CU) /**< \brief (TWI0) Interrupt Mask Register */ + #define REG_TWI0_RHR (0x400A8030U) /**< \brief (TWI0) Receive Holding Register */ + #define REG_TWI0_THR (0x400A8034U) /**< \brief (TWI0) Transmit Holding Register */ + #define REG_TWI0_WPMR (0x400A80E4U) /**< \brief (TWI0) Write Protection Mode Register */ + #define REG_TWI0_WPSR (0x400A80E8U) /**< \brief (TWI0) Write Protection Status Register */ + #define REG_TWI0_RPR (0x400A8100U) /**< \brief (TWI0) Receive Pointer Register */ + #define REG_TWI0_RCR (0x400A8104U) /**< \brief (TWI0) Receive Counter Register */ + #define REG_TWI0_TPR (0x400A8108U) /**< \brief (TWI0) Transmit Pointer Register */ + #define REG_TWI0_TCR (0x400A810CU) /**< \brief (TWI0) Transmit Counter Register */ + #define REG_TWI0_RNPR (0x400A8110U) /**< \brief (TWI0) Receive Next Pointer Register */ + #define REG_TWI0_RNCR (0x400A8114U) /**< \brief (TWI0) Receive Next Counter Register */ + #define REG_TWI0_TNPR (0x400A8118U) /**< \brief (TWI0) Transmit Next Pointer Register */ + #define REG_TWI0_TNCR (0x400A811CU) /**< \brief (TWI0) Transmit Next Counter Register */ + #define REG_TWI0_PTCR (0x400A8120U) /**< \brief (TWI0) Transfer Control Register */ + #define REG_TWI0_PTSR (0x400A8124U) /**< \brief (TWI0) Transfer Status Register */ +#else + #define REG_TWI0_CR (*(__O uint32_t*)0x400A8000U) /**< \brief (TWI0) Control Register */ + #define REG_TWI0_MMR (*(__IO uint32_t*)0x400A8004U) /**< \brief (TWI0) Master Mode Register */ + #define REG_TWI0_SMR (*(__IO uint32_t*)0x400A8008U) /**< \brief (TWI0) Slave Mode Register */ + #define REG_TWI0_IADR (*(__IO uint32_t*)0x400A800CU) /**< \brief (TWI0) Internal Address Register */ + #define REG_TWI0_CWGR (*(__IO uint32_t*)0x400A8010U) /**< \brief (TWI0) Clock Waveform Generator Register */ + #define REG_TWI0_SR (*(__I uint32_t*)0x400A8020U) /**< \brief (TWI0) Status Register */ + #define REG_TWI0_IER (*(__O uint32_t*)0x400A8024U) /**< \brief (TWI0) Interrupt Enable Register */ + #define REG_TWI0_IDR (*(__O uint32_t*)0x400A8028U) /**< \brief (TWI0) Interrupt Disable Register */ + #define REG_TWI0_IMR (*(__I uint32_t*)0x400A802CU) /**< \brief (TWI0) Interrupt Mask Register */ + #define REG_TWI0_RHR (*(__I uint32_t*)0x400A8030U) /**< \brief (TWI0) Receive Holding Register */ + #define REG_TWI0_THR (*(__O uint32_t*)0x400A8034U) /**< \brief (TWI0) Transmit Holding Register */ + #define REG_TWI0_WPMR (*(__IO uint32_t*)0x400A80E4U) /**< \brief (TWI0) Write Protection Mode Register */ + #define REG_TWI0_WPSR (*(__I uint32_t*)0x400A80E8U) /**< \brief (TWI0) Write Protection Status Register */ + #define REG_TWI0_RPR (*(__IO uint32_t*)0x400A8100U) /**< \brief (TWI0) Receive Pointer Register */ + #define REG_TWI0_RCR (*(__IO uint32_t*)0x400A8104U) /**< \brief (TWI0) Receive Counter Register */ + #define REG_TWI0_TPR (*(__IO uint32_t*)0x400A8108U) /**< \brief (TWI0) Transmit Pointer Register */ + #define REG_TWI0_TCR (*(__IO uint32_t*)0x400A810CU) /**< \brief (TWI0) Transmit Counter Register */ + #define REG_TWI0_RNPR (*(__IO uint32_t*)0x400A8110U) /**< \brief (TWI0) Receive Next Pointer Register */ + #define REG_TWI0_RNCR (*(__IO uint32_t*)0x400A8114U) /**< \brief (TWI0) Receive Next Counter Register */ + #define REG_TWI0_TNPR (*(__IO uint32_t*)0x400A8118U) /**< \brief (TWI0) Transmit Next Pointer Register */ + #define REG_TWI0_TNCR (*(__IO uint32_t*)0x400A811CU) /**< \brief (TWI0) Transmit Next Counter Register */ + #define REG_TWI0_PTCR (*(__O uint32_t*)0x400A8120U) /**< \brief (TWI0) Transfer Control Register */ + #define REG_TWI0_PTSR (*(__I uint32_t*)0x400A8124U) /**< \brief (TWI0) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_TWI0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi1.h new file mode 100644 index 0000000..cee299a --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/twi1.h @@ -0,0 +1,99 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_TWI1_INSTANCE_ +#define _SAM4E_TWI1_INSTANCE_ + +/* ========== Register definition for TWI1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_TWI1_CR (0x400AC000U) /**< \brief (TWI1) Control Register */ + #define REG_TWI1_MMR (0x400AC004U) /**< \brief (TWI1) Master Mode Register */ + #define REG_TWI1_SMR (0x400AC008U) /**< \brief (TWI1) Slave Mode Register */ + #define REG_TWI1_IADR (0x400AC00CU) /**< \brief (TWI1) Internal Address Register */ + #define REG_TWI1_CWGR (0x400AC010U) /**< \brief (TWI1) Clock Waveform Generator Register */ + #define REG_TWI1_SR (0x400AC020U) /**< \brief (TWI1) Status Register */ + #define REG_TWI1_IER (0x400AC024U) /**< \brief (TWI1) Interrupt Enable Register */ + #define REG_TWI1_IDR (0x400AC028U) /**< \brief (TWI1) Interrupt Disable Register */ + #define REG_TWI1_IMR (0x400AC02CU) /**< \brief (TWI1) Interrupt Mask Register */ + #define REG_TWI1_RHR (0x400AC030U) /**< \brief (TWI1) Receive Holding Register */ + #define REG_TWI1_THR (0x400AC034U) /**< \brief (TWI1) Transmit Holding Register */ + #define REG_TWI1_WPMR (0x400AC0E4U) /**< \brief (TWI1) Write Protection Mode Register */ + #define REG_TWI1_WPSR (0x400AC0E8U) /**< \brief (TWI1) Write Protection Status Register */ + #define REG_TWI1_RPR (0x400AC100U) /**< \brief (TWI1) Receive Pointer Register */ + #define REG_TWI1_RCR (0x400AC104U) /**< \brief (TWI1) Receive Counter Register */ + #define REG_TWI1_TPR (0x400AC108U) /**< \brief (TWI1) Transmit Pointer Register */ + #define REG_TWI1_TCR (0x400AC10CU) /**< \brief (TWI1) Transmit Counter Register */ + #define REG_TWI1_RNPR (0x400AC110U) /**< \brief (TWI1) Receive Next Pointer Register */ + #define REG_TWI1_RNCR (0x400AC114U) /**< \brief (TWI1) Receive Next Counter Register */ + #define REG_TWI1_TNPR (0x400AC118U) /**< \brief (TWI1) Transmit Next Pointer Register */ + #define REG_TWI1_TNCR (0x400AC11CU) /**< \brief (TWI1) Transmit Next Counter Register */ + #define REG_TWI1_PTCR (0x400AC120U) /**< \brief (TWI1) Transfer Control Register */ + #define REG_TWI1_PTSR (0x400AC124U) /**< \brief (TWI1) Transfer Status Register */ +#else + #define REG_TWI1_CR (*(__O uint32_t*)0x400AC000U) /**< \brief (TWI1) Control Register */ + #define REG_TWI1_MMR (*(__IO uint32_t*)0x400AC004U) /**< \brief (TWI1) Master Mode Register */ + #define REG_TWI1_SMR (*(__IO uint32_t*)0x400AC008U) /**< \brief (TWI1) Slave Mode Register */ + #define REG_TWI1_IADR (*(__IO uint32_t*)0x400AC00CU) /**< \brief (TWI1) Internal Address Register */ + #define REG_TWI1_CWGR (*(__IO uint32_t*)0x400AC010U) /**< \brief (TWI1) Clock Waveform Generator Register */ + #define REG_TWI1_SR (*(__I uint32_t*)0x400AC020U) /**< \brief (TWI1) Status Register */ + #define REG_TWI1_IER (*(__O uint32_t*)0x400AC024U) /**< \brief (TWI1) Interrupt Enable Register */ + #define REG_TWI1_IDR (*(__O uint32_t*)0x400AC028U) /**< \brief (TWI1) Interrupt Disable Register */ + #define REG_TWI1_IMR (*(__I uint32_t*)0x400AC02CU) /**< \brief (TWI1) Interrupt Mask Register */ + #define REG_TWI1_RHR (*(__I uint32_t*)0x400AC030U) /**< \brief (TWI1) Receive Holding Register */ + #define REG_TWI1_THR (*(__O uint32_t*)0x400AC034U) /**< \brief (TWI1) Transmit Holding Register */ + #define REG_TWI1_WPMR (*(__IO uint32_t*)0x400AC0E4U) /**< \brief (TWI1) Write Protection Mode Register */ + #define REG_TWI1_WPSR (*(__I uint32_t*)0x400AC0E8U) /**< \brief (TWI1) Write Protection Status Register */ + #define REG_TWI1_RPR (*(__IO uint32_t*)0x400AC100U) /**< \brief (TWI1) Receive Pointer Register */ + #define REG_TWI1_RCR (*(__IO uint32_t*)0x400AC104U) /**< \brief (TWI1) Receive Counter Register */ + #define REG_TWI1_TPR (*(__IO uint32_t*)0x400AC108U) /**< \brief (TWI1) Transmit Pointer Register */ + #define REG_TWI1_TCR (*(__IO uint32_t*)0x400AC10CU) /**< \brief (TWI1) Transmit Counter Register */ + #define REG_TWI1_RNPR (*(__IO uint32_t*)0x400AC110U) /**< \brief (TWI1) Receive Next Pointer Register */ + #define REG_TWI1_RNCR (*(__IO uint32_t*)0x400AC114U) /**< \brief (TWI1) Receive Next Counter Register */ + #define REG_TWI1_TNPR (*(__IO uint32_t*)0x400AC118U) /**< \brief (TWI1) Transmit Next Pointer Register */ + #define REG_TWI1_TNCR (*(__IO uint32_t*)0x400AC11CU) /**< \brief (TWI1) Transmit Next Counter Register */ + #define REG_TWI1_PTCR (*(__O uint32_t*)0x400AC120U) /**< \brief (TWI1) Transfer Control Register */ + #define REG_TWI1_PTSR (*(__I uint32_t*)0x400AC124U) /**< \brief (TWI1) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_TWI1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart0.h new file mode 100644 index 0000000..f1ec358 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart0.h @@ -0,0 +1,93 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_UART0_INSTANCE_ +#define _SAM4E_UART0_INSTANCE_ + +/* ========== Register definition for UART0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_UART0_CR (0x400E0600U) /**< \brief (UART0) Control Register */ + #define REG_UART0_MR (0x400E0604U) /**< \brief (UART0) Mode Register */ + #define REG_UART0_IER (0x400E0608U) /**< \brief (UART0) Interrupt Enable Register */ + #define REG_UART0_IDR (0x400E060CU) /**< \brief (UART0) Interrupt Disable Register */ + #define REG_UART0_IMR (0x400E0610U) /**< \brief (UART0) Interrupt Mask Register */ + #define REG_UART0_SR (0x400E0614U) /**< \brief (UART0) Status Register */ + #define REG_UART0_RHR (0x400E0618U) /**< \brief (UART0) Receive Holding Register */ + #define REG_UART0_THR (0x400E061CU) /**< \brief (UART0) Transmit Holding Register */ + #define REG_UART0_BRGR (0x400E0620U) /**< \brief (UART0) Baud Rate Generator Register */ + #define REG_UART0_WPMR (0x400E06E4U) /**< \brief (UART0) Write Protection Mode Register */ + #define REG_UART0_RPR (0x400E0700U) /**< \brief (UART0) Receive Pointer Register */ + #define REG_UART0_RCR (0x400E0704U) /**< \brief (UART0) Receive Counter Register */ + #define REG_UART0_TPR (0x400E0708U) /**< \brief (UART0) Transmit Pointer Register */ + #define REG_UART0_TCR (0x400E070CU) /**< \brief (UART0) Transmit Counter Register */ + #define REG_UART0_RNPR (0x400E0710U) /**< \brief (UART0) Receive Next Pointer Register */ + #define REG_UART0_RNCR (0x400E0714U) /**< \brief (UART0) Receive Next Counter Register */ + #define REG_UART0_TNPR (0x400E0718U) /**< \brief (UART0) Transmit Next Pointer Register */ + #define REG_UART0_TNCR (0x400E071CU) /**< \brief (UART0) Transmit Next Counter Register */ + #define REG_UART0_PTCR (0x400E0720U) /**< \brief (UART0) Transfer Control Register */ + #define REG_UART0_PTSR (0x400E0724U) /**< \brief (UART0) Transfer Status Register */ +#else + #define REG_UART0_CR (*(__O uint32_t*)0x400E0600U) /**< \brief (UART0) Control Register */ + #define REG_UART0_MR (*(__IO uint32_t*)0x400E0604U) /**< \brief (UART0) Mode Register */ + #define REG_UART0_IER (*(__O uint32_t*)0x400E0608U) /**< \brief (UART0) Interrupt Enable Register */ + #define REG_UART0_IDR (*(__O uint32_t*)0x400E060CU) /**< \brief (UART0) Interrupt Disable Register */ + #define REG_UART0_IMR (*(__I uint32_t*)0x400E0610U) /**< \brief (UART0) Interrupt Mask Register */ + #define REG_UART0_SR (*(__I uint32_t*)0x400E0614U) /**< \brief (UART0) Status Register */ + #define REG_UART0_RHR (*(__I uint32_t*)0x400E0618U) /**< \brief (UART0) Receive Holding Register */ + #define REG_UART0_THR (*(__O uint32_t*)0x400E061CU) /**< \brief (UART0) Transmit Holding Register */ + #define REG_UART0_BRGR (*(__IO uint32_t*)0x400E0620U) /**< \brief (UART0) Baud Rate Generator Register */ + #define REG_UART0_WPMR (*(__IO uint32_t*)0x400E06E4U) /**< \brief (UART0) Write Protection Mode Register */ + #define REG_UART0_RPR (*(__IO uint32_t*)0x400E0700U) /**< \brief (UART0) Receive Pointer Register */ + #define REG_UART0_RCR (*(__IO uint32_t*)0x400E0704U) /**< \brief (UART0) Receive Counter Register */ + #define REG_UART0_TPR (*(__IO uint32_t*)0x400E0708U) /**< \brief (UART0) Transmit Pointer Register */ + #define REG_UART0_TCR (*(__IO uint32_t*)0x400E070CU) /**< \brief (UART0) Transmit Counter Register */ + #define REG_UART0_RNPR (*(__IO uint32_t*)0x400E0710U) /**< \brief (UART0) Receive Next Pointer Register */ + #define REG_UART0_RNCR (*(__IO uint32_t*)0x400E0714U) /**< \brief (UART0) Receive Next Counter Register */ + #define REG_UART0_TNPR (*(__IO uint32_t*)0x400E0718U) /**< \brief (UART0) Transmit Next Pointer Register */ + #define REG_UART0_TNCR (*(__IO uint32_t*)0x400E071CU) /**< \brief (UART0) Transmit Next Counter Register */ + #define REG_UART0_PTCR (*(__O uint32_t*)0x400E0720U) /**< \brief (UART0) Transfer Control Register */ + #define REG_UART0_PTSR (*(__I uint32_t*)0x400E0724U) /**< \brief (UART0) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_UART0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart1.h new file mode 100644 index 0000000..3faae5e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/uart1.h @@ -0,0 +1,93 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_UART1_INSTANCE_ +#define _SAM4E_UART1_INSTANCE_ + +/* ========== Register definition for UART1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_UART1_CR (0x40060600U) /**< \brief (UART1) Control Register */ + #define REG_UART1_MR (0x40060604U) /**< \brief (UART1) Mode Register */ + #define REG_UART1_IER (0x40060608U) /**< \brief (UART1) Interrupt Enable Register */ + #define REG_UART1_IDR (0x4006060CU) /**< \brief (UART1) Interrupt Disable Register */ + #define REG_UART1_IMR (0x40060610U) /**< \brief (UART1) Interrupt Mask Register */ + #define REG_UART1_SR (0x40060614U) /**< \brief (UART1) Status Register */ + #define REG_UART1_RHR (0x40060618U) /**< \brief (UART1) Receive Holding Register */ + #define REG_UART1_THR (0x4006061CU) /**< \brief (UART1) Transmit Holding Register */ + #define REG_UART1_BRGR (0x40060620U) /**< \brief (UART1) Baud Rate Generator Register */ + #define REG_UART1_WPMR (0x400606E4U) /**< \brief (UART1) Write Protection Mode Register */ + #define REG_UART1_RPR (0x40060700U) /**< \brief (UART1) Receive Pointer Register */ + #define REG_UART1_RCR (0x40060704U) /**< \brief (UART1) Receive Counter Register */ + #define REG_UART1_TPR (0x40060708U) /**< \brief (UART1) Transmit Pointer Register */ + #define REG_UART1_TCR (0x4006070CU) /**< \brief (UART1) Transmit Counter Register */ + #define REG_UART1_RNPR (0x40060710U) /**< \brief (UART1) Receive Next Pointer Register */ + #define REG_UART1_RNCR (0x40060714U) /**< \brief (UART1) Receive Next Counter Register */ + #define REG_UART1_TNPR (0x40060718U) /**< \brief (UART1) Transmit Next Pointer Register */ + #define REG_UART1_TNCR (0x4006071CU) /**< \brief (UART1) Transmit Next Counter Register */ + #define REG_UART1_PTCR (0x40060720U) /**< \brief (UART1) Transfer Control Register */ + #define REG_UART1_PTSR (0x40060724U) /**< \brief (UART1) Transfer Status Register */ +#else + #define REG_UART1_CR (*(__O uint32_t*)0x40060600U) /**< \brief (UART1) Control Register */ + #define REG_UART1_MR (*(__IO uint32_t*)0x40060604U) /**< \brief (UART1) Mode Register */ + #define REG_UART1_IER (*(__O uint32_t*)0x40060608U) /**< \brief (UART1) Interrupt Enable Register */ + #define REG_UART1_IDR (*(__O uint32_t*)0x4006060CU) /**< \brief (UART1) Interrupt Disable Register */ + #define REG_UART1_IMR (*(__I uint32_t*)0x40060610U) /**< \brief (UART1) Interrupt Mask Register */ + #define REG_UART1_SR (*(__I uint32_t*)0x40060614U) /**< \brief (UART1) Status Register */ + #define REG_UART1_RHR (*(__I uint32_t*)0x40060618U) /**< \brief (UART1) Receive Holding Register */ + #define REG_UART1_THR (*(__O uint32_t*)0x4006061CU) /**< \brief (UART1) Transmit Holding Register */ + #define REG_UART1_BRGR (*(__IO uint32_t*)0x40060620U) /**< \brief (UART1) Baud Rate Generator Register */ + #define REG_UART1_WPMR (*(__IO uint32_t*)0x400606E4U) /**< \brief (UART1) Write Protection Mode Register */ + #define REG_UART1_RPR (*(__IO uint32_t*)0x40060700U) /**< \brief (UART1) Receive Pointer Register */ + #define REG_UART1_RCR (*(__IO uint32_t*)0x40060704U) /**< \brief (UART1) Receive Counter Register */ + #define REG_UART1_TPR (*(__IO uint32_t*)0x40060708U) /**< \brief (UART1) Transmit Pointer Register */ + #define REG_UART1_TCR (*(__IO uint32_t*)0x4006070CU) /**< \brief (UART1) Transmit Counter Register */ + #define REG_UART1_RNPR (*(__IO uint32_t*)0x40060710U) /**< \brief (UART1) Receive Next Pointer Register */ + #define REG_UART1_RNCR (*(__IO uint32_t*)0x40060714U) /**< \brief (UART1) Receive Next Counter Register */ + #define REG_UART1_TNPR (*(__IO uint32_t*)0x40060718U) /**< \brief (UART1) Transmit Next Pointer Register */ + #define REG_UART1_TNCR (*(__IO uint32_t*)0x4006071CU) /**< \brief (UART1) Transmit Next Counter Register */ + #define REG_UART1_PTCR (*(__O uint32_t*)0x40060720U) /**< \brief (UART1) Transfer Control Register */ + #define REG_UART1_PTSR (*(__I uint32_t*)0x40060724U) /**< \brief (UART1) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_UART1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/udp.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/udp.h new file mode 100644 index 0000000..215b647 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/udp.h @@ -0,0 +1,77 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_UDP_INSTANCE_ +#define _SAM4E_UDP_INSTANCE_ + +/* ========== Register definition for UDP peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_UDP_FRM_NUM (0x40084000U) /**< \brief (UDP) Frame Number Register */ + #define REG_UDP_GLB_STAT (0x40084004U) /**< \brief (UDP) Global State Register */ + #define REG_UDP_FADDR (0x40084008U) /**< \brief (UDP) Function Address Register */ + #define REG_UDP_IER (0x40084010U) /**< \brief (UDP) Interrupt Enable Register */ + #define REG_UDP_IDR (0x40084014U) /**< \brief (UDP) Interrupt Disable Register */ + #define REG_UDP_IMR (0x40084018U) /**< \brief (UDP) Interrupt Mask Register */ + #define REG_UDP_ISR (0x4008401CU) /**< \brief (UDP) Interrupt Status Register */ + #define REG_UDP_ICR (0x40084020U) /**< \brief (UDP) Interrupt Clear Register */ + #define REG_UDP_RST_EP (0x40084028U) /**< \brief (UDP) Reset Endpoint Register */ + #define REG_UDP_CSR (0x40084030U) /**< \brief (UDP) Endpoint Control and Status Register */ + #define REG_UDP_FDR (0x40084050U) /**< \brief (UDP) Endpoint FIFO Data Register */ + #define REG_UDP_TXVC (0x40084074U) /**< \brief (UDP) Transceiver Control Register */ +#else + #define REG_UDP_FRM_NUM (*(__I uint32_t*)0x40084000U) /**< \brief (UDP) Frame Number Register */ + #define REG_UDP_GLB_STAT (*(__IO uint32_t*)0x40084004U) /**< \brief (UDP) Global State Register */ + #define REG_UDP_FADDR (*(__IO uint32_t*)0x40084008U) /**< \brief (UDP) Function Address Register */ + #define REG_UDP_IER (*(__O uint32_t*)0x40084010U) /**< \brief (UDP) Interrupt Enable Register */ + #define REG_UDP_IDR (*(__O uint32_t*)0x40084014U) /**< \brief (UDP) Interrupt Disable Register */ + #define REG_UDP_IMR (*(__I uint32_t*)0x40084018U) /**< \brief (UDP) Interrupt Mask Register */ + #define REG_UDP_ISR (*(__I uint32_t*)0x4008401CU) /**< \brief (UDP) Interrupt Status Register */ + #define REG_UDP_ICR (*(__O uint32_t*)0x40084020U) /**< \brief (UDP) Interrupt Clear Register */ + #define REG_UDP_RST_EP (*(__IO uint32_t*)0x40084028U) /**< \brief (UDP) Reset Endpoint Register */ + #define REG_UDP_CSR (*(__IO uint32_t*)0x40084030U) /**< \brief (UDP) Endpoint Control and Status Register */ + #define REG_UDP_FDR (*(__IO uint32_t*)0x40084050U) /**< \brief (UDP) Endpoint FIFO Data Register */ + #define REG_UDP_TXVC (*(__IO uint32_t*)0x40084074U) /**< \brief (UDP) Transceiver Control Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_UDP_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart0.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart0.h new file mode 100644 index 0000000..38b0cdc --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart0.h @@ -0,0 +1,107 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_USART0_INSTANCE_ +#define _SAM4E_USART0_INSTANCE_ + +/* ========== Register definition for USART0 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_USART0_CR (0x400A0000U) /**< \brief (USART0) Control Register */ + #define REG_USART0_MR (0x400A0004U) /**< \brief (USART0) Mode Register */ + #define REG_USART0_IER (0x400A0008U) /**< \brief (USART0) Interrupt Enable Register */ + #define REG_USART0_IDR (0x400A000CU) /**< \brief (USART0) Interrupt Disable Register */ + #define REG_USART0_IMR (0x400A0010U) /**< \brief (USART0) Interrupt Mask Register */ + #define REG_USART0_CSR (0x400A0014U) /**< \brief (USART0) Channel Status Register */ + #define REG_USART0_RHR (0x400A0018U) /**< \brief (USART0) Receive Holding Register */ + #define REG_USART0_THR (0x400A001CU) /**< \brief (USART0) Transmit Holding Register */ + #define REG_USART0_BRGR (0x400A0020U) /**< \brief (USART0) Baud Rate Generator Register */ + #define REG_USART0_RTOR (0x400A0024U) /**< \brief (USART0) Receiver Time-out Register */ + #define REG_USART0_TTGR (0x400A0028U) /**< \brief (USART0) Transmitter Timeguard Register */ + #define REG_USART0_FIDI (0x400A0040U) /**< \brief (USART0) FI DI Ratio Register */ + #define REG_USART0_NER (0x400A0044U) /**< \brief (USART0) Number of Errors Register */ + #define REG_USART0_IF (0x400A004CU) /**< \brief (USART0) IrDA Filter Register */ + #define REG_USART0_MAN (0x400A0050U) /**< \brief (USART0) Manchester Configuration Register */ + #define REG_USART0_WPMR (0x400A00E4U) /**< \brief (USART0) Write Protection Mode Register */ + #define REG_USART0_WPSR (0x400A00E8U) /**< \brief (USART0) Write Protection Status Register */ + #define REG_USART0_RPR (0x400A0100U) /**< \brief (USART0) Receive Pointer Register */ + #define REG_USART0_RCR (0x400A0104U) /**< \brief (USART0) Receive Counter Register */ + #define REG_USART0_TPR (0x400A0108U) /**< \brief (USART0) Transmit Pointer Register */ + #define REG_USART0_TCR (0x400A010CU) /**< \brief (USART0) Transmit Counter Register */ + #define REG_USART0_RNPR (0x400A0110U) /**< \brief (USART0) Receive Next Pointer Register */ + #define REG_USART0_RNCR (0x400A0114U) /**< \brief (USART0) Receive Next Counter Register */ + #define REG_USART0_TNPR (0x400A0118U) /**< \brief (USART0) Transmit Next Pointer Register */ + #define REG_USART0_TNCR (0x400A011CU) /**< \brief (USART0) Transmit Next Counter Register */ + #define REG_USART0_PTCR (0x400A0120U) /**< \brief (USART0) Transfer Control Register */ + #define REG_USART0_PTSR (0x400A0124U) /**< \brief (USART0) Transfer Status Register */ +#else + #define REG_USART0_CR (*(__O uint32_t*)0x400A0000U) /**< \brief (USART0) Control Register */ + #define REG_USART0_MR (*(__IO uint32_t*)0x400A0004U) /**< \brief (USART0) Mode Register */ + #define REG_USART0_IER (*(__O uint32_t*)0x400A0008U) /**< \brief (USART0) Interrupt Enable Register */ + #define REG_USART0_IDR (*(__O uint32_t*)0x400A000CU) /**< \brief (USART0) Interrupt Disable Register */ + #define REG_USART0_IMR (*(__I uint32_t*)0x400A0010U) /**< \brief (USART0) Interrupt Mask Register */ + #define REG_USART0_CSR (*(__I uint32_t*)0x400A0014U) /**< \brief (USART0) Channel Status Register */ + #define REG_USART0_RHR (*(__I uint32_t*)0x400A0018U) /**< \brief (USART0) Receive Holding Register */ + #define REG_USART0_THR (*(__O uint32_t*)0x400A001CU) /**< \brief (USART0) Transmit Holding Register */ + #define REG_USART0_BRGR (*(__IO uint32_t*)0x400A0020U) /**< \brief (USART0) Baud Rate Generator Register */ + #define REG_USART0_RTOR (*(__IO uint32_t*)0x400A0024U) /**< \brief (USART0) Receiver Time-out Register */ + #define REG_USART0_TTGR (*(__IO uint32_t*)0x400A0028U) /**< \brief (USART0) Transmitter Timeguard Register */ + #define REG_USART0_FIDI (*(__IO uint32_t*)0x400A0040U) /**< \brief (USART0) FI DI Ratio Register */ + #define REG_USART0_NER (*(__I uint32_t*)0x400A0044U) /**< \brief (USART0) Number of Errors Register */ + #define REG_USART0_IF (*(__IO uint32_t*)0x400A004CU) /**< \brief (USART0) IrDA Filter Register */ + #define REG_USART0_MAN (*(__IO uint32_t*)0x400A0050U) /**< \brief (USART0) Manchester Configuration Register */ + #define REG_USART0_WPMR (*(__IO uint32_t*)0x400A00E4U) /**< \brief (USART0) Write Protection Mode Register */ + #define REG_USART0_WPSR (*(__I uint32_t*)0x400A00E8U) /**< \brief (USART0) Write Protection Status Register */ + #define REG_USART0_RPR (*(__IO uint32_t*)0x400A0100U) /**< \brief (USART0) Receive Pointer Register */ + #define REG_USART0_RCR (*(__IO uint32_t*)0x400A0104U) /**< \brief (USART0) Receive Counter Register */ + #define REG_USART0_TPR (*(__IO uint32_t*)0x400A0108U) /**< \brief (USART0) Transmit Pointer Register */ + #define REG_USART0_TCR (*(__IO uint32_t*)0x400A010CU) /**< \brief (USART0) Transmit Counter Register */ + #define REG_USART0_RNPR (*(__IO uint32_t*)0x400A0110U) /**< \brief (USART0) Receive Next Pointer Register */ + #define REG_USART0_RNCR (*(__IO uint32_t*)0x400A0114U) /**< \brief (USART0) Receive Next Counter Register */ + #define REG_USART0_TNPR (*(__IO uint32_t*)0x400A0118U) /**< \brief (USART0) Transmit Next Pointer Register */ + #define REG_USART0_TNCR (*(__IO uint32_t*)0x400A011CU) /**< \brief (USART0) Transmit Next Counter Register */ + #define REG_USART0_PTCR (*(__O uint32_t*)0x400A0120U) /**< \brief (USART0) Transfer Control Register */ + #define REG_USART0_PTSR (*(__I uint32_t*)0x400A0124U) /**< \brief (USART0) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_USART0_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart1.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart1.h new file mode 100644 index 0000000..d7dc9c8 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/usart1.h @@ -0,0 +1,107 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_USART1_INSTANCE_ +#define _SAM4E_USART1_INSTANCE_ + +/* ========== Register definition for USART1 peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_USART1_CR (0x400A4000U) /**< \brief (USART1) Control Register */ + #define REG_USART1_MR (0x400A4004U) /**< \brief (USART1) Mode Register */ + #define REG_USART1_IER (0x400A4008U) /**< \brief (USART1) Interrupt Enable Register */ + #define REG_USART1_IDR (0x400A400CU) /**< \brief (USART1) Interrupt Disable Register */ + #define REG_USART1_IMR (0x400A4010U) /**< \brief (USART1) Interrupt Mask Register */ + #define REG_USART1_CSR (0x400A4014U) /**< \brief (USART1) Channel Status Register */ + #define REG_USART1_RHR (0x400A4018U) /**< \brief (USART1) Receive Holding Register */ + #define REG_USART1_THR (0x400A401CU) /**< \brief (USART1) Transmit Holding Register */ + #define REG_USART1_BRGR (0x400A4020U) /**< \brief (USART1) Baud Rate Generator Register */ + #define REG_USART1_RTOR (0x400A4024U) /**< \brief (USART1) Receiver Time-out Register */ + #define REG_USART1_TTGR (0x400A4028U) /**< \brief (USART1) Transmitter Timeguard Register */ + #define REG_USART1_FIDI (0x400A4040U) /**< \brief (USART1) FI DI Ratio Register */ + #define REG_USART1_NER (0x400A4044U) /**< \brief (USART1) Number of Errors Register */ + #define REG_USART1_IF (0x400A404CU) /**< \brief (USART1) IrDA Filter Register */ + #define REG_USART1_MAN (0x400A4050U) /**< \brief (USART1) Manchester Configuration Register */ + #define REG_USART1_WPMR (0x400A40E4U) /**< \brief (USART1) Write Protection Mode Register */ + #define REG_USART1_WPSR (0x400A40E8U) /**< \brief (USART1) Write Protection Status Register */ + #define REG_USART1_RPR (0x400A4100U) /**< \brief (USART1) Receive Pointer Register */ + #define REG_USART1_RCR (0x400A4104U) /**< \brief (USART1) Receive Counter Register */ + #define REG_USART1_TPR (0x400A4108U) /**< \brief (USART1) Transmit Pointer Register */ + #define REG_USART1_TCR (0x400A410CU) /**< \brief (USART1) Transmit Counter Register */ + #define REG_USART1_RNPR (0x400A4110U) /**< \brief (USART1) Receive Next Pointer Register */ + #define REG_USART1_RNCR (0x400A4114U) /**< \brief (USART1) Receive Next Counter Register */ + #define REG_USART1_TNPR (0x400A4118U) /**< \brief (USART1) Transmit Next Pointer Register */ + #define REG_USART1_TNCR (0x400A411CU) /**< \brief (USART1) Transmit Next Counter Register */ + #define REG_USART1_PTCR (0x400A4120U) /**< \brief (USART1) Transfer Control Register */ + #define REG_USART1_PTSR (0x400A4124U) /**< \brief (USART1) Transfer Status Register */ +#else + #define REG_USART1_CR (*(__O uint32_t*)0x400A4000U) /**< \brief (USART1) Control Register */ + #define REG_USART1_MR (*(__IO uint32_t*)0x400A4004U) /**< \brief (USART1) Mode Register */ + #define REG_USART1_IER (*(__O uint32_t*)0x400A4008U) /**< \brief (USART1) Interrupt Enable Register */ + #define REG_USART1_IDR (*(__O uint32_t*)0x400A400CU) /**< \brief (USART1) Interrupt Disable Register */ + #define REG_USART1_IMR (*(__I uint32_t*)0x400A4010U) /**< \brief (USART1) Interrupt Mask Register */ + #define REG_USART1_CSR (*(__I uint32_t*)0x400A4014U) /**< \brief (USART1) Channel Status Register */ + #define REG_USART1_RHR (*(__I uint32_t*)0x400A4018U) /**< \brief (USART1) Receive Holding Register */ + #define REG_USART1_THR (*(__O uint32_t*)0x400A401CU) /**< \brief (USART1) Transmit Holding Register */ + #define REG_USART1_BRGR (*(__IO uint32_t*)0x400A4020U) /**< \brief (USART1) Baud Rate Generator Register */ + #define REG_USART1_RTOR (*(__IO uint32_t*)0x400A4024U) /**< \brief (USART1) Receiver Time-out Register */ + #define REG_USART1_TTGR (*(__IO uint32_t*)0x400A4028U) /**< \brief (USART1) Transmitter Timeguard Register */ + #define REG_USART1_FIDI (*(__IO uint32_t*)0x400A4040U) /**< \brief (USART1) FI DI Ratio Register */ + #define REG_USART1_NER (*(__I uint32_t*)0x400A4044U) /**< \brief (USART1) Number of Errors Register */ + #define REG_USART1_IF (*(__IO uint32_t*)0x400A404CU) /**< \brief (USART1) IrDA Filter Register */ + #define REG_USART1_MAN (*(__IO uint32_t*)0x400A4050U) /**< \brief (USART1) Manchester Configuration Register */ + #define REG_USART1_WPMR (*(__IO uint32_t*)0x400A40E4U) /**< \brief (USART1) Write Protection Mode Register */ + #define REG_USART1_WPSR (*(__I uint32_t*)0x400A40E8U) /**< \brief (USART1) Write Protection Status Register */ + #define REG_USART1_RPR (*(__IO uint32_t*)0x400A4100U) /**< \brief (USART1) Receive Pointer Register */ + #define REG_USART1_RCR (*(__IO uint32_t*)0x400A4104U) /**< \brief (USART1) Receive Counter Register */ + #define REG_USART1_TPR (*(__IO uint32_t*)0x400A4108U) /**< \brief (USART1) Transmit Pointer Register */ + #define REG_USART1_TCR (*(__IO uint32_t*)0x400A410CU) /**< \brief (USART1) Transmit Counter Register */ + #define REG_USART1_RNPR (*(__IO uint32_t*)0x400A4110U) /**< \brief (USART1) Receive Next Pointer Register */ + #define REG_USART1_RNCR (*(__IO uint32_t*)0x400A4114U) /**< \brief (USART1) Receive Next Counter Register */ + #define REG_USART1_TNPR (*(__IO uint32_t*)0x400A4118U) /**< \brief (USART1) Transmit Next Pointer Register */ + #define REG_USART1_TNCR (*(__IO uint32_t*)0x400A411CU) /**< \brief (USART1) Transmit Next Counter Register */ + #define REG_USART1_PTCR (*(__O uint32_t*)0x400A4120U) /**< \brief (USART1) Transfer Control Register */ + #define REG_USART1_PTSR (*(__I uint32_t*)0x400A4124U) /**< \brief (USART1) Transfer Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_USART1_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/wdt.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/wdt.h new file mode 100644 index 0000000..1f99d52 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/instance/wdt.h @@ -0,0 +1,59 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E_WDT_INSTANCE_ +#define _SAM4E_WDT_INSTANCE_ + +/* ========== Register definition for WDT peripheral ========== */ +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) + #define REG_WDT_CR (0x400E1850U) /**< \brief (WDT) Control Register */ + #define REG_WDT_MR (0x400E1854U) /**< \brief (WDT) Mode Register */ + #define REG_WDT_SR (0x400E1858U) /**< \brief (WDT) Status Register */ +#else + #define REG_WDT_CR (*(__O uint32_t*)0x400E1850U) /**< \brief (WDT) Control Register */ + #define REG_WDT_MR (*(__IO uint32_t*)0x400E1854U) /**< \brief (WDT) Mode Register */ + #define REG_WDT_SR (*(__I uint32_t*)0x400E1858U) /**< \brief (WDT) Status Register */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#endif /* _SAM4E_WDT_INSTANCE_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16c.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16c.h new file mode 100644 index 0000000..b0df87d --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16c.h @@ -0,0 +1,395 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E16C_PIO_ +#define _SAM4E16C_PIO_ + +#define PIO_PA0 (1u << 0) /**< \brief Pin Controlled by PA0 */ +#define PIO_PA1 (1u << 1) /**< \brief Pin Controlled by PA1 */ +#define PIO_PA2 (1u << 2) /**< \brief Pin Controlled by PA2 */ +#define PIO_PA3 (1u << 3) /**< \brief Pin Controlled by PA3 */ +#define PIO_PA4 (1u << 4) /**< \brief Pin Controlled by PA4 */ +#define PIO_PA5 (1u << 5) /**< \brief Pin Controlled by PA5 */ +#define PIO_PA6 (1u << 6) /**< \brief Pin Controlled by PA6 */ +#define PIO_PA7 (1u << 7) /**< \brief Pin Controlled by PA7 */ +#define PIO_PA8 (1u << 8) /**< \brief Pin Controlled by PA8 */ +#define PIO_PA9 (1u << 9) /**< \brief Pin Controlled by PA9 */ +#define PIO_PA10 (1u << 10) /**< \brief Pin Controlled by PA10 */ +#define PIO_PA11 (1u << 11) /**< \brief Pin Controlled by PA11 */ +#define PIO_PA12 (1u << 12) /**< \brief Pin Controlled by PA12 */ +#define PIO_PA13 (1u << 13) /**< \brief Pin Controlled by PA13 */ +#define PIO_PA14 (1u << 14) /**< \brief Pin Controlled by PA14 */ +#define PIO_PA15 (1u << 15) /**< \brief Pin Controlled by PA15 */ +#define PIO_PA16 (1u << 16) /**< \brief Pin Controlled by PA16 */ +#define PIO_PA17 (1u << 17) /**< \brief Pin Controlled by PA17 */ +#define PIO_PA18 (1u << 18) /**< \brief Pin Controlled by PA18 */ +#define PIO_PA19 (1u << 19) /**< \brief Pin Controlled by PA19 */ +#define PIO_PA20 (1u << 20) /**< \brief Pin Controlled by PA20 */ +#define PIO_PA21 (1u << 21) /**< \brief Pin Controlled by PA21 */ +#define PIO_PA22 (1u << 22) /**< \brief Pin Controlled by PA22 */ +#define PIO_PA23 (1u << 23) /**< \brief Pin Controlled by PA23 */ +#define PIO_PA24 (1u << 24) /**< \brief Pin Controlled by PA24 */ +#define PIO_PA25 (1u << 25) /**< \brief Pin Controlled by PA25 */ +#define PIO_PA26 (1u << 26) /**< \brief Pin Controlled by PA26 */ +#define PIO_PA27 (1u << 27) /**< \brief Pin Controlled by PA27 */ +#define PIO_PA28 (1u << 28) /**< \brief Pin Controlled by PA28 */ +#define PIO_PA29 (1u << 29) /**< \brief Pin Controlled by PA29 */ +#define PIO_PA30 (1u << 30) /**< \brief Pin Controlled by PA30 */ +#define PIO_PA31 (1u << 31) /**< \brief Pin Controlled by PA31 */ +#define PIO_PB0 (1u << 0) /**< \brief Pin Controlled by PB0 */ +#define PIO_PB1 (1u << 1) /**< \brief Pin Controlled by PB1 */ +#define PIO_PB2 (1u << 2) /**< \brief Pin Controlled by PB2 */ +#define PIO_PB3 (1u << 3) /**< \brief Pin Controlled by PB3 */ +#define PIO_PB4 (1u << 4) /**< \brief Pin Controlled by PB4 */ +#define PIO_PB5 (1u << 5) /**< \brief Pin Controlled by PB5 */ +#define PIO_PB6 (1u << 6) /**< \brief Pin Controlled by PB6 */ +#define PIO_PB7 (1u << 7) /**< \brief Pin Controlled by PB7 */ +#define PIO_PB8 (1u << 8) /**< \brief Pin Controlled by PB8 */ +#define PIO_PB9 (1u << 9) /**< \brief Pin Controlled by PB9 */ +#define PIO_PB10 (1u << 10) /**< \brief Pin Controlled by PB10 */ +#define PIO_PB11 (1u << 11) /**< \brief Pin Controlled by PB11 */ +#define PIO_PB12 (1u << 12) /**< \brief Pin Controlled by PB12 */ +#define PIO_PB13 (1u << 13) /**< \brief Pin Controlled by PB13 */ +#define PIO_PB14 (1u << 14) /**< \brief Pin Controlled by PB14 */ +#define PIO_PD0 (1u << 0) /**< \brief Pin Controlled by PD0 */ +#define PIO_PD1 (1u << 1) /**< \brief Pin Controlled by PD1 */ +#define PIO_PD2 (1u << 2) /**< \brief Pin Controlled by PD2 */ +#define PIO_PD3 (1u << 3) /**< \brief Pin Controlled by PD3 */ +#define PIO_PD4 (1u << 4) /**< \brief Pin Controlled by PD4 */ +#define PIO_PD5 (1u << 5) /**< \brief Pin Controlled by PD5 */ +#define PIO_PD6 (1u << 6) /**< \brief Pin Controlled by PD6 */ +#define PIO_PD7 (1u << 7) /**< \brief Pin Controlled by PD7 */ +#define PIO_PD8 (1u << 8) /**< \brief Pin Controlled by PD8 */ +#define PIO_PD9 (1u << 9) /**< \brief Pin Controlled by PD9 */ +#define PIO_PD10 (1u << 10) /**< \brief Pin Controlled by PD10 */ +#define PIO_PD11 (1u << 11) /**< \brief Pin Controlled by PD11 */ +#define PIO_PD12 (1u << 12) /**< \brief Pin Controlled by PD12 */ +#define PIO_PD13 (1u << 13) /**< \brief Pin Controlled by PD13 */ +#define PIO_PD14 (1u << 14) /**< \brief Pin Controlled by PD14 */ +#define PIO_PD15 (1u << 15) /**< \brief Pin Controlled by PD15 */ +#define PIO_PD16 (1u << 16) /**< \brief Pin Controlled by PD16 */ +#define PIO_PD17 (1u << 17) /**< \brief Pin Controlled by PD17 */ +#define PIO_PD18 (1u << 18) /**< \brief Pin Controlled by PD18 */ +#define PIO_PD19 (1u << 19) /**< \brief Pin Controlled by PD19 */ +#define PIO_PD20 (1u << 20) /**< \brief Pin Controlled by PD20 */ +#define PIO_PD21 (1u << 21) /**< \brief Pin Controlled by PD21 */ +#define PIO_PD22 (1u << 22) /**< \brief Pin Controlled by PD22 */ +#define PIO_PD23 (1u << 23) /**< \brief Pin Controlled by PD23 */ +#define PIO_PD24 (1u << 24) /**< \brief Pin Controlled by PD24 */ +#define PIO_PD25 (1u << 25) /**< \brief Pin Controlled by PD25 */ +#define PIO_PD26 (1u << 26) /**< \brief Pin Controlled by PD26 */ +#define PIO_PD27 (1u << 27) /**< \brief Pin Controlled by PD27 */ +#define PIO_PD28 (1u << 28) /**< \brief Pin Controlled by PD28 */ +#define PIO_PD29 (1u << 29) /**< \brief Pin Controlled by PD29 */ +#define PIO_PD30 (1u << 30) /**< \brief Pin Controlled by PD30 */ +#define PIO_PD31 (1u << 31) /**< \brief Pin Controlled by PD31 */ +/* ========== Pio definition for AFEC0 peripheral ========== */ +#define PIO_PA17X1_AFE0_AD0 (1u << 17) /**< \brief Afec0 signal: AFE0_AD0 */ +#define PIO_PA18X1_AFE0_AD1 (1u << 18) /**< \brief Afec0 signal: AFE0_AD1 */ +#define PIO_PC30X1_AFE0_AD10 (1u << 30) /**< \brief Afec0 signal: AFE0_AD10 */ +#define PIO_PC31X1_AFE0_AD11 (1u << 31) /**< \brief Afec0 signal: AFE0_AD11 */ +#define PIO_PC26X1_AFE0_AD12 (1u << 26) /**< \brief Afec0 signal: AFE0_AD12 */ +#define PIO_PC27X1_AFE0_AD13 (1u << 27) /**< \brief Afec0 signal: AFE0_AD13 */ +#define PIO_PC0X1_AFE0_AD14 (1u << 0) /**< \brief Afec0 signal: AFE0_AD14 */ +#define PIO_PA19X1_AFE0_AD2 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA19X1_WKUP9 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA20X1_AFE0_AD3 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PA20X1_WKUP10 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PB0X1_AFE0_AD4 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB0X1_RTCOUT0 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB1X1_AFE0_AD5 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PB1X1_RTCOUT1 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PC13X1_AFE0_AD6 (1u << 13) /**< \brief Afec0 signal: AFE0_AD6 */ +#define PIO_PC15X1_AFE0_AD7 (1u << 15) /**< \brief Afec0 signal: AFE0_AD7 */ +#define PIO_PC12X1_AFE0_AD8 (1u << 12) /**< \brief Afec0 signal: AFE0_AD8 */ +#define PIO_PC29X1_AFE0_AD9 (1u << 29) /**< \brief Afec0 signal: AFE0_AD9 */ +#define PIO_PA8B_AFE0_ADTRG (1u << 8) /**< \brief Afec0 signal: AFE0_ADTRG */ +/* ========== Pio definition for AFEC1 peripheral ========== */ +#define PIO_PB2X1_AFE1_AD0 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB2X1_WKUP12 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB3X1_AFE1_AD1 (1u << 3) /**< \brief Afec1 signal: AFE1_AD1 */ +#define PIO_PA21X1_AFE1_AD2 (1u << 21) /**< \brief Afec1 signal: AFE1_AD2 */ +#define PIO_PA22X1_AFE1_AD3 (1u << 22) /**< \brief Afec1 signal: AFE1_AD3 */ +#define PIO_PC1X1_AFE1_AD4 (1u << 1) /**< \brief Afec1 signal: AFE1_AD4 */ +#define PIO_PC2X1_AFE1_AD5 (1u << 2) /**< \brief Afec1 signal: AFE1_AD5 */ +#define PIO_PC3X1_AFE1_AD6 (1u << 3) /**< \brief Afec1 signal: AFE1_AD6 */ +#define PIO_PC4X1_AFE1_AD7 (1u << 4) /**< \brief Afec1 signal: AFE1_AD7 */ +/* ========== Pio definition for CAN0 peripheral ========== */ +#define PIO_PB3A_CANRX0 (1u << 3) /**< \brief Can0 signal: CANRX0 */ +#define PIO_PB2A_CANTX0 (1u << 2) /**< \brief Can0 signal: CANTX0 */ +/* ========== Pio definition for DACC peripheral ========== */ +#define PIO_PB13X1_DAC0 (1u << 13) /**< \brief Dacc signal: DAC0 */ +#define PIO_PB14X1_DAC1 (1u << 14) /**< \brief Dacc signal: DAC1 */ +#define PIO_PA2C_DATRG (1u << 2) /**< \brief Dacc signal: DATRG */ +/* ========== Pio definition for GMAC peripheral ========== */ +#define PIO_PD13A_GCOL (1u << 13) /**< \brief Gmac signal: GCOL */ +#define PIO_PD10A_GCRS (1u << 10) /**< \brief Gmac signal: GCRS */ +#define PIO_PD4A_GCRSDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD4A_GRXDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD8A_GMDC (1u << 8) /**< \brief Gmac signal: GMDC */ +#define PIO_PD9A_GMDIO (1u << 9) /**< \brief Gmac signal: GMDIO */ +#define PIO_PD5A_GRX0 (1u << 5) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD6A_GRX0 (1u << 6) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD11A_GRX2 (1u << 11) /**< \brief Gmac signal: GRX2 */ +#define PIO_PD12A_GRX3 (1u << 12) /**< \brief Gmac signal: GRX3 */ +#define PIO_PD14A_GRXCK (1u << 14) /**< \brief Gmac signal: GRXCK */ +#define PIO_PD7A_GRXER (1u << 7) /**< \brief Gmac signal: GRXER */ +#define PIO_PD2A_GTX0 (1u << 2) /**< \brief Gmac signal: GTX0 */ +#define PIO_PD3A_GTX1 (1u << 3) /**< \brief Gmac signal: GTX1 */ +#define PIO_PD15A_GTX2 (1u << 15) /**< \brief Gmac signal: GTX2 */ +#define PIO_PD16A_GTX3 (1u << 16) /**< \brief Gmac signal: GTX3 */ +#define PIO_PD0A_GTXCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD0A_GREFCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD1A_GTXEN (1u << 1) /**< \brief Gmac signal: GTXEN */ +#define PIO_PD17A_GTXER (1u << 17) /**< \brief Gmac signal: GTXER */ +/* ========== Pio definition for HSMCI peripheral ========== */ +#define PIO_PA28C_MCCDA (1u << 28) /**< \brief Hsmci signal: MCCDA */ +#define PIO_PA29C_MCCK (1u << 29) /**< \brief Hsmci signal: MCCK */ +#define PIO_PA30C_MCDA0 (1u << 30) /**< \brief Hsmci signal: MCDA0 */ +#define PIO_PA31C_MCDA1 (1u << 31) /**< \brief Hsmci signal: MCDA1 */ +#define PIO_PA26C_MCDA2 (1u << 26) /**< \brief Hsmci signal: MCDA2 */ +#define PIO_PA27C_MCDA3 (1u << 27) /**< \brief Hsmci signal: MCDA3 */ +/* ========== Pio definition for PIOA peripheral ========== */ +#define PIO_PA24X1_PIODC0 (1u << 24) /**< \brief Pioa signal: PIODC0 */ +#define PIO_PA25X1_PIODC1 (1u << 25) /**< \brief Pioa signal: PIODC1 */ +#define PIO_PA26X1_PIODC2 (1u << 26) /**< \brief Pioa signal: PIODC2 */ +#define PIO_PA27X1_PIODC3 (1u << 27) /**< \brief Pioa signal: PIODC3 */ +#define PIO_PA28X1_PIODC4 (1u << 28) /**< \brief Pioa signal: PIODC4 */ +#define PIO_PA29X1_PIODC5 (1u << 29) /**< \brief Pioa signal: PIODC5 */ +#define PIO_PA31X1_PIODC7 (1u << 31) /**< \brief Pioa signal: PIODC7 */ +#define PIO_PA23X1_PIODCCLK (1u << 23) /**< \brief Pioa signal: PIODCCLK */ +#define PIO_PA30X1_WKUP11 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA30X1_PIODC6 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA15X1_WKUP14 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA15X1_PIODCEN1 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA16X1_WKUP15 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +#define PIO_PA16X1_PIODCEN2 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +/* ========== Pio definition for PMC peripheral ========== */ +#define PIO_PA6B_PCK0 (1u << 6) /**< \brief Pmc signal: PCK0 */ +#define PIO_PB13B_PCK0 (1u << 13) /**< \brief Pmc signal: PCK0 */ +#define PIO_PA17B_PCK1 (1u << 17) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA21B_PCK1 (1u << 21) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA18B_PCK2 (1u << 18) /**< \brief Pmc signal: PCK2 */ +#define PIO_PA31B_PCK2 (1u << 31) /**< \brief Pmc signal: PCK2 */ +#define PIO_PB3B_PCK2 (1u << 3) /**< \brief Pmc signal: PCK2 */ +/* ========== Pio definition for PWM peripheral ========== */ +#define PIO_PA9C_PWMFI0 (1u << 9) /**< \brief Pwm signal: PWMFI0 */ +#define PIO_PA0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA11B_PWMH0 (1u << 11) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA23B_PWMH0 (1u << 23) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PB0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PC18B_PWMH0 (1u << 18) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PD20A_PWMH0 (1u << 20) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA12B_PWMH1 (1u << 12) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA24B_PWMH1 (1u << 24) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PB1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PC19B_PWMH1 (1u << 19) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PD21A_PWMH1 (1u << 21) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA2A_PWMH2 (1u << 2) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA13B_PWMH2 (1u << 13) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA25B_PWMH2 (1u << 25) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PB4B_PWMH2 (1u << 4) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PC20B_PWMH2 (1u << 20) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PD22A_PWMH2 (1u << 22) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA7B_PWMH3 (1u << 7) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA17C_PWMH3 (1u << 17) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PB14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PC21B_PWMH3 (1u << 21) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PD23A_PWMH3 (1u << 23) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA19B_PWML0 (1u << 19) /**< \brief Pwm signal: PWML0 */ +#define PIO_PB5B_PWML0 (1u << 5) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC0B_PWML0 (1u << 0) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC13B_PWML0 (1u << 13) /**< \brief Pwm signal: PWML0 */ +#define PIO_PD24A_PWML0 (1u << 24) /**< \brief Pwm signal: PWML0 */ +#define PIO_PA20B_PWML1 (1u << 20) /**< \brief Pwm signal: PWML1 */ +#define PIO_PB12A_PWML1 (1u << 12) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC1B_PWML1 (1u << 1) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC15B_PWML1 (1u << 15) /**< \brief Pwm signal: PWML1 */ +#define PIO_PD25A_PWML1 (1u << 25) /**< \brief Pwm signal: PWML1 */ +#define PIO_PA16C_PWML2 (1u << 16) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA30A_PWML2 (1u << 30) /**< \brief Pwm signal: PWML2 */ +#define PIO_PB13A_PWML2 (1u << 13) /**< \brief Pwm signal: PWML2 */ +#define PIO_PC2B_PWML2 (1u << 2) /**< \brief Pwm signal: PWML2 */ +#define PIO_PD26A_PWML2 (1u << 26) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA15C_PWML3 (1u << 15) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC3B_PWML3 (1u << 3) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC22B_PWML3 (1u << 22) /**< \brief Pwm signal: PWML3 */ +#define PIO_PD27A_PWML3 (1u << 27) /**< \brief Pwm signal: PWML3 */ +/* ========== Pio definition for SPI peripheral ========== */ +#define PIO_PA12A_MISO (1u << 12) /**< \brief Spi signal: MISO */ +#define PIO_PA13A_MOSI (1u << 13) /**< \brief Spi signal: MOSI */ +#define PIO_PA11A_NPCS0 (1u << 11) /**< \brief Spi signal: NPCS0 */ +#define PIO_PA9B_NPCS1 (1u << 9) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA31A_NPCS1 (1u << 31) /**< \brief Spi signal: NPCS1 */ +#define PIO_PB14A_NPCS1 (1u << 14) /**< \brief Spi signal: NPCS1 */ +#define PIO_PC4B_NPCS1 (1u << 4) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA10B_NPCS2 (1u << 10) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA30B_NPCS2 (1u << 30) /**< \brief Spi signal: NPCS2 */ +#define PIO_PB2B_NPCS2 (1u << 2) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA3B_NPCS3 (1u << 3) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA5B_NPCS3 (1u << 5) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA22B_NPCS3 (1u << 22) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA14A_SPCK (1u << 14) /**< \brief Spi signal: SPCK */ +/* ========== Pio definition for TC0 peripheral ========== */ +#define PIO_PA4B_TCLK0 (1u << 4) /**< \brief Tc0 signal: TCLK0 */ +#define PIO_PA28B_TCLK1 (1u << 28) /**< \brief Tc0 signal: TCLK1 */ +#define PIO_PA29B_TCLK2 (1u << 29) /**< \brief Tc0 signal: TCLK2 */ +#define PIO_PA0B_TIOA0 (1u << 0) /**< \brief Tc0 signal: TIOA0 */ +#define PIO_PA15B_TIOA1 (1u << 15) /**< \brief Tc0 signal: TIOA1 */ +#define PIO_PA26B_TIOA2 (1u << 26) /**< \brief Tc0 signal: TIOA2 */ +#define PIO_PA1B_TIOB0 (1u << 1) /**< \brief Tc0 signal: TIOB0 */ +#define PIO_PA16B_TIOB1 (1u << 16) /**< \brief Tc0 signal: TIOB1 */ +#define PIO_PA27B_TIOB2 (1u << 27) /**< \brief Tc0 signal: TIOB2 */ +/* ========== Pio definition for TWI0 peripheral ========== */ +#define PIO_PA4A_TWCK0 (1u << 4) /**< \brief Twi0 signal: TWCK0 */ +#define PIO_PA3A_TWD0 (1u << 3) /**< \brief Twi0 signal: TWD0 */ +/* ========== Pio definition for TWI1 peripheral ========== */ +#define PIO_PB5A_TWCK1 (1u << 5) /**< \brief Twi1 signal: TWCK1 */ +#define PIO_PB4A_TWD1 (1u << 4) /**< \brief Twi1 signal: TWD1 */ +/* ========== Pio definition for UART0 peripheral ========== */ +#define PIO_PA9A_URXD0 (1u << 9) /**< \brief Uart0 signal: URXD0 */ +#define PIO_PA10A_UTXD0 (1u << 10) /**< \brief Uart0 signal: UTXD0 */ +/* ========== Pio definition for UART1 peripheral ========== */ +#define PIO_PA5C_URXD1 (1u << 5) /**< \brief Uart1 signal: URXD1 */ +#define PIO_PA6C_UTXD1 (1u << 6) /**< \brief Uart1 signal: UTXD1 */ +/* ========== Pio definition for USART0 peripheral ========== */ +#define PIO_PB2C_CTS0 (1u << 2) /**< \brief Usart0 signal: CTS0 */ +#define PIO_PB3C_RTS0 (1u << 3) /**< \brief Usart0 signal: RTS0 */ +#define PIO_PB0C_RXD0 (1u << 0) /**< \brief Usart0 signal: RXD0 */ +#define PIO_PB13C_SCK0 (1u << 13) /**< \brief Usart0 signal: SCK0 */ +#define PIO_PB1C_TXD0 (1u << 1) /**< \brief Usart0 signal: TXD0 */ +/* ========== Pio definition for USART1 peripheral ========== */ +#define PIO_PA25A_CTS1 (1u << 25) /**< \brief Usart1 signal: CTS1 */ +#define PIO_PA26A_DCD1 (1u << 26) /**< \brief Usart1 signal: DCD1 */ +#define PIO_PA28A_DSR1 (1u << 28) /**< \brief Usart1 signal: DSR1 */ +#define PIO_PA27A_DTR1 (1u << 27) /**< \brief Usart1 signal: DTR1 */ +#define PIO_PA29A_RI1 (1u << 29) /**< \brief Usart1 signal: RI1 */ +#define PIO_PA24A_RTS1 (1u << 24) /**< \brief Usart1 signal: RTS1 */ +#define PIO_PA21A_RXD1 (1u << 21) /**< \brief Usart1 signal: RXD1 */ +#define PIO_PA23A_SCK1 (1u << 23) /**< \brief Usart1 signal: SCK1 */ +#define PIO_PA22A_TXD1 (1u << 22) /**< \brief Usart1 signal: TXD1 */ +/* ========== Pio indexes ========== */ +#define PIO_PA0_IDX 0 +#define PIO_PA1_IDX 1 +#define PIO_PA2_IDX 2 +#define PIO_PA3_IDX 3 +#define PIO_PA4_IDX 4 +#define PIO_PA5_IDX 5 +#define PIO_PA6_IDX 6 +#define PIO_PA7_IDX 7 +#define PIO_PA8_IDX 8 +#define PIO_PA9_IDX 9 +#define PIO_PA10_IDX 10 +#define PIO_PA11_IDX 11 +#define PIO_PA12_IDX 12 +#define PIO_PA13_IDX 13 +#define PIO_PA14_IDX 14 +#define PIO_PA15_IDX 15 +#define PIO_PA16_IDX 16 +#define PIO_PA17_IDX 17 +#define PIO_PA18_IDX 18 +#define PIO_PA19_IDX 19 +#define PIO_PA20_IDX 20 +#define PIO_PA21_IDX 21 +#define PIO_PA22_IDX 22 +#define PIO_PA23_IDX 23 +#define PIO_PA24_IDX 24 +#define PIO_PA25_IDX 25 +#define PIO_PA26_IDX 26 +#define PIO_PA27_IDX 27 +#define PIO_PA28_IDX 28 +#define PIO_PA29_IDX 29 +#define PIO_PA30_IDX 30 +#define PIO_PA31_IDX 31 +#define PIO_PB0_IDX 32 +#define PIO_PB1_IDX 33 +#define PIO_PB2_IDX 34 +#define PIO_PB3_IDX 35 +#define PIO_PB4_IDX 36 +#define PIO_PB5_IDX 37 +#define PIO_PB6_IDX 38 +#define PIO_PB7_IDX 39 +#define PIO_PB8_IDX 40 +#define PIO_PB9_IDX 41 +#define PIO_PB10_IDX 42 +#define PIO_PB11_IDX 43 +#define PIO_PB12_IDX 44 +#define PIO_PB13_IDX 45 +#define PIO_PB14_IDX 46 +#define PIO_PD0_IDX 96 +#define PIO_PD1_IDX 97 +#define PIO_PD2_IDX 98 +#define PIO_PD3_IDX 99 +#define PIO_PD4_IDX 100 +#define PIO_PD5_IDX 101 +#define PIO_PD6_IDX 102 +#define PIO_PD7_IDX 103 +#define PIO_PD8_IDX 104 +#define PIO_PD9_IDX 105 +#define PIO_PD10_IDX 106 +#define PIO_PD11_IDX 107 +#define PIO_PD12_IDX 108 +#define PIO_PD13_IDX 109 +#define PIO_PD14_IDX 110 +#define PIO_PD15_IDX 111 +#define PIO_PD16_IDX 112 +#define PIO_PD17_IDX 113 +#define PIO_PD18_IDX 114 +#define PIO_PD19_IDX 115 +#define PIO_PD20_IDX 116 +#define PIO_PD21_IDX 117 +#define PIO_PD22_IDX 118 +#define PIO_PD23_IDX 119 +#define PIO_PD24_IDX 120 +#define PIO_PD25_IDX 121 +#define PIO_PD26_IDX 122 +#define PIO_PD27_IDX 123 +#define PIO_PD28_IDX 124 +#define PIO_PD29_IDX 125 +#define PIO_PD30_IDX 126 +#define PIO_PD31_IDX 127 + +#endif /* _SAM4E16C_PIO_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16e.h new file mode 100644 index 0000000..81d5c31 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e16e.h @@ -0,0 +1,540 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E16E_PIO_ +#define _SAM4E16E_PIO_ + +#define PIO_PA0 (1u << 0) /**< \brief Pin Controlled by PA0 */ +#define PIO_PA1 (1u << 1) /**< \brief Pin Controlled by PA1 */ +#define PIO_PA2 (1u << 2) /**< \brief Pin Controlled by PA2 */ +#define PIO_PA3 (1u << 3) /**< \brief Pin Controlled by PA3 */ +#define PIO_PA4 (1u << 4) /**< \brief Pin Controlled by PA4 */ +#define PIO_PA5 (1u << 5) /**< \brief Pin Controlled by PA5 */ +#define PIO_PA6 (1u << 6) /**< \brief Pin Controlled by PA6 */ +#define PIO_PA7 (1u << 7) /**< \brief Pin Controlled by PA7 */ +#define PIO_PA8 (1u << 8) /**< \brief Pin Controlled by PA8 */ +#define PIO_PA9 (1u << 9) /**< \brief Pin Controlled by PA9 */ +#define PIO_PA10 (1u << 10) /**< \brief Pin Controlled by PA10 */ +#define PIO_PA11 (1u << 11) /**< \brief Pin Controlled by PA11 */ +#define PIO_PA12 (1u << 12) /**< \brief Pin Controlled by PA12 */ +#define PIO_PA13 (1u << 13) /**< \brief Pin Controlled by PA13 */ +#define PIO_PA14 (1u << 14) /**< \brief Pin Controlled by PA14 */ +#define PIO_PA15 (1u << 15) /**< \brief Pin Controlled by PA15 */ +#define PIO_PA16 (1u << 16) /**< \brief Pin Controlled by PA16 */ +#define PIO_PA17 (1u << 17) /**< \brief Pin Controlled by PA17 */ +#define PIO_PA18 (1u << 18) /**< \brief Pin Controlled by PA18 */ +#define PIO_PA19 (1u << 19) /**< \brief Pin Controlled by PA19 */ +#define PIO_PA20 (1u << 20) /**< \brief Pin Controlled by PA20 */ +#define PIO_PA21 (1u << 21) /**< \brief Pin Controlled by PA21 */ +#define PIO_PA22 (1u << 22) /**< \brief Pin Controlled by PA22 */ +#define PIO_PA23 (1u << 23) /**< \brief Pin Controlled by PA23 */ +#define PIO_PA24 (1u << 24) /**< \brief Pin Controlled by PA24 */ +#define PIO_PA25 (1u << 25) /**< \brief Pin Controlled by PA25 */ +#define PIO_PA26 (1u << 26) /**< \brief Pin Controlled by PA26 */ +#define PIO_PA27 (1u << 27) /**< \brief Pin Controlled by PA27 */ +#define PIO_PA28 (1u << 28) /**< \brief Pin Controlled by PA28 */ +#define PIO_PA29 (1u << 29) /**< \brief Pin Controlled by PA29 */ +#define PIO_PA30 (1u << 30) /**< \brief Pin Controlled by PA30 */ +#define PIO_PA31 (1u << 31) /**< \brief Pin Controlled by PA31 */ +#define PIO_PB0 (1u << 0) /**< \brief Pin Controlled by PB0 */ +#define PIO_PB1 (1u << 1) /**< \brief Pin Controlled by PB1 */ +#define PIO_PB2 (1u << 2) /**< \brief Pin Controlled by PB2 */ +#define PIO_PB3 (1u << 3) /**< \brief Pin Controlled by PB3 */ +#define PIO_PB4 (1u << 4) /**< \brief Pin Controlled by PB4 */ +#define PIO_PB5 (1u << 5) /**< \brief Pin Controlled by PB5 */ +#define PIO_PB6 (1u << 6) /**< \brief Pin Controlled by PB6 */ +#define PIO_PB7 (1u << 7) /**< \brief Pin Controlled by PB7 */ +#define PIO_PB8 (1u << 8) /**< \brief Pin Controlled by PB8 */ +#define PIO_PB9 (1u << 9) /**< \brief Pin Controlled by PB9 */ +#define PIO_PB10 (1u << 10) /**< \brief Pin Controlled by PB10 */ +#define PIO_PB11 (1u << 11) /**< \brief Pin Controlled by PB11 */ +#define PIO_PB12 (1u << 12) /**< \brief Pin Controlled by PB12 */ +#define PIO_PB13 (1u << 13) /**< \brief Pin Controlled by PB13 */ +#define PIO_PB14 (1u << 14) /**< \brief Pin Controlled by PB14 */ +#define PIO_PC0 (1u << 0) /**< \brief Pin Controlled by PC0 */ +#define PIO_PC1 (1u << 1) /**< \brief Pin Controlled by PC1 */ +#define PIO_PC2 (1u << 2) /**< \brief Pin Controlled by PC2 */ +#define PIO_PC3 (1u << 3) /**< \brief Pin Controlled by PC3 */ +#define PIO_PC4 (1u << 4) /**< \brief Pin Controlled by PC4 */ +#define PIO_PC5 (1u << 5) /**< \brief Pin Controlled by PC5 */ +#define PIO_PC6 (1u << 6) /**< \brief Pin Controlled by PC6 */ +#define PIO_PC7 (1u << 7) /**< \brief Pin Controlled by PC7 */ +#define PIO_PC8 (1u << 8) /**< \brief Pin Controlled by PC8 */ +#define PIO_PC9 (1u << 9) /**< \brief Pin Controlled by PC9 */ +#define PIO_PC10 (1u << 10) /**< \brief Pin Controlled by PC10 */ +#define PIO_PC11 (1u << 11) /**< \brief Pin Controlled by PC11 */ +#define PIO_PC12 (1u << 12) /**< \brief Pin Controlled by PC12 */ +#define PIO_PC13 (1u << 13) /**< \brief Pin Controlled by PC13 */ +#define PIO_PC14 (1u << 14) /**< \brief Pin Controlled by PC14 */ +#define PIO_PC15 (1u << 15) /**< \brief Pin Controlled by PC15 */ +#define PIO_PC16 (1u << 16) /**< \brief Pin Controlled by PC16 */ +#define PIO_PC17 (1u << 17) /**< \brief Pin Controlled by PC17 */ +#define PIO_PC18 (1u << 18) /**< \brief Pin Controlled by PC18 */ +#define PIO_PC19 (1u << 19) /**< \brief Pin Controlled by PC19 */ +#define PIO_PC20 (1u << 20) /**< \brief Pin Controlled by PC20 */ +#define PIO_PC21 (1u << 21) /**< \brief Pin Controlled by PC21 */ +#define PIO_PC22 (1u << 22) /**< \brief Pin Controlled by PC22 */ +#define PIO_PC23 (1u << 23) /**< \brief Pin Controlled by PC23 */ +#define PIO_PC24 (1u << 24) /**< \brief Pin Controlled by PC24 */ +#define PIO_PC25 (1u << 25) /**< \brief Pin Controlled by PC25 */ +#define PIO_PC26 (1u << 26) /**< \brief Pin Controlled by PC26 */ +#define PIO_PC27 (1u << 27) /**< \brief Pin Controlled by PC27 */ +#define PIO_PC28 (1u << 28) /**< \brief Pin Controlled by PC28 */ +#define PIO_PC29 (1u << 29) /**< \brief Pin Controlled by PC29 */ +#define PIO_PC30 (1u << 30) /**< \brief Pin Controlled by PC30 */ +#define PIO_PC31 (1u << 31) /**< \brief Pin Controlled by PC31 */ +#define PIO_PD0 (1u << 0) /**< \brief Pin Controlled by PD0 */ +#define PIO_PD1 (1u << 1) /**< \brief Pin Controlled by PD1 */ +#define PIO_PD2 (1u << 2) /**< \brief Pin Controlled by PD2 */ +#define PIO_PD3 (1u << 3) /**< \brief Pin Controlled by PD3 */ +#define PIO_PD4 (1u << 4) /**< \brief Pin Controlled by PD4 */ +#define PIO_PD5 (1u << 5) /**< \brief Pin Controlled by PD5 */ +#define PIO_PD6 (1u << 6) /**< \brief Pin Controlled by PD6 */ +#define PIO_PD7 (1u << 7) /**< \brief Pin Controlled by PD7 */ +#define PIO_PD8 (1u << 8) /**< \brief Pin Controlled by PD8 */ +#define PIO_PD9 (1u << 9) /**< \brief Pin Controlled by PD9 */ +#define PIO_PD10 (1u << 10) /**< \brief Pin Controlled by PD10 */ +#define PIO_PD11 (1u << 11) /**< \brief Pin Controlled by PD11 */ +#define PIO_PD12 (1u << 12) /**< \brief Pin Controlled by PD12 */ +#define PIO_PD13 (1u << 13) /**< \brief Pin Controlled by PD13 */ +#define PIO_PD14 (1u << 14) /**< \brief Pin Controlled by PD14 */ +#define PIO_PD15 (1u << 15) /**< \brief Pin Controlled by PD15 */ +#define PIO_PD16 (1u << 16) /**< \brief Pin Controlled by PD16 */ +#define PIO_PD17 (1u << 17) /**< \brief Pin Controlled by PD17 */ +#define PIO_PD18 (1u << 18) /**< \brief Pin Controlled by PD18 */ +#define PIO_PD19 (1u << 19) /**< \brief Pin Controlled by PD19 */ +#define PIO_PD20 (1u << 20) /**< \brief Pin Controlled by PD20 */ +#define PIO_PD21 (1u << 21) /**< \brief Pin Controlled by PD21 */ +#define PIO_PD22 (1u << 22) /**< \brief Pin Controlled by PD22 */ +#define PIO_PD23 (1u << 23) /**< \brief Pin Controlled by PD23 */ +#define PIO_PD24 (1u << 24) /**< \brief Pin Controlled by PD24 */ +#define PIO_PD25 (1u << 25) /**< \brief Pin Controlled by PD25 */ +#define PIO_PD26 (1u << 26) /**< \brief Pin Controlled by PD26 */ +#define PIO_PD27 (1u << 27) /**< \brief Pin Controlled by PD27 */ +#define PIO_PD28 (1u << 28) /**< \brief Pin Controlled by PD28 */ +#define PIO_PD29 (1u << 29) /**< \brief Pin Controlled by PD29 */ +#define PIO_PD30 (1u << 30) /**< \brief Pin Controlled by PD30 */ +#define PIO_PD31 (1u << 31) /**< \brief Pin Controlled by PD31 */ +#define PIO_PE0 (1u << 0) /**< \brief Pin Controlled by PE0 */ +#define PIO_PE1 (1u << 1) /**< \brief Pin Controlled by PE1 */ +#define PIO_PE2 (1u << 2) /**< \brief Pin Controlled by PE2 */ +#define PIO_PE3 (1u << 3) /**< \brief Pin Controlled by PE3 */ +#define PIO_PE4 (1u << 4) /**< \brief Pin Controlled by PE4 */ +#define PIO_PE5 (1u << 5) /**< \brief Pin Controlled by PE5 */ +/* ========== Pio definition for AFEC0 peripheral ========== */ +#define PIO_PA17X1_AFE0_AD0 (1u << 17) /**< \brief Afec0 signal: AFE0_AD0 */ +#define PIO_PA18X1_AFE0_AD1 (1u << 18) /**< \brief Afec0 signal: AFE0_AD1 */ +#define PIO_PC30X1_AFE0_AD10 (1u << 30) /**< \brief Afec0 signal: AFE0_AD10 */ +#define PIO_PC31X1_AFE0_AD11 (1u << 31) /**< \brief Afec0 signal: AFE0_AD11 */ +#define PIO_PC26X1_AFE0_AD12 (1u << 26) /**< \brief Afec0 signal: AFE0_AD12 */ +#define PIO_PC27X1_AFE0_AD13 (1u << 27) /**< \brief Afec0 signal: AFE0_AD13 */ +#define PIO_PC0X1_AFE0_AD14 (1u << 0) /**< \brief Afec0 signal: AFE0_AD14 */ +#define PIO_PA19X1_AFE0_AD2 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA19X1_WKUP9 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA20X1_AFE0_AD3 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PA20X1_WKUP10 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PB0X1_AFE0_AD4 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB0X1_RTCOUT0 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB1X1_AFE0_AD5 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PB1X1_RTCOUT1 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PC13X1_AFE0_AD6 (1u << 13) /**< \brief Afec0 signal: AFE0_AD6 */ +#define PIO_PC15X1_AFE0_AD7 (1u << 15) /**< \brief Afec0 signal: AFE0_AD7 */ +#define PIO_PC12X1_AFE0_AD8 (1u << 12) /**< \brief Afec0 signal: AFE0_AD8 */ +#define PIO_PC29X1_AFE0_AD9 (1u << 29) /**< \brief Afec0 signal: AFE0_AD9 */ +#define PIO_PA8B_AFE0_ADTRG (1u << 8) /**< \brief Afec0 signal: AFE0_ADTRG */ +/* ========== Pio definition for AFEC1 peripheral ========== */ +#define PIO_PB2X1_AFE1_AD0 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB2X1_WKUP12 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB3X1_AFE1_AD1 (1u << 3) /**< \brief Afec1 signal: AFE1_AD1 */ +#define PIO_PA21X1_AFE1_AD2 (1u << 21) /**< \brief Afec1 signal: AFE1_AD2 */ +#define PIO_PA22X1_AFE1_AD3 (1u << 22) /**< \brief Afec1 signal: AFE1_AD3 */ +#define PIO_PC1X1_AFE1_AD4 (1u << 1) /**< \brief Afec1 signal: AFE1_AD4 */ +#define PIO_PC2X1_AFE1_AD5 (1u << 2) /**< \brief Afec1 signal: AFE1_AD5 */ +#define PIO_PC3X1_AFE1_AD6 (1u << 3) /**< \brief Afec1 signal: AFE1_AD6 */ +#define PIO_PC4X1_AFE1_AD7 (1u << 4) /**< \brief Afec1 signal: AFE1_AD7 */ +/* ========== Pio definition for CAN0 peripheral ========== */ +#define PIO_PB3A_CANRX0 (1u << 3) /**< \brief Can0 signal: CANRX0 */ +#define PIO_PB2A_CANTX0 (1u << 2) /**< \brief Can0 signal: CANTX0 */ +/* ========== Pio definition for CAN1 peripheral ========== */ +#define PIO_PC12C_CANRX1 (1u << 12) /**< \brief Can1 signal: CANRX1 */ +#define PIO_PC15C_CANTX1 (1u << 15) /**< \brief Can1 signal: CANTX1 */ +/* ========== Pio definition for DACC peripheral ========== */ +#define PIO_PB13X1_DAC0 (1u << 13) /**< \brief Dacc signal: DAC0 */ +#define PIO_PB14X1_DAC1 (1u << 14) /**< \brief Dacc signal: DAC1 */ +#define PIO_PA2C_DATRG (1u << 2) /**< \brief Dacc signal: DATRG */ +/* ========== Pio definition for EBI peripheral ========== */ +#define PIO_PC18A_A0 (1u << 18) /**< \brief Ebi signal: A0 */ +#define PIO_PC19A_A1 (1u << 19) /**< \brief Ebi signal: A1 */ +#define PIO_PC28A_A10 (1u << 28) /**< \brief Ebi signal: A10 */ +#define PIO_PC29A_A11 (1u << 29) /**< \brief Ebi signal: A11 */ +#define PIO_PC30A_A12 (1u << 30) /**< \brief Ebi signal: A12 */ +#define PIO_PC31A_A13 (1u << 31) /**< \brief Ebi signal: A13 */ +#define PIO_PA18C_A14 (1u << 18) /**< \brief Ebi signal: A14 */ +#define PIO_PA19C_A15 (1u << 19) /**< \brief Ebi signal: A15 */ +#define PIO_PA20C_A16 (1u << 20) /**< \brief Ebi signal: A16 */ +#define PIO_PA0C_A17 (1u << 0) /**< \brief Ebi signal: A17 */ +#define PIO_PA1C_A18 (1u << 1) /**< \brief Ebi signal: A18 */ +#define PIO_PA23C_A19 (1u << 23) /**< \brief Ebi signal: A19 */ +#define PIO_PC20A_A2 (1u << 20) /**< \brief Ebi signal: A2 */ +#define PIO_PA24C_A20 (1u << 24) /**< \brief Ebi signal: A20 */ +#define PIO_PC16A_A21 (1u << 16) /**< \brief Ebi signal: A21/NANDALE */ +#define PIO_PC16A_NANDALE (1u << 16) /**< \brief Ebi signal: A21/NANDALE */ +#define PIO_PC17A_A22 (1u << 17) /**< \brief Ebi signal: A22/NANDCLE */ +#define PIO_PC17A_NANDCLE (1u << 17) /**< \brief Ebi signal: A22/NANDCLE */ +#define PIO_PA25C_A23 (1u << 25) /**< \brief Ebi signal: A23 */ +#define PIO_PC21A_A3 (1u << 21) /**< \brief Ebi signal: A3 */ +#define PIO_PC22A_A4 (1u << 22) /**< \brief Ebi signal: A4 */ +#define PIO_PC23A_A5 (1u << 23) /**< \brief Ebi signal: A5 */ +#define PIO_PC24A_A6 (1u << 24) /**< \brief Ebi signal: A6 */ +#define PIO_PC25A_A7 (1u << 25) /**< \brief Ebi signal: A7 */ +#define PIO_PC26A_A8 (1u << 26) /**< \brief Ebi signal: A8 */ +#define PIO_PC27A_A9 (1u << 27) /**< \brief Ebi signal: A9 */ +#define PIO_PC0A_D0 (1u << 0) /**< \brief Ebi signal: D0 */ +#define PIO_PC1A_D1 (1u << 1) /**< \brief Ebi signal: D1 */ +#define PIO_PC2A_D2 (1u << 2) /**< \brief Ebi signal: D2 */ +#define PIO_PC3A_D3 (1u << 3) /**< \brief Ebi signal: D3 */ +#define PIO_PC4A_D4 (1u << 4) /**< \brief Ebi signal: D4 */ +#define PIO_PC5A_D5 (1u << 5) /**< \brief Ebi signal: D5 */ +#define PIO_PC6A_D6 (1u << 6) /**< \brief Ebi signal: D6 */ +#define PIO_PC7A_D7 (1u << 7) /**< \brief Ebi signal: D7 */ +#define PIO_PC9A_NANDOE (1u << 9) /**< \brief Ebi signal: NANDOE */ +#define PIO_PC10A_NANDWE (1u << 10) /**< \brief Ebi signal: NANDWE */ +#define PIO_PC14A_NCS0 (1u << 14) /**< \brief Ebi signal: NCS0 */ +#define PIO_PC15A_NCS1 (1u << 15) /**< \brief Ebi signal: NCS1 */ +#define PIO_PD18A_NCS1 (1u << 18) /**< \brief Ebi signal: NCS1 */ +#define PIO_PA22C_NCS2 (1u << 22) /**< \brief Ebi signal: NCS2 */ +#define PIO_PC12A_NCS3 (1u << 12) /**< \brief Ebi signal: NCS3 */ +#define PIO_PD19A_NCS3 (1u << 19) /**< \brief Ebi signal: NCS3 */ +#define PIO_PC11A_NRD (1u << 11) /**< \brief Ebi signal: NRD */ +#define PIO_PC13A_NWAIT (1u << 13) /**< \brief Ebi signal: NWAIT */ +#define PIO_PC8A_NWE (1u << 8) /**< \brief Ebi signal: NWE */ +/* ========== Pio definition for GMAC peripheral ========== */ +#define PIO_PD13A_GCOL (1u << 13) /**< \brief Gmac signal: GCOL */ +#define PIO_PD10A_GCRS (1u << 10) /**< \brief Gmac signal: GCRS */ +#define PIO_PD4A_GCRSDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD4A_GRXDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD8A_GMDC (1u << 8) /**< \brief Gmac signal: GMDC */ +#define PIO_PD9A_GMDIO (1u << 9) /**< \brief Gmac signal: GMDIO */ +#define PIO_PD5A_GRX0 (1u << 5) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD6A_GRX0 (1u << 6) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD11A_GRX2 (1u << 11) /**< \brief Gmac signal: GRX2 */ +#define PIO_PD12A_GRX3 (1u << 12) /**< \brief Gmac signal: GRX3 */ +#define PIO_PD14A_GRXCK (1u << 14) /**< \brief Gmac signal: GRXCK */ +#define PIO_PD7A_GRXER (1u << 7) /**< \brief Gmac signal: GRXER */ +#define PIO_PD2A_GTX0 (1u << 2) /**< \brief Gmac signal: GTX0 */ +#define PIO_PD3A_GTX1 (1u << 3) /**< \brief Gmac signal: GTX1 */ +#define PIO_PD15A_GTX2 (1u << 15) /**< \brief Gmac signal: GTX2 */ +#define PIO_PD16A_GTX3 (1u << 16) /**< \brief Gmac signal: GTX3 */ +#define PIO_PD0A_GTXCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD0A_GREFCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD1A_GTXEN (1u << 1) /**< \brief Gmac signal: GTXEN */ +#define PIO_PD17A_GTXER (1u << 17) /**< \brief Gmac signal: GTXER */ +/* ========== Pio definition for HSMCI peripheral ========== */ +#define PIO_PA28C_MCCDA (1u << 28) /**< \brief Hsmci signal: MCCDA */ +#define PIO_PA29C_MCCK (1u << 29) /**< \brief Hsmci signal: MCCK */ +#define PIO_PA30C_MCDA0 (1u << 30) /**< \brief Hsmci signal: MCDA0 */ +#define PIO_PA31C_MCDA1 (1u << 31) /**< \brief Hsmci signal: MCDA1 */ +#define PIO_PA26C_MCDA2 (1u << 26) /**< \brief Hsmci signal: MCDA2 */ +#define PIO_PA27C_MCDA3 (1u << 27) /**< \brief Hsmci signal: MCDA3 */ +/* ========== Pio definition for PIOA peripheral ========== */ +#define PIO_PA24X1_PIODC0 (1u << 24) /**< \brief Pioa signal: PIODC0 */ +#define PIO_PA25X1_PIODC1 (1u << 25) /**< \brief Pioa signal: PIODC1 */ +#define PIO_PA26X1_PIODC2 (1u << 26) /**< \brief Pioa signal: PIODC2 */ +#define PIO_PA27X1_PIODC3 (1u << 27) /**< \brief Pioa signal: PIODC3 */ +#define PIO_PA28X1_PIODC4 (1u << 28) /**< \brief Pioa signal: PIODC4 */ +#define PIO_PA29X1_PIODC5 (1u << 29) /**< \brief Pioa signal: PIODC5 */ +#define PIO_PA31X1_PIODC7 (1u << 31) /**< \brief Pioa signal: PIODC7 */ +#define PIO_PA23X1_PIODCCLK (1u << 23) /**< \brief Pioa signal: PIODCCLK */ +#define PIO_PA30X1_WKUP11 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA30X1_PIODC6 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA15X1_WKUP14 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA15X1_PIODCEN1 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA16X1_WKUP15 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +#define PIO_PA16X1_PIODCEN2 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +/* ========== Pio definition for PMC peripheral ========== */ +#define PIO_PA6B_PCK0 (1u << 6) /**< \brief Pmc signal: PCK0 */ +#define PIO_PB13B_PCK0 (1u << 13) /**< \brief Pmc signal: PCK0 */ +#define PIO_PA17B_PCK1 (1u << 17) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA21B_PCK1 (1u << 21) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA18B_PCK2 (1u << 18) /**< \brief Pmc signal: PCK2 */ +#define PIO_PA31B_PCK2 (1u << 31) /**< \brief Pmc signal: PCK2 */ +#define PIO_PB3B_PCK2 (1u << 3) /**< \brief Pmc signal: PCK2 */ +/* ========== Pio definition for PWM peripheral ========== */ +#define PIO_PA9C_PWMFI0 (1u << 9) /**< \brief Pwm signal: PWMFI0 */ +#define PIO_PA0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA11B_PWMH0 (1u << 11) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA23B_PWMH0 (1u << 23) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PB0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PC18B_PWMH0 (1u << 18) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PD20A_PWMH0 (1u << 20) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA12B_PWMH1 (1u << 12) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA24B_PWMH1 (1u << 24) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PB1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PC19B_PWMH1 (1u << 19) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PD21A_PWMH1 (1u << 21) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA2A_PWMH2 (1u << 2) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA13B_PWMH2 (1u << 13) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA25B_PWMH2 (1u << 25) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PB4B_PWMH2 (1u << 4) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PC20B_PWMH2 (1u << 20) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PD22A_PWMH2 (1u << 22) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA7B_PWMH3 (1u << 7) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA17C_PWMH3 (1u << 17) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PB14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PC21B_PWMH3 (1u << 21) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PD23A_PWMH3 (1u << 23) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA19B_PWML0 (1u << 19) /**< \brief Pwm signal: PWML0 */ +#define PIO_PB5B_PWML0 (1u << 5) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC0B_PWML0 (1u << 0) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC13B_PWML0 (1u << 13) /**< \brief Pwm signal: PWML0 */ +#define PIO_PD24A_PWML0 (1u << 24) /**< \brief Pwm signal: PWML0 */ +#define PIO_PA20B_PWML1 (1u << 20) /**< \brief Pwm signal: PWML1 */ +#define PIO_PB12A_PWML1 (1u << 12) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC1B_PWML1 (1u << 1) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC15B_PWML1 (1u << 15) /**< \brief Pwm signal: PWML1 */ +#define PIO_PD25A_PWML1 (1u << 25) /**< \brief Pwm signal: PWML1 */ +#define PIO_PA16C_PWML2 (1u << 16) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA30A_PWML2 (1u << 30) /**< \brief Pwm signal: PWML2 */ +#define PIO_PB13A_PWML2 (1u << 13) /**< \brief Pwm signal: PWML2 */ +#define PIO_PC2B_PWML2 (1u << 2) /**< \brief Pwm signal: PWML2 */ +#define PIO_PD26A_PWML2 (1u << 26) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA15C_PWML3 (1u << 15) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC3B_PWML3 (1u << 3) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC22B_PWML3 (1u << 22) /**< \brief Pwm signal: PWML3 */ +#define PIO_PD27A_PWML3 (1u << 27) /**< \brief Pwm signal: PWML3 */ +/* ========== Pio definition for SPI peripheral ========== */ +#define PIO_PA12A_MISO (1u << 12) /**< \brief Spi signal: MISO */ +#define PIO_PA13A_MOSI (1u << 13) /**< \brief Spi signal: MOSI */ +#define PIO_PA11A_NPCS0 (1u << 11) /**< \brief Spi signal: NPCS0 */ +#define PIO_PA9B_NPCS1 (1u << 9) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA31A_NPCS1 (1u << 31) /**< \brief Spi signal: NPCS1 */ +#define PIO_PB14A_NPCS1 (1u << 14) /**< \brief Spi signal: NPCS1 */ +#define PIO_PC4B_NPCS1 (1u << 4) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA10B_NPCS2 (1u << 10) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA30B_NPCS2 (1u << 30) /**< \brief Spi signal: NPCS2 */ +#define PIO_PB2B_NPCS2 (1u << 2) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA3B_NPCS3 (1u << 3) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA5B_NPCS3 (1u << 5) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA22B_NPCS3 (1u << 22) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA14A_SPCK (1u << 14) /**< \brief Spi signal: SPCK */ +/* ========== Pio definition for TC0 peripheral ========== */ +#define PIO_PA4B_TCLK0 (1u << 4) /**< \brief Tc0 signal: TCLK0 */ +#define PIO_PA28B_TCLK1 (1u << 28) /**< \brief Tc0 signal: TCLK1 */ +#define PIO_PA29B_TCLK2 (1u << 29) /**< \brief Tc0 signal: TCLK2 */ +#define PIO_PA0B_TIOA0 (1u << 0) /**< \brief Tc0 signal: TIOA0 */ +#define PIO_PA15B_TIOA1 (1u << 15) /**< \brief Tc0 signal: TIOA1 */ +#define PIO_PA26B_TIOA2 (1u << 26) /**< \brief Tc0 signal: TIOA2 */ +#define PIO_PA1B_TIOB0 (1u << 1) /**< \brief Tc0 signal: TIOB0 */ +#define PIO_PA16B_TIOB1 (1u << 16) /**< \brief Tc0 signal: TIOB1 */ +#define PIO_PA27B_TIOB2 (1u << 27) /**< \brief Tc0 signal: TIOB2 */ +/* ========== Pio definition for TC1 peripheral ========== */ +#define PIO_PC25B_TCLK3 (1u << 25) /**< \brief Tc1 signal: TCLK3 */ +#define PIO_PC28B_TCLK4 (1u << 28) /**< \brief Tc1 signal: TCLK4 */ +#define PIO_PC31B_TCLK5 (1u << 31) /**< \brief Tc1 signal: TCLK5 */ +#define PIO_PC23B_TIOA3 (1u << 23) /**< \brief Tc1 signal: TIOA3 */ +#define PIO_PC26B_TIOA4 (1u << 26) /**< \brief Tc1 signal: TIOA4 */ +#define PIO_PC29B_TIOA5 (1u << 29) /**< \brief Tc1 signal: TIOA5 */ +#define PIO_PC24B_TIOB3 (1u << 24) /**< \brief Tc1 signal: TIOB3 */ +#define PIO_PC27B_TIOB4 (1u << 27) /**< \brief Tc1 signal: TIOB4 */ +#define PIO_PC30B_TIOB5 (1u << 30) /**< \brief Tc1 signal: TIOB5 */ +/* ========== Pio definition for TC2 peripheral ========== */ +#define PIO_PC7B_TCLK6 (1u << 7) /**< \brief Tc2 signal: TCLK6 */ +#define PIO_PC10B_TCLK7 (1u << 10) /**< \brief Tc2 signal: TCLK7 */ +#define PIO_PC14B_TCLK8 (1u << 14) /**< \brief Tc2 signal: TCLK8 */ +#define PIO_PC5B_TIOA6 (1u << 5) /**< \brief Tc2 signal: TIOA6 */ +#define PIO_PC8B_TIOA7 (1u << 8) /**< \brief Tc2 signal: TIOA7 */ +#define PIO_PC11B_TIOA8 (1u << 11) /**< \brief Tc2 signal: TIOA8 */ +#define PIO_PC6B_TIOB6 (1u << 6) /**< \brief Tc2 signal: TIOB6 */ +#define PIO_PC9B_TIOB7 (1u << 9) /**< \brief Tc2 signal: TIOB7 */ +#define PIO_PC12B_TIOB8 (1u << 12) /**< \brief Tc2 signal: TIOB8 */ +/* ========== Pio definition for TWI0 peripheral ========== */ +#define PIO_PA4A_TWCK0 (1u << 4) /**< \brief Twi0 signal: TWCK0 */ +#define PIO_PA3A_TWD0 (1u << 3) /**< \brief Twi0 signal: TWD0 */ +/* ========== Pio definition for TWI1 peripheral ========== */ +#define PIO_PB5A_TWCK1 (1u << 5) /**< \brief Twi1 signal: TWCK1 */ +#define PIO_PB4A_TWD1 (1u << 4) /**< \brief Twi1 signal: TWD1 */ +/* ========== Pio definition for UART0 peripheral ========== */ +#define PIO_PA9A_URXD0 (1u << 9) /**< \brief Uart0 signal: URXD0 */ +#define PIO_PA10A_UTXD0 (1u << 10) /**< \brief Uart0 signal: UTXD0 */ +/* ========== Pio definition for UART1 peripheral ========== */ +#define PIO_PA5C_URXD1 (1u << 5) /**< \brief Uart1 signal: URXD1 */ +#define PIO_PA6C_UTXD1 (1u << 6) /**< \brief Uart1 signal: UTXD1 */ +/* ========== Pio definition for USART0 peripheral ========== */ +#define PIO_PB2C_CTS0 (1u << 2) /**< \brief Usart0 signal: CTS0 */ +#define PIO_PB3C_RTS0 (1u << 3) /**< \brief Usart0 signal: RTS0 */ +#define PIO_PB0C_RXD0 (1u << 0) /**< \brief Usart0 signal: RXD0 */ +#define PIO_PB13C_SCK0 (1u << 13) /**< \brief Usart0 signal: SCK0 */ +#define PIO_PB1C_TXD0 (1u << 1) /**< \brief Usart0 signal: TXD0 */ +/* ========== Pio definition for USART1 peripheral ========== */ +#define PIO_PA25A_CTS1 (1u << 25) /**< \brief Usart1 signal: CTS1 */ +#define PIO_PA26A_DCD1 (1u << 26) /**< \brief Usart1 signal: DCD1 */ +#define PIO_PA28A_DSR1 (1u << 28) /**< \brief Usart1 signal: DSR1 */ +#define PIO_PA27A_DTR1 (1u << 27) /**< \brief Usart1 signal: DTR1 */ +#define PIO_PA29A_RI1 (1u << 29) /**< \brief Usart1 signal: RI1 */ +#define PIO_PA24A_RTS1 (1u << 24) /**< \brief Usart1 signal: RTS1 */ +#define PIO_PA21A_RXD1 (1u << 21) /**< \brief Usart1 signal: RXD1 */ +#define PIO_PA23A_SCK1 (1u << 23) /**< \brief Usart1 signal: SCK1 */ +#define PIO_PA22A_TXD1 (1u << 22) /**< \brief Usart1 signal: TXD1 */ +/* ========== Pio indexes ========== */ +#define PIO_PA0_IDX 0 +#define PIO_PA1_IDX 1 +#define PIO_PA2_IDX 2 +#define PIO_PA3_IDX 3 +#define PIO_PA4_IDX 4 +#define PIO_PA5_IDX 5 +#define PIO_PA6_IDX 6 +#define PIO_PA7_IDX 7 +#define PIO_PA8_IDX 8 +#define PIO_PA9_IDX 9 +#define PIO_PA10_IDX 10 +#define PIO_PA11_IDX 11 +#define PIO_PA12_IDX 12 +#define PIO_PA13_IDX 13 +#define PIO_PA14_IDX 14 +#define PIO_PA15_IDX 15 +#define PIO_PA16_IDX 16 +#define PIO_PA17_IDX 17 +#define PIO_PA18_IDX 18 +#define PIO_PA19_IDX 19 +#define PIO_PA20_IDX 20 +#define PIO_PA21_IDX 21 +#define PIO_PA22_IDX 22 +#define PIO_PA23_IDX 23 +#define PIO_PA24_IDX 24 +#define PIO_PA25_IDX 25 +#define PIO_PA26_IDX 26 +#define PIO_PA27_IDX 27 +#define PIO_PA28_IDX 28 +#define PIO_PA29_IDX 29 +#define PIO_PA30_IDX 30 +#define PIO_PA31_IDX 31 +#define PIO_PB0_IDX 32 +#define PIO_PB1_IDX 33 +#define PIO_PB2_IDX 34 +#define PIO_PB3_IDX 35 +#define PIO_PB4_IDX 36 +#define PIO_PB5_IDX 37 +#define PIO_PB6_IDX 38 +#define PIO_PB7_IDX 39 +#define PIO_PB8_IDX 40 +#define PIO_PB9_IDX 41 +#define PIO_PB10_IDX 42 +#define PIO_PB11_IDX 43 +#define PIO_PB12_IDX 44 +#define PIO_PB13_IDX 45 +#define PIO_PB14_IDX 46 +#define PIO_PC0_IDX 64 +#define PIO_PC1_IDX 65 +#define PIO_PC2_IDX 66 +#define PIO_PC3_IDX 67 +#define PIO_PC4_IDX 68 +#define PIO_PC5_IDX 69 +#define PIO_PC6_IDX 70 +#define PIO_PC7_IDX 71 +#define PIO_PC8_IDX 72 +#define PIO_PC9_IDX 73 +#define PIO_PC10_IDX 74 +#define PIO_PC11_IDX 75 +#define PIO_PC12_IDX 76 +#define PIO_PC13_IDX 77 +#define PIO_PC14_IDX 78 +#define PIO_PC15_IDX 79 +#define PIO_PC16_IDX 80 +#define PIO_PC17_IDX 81 +#define PIO_PC18_IDX 82 +#define PIO_PC19_IDX 83 +#define PIO_PC20_IDX 84 +#define PIO_PC21_IDX 85 +#define PIO_PC22_IDX 86 +#define PIO_PC23_IDX 87 +#define PIO_PC24_IDX 88 +#define PIO_PC25_IDX 89 +#define PIO_PC26_IDX 90 +#define PIO_PC27_IDX 91 +#define PIO_PC28_IDX 92 +#define PIO_PC29_IDX 93 +#define PIO_PC30_IDX 94 +#define PIO_PC31_IDX 95 +#define PIO_PD0_IDX 96 +#define PIO_PD1_IDX 97 +#define PIO_PD2_IDX 98 +#define PIO_PD3_IDX 99 +#define PIO_PD4_IDX 100 +#define PIO_PD5_IDX 101 +#define PIO_PD6_IDX 102 +#define PIO_PD7_IDX 103 +#define PIO_PD8_IDX 104 +#define PIO_PD9_IDX 105 +#define PIO_PD10_IDX 106 +#define PIO_PD11_IDX 107 +#define PIO_PD12_IDX 108 +#define PIO_PD13_IDX 109 +#define PIO_PD14_IDX 110 +#define PIO_PD15_IDX 111 +#define PIO_PD16_IDX 112 +#define PIO_PD17_IDX 113 +#define PIO_PD18_IDX 114 +#define PIO_PD19_IDX 115 +#define PIO_PD20_IDX 116 +#define PIO_PD21_IDX 117 +#define PIO_PD22_IDX 118 +#define PIO_PD23_IDX 119 +#define PIO_PD24_IDX 120 +#define PIO_PD25_IDX 121 +#define PIO_PD26_IDX 122 +#define PIO_PD27_IDX 123 +#define PIO_PD28_IDX 124 +#define PIO_PD29_IDX 125 +#define PIO_PD30_IDX 126 +#define PIO_PD31_IDX 127 +#define PIO_PE0_IDX 128 +#define PIO_PE1_IDX 129 +#define PIO_PE2_IDX 130 +#define PIO_PE3_IDX 131 +#define PIO_PE4_IDX 132 +#define PIO_PE5_IDX 133 + +#endif /* _SAM4E16E_PIO_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8c.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8c.h new file mode 100644 index 0000000..c9209a2 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8c.h @@ -0,0 +1,395 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E8C_PIO_ +#define _SAM4E8C_PIO_ + +#define PIO_PA0 (1u << 0) /**< \brief Pin Controlled by PA0 */ +#define PIO_PA1 (1u << 1) /**< \brief Pin Controlled by PA1 */ +#define PIO_PA2 (1u << 2) /**< \brief Pin Controlled by PA2 */ +#define PIO_PA3 (1u << 3) /**< \brief Pin Controlled by PA3 */ +#define PIO_PA4 (1u << 4) /**< \brief Pin Controlled by PA4 */ +#define PIO_PA5 (1u << 5) /**< \brief Pin Controlled by PA5 */ +#define PIO_PA6 (1u << 6) /**< \brief Pin Controlled by PA6 */ +#define PIO_PA7 (1u << 7) /**< \brief Pin Controlled by PA7 */ +#define PIO_PA8 (1u << 8) /**< \brief Pin Controlled by PA8 */ +#define PIO_PA9 (1u << 9) /**< \brief Pin Controlled by PA9 */ +#define PIO_PA10 (1u << 10) /**< \brief Pin Controlled by PA10 */ +#define PIO_PA11 (1u << 11) /**< \brief Pin Controlled by PA11 */ +#define PIO_PA12 (1u << 12) /**< \brief Pin Controlled by PA12 */ +#define PIO_PA13 (1u << 13) /**< \brief Pin Controlled by PA13 */ +#define PIO_PA14 (1u << 14) /**< \brief Pin Controlled by PA14 */ +#define PIO_PA15 (1u << 15) /**< \brief Pin Controlled by PA15 */ +#define PIO_PA16 (1u << 16) /**< \brief Pin Controlled by PA16 */ +#define PIO_PA17 (1u << 17) /**< \brief Pin Controlled by PA17 */ +#define PIO_PA18 (1u << 18) /**< \brief Pin Controlled by PA18 */ +#define PIO_PA19 (1u << 19) /**< \brief Pin Controlled by PA19 */ +#define PIO_PA20 (1u << 20) /**< \brief Pin Controlled by PA20 */ +#define PIO_PA21 (1u << 21) /**< \brief Pin Controlled by PA21 */ +#define PIO_PA22 (1u << 22) /**< \brief Pin Controlled by PA22 */ +#define PIO_PA23 (1u << 23) /**< \brief Pin Controlled by PA23 */ +#define PIO_PA24 (1u << 24) /**< \brief Pin Controlled by PA24 */ +#define PIO_PA25 (1u << 25) /**< \brief Pin Controlled by PA25 */ +#define PIO_PA26 (1u << 26) /**< \brief Pin Controlled by PA26 */ +#define PIO_PA27 (1u << 27) /**< \brief Pin Controlled by PA27 */ +#define PIO_PA28 (1u << 28) /**< \brief Pin Controlled by PA28 */ +#define PIO_PA29 (1u << 29) /**< \brief Pin Controlled by PA29 */ +#define PIO_PA30 (1u << 30) /**< \brief Pin Controlled by PA30 */ +#define PIO_PA31 (1u << 31) /**< \brief Pin Controlled by PA31 */ +#define PIO_PB0 (1u << 0) /**< \brief Pin Controlled by PB0 */ +#define PIO_PB1 (1u << 1) /**< \brief Pin Controlled by PB1 */ +#define PIO_PB2 (1u << 2) /**< \brief Pin Controlled by PB2 */ +#define PIO_PB3 (1u << 3) /**< \brief Pin Controlled by PB3 */ +#define PIO_PB4 (1u << 4) /**< \brief Pin Controlled by PB4 */ +#define PIO_PB5 (1u << 5) /**< \brief Pin Controlled by PB5 */ +#define PIO_PB6 (1u << 6) /**< \brief Pin Controlled by PB6 */ +#define PIO_PB7 (1u << 7) /**< \brief Pin Controlled by PB7 */ +#define PIO_PB8 (1u << 8) /**< \brief Pin Controlled by PB8 */ +#define PIO_PB9 (1u << 9) /**< \brief Pin Controlled by PB9 */ +#define PIO_PB10 (1u << 10) /**< \brief Pin Controlled by PB10 */ +#define PIO_PB11 (1u << 11) /**< \brief Pin Controlled by PB11 */ +#define PIO_PB12 (1u << 12) /**< \brief Pin Controlled by PB12 */ +#define PIO_PB13 (1u << 13) /**< \brief Pin Controlled by PB13 */ +#define PIO_PB14 (1u << 14) /**< \brief Pin Controlled by PB14 */ +#define PIO_PD0 (1u << 0) /**< \brief Pin Controlled by PD0 */ +#define PIO_PD1 (1u << 1) /**< \brief Pin Controlled by PD1 */ +#define PIO_PD2 (1u << 2) /**< \brief Pin Controlled by PD2 */ +#define PIO_PD3 (1u << 3) /**< \brief Pin Controlled by PD3 */ +#define PIO_PD4 (1u << 4) /**< \brief Pin Controlled by PD4 */ +#define PIO_PD5 (1u << 5) /**< \brief Pin Controlled by PD5 */ +#define PIO_PD6 (1u << 6) /**< \brief Pin Controlled by PD6 */ +#define PIO_PD7 (1u << 7) /**< \brief Pin Controlled by PD7 */ +#define PIO_PD8 (1u << 8) /**< \brief Pin Controlled by PD8 */ +#define PIO_PD9 (1u << 9) /**< \brief Pin Controlled by PD9 */ +#define PIO_PD10 (1u << 10) /**< \brief Pin Controlled by PD10 */ +#define PIO_PD11 (1u << 11) /**< \brief Pin Controlled by PD11 */ +#define PIO_PD12 (1u << 12) /**< \brief Pin Controlled by PD12 */ +#define PIO_PD13 (1u << 13) /**< \brief Pin Controlled by PD13 */ +#define PIO_PD14 (1u << 14) /**< \brief Pin Controlled by PD14 */ +#define PIO_PD15 (1u << 15) /**< \brief Pin Controlled by PD15 */ +#define PIO_PD16 (1u << 16) /**< \brief Pin Controlled by PD16 */ +#define PIO_PD17 (1u << 17) /**< \brief Pin Controlled by PD17 */ +#define PIO_PD18 (1u << 18) /**< \brief Pin Controlled by PD18 */ +#define PIO_PD19 (1u << 19) /**< \brief Pin Controlled by PD19 */ +#define PIO_PD20 (1u << 20) /**< \brief Pin Controlled by PD20 */ +#define PIO_PD21 (1u << 21) /**< \brief Pin Controlled by PD21 */ +#define PIO_PD22 (1u << 22) /**< \brief Pin Controlled by PD22 */ +#define PIO_PD23 (1u << 23) /**< \brief Pin Controlled by PD23 */ +#define PIO_PD24 (1u << 24) /**< \brief Pin Controlled by PD24 */ +#define PIO_PD25 (1u << 25) /**< \brief Pin Controlled by PD25 */ +#define PIO_PD26 (1u << 26) /**< \brief Pin Controlled by PD26 */ +#define PIO_PD27 (1u << 27) /**< \brief Pin Controlled by PD27 */ +#define PIO_PD28 (1u << 28) /**< \brief Pin Controlled by PD28 */ +#define PIO_PD29 (1u << 29) /**< \brief Pin Controlled by PD29 */ +#define PIO_PD30 (1u << 30) /**< \brief Pin Controlled by PD30 */ +#define PIO_PD31 (1u << 31) /**< \brief Pin Controlled by PD31 */ +/* ========== Pio definition for AFEC0 peripheral ========== */ +#define PIO_PA17X1_AFE0_AD0 (1u << 17) /**< \brief Afec0 signal: AFE0_AD0 */ +#define PIO_PA18X1_AFE0_AD1 (1u << 18) /**< \brief Afec0 signal: AFE0_AD1 */ +#define PIO_PC30X1_AFE0_AD10 (1u << 30) /**< \brief Afec0 signal: AFE0_AD10 */ +#define PIO_PC31X1_AFE0_AD11 (1u << 31) /**< \brief Afec0 signal: AFE0_AD11 */ +#define PIO_PC26X1_AFE0_AD12 (1u << 26) /**< \brief Afec0 signal: AFE0_AD12 */ +#define PIO_PC27X1_AFE0_AD13 (1u << 27) /**< \brief Afec0 signal: AFE0_AD13 */ +#define PIO_PC0X1_AFE0_AD14 (1u << 0) /**< \brief Afec0 signal: AFE0_AD14 */ +#define PIO_PA19X1_AFE0_AD2 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA19X1_WKUP9 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA20X1_AFE0_AD3 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PA20X1_WKUP10 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PB0X1_AFE0_AD4 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB0X1_RTCOUT0 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB1X1_AFE0_AD5 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PB1X1_RTCOUT1 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PC13X1_AFE0_AD6 (1u << 13) /**< \brief Afec0 signal: AFE0_AD6 */ +#define PIO_PC15X1_AFE0_AD7 (1u << 15) /**< \brief Afec0 signal: AFE0_AD7 */ +#define PIO_PC12X1_AFE0_AD8 (1u << 12) /**< \brief Afec0 signal: AFE0_AD8 */ +#define PIO_PC29X1_AFE0_AD9 (1u << 29) /**< \brief Afec0 signal: AFE0_AD9 */ +#define PIO_PA8B_AFE0_ADTRG (1u << 8) /**< \brief Afec0 signal: AFE0_ADTRG */ +/* ========== Pio definition for AFEC1 peripheral ========== */ +#define PIO_PB2X1_AFE1_AD0 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB2X1_WKUP12 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB3X1_AFE1_AD1 (1u << 3) /**< \brief Afec1 signal: AFE1_AD1 */ +#define PIO_PA21X1_AFE1_AD2 (1u << 21) /**< \brief Afec1 signal: AFE1_AD2 */ +#define PIO_PA22X1_AFE1_AD3 (1u << 22) /**< \brief Afec1 signal: AFE1_AD3 */ +#define PIO_PC1X1_AFE1_AD4 (1u << 1) /**< \brief Afec1 signal: AFE1_AD4 */ +#define PIO_PC2X1_AFE1_AD5 (1u << 2) /**< \brief Afec1 signal: AFE1_AD5 */ +#define PIO_PC3X1_AFE1_AD6 (1u << 3) /**< \brief Afec1 signal: AFE1_AD6 */ +#define PIO_PC4X1_AFE1_AD7 (1u << 4) /**< \brief Afec1 signal: AFE1_AD7 */ +/* ========== Pio definition for CAN0 peripheral ========== */ +#define PIO_PB3A_CANRX0 (1u << 3) /**< \brief Can0 signal: CANRX0 */ +#define PIO_PB2A_CANTX0 (1u << 2) /**< \brief Can0 signal: CANTX0 */ +/* ========== Pio definition for DACC peripheral ========== */ +#define PIO_PB13X1_DAC0 (1u << 13) /**< \brief Dacc signal: DAC0 */ +#define PIO_PB14X1_DAC1 (1u << 14) /**< \brief Dacc signal: DAC1 */ +#define PIO_PA2C_DATRG (1u << 2) /**< \brief Dacc signal: DATRG */ +/* ========== Pio definition for GMAC peripheral ========== */ +#define PIO_PD13A_GCOL (1u << 13) /**< \brief Gmac signal: GCOL */ +#define PIO_PD10A_GCRS (1u << 10) /**< \brief Gmac signal: GCRS */ +#define PIO_PD4A_GCRSDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD4A_GRXDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD8A_GMDC (1u << 8) /**< \brief Gmac signal: GMDC */ +#define PIO_PD9A_GMDIO (1u << 9) /**< \brief Gmac signal: GMDIO */ +#define PIO_PD5A_GRX0 (1u << 5) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD6A_GRX0 (1u << 6) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD11A_GRX2 (1u << 11) /**< \brief Gmac signal: GRX2 */ +#define PIO_PD12A_GRX3 (1u << 12) /**< \brief Gmac signal: GRX3 */ +#define PIO_PD14A_GRXCK (1u << 14) /**< \brief Gmac signal: GRXCK */ +#define PIO_PD7A_GRXER (1u << 7) /**< \brief Gmac signal: GRXER */ +#define PIO_PD2A_GTX0 (1u << 2) /**< \brief Gmac signal: GTX0 */ +#define PIO_PD3A_GTX1 (1u << 3) /**< \brief Gmac signal: GTX1 */ +#define PIO_PD15A_GTX2 (1u << 15) /**< \brief Gmac signal: GTX2 */ +#define PIO_PD16A_GTX3 (1u << 16) /**< \brief Gmac signal: GTX3 */ +#define PIO_PD0A_GTXCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD0A_GREFCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD1A_GTXEN (1u << 1) /**< \brief Gmac signal: GTXEN */ +#define PIO_PD17A_GTXER (1u << 17) /**< \brief Gmac signal: GTXER */ +/* ========== Pio definition for HSMCI peripheral ========== */ +#define PIO_PA28C_MCCDA (1u << 28) /**< \brief Hsmci signal: MCCDA */ +#define PIO_PA29C_MCCK (1u << 29) /**< \brief Hsmci signal: MCCK */ +#define PIO_PA30C_MCDA0 (1u << 30) /**< \brief Hsmci signal: MCDA0 */ +#define PIO_PA31C_MCDA1 (1u << 31) /**< \brief Hsmci signal: MCDA1 */ +#define PIO_PA26C_MCDA2 (1u << 26) /**< \brief Hsmci signal: MCDA2 */ +#define PIO_PA27C_MCDA3 (1u << 27) /**< \brief Hsmci signal: MCDA3 */ +/* ========== Pio definition for PIOA peripheral ========== */ +#define PIO_PA24X1_PIODC0 (1u << 24) /**< \brief Pioa signal: PIODC0 */ +#define PIO_PA25X1_PIODC1 (1u << 25) /**< \brief Pioa signal: PIODC1 */ +#define PIO_PA26X1_PIODC2 (1u << 26) /**< \brief Pioa signal: PIODC2 */ +#define PIO_PA27X1_PIODC3 (1u << 27) /**< \brief Pioa signal: PIODC3 */ +#define PIO_PA28X1_PIODC4 (1u << 28) /**< \brief Pioa signal: PIODC4 */ +#define PIO_PA29X1_PIODC5 (1u << 29) /**< \brief Pioa signal: PIODC5 */ +#define PIO_PA31X1_PIODC7 (1u << 31) /**< \brief Pioa signal: PIODC7 */ +#define PIO_PA23X1_PIODCCLK (1u << 23) /**< \brief Pioa signal: PIODCCLK */ +#define PIO_PA30X1_WKUP11 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA30X1_PIODC6 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA15X1_WKUP14 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA15X1_PIODCEN1 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA16X1_WKUP15 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +#define PIO_PA16X1_PIODCEN2 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +/* ========== Pio definition for PMC peripheral ========== */ +#define PIO_PA6B_PCK0 (1u << 6) /**< \brief Pmc signal: PCK0 */ +#define PIO_PB13B_PCK0 (1u << 13) /**< \brief Pmc signal: PCK0 */ +#define PIO_PA17B_PCK1 (1u << 17) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA21B_PCK1 (1u << 21) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA18B_PCK2 (1u << 18) /**< \brief Pmc signal: PCK2 */ +#define PIO_PA31B_PCK2 (1u << 31) /**< \brief Pmc signal: PCK2 */ +#define PIO_PB3B_PCK2 (1u << 3) /**< \brief Pmc signal: PCK2 */ +/* ========== Pio definition for PWM peripheral ========== */ +#define PIO_PA9C_PWMFI0 (1u << 9) /**< \brief Pwm signal: PWMFI0 */ +#define PIO_PA0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA11B_PWMH0 (1u << 11) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA23B_PWMH0 (1u << 23) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PB0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PC18B_PWMH0 (1u << 18) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PD20A_PWMH0 (1u << 20) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA12B_PWMH1 (1u << 12) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA24B_PWMH1 (1u << 24) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PB1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PC19B_PWMH1 (1u << 19) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PD21A_PWMH1 (1u << 21) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA2A_PWMH2 (1u << 2) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA13B_PWMH2 (1u << 13) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA25B_PWMH2 (1u << 25) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PB4B_PWMH2 (1u << 4) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PC20B_PWMH2 (1u << 20) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PD22A_PWMH2 (1u << 22) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA7B_PWMH3 (1u << 7) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA17C_PWMH3 (1u << 17) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PB14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PC21B_PWMH3 (1u << 21) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PD23A_PWMH3 (1u << 23) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA19B_PWML0 (1u << 19) /**< \brief Pwm signal: PWML0 */ +#define PIO_PB5B_PWML0 (1u << 5) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC0B_PWML0 (1u << 0) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC13B_PWML0 (1u << 13) /**< \brief Pwm signal: PWML0 */ +#define PIO_PD24A_PWML0 (1u << 24) /**< \brief Pwm signal: PWML0 */ +#define PIO_PA20B_PWML1 (1u << 20) /**< \brief Pwm signal: PWML1 */ +#define PIO_PB12A_PWML1 (1u << 12) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC1B_PWML1 (1u << 1) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC15B_PWML1 (1u << 15) /**< \brief Pwm signal: PWML1 */ +#define PIO_PD25A_PWML1 (1u << 25) /**< \brief Pwm signal: PWML1 */ +#define PIO_PA16C_PWML2 (1u << 16) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA30A_PWML2 (1u << 30) /**< \brief Pwm signal: PWML2 */ +#define PIO_PB13A_PWML2 (1u << 13) /**< \brief Pwm signal: PWML2 */ +#define PIO_PC2B_PWML2 (1u << 2) /**< \brief Pwm signal: PWML2 */ +#define PIO_PD26A_PWML2 (1u << 26) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA15C_PWML3 (1u << 15) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC3B_PWML3 (1u << 3) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC22B_PWML3 (1u << 22) /**< \brief Pwm signal: PWML3 */ +#define PIO_PD27A_PWML3 (1u << 27) /**< \brief Pwm signal: PWML3 */ +/* ========== Pio definition for SPI peripheral ========== */ +#define PIO_PA12A_MISO (1u << 12) /**< \brief Spi signal: MISO */ +#define PIO_PA13A_MOSI (1u << 13) /**< \brief Spi signal: MOSI */ +#define PIO_PA11A_NPCS0 (1u << 11) /**< \brief Spi signal: NPCS0 */ +#define PIO_PA9B_NPCS1 (1u << 9) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA31A_NPCS1 (1u << 31) /**< \brief Spi signal: NPCS1 */ +#define PIO_PB14A_NPCS1 (1u << 14) /**< \brief Spi signal: NPCS1 */ +#define PIO_PC4B_NPCS1 (1u << 4) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA10B_NPCS2 (1u << 10) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA30B_NPCS2 (1u << 30) /**< \brief Spi signal: NPCS2 */ +#define PIO_PB2B_NPCS2 (1u << 2) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA3B_NPCS3 (1u << 3) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA5B_NPCS3 (1u << 5) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA22B_NPCS3 (1u << 22) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA14A_SPCK (1u << 14) /**< \brief Spi signal: SPCK */ +/* ========== Pio definition for TC0 peripheral ========== */ +#define PIO_PA4B_TCLK0 (1u << 4) /**< \brief Tc0 signal: TCLK0 */ +#define PIO_PA28B_TCLK1 (1u << 28) /**< \brief Tc0 signal: TCLK1 */ +#define PIO_PA29B_TCLK2 (1u << 29) /**< \brief Tc0 signal: TCLK2 */ +#define PIO_PA0B_TIOA0 (1u << 0) /**< \brief Tc0 signal: TIOA0 */ +#define PIO_PA15B_TIOA1 (1u << 15) /**< \brief Tc0 signal: TIOA1 */ +#define PIO_PA26B_TIOA2 (1u << 26) /**< \brief Tc0 signal: TIOA2 */ +#define PIO_PA1B_TIOB0 (1u << 1) /**< \brief Tc0 signal: TIOB0 */ +#define PIO_PA16B_TIOB1 (1u << 16) /**< \brief Tc0 signal: TIOB1 */ +#define PIO_PA27B_TIOB2 (1u << 27) /**< \brief Tc0 signal: TIOB2 */ +/* ========== Pio definition for TWI0 peripheral ========== */ +#define PIO_PA4A_TWCK0 (1u << 4) /**< \brief Twi0 signal: TWCK0 */ +#define PIO_PA3A_TWD0 (1u << 3) /**< \brief Twi0 signal: TWD0 */ +/* ========== Pio definition for TWI1 peripheral ========== */ +#define PIO_PB5A_TWCK1 (1u << 5) /**< \brief Twi1 signal: TWCK1 */ +#define PIO_PB4A_TWD1 (1u << 4) /**< \brief Twi1 signal: TWD1 */ +/* ========== Pio definition for UART0 peripheral ========== */ +#define PIO_PA9A_URXD0 (1u << 9) /**< \brief Uart0 signal: URXD0 */ +#define PIO_PA10A_UTXD0 (1u << 10) /**< \brief Uart0 signal: UTXD0 */ +/* ========== Pio definition for UART1 peripheral ========== */ +#define PIO_PA5C_URXD1 (1u << 5) /**< \brief Uart1 signal: URXD1 */ +#define PIO_PA6C_UTXD1 (1u << 6) /**< \brief Uart1 signal: UTXD1 */ +/* ========== Pio definition for USART0 peripheral ========== */ +#define PIO_PB2C_CTS0 (1u << 2) /**< \brief Usart0 signal: CTS0 */ +#define PIO_PB3C_RTS0 (1u << 3) /**< \brief Usart0 signal: RTS0 */ +#define PIO_PB0C_RXD0 (1u << 0) /**< \brief Usart0 signal: RXD0 */ +#define PIO_PB13C_SCK0 (1u << 13) /**< \brief Usart0 signal: SCK0 */ +#define PIO_PB1C_TXD0 (1u << 1) /**< \brief Usart0 signal: TXD0 */ +/* ========== Pio definition for USART1 peripheral ========== */ +#define PIO_PA25A_CTS1 (1u << 25) /**< \brief Usart1 signal: CTS1 */ +#define PIO_PA26A_DCD1 (1u << 26) /**< \brief Usart1 signal: DCD1 */ +#define PIO_PA28A_DSR1 (1u << 28) /**< \brief Usart1 signal: DSR1 */ +#define PIO_PA27A_DTR1 (1u << 27) /**< \brief Usart1 signal: DTR1 */ +#define PIO_PA29A_RI1 (1u << 29) /**< \brief Usart1 signal: RI1 */ +#define PIO_PA24A_RTS1 (1u << 24) /**< \brief Usart1 signal: RTS1 */ +#define PIO_PA21A_RXD1 (1u << 21) /**< \brief Usart1 signal: RXD1 */ +#define PIO_PA23A_SCK1 (1u << 23) /**< \brief Usart1 signal: SCK1 */ +#define PIO_PA22A_TXD1 (1u << 22) /**< \brief Usart1 signal: TXD1 */ +/* ========== Pio indexes ========== */ +#define PIO_PA0_IDX 0 +#define PIO_PA1_IDX 1 +#define PIO_PA2_IDX 2 +#define PIO_PA3_IDX 3 +#define PIO_PA4_IDX 4 +#define PIO_PA5_IDX 5 +#define PIO_PA6_IDX 6 +#define PIO_PA7_IDX 7 +#define PIO_PA8_IDX 8 +#define PIO_PA9_IDX 9 +#define PIO_PA10_IDX 10 +#define PIO_PA11_IDX 11 +#define PIO_PA12_IDX 12 +#define PIO_PA13_IDX 13 +#define PIO_PA14_IDX 14 +#define PIO_PA15_IDX 15 +#define PIO_PA16_IDX 16 +#define PIO_PA17_IDX 17 +#define PIO_PA18_IDX 18 +#define PIO_PA19_IDX 19 +#define PIO_PA20_IDX 20 +#define PIO_PA21_IDX 21 +#define PIO_PA22_IDX 22 +#define PIO_PA23_IDX 23 +#define PIO_PA24_IDX 24 +#define PIO_PA25_IDX 25 +#define PIO_PA26_IDX 26 +#define PIO_PA27_IDX 27 +#define PIO_PA28_IDX 28 +#define PIO_PA29_IDX 29 +#define PIO_PA30_IDX 30 +#define PIO_PA31_IDX 31 +#define PIO_PB0_IDX 32 +#define PIO_PB1_IDX 33 +#define PIO_PB2_IDX 34 +#define PIO_PB3_IDX 35 +#define PIO_PB4_IDX 36 +#define PIO_PB5_IDX 37 +#define PIO_PB6_IDX 38 +#define PIO_PB7_IDX 39 +#define PIO_PB8_IDX 40 +#define PIO_PB9_IDX 41 +#define PIO_PB10_IDX 42 +#define PIO_PB11_IDX 43 +#define PIO_PB12_IDX 44 +#define PIO_PB13_IDX 45 +#define PIO_PB14_IDX 46 +#define PIO_PD0_IDX 96 +#define PIO_PD1_IDX 97 +#define PIO_PD2_IDX 98 +#define PIO_PD3_IDX 99 +#define PIO_PD4_IDX 100 +#define PIO_PD5_IDX 101 +#define PIO_PD6_IDX 102 +#define PIO_PD7_IDX 103 +#define PIO_PD8_IDX 104 +#define PIO_PD9_IDX 105 +#define PIO_PD10_IDX 106 +#define PIO_PD11_IDX 107 +#define PIO_PD12_IDX 108 +#define PIO_PD13_IDX 109 +#define PIO_PD14_IDX 110 +#define PIO_PD15_IDX 111 +#define PIO_PD16_IDX 112 +#define PIO_PD17_IDX 113 +#define PIO_PD18_IDX 114 +#define PIO_PD19_IDX 115 +#define PIO_PD20_IDX 116 +#define PIO_PD21_IDX 117 +#define PIO_PD22_IDX 118 +#define PIO_PD23_IDX 119 +#define PIO_PD24_IDX 120 +#define PIO_PD25_IDX 121 +#define PIO_PD26_IDX 122 +#define PIO_PD27_IDX 123 +#define PIO_PD28_IDX 124 +#define PIO_PD29_IDX 125 +#define PIO_PD30_IDX 126 +#define PIO_PD31_IDX 127 + +#endif /* _SAM4E8C_PIO_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8e.h new file mode 100644 index 0000000..7800359 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/pio/sam4e8e.h @@ -0,0 +1,540 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E8E_PIO_ +#define _SAM4E8E_PIO_ + +#define PIO_PA0 (1u << 0) /**< \brief Pin Controlled by PA0 */ +#define PIO_PA1 (1u << 1) /**< \brief Pin Controlled by PA1 */ +#define PIO_PA2 (1u << 2) /**< \brief Pin Controlled by PA2 */ +#define PIO_PA3 (1u << 3) /**< \brief Pin Controlled by PA3 */ +#define PIO_PA4 (1u << 4) /**< \brief Pin Controlled by PA4 */ +#define PIO_PA5 (1u << 5) /**< \brief Pin Controlled by PA5 */ +#define PIO_PA6 (1u << 6) /**< \brief Pin Controlled by PA6 */ +#define PIO_PA7 (1u << 7) /**< \brief Pin Controlled by PA7 */ +#define PIO_PA8 (1u << 8) /**< \brief Pin Controlled by PA8 */ +#define PIO_PA9 (1u << 9) /**< \brief Pin Controlled by PA9 */ +#define PIO_PA10 (1u << 10) /**< \brief Pin Controlled by PA10 */ +#define PIO_PA11 (1u << 11) /**< \brief Pin Controlled by PA11 */ +#define PIO_PA12 (1u << 12) /**< \brief Pin Controlled by PA12 */ +#define PIO_PA13 (1u << 13) /**< \brief Pin Controlled by PA13 */ +#define PIO_PA14 (1u << 14) /**< \brief Pin Controlled by PA14 */ +#define PIO_PA15 (1u << 15) /**< \brief Pin Controlled by PA15 */ +#define PIO_PA16 (1u << 16) /**< \brief Pin Controlled by PA16 */ +#define PIO_PA17 (1u << 17) /**< \brief Pin Controlled by PA17 */ +#define PIO_PA18 (1u << 18) /**< \brief Pin Controlled by PA18 */ +#define PIO_PA19 (1u << 19) /**< \brief Pin Controlled by PA19 */ +#define PIO_PA20 (1u << 20) /**< \brief Pin Controlled by PA20 */ +#define PIO_PA21 (1u << 21) /**< \brief Pin Controlled by PA21 */ +#define PIO_PA22 (1u << 22) /**< \brief Pin Controlled by PA22 */ +#define PIO_PA23 (1u << 23) /**< \brief Pin Controlled by PA23 */ +#define PIO_PA24 (1u << 24) /**< \brief Pin Controlled by PA24 */ +#define PIO_PA25 (1u << 25) /**< \brief Pin Controlled by PA25 */ +#define PIO_PA26 (1u << 26) /**< \brief Pin Controlled by PA26 */ +#define PIO_PA27 (1u << 27) /**< \brief Pin Controlled by PA27 */ +#define PIO_PA28 (1u << 28) /**< \brief Pin Controlled by PA28 */ +#define PIO_PA29 (1u << 29) /**< \brief Pin Controlled by PA29 */ +#define PIO_PA30 (1u << 30) /**< \brief Pin Controlled by PA30 */ +#define PIO_PA31 (1u << 31) /**< \brief Pin Controlled by PA31 */ +#define PIO_PB0 (1u << 0) /**< \brief Pin Controlled by PB0 */ +#define PIO_PB1 (1u << 1) /**< \brief Pin Controlled by PB1 */ +#define PIO_PB2 (1u << 2) /**< \brief Pin Controlled by PB2 */ +#define PIO_PB3 (1u << 3) /**< \brief Pin Controlled by PB3 */ +#define PIO_PB4 (1u << 4) /**< \brief Pin Controlled by PB4 */ +#define PIO_PB5 (1u << 5) /**< \brief Pin Controlled by PB5 */ +#define PIO_PB6 (1u << 6) /**< \brief Pin Controlled by PB6 */ +#define PIO_PB7 (1u << 7) /**< \brief Pin Controlled by PB7 */ +#define PIO_PB8 (1u << 8) /**< \brief Pin Controlled by PB8 */ +#define PIO_PB9 (1u << 9) /**< \brief Pin Controlled by PB9 */ +#define PIO_PB10 (1u << 10) /**< \brief Pin Controlled by PB10 */ +#define PIO_PB11 (1u << 11) /**< \brief Pin Controlled by PB11 */ +#define PIO_PB12 (1u << 12) /**< \brief Pin Controlled by PB12 */ +#define PIO_PB13 (1u << 13) /**< \brief Pin Controlled by PB13 */ +#define PIO_PB14 (1u << 14) /**< \brief Pin Controlled by PB14 */ +#define PIO_PC0 (1u << 0) /**< \brief Pin Controlled by PC0 */ +#define PIO_PC1 (1u << 1) /**< \brief Pin Controlled by PC1 */ +#define PIO_PC2 (1u << 2) /**< \brief Pin Controlled by PC2 */ +#define PIO_PC3 (1u << 3) /**< \brief Pin Controlled by PC3 */ +#define PIO_PC4 (1u << 4) /**< \brief Pin Controlled by PC4 */ +#define PIO_PC5 (1u << 5) /**< \brief Pin Controlled by PC5 */ +#define PIO_PC6 (1u << 6) /**< \brief Pin Controlled by PC6 */ +#define PIO_PC7 (1u << 7) /**< \brief Pin Controlled by PC7 */ +#define PIO_PC8 (1u << 8) /**< \brief Pin Controlled by PC8 */ +#define PIO_PC9 (1u << 9) /**< \brief Pin Controlled by PC9 */ +#define PIO_PC10 (1u << 10) /**< \brief Pin Controlled by PC10 */ +#define PIO_PC11 (1u << 11) /**< \brief Pin Controlled by PC11 */ +#define PIO_PC12 (1u << 12) /**< \brief Pin Controlled by PC12 */ +#define PIO_PC13 (1u << 13) /**< \brief Pin Controlled by PC13 */ +#define PIO_PC14 (1u << 14) /**< \brief Pin Controlled by PC14 */ +#define PIO_PC15 (1u << 15) /**< \brief Pin Controlled by PC15 */ +#define PIO_PC16 (1u << 16) /**< \brief Pin Controlled by PC16 */ +#define PIO_PC17 (1u << 17) /**< \brief Pin Controlled by PC17 */ +#define PIO_PC18 (1u << 18) /**< \brief Pin Controlled by PC18 */ +#define PIO_PC19 (1u << 19) /**< \brief Pin Controlled by PC19 */ +#define PIO_PC20 (1u << 20) /**< \brief Pin Controlled by PC20 */ +#define PIO_PC21 (1u << 21) /**< \brief Pin Controlled by PC21 */ +#define PIO_PC22 (1u << 22) /**< \brief Pin Controlled by PC22 */ +#define PIO_PC23 (1u << 23) /**< \brief Pin Controlled by PC23 */ +#define PIO_PC24 (1u << 24) /**< \brief Pin Controlled by PC24 */ +#define PIO_PC25 (1u << 25) /**< \brief Pin Controlled by PC25 */ +#define PIO_PC26 (1u << 26) /**< \brief Pin Controlled by PC26 */ +#define PIO_PC27 (1u << 27) /**< \brief Pin Controlled by PC27 */ +#define PIO_PC28 (1u << 28) /**< \brief Pin Controlled by PC28 */ +#define PIO_PC29 (1u << 29) /**< \brief Pin Controlled by PC29 */ +#define PIO_PC30 (1u << 30) /**< \brief Pin Controlled by PC30 */ +#define PIO_PC31 (1u << 31) /**< \brief Pin Controlled by PC31 */ +#define PIO_PD0 (1u << 0) /**< \brief Pin Controlled by PD0 */ +#define PIO_PD1 (1u << 1) /**< \brief Pin Controlled by PD1 */ +#define PIO_PD2 (1u << 2) /**< \brief Pin Controlled by PD2 */ +#define PIO_PD3 (1u << 3) /**< \brief Pin Controlled by PD3 */ +#define PIO_PD4 (1u << 4) /**< \brief Pin Controlled by PD4 */ +#define PIO_PD5 (1u << 5) /**< \brief Pin Controlled by PD5 */ +#define PIO_PD6 (1u << 6) /**< \brief Pin Controlled by PD6 */ +#define PIO_PD7 (1u << 7) /**< \brief Pin Controlled by PD7 */ +#define PIO_PD8 (1u << 8) /**< \brief Pin Controlled by PD8 */ +#define PIO_PD9 (1u << 9) /**< \brief Pin Controlled by PD9 */ +#define PIO_PD10 (1u << 10) /**< \brief Pin Controlled by PD10 */ +#define PIO_PD11 (1u << 11) /**< \brief Pin Controlled by PD11 */ +#define PIO_PD12 (1u << 12) /**< \brief Pin Controlled by PD12 */ +#define PIO_PD13 (1u << 13) /**< \brief Pin Controlled by PD13 */ +#define PIO_PD14 (1u << 14) /**< \brief Pin Controlled by PD14 */ +#define PIO_PD15 (1u << 15) /**< \brief Pin Controlled by PD15 */ +#define PIO_PD16 (1u << 16) /**< \brief Pin Controlled by PD16 */ +#define PIO_PD17 (1u << 17) /**< \brief Pin Controlled by PD17 */ +#define PIO_PD18 (1u << 18) /**< \brief Pin Controlled by PD18 */ +#define PIO_PD19 (1u << 19) /**< \brief Pin Controlled by PD19 */ +#define PIO_PD20 (1u << 20) /**< \brief Pin Controlled by PD20 */ +#define PIO_PD21 (1u << 21) /**< \brief Pin Controlled by PD21 */ +#define PIO_PD22 (1u << 22) /**< \brief Pin Controlled by PD22 */ +#define PIO_PD23 (1u << 23) /**< \brief Pin Controlled by PD23 */ +#define PIO_PD24 (1u << 24) /**< \brief Pin Controlled by PD24 */ +#define PIO_PD25 (1u << 25) /**< \brief Pin Controlled by PD25 */ +#define PIO_PD26 (1u << 26) /**< \brief Pin Controlled by PD26 */ +#define PIO_PD27 (1u << 27) /**< \brief Pin Controlled by PD27 */ +#define PIO_PD28 (1u << 28) /**< \brief Pin Controlled by PD28 */ +#define PIO_PD29 (1u << 29) /**< \brief Pin Controlled by PD29 */ +#define PIO_PD30 (1u << 30) /**< \brief Pin Controlled by PD30 */ +#define PIO_PD31 (1u << 31) /**< \brief Pin Controlled by PD31 */ +#define PIO_PE0 (1u << 0) /**< \brief Pin Controlled by PE0 */ +#define PIO_PE1 (1u << 1) /**< \brief Pin Controlled by PE1 */ +#define PIO_PE2 (1u << 2) /**< \brief Pin Controlled by PE2 */ +#define PIO_PE3 (1u << 3) /**< \brief Pin Controlled by PE3 */ +#define PIO_PE4 (1u << 4) /**< \brief Pin Controlled by PE4 */ +#define PIO_PE5 (1u << 5) /**< \brief Pin Controlled by PE5 */ +/* ========== Pio definition for AFEC0 peripheral ========== */ +#define PIO_PA17X1_AFE0_AD0 (1u << 17) /**< \brief Afec0 signal: AFE0_AD0 */ +#define PIO_PA18X1_AFE0_AD1 (1u << 18) /**< \brief Afec0 signal: AFE0_AD1 */ +#define PIO_PC30X1_AFE0_AD10 (1u << 30) /**< \brief Afec0 signal: AFE0_AD10 */ +#define PIO_PC31X1_AFE0_AD11 (1u << 31) /**< \brief Afec0 signal: AFE0_AD11 */ +#define PIO_PC26X1_AFE0_AD12 (1u << 26) /**< \brief Afec0 signal: AFE0_AD12 */ +#define PIO_PC27X1_AFE0_AD13 (1u << 27) /**< \brief Afec0 signal: AFE0_AD13 */ +#define PIO_PC0X1_AFE0_AD14 (1u << 0) /**< \brief Afec0 signal: AFE0_AD14 */ +#define PIO_PA19X1_AFE0_AD2 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA19X1_WKUP9 (1u << 19) /**< \brief Afec0 signal: AFE0_AD2/WKUP9 */ +#define PIO_PA20X1_AFE0_AD3 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PA20X1_WKUP10 (1u << 20) /**< \brief Afec0 signal: AFE0_AD3/WKUP10 */ +#define PIO_PB0X1_AFE0_AD4 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB0X1_RTCOUT0 (1u << 0) /**< \brief Afec0 signal: AFE0_AD4/RTCOUT0 */ +#define PIO_PB1X1_AFE0_AD5 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PB1X1_RTCOUT1 (1u << 1) /**< \brief Afec0 signal: AFE0_AD5/RTCOUT1 */ +#define PIO_PC13X1_AFE0_AD6 (1u << 13) /**< \brief Afec0 signal: AFE0_AD6 */ +#define PIO_PC15X1_AFE0_AD7 (1u << 15) /**< \brief Afec0 signal: AFE0_AD7 */ +#define PIO_PC12X1_AFE0_AD8 (1u << 12) /**< \brief Afec0 signal: AFE0_AD8 */ +#define PIO_PC29X1_AFE0_AD9 (1u << 29) /**< \brief Afec0 signal: AFE0_AD9 */ +#define PIO_PA8B_AFE0_ADTRG (1u << 8) /**< \brief Afec0 signal: AFE0_ADTRG */ +/* ========== Pio definition for AFEC1 peripheral ========== */ +#define PIO_PB2X1_AFE1_AD0 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB2X1_WKUP12 (1u << 2) /**< \brief Afec1 signal: AFE1_AD0/WKUP12 */ +#define PIO_PB3X1_AFE1_AD1 (1u << 3) /**< \brief Afec1 signal: AFE1_AD1 */ +#define PIO_PA21X1_AFE1_AD2 (1u << 21) /**< \brief Afec1 signal: AFE1_AD2 */ +#define PIO_PA22X1_AFE1_AD3 (1u << 22) /**< \brief Afec1 signal: AFE1_AD3 */ +#define PIO_PC1X1_AFE1_AD4 (1u << 1) /**< \brief Afec1 signal: AFE1_AD4 */ +#define PIO_PC2X1_AFE1_AD5 (1u << 2) /**< \brief Afec1 signal: AFE1_AD5 */ +#define PIO_PC3X1_AFE1_AD6 (1u << 3) /**< \brief Afec1 signal: AFE1_AD6 */ +#define PIO_PC4X1_AFE1_AD7 (1u << 4) /**< \brief Afec1 signal: AFE1_AD7 */ +/* ========== Pio definition for CAN0 peripheral ========== */ +#define PIO_PB3A_CANRX0 (1u << 3) /**< \brief Can0 signal: CANRX0 */ +#define PIO_PB2A_CANTX0 (1u << 2) /**< \brief Can0 signal: CANTX0 */ +/* ========== Pio definition for CAN1 peripheral ========== */ +#define PIO_PC12C_CANRX1 (1u << 12) /**< \brief Can1 signal: CANRX1 */ +#define PIO_PC15C_CANTX1 (1u << 15) /**< \brief Can1 signal: CANTX1 */ +/* ========== Pio definition for DACC peripheral ========== */ +#define PIO_PB13X1_DAC0 (1u << 13) /**< \brief Dacc signal: DAC0 */ +#define PIO_PB14X1_DAC1 (1u << 14) /**< \brief Dacc signal: DAC1 */ +#define PIO_PA2C_DATRG (1u << 2) /**< \brief Dacc signal: DATRG */ +/* ========== Pio definition for EBI peripheral ========== */ +#define PIO_PC18A_A0 (1u << 18) /**< \brief Ebi signal: A0 */ +#define PIO_PC19A_A1 (1u << 19) /**< \brief Ebi signal: A1 */ +#define PIO_PC28A_A10 (1u << 28) /**< \brief Ebi signal: A10 */ +#define PIO_PC29A_A11 (1u << 29) /**< \brief Ebi signal: A11 */ +#define PIO_PC30A_A12 (1u << 30) /**< \brief Ebi signal: A12 */ +#define PIO_PC31A_A13 (1u << 31) /**< \brief Ebi signal: A13 */ +#define PIO_PA18C_A14 (1u << 18) /**< \brief Ebi signal: A14 */ +#define PIO_PA19C_A15 (1u << 19) /**< \brief Ebi signal: A15 */ +#define PIO_PA20C_A16 (1u << 20) /**< \brief Ebi signal: A16 */ +#define PIO_PA0C_A17 (1u << 0) /**< \brief Ebi signal: A17 */ +#define PIO_PA1C_A18 (1u << 1) /**< \brief Ebi signal: A18 */ +#define PIO_PA23C_A19 (1u << 23) /**< \brief Ebi signal: A19 */ +#define PIO_PC20A_A2 (1u << 20) /**< \brief Ebi signal: A2 */ +#define PIO_PA24C_A20 (1u << 24) /**< \brief Ebi signal: A20 */ +#define PIO_PC16A_A21 (1u << 16) /**< \brief Ebi signal: A21/NANDALE */ +#define PIO_PC16A_NANDALE (1u << 16) /**< \brief Ebi signal: A21/NANDALE */ +#define PIO_PC17A_A22 (1u << 17) /**< \brief Ebi signal: A22/NANDCLE */ +#define PIO_PC17A_NANDCLE (1u << 17) /**< \brief Ebi signal: A22/NANDCLE */ +#define PIO_PA25C_A23 (1u << 25) /**< \brief Ebi signal: A23 */ +#define PIO_PC21A_A3 (1u << 21) /**< \brief Ebi signal: A3 */ +#define PIO_PC22A_A4 (1u << 22) /**< \brief Ebi signal: A4 */ +#define PIO_PC23A_A5 (1u << 23) /**< \brief Ebi signal: A5 */ +#define PIO_PC24A_A6 (1u << 24) /**< \brief Ebi signal: A6 */ +#define PIO_PC25A_A7 (1u << 25) /**< \brief Ebi signal: A7 */ +#define PIO_PC26A_A8 (1u << 26) /**< \brief Ebi signal: A8 */ +#define PIO_PC27A_A9 (1u << 27) /**< \brief Ebi signal: A9 */ +#define PIO_PC0A_D0 (1u << 0) /**< \brief Ebi signal: D0 */ +#define PIO_PC1A_D1 (1u << 1) /**< \brief Ebi signal: D1 */ +#define PIO_PC2A_D2 (1u << 2) /**< \brief Ebi signal: D2 */ +#define PIO_PC3A_D3 (1u << 3) /**< \brief Ebi signal: D3 */ +#define PIO_PC4A_D4 (1u << 4) /**< \brief Ebi signal: D4 */ +#define PIO_PC5A_D5 (1u << 5) /**< \brief Ebi signal: D5 */ +#define PIO_PC6A_D6 (1u << 6) /**< \brief Ebi signal: D6 */ +#define PIO_PC7A_D7 (1u << 7) /**< \brief Ebi signal: D7 */ +#define PIO_PC9A_NANDOE (1u << 9) /**< \brief Ebi signal: NANDOE */ +#define PIO_PC10A_NANDWE (1u << 10) /**< \brief Ebi signal: NANDWE */ +#define PIO_PC14A_NCS0 (1u << 14) /**< \brief Ebi signal: NCS0 */ +#define PIO_PC15A_NCS1 (1u << 15) /**< \brief Ebi signal: NCS1 */ +#define PIO_PD18A_NCS1 (1u << 18) /**< \brief Ebi signal: NCS1 */ +#define PIO_PA22C_NCS2 (1u << 22) /**< \brief Ebi signal: NCS2 */ +#define PIO_PC12A_NCS3 (1u << 12) /**< \brief Ebi signal: NCS3 */ +#define PIO_PD19A_NCS3 (1u << 19) /**< \brief Ebi signal: NCS3 */ +#define PIO_PC11A_NRD (1u << 11) /**< \brief Ebi signal: NRD */ +#define PIO_PC13A_NWAIT (1u << 13) /**< \brief Ebi signal: NWAIT */ +#define PIO_PC8A_NWE (1u << 8) /**< \brief Ebi signal: NWE */ +/* ========== Pio definition for GMAC peripheral ========== */ +#define PIO_PD13A_GCOL (1u << 13) /**< \brief Gmac signal: GCOL */ +#define PIO_PD10A_GCRS (1u << 10) /**< \brief Gmac signal: GCRS */ +#define PIO_PD4A_GCRSDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD4A_GRXDV (1u << 4) /**< \brief Gmac signal: GCRSDV/GRXDV */ +#define PIO_PD8A_GMDC (1u << 8) /**< \brief Gmac signal: GMDC */ +#define PIO_PD9A_GMDIO (1u << 9) /**< \brief Gmac signal: GMDIO */ +#define PIO_PD5A_GRX0 (1u << 5) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD6A_GRX0 (1u << 6) /**< \brief Gmac signal: GRX0 */ +#define PIO_PD11A_GRX2 (1u << 11) /**< \brief Gmac signal: GRX2 */ +#define PIO_PD12A_GRX3 (1u << 12) /**< \brief Gmac signal: GRX3 */ +#define PIO_PD14A_GRXCK (1u << 14) /**< \brief Gmac signal: GRXCK */ +#define PIO_PD7A_GRXER (1u << 7) /**< \brief Gmac signal: GRXER */ +#define PIO_PD2A_GTX0 (1u << 2) /**< \brief Gmac signal: GTX0 */ +#define PIO_PD3A_GTX1 (1u << 3) /**< \brief Gmac signal: GTX1 */ +#define PIO_PD15A_GTX2 (1u << 15) /**< \brief Gmac signal: GTX2 */ +#define PIO_PD16A_GTX3 (1u << 16) /**< \brief Gmac signal: GTX3 */ +#define PIO_PD0A_GTXCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD0A_GREFCK (1u << 0) /**< \brief Gmac signal: GTXCK/GREFCK */ +#define PIO_PD1A_GTXEN (1u << 1) /**< \brief Gmac signal: GTXEN */ +#define PIO_PD17A_GTXER (1u << 17) /**< \brief Gmac signal: GTXER */ +/* ========== Pio definition for HSMCI peripheral ========== */ +#define PIO_PA28C_MCCDA (1u << 28) /**< \brief Hsmci signal: MCCDA */ +#define PIO_PA29C_MCCK (1u << 29) /**< \brief Hsmci signal: MCCK */ +#define PIO_PA30C_MCDA0 (1u << 30) /**< \brief Hsmci signal: MCDA0 */ +#define PIO_PA31C_MCDA1 (1u << 31) /**< \brief Hsmci signal: MCDA1 */ +#define PIO_PA26C_MCDA2 (1u << 26) /**< \brief Hsmci signal: MCDA2 */ +#define PIO_PA27C_MCDA3 (1u << 27) /**< \brief Hsmci signal: MCDA3 */ +/* ========== Pio definition for PIOA peripheral ========== */ +#define PIO_PA24X1_PIODC0 (1u << 24) /**< \brief Pioa signal: PIODC0 */ +#define PIO_PA25X1_PIODC1 (1u << 25) /**< \brief Pioa signal: PIODC1 */ +#define PIO_PA26X1_PIODC2 (1u << 26) /**< \brief Pioa signal: PIODC2 */ +#define PIO_PA27X1_PIODC3 (1u << 27) /**< \brief Pioa signal: PIODC3 */ +#define PIO_PA28X1_PIODC4 (1u << 28) /**< \brief Pioa signal: PIODC4 */ +#define PIO_PA29X1_PIODC5 (1u << 29) /**< \brief Pioa signal: PIODC5 */ +#define PIO_PA31X1_PIODC7 (1u << 31) /**< \brief Pioa signal: PIODC7 */ +#define PIO_PA23X1_PIODCCLK (1u << 23) /**< \brief Pioa signal: PIODCCLK */ +#define PIO_PA30X1_WKUP11 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA30X1_PIODC6 (1u << 30) /**< \brief Pioa signal: WKUP11/PIODC6 */ +#define PIO_PA15X1_WKUP14 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA15X1_PIODCEN1 (1u << 15) /**< \brief Pioa signal: WKUP14/PIODCEN1 */ +#define PIO_PA16X1_WKUP15 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +#define PIO_PA16X1_PIODCEN2 (1u << 16) /**< \brief Pioa signal: WKUP15/PIODCEN2 */ +/* ========== Pio definition for PMC peripheral ========== */ +#define PIO_PA6B_PCK0 (1u << 6) /**< \brief Pmc signal: PCK0 */ +#define PIO_PB13B_PCK0 (1u << 13) /**< \brief Pmc signal: PCK0 */ +#define PIO_PA17B_PCK1 (1u << 17) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA21B_PCK1 (1u << 21) /**< \brief Pmc signal: PCK1 */ +#define PIO_PA18B_PCK2 (1u << 18) /**< \brief Pmc signal: PCK2 */ +#define PIO_PA31B_PCK2 (1u << 31) /**< \brief Pmc signal: PCK2 */ +#define PIO_PB3B_PCK2 (1u << 3) /**< \brief Pmc signal: PCK2 */ +/* ========== Pio definition for PWM peripheral ========== */ +#define PIO_PA9C_PWMFI0 (1u << 9) /**< \brief Pwm signal: PWMFI0 */ +#define PIO_PA0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA11B_PWMH0 (1u << 11) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA23B_PWMH0 (1u << 23) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PB0A_PWMH0 (1u << 0) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PC18B_PWMH0 (1u << 18) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PD20A_PWMH0 (1u << 20) /**< \brief Pwm signal: PWMH0 */ +#define PIO_PA1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA12B_PWMH1 (1u << 12) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA24B_PWMH1 (1u << 24) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PB1A_PWMH1 (1u << 1) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PC19B_PWMH1 (1u << 19) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PD21A_PWMH1 (1u << 21) /**< \brief Pwm signal: PWMH1 */ +#define PIO_PA2A_PWMH2 (1u << 2) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA13B_PWMH2 (1u << 13) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA25B_PWMH2 (1u << 25) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PB4B_PWMH2 (1u << 4) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PC20B_PWMH2 (1u << 20) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PD22A_PWMH2 (1u << 22) /**< \brief Pwm signal: PWMH2 */ +#define PIO_PA7B_PWMH3 (1u << 7) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA17C_PWMH3 (1u << 17) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PB14B_PWMH3 (1u << 14) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PC21B_PWMH3 (1u << 21) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PD23A_PWMH3 (1u << 23) /**< \brief Pwm signal: PWMH3 */ +#define PIO_PA19B_PWML0 (1u << 19) /**< \brief Pwm signal: PWML0 */ +#define PIO_PB5B_PWML0 (1u << 5) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC0B_PWML0 (1u << 0) /**< \brief Pwm signal: PWML0 */ +#define PIO_PC13B_PWML0 (1u << 13) /**< \brief Pwm signal: PWML0 */ +#define PIO_PD24A_PWML0 (1u << 24) /**< \brief Pwm signal: PWML0 */ +#define PIO_PA20B_PWML1 (1u << 20) /**< \brief Pwm signal: PWML1 */ +#define PIO_PB12A_PWML1 (1u << 12) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC1B_PWML1 (1u << 1) /**< \brief Pwm signal: PWML1 */ +#define PIO_PC15B_PWML1 (1u << 15) /**< \brief Pwm signal: PWML1 */ +#define PIO_PD25A_PWML1 (1u << 25) /**< \brief Pwm signal: PWML1 */ +#define PIO_PA16C_PWML2 (1u << 16) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA30A_PWML2 (1u << 30) /**< \brief Pwm signal: PWML2 */ +#define PIO_PB13A_PWML2 (1u << 13) /**< \brief Pwm signal: PWML2 */ +#define PIO_PC2B_PWML2 (1u << 2) /**< \brief Pwm signal: PWML2 */ +#define PIO_PD26A_PWML2 (1u << 26) /**< \brief Pwm signal: PWML2 */ +#define PIO_PA15C_PWML3 (1u << 15) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC3B_PWML3 (1u << 3) /**< \brief Pwm signal: PWML3 */ +#define PIO_PC22B_PWML3 (1u << 22) /**< \brief Pwm signal: PWML3 */ +#define PIO_PD27A_PWML3 (1u << 27) /**< \brief Pwm signal: PWML3 */ +/* ========== Pio definition for SPI peripheral ========== */ +#define PIO_PA12A_MISO (1u << 12) /**< \brief Spi signal: MISO */ +#define PIO_PA13A_MOSI (1u << 13) /**< \brief Spi signal: MOSI */ +#define PIO_PA11A_NPCS0 (1u << 11) /**< \brief Spi signal: NPCS0 */ +#define PIO_PA9B_NPCS1 (1u << 9) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA31A_NPCS1 (1u << 31) /**< \brief Spi signal: NPCS1 */ +#define PIO_PB14A_NPCS1 (1u << 14) /**< \brief Spi signal: NPCS1 */ +#define PIO_PC4B_NPCS1 (1u << 4) /**< \brief Spi signal: NPCS1 */ +#define PIO_PA10B_NPCS2 (1u << 10) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA30B_NPCS2 (1u << 30) /**< \brief Spi signal: NPCS2 */ +#define PIO_PB2B_NPCS2 (1u << 2) /**< \brief Spi signal: NPCS2 */ +#define PIO_PA3B_NPCS3 (1u << 3) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA5B_NPCS3 (1u << 5) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA22B_NPCS3 (1u << 22) /**< \brief Spi signal: NPCS3 */ +#define PIO_PA14A_SPCK (1u << 14) /**< \brief Spi signal: SPCK */ +/* ========== Pio definition for TC0 peripheral ========== */ +#define PIO_PA4B_TCLK0 (1u << 4) /**< \brief Tc0 signal: TCLK0 */ +#define PIO_PA28B_TCLK1 (1u << 28) /**< \brief Tc0 signal: TCLK1 */ +#define PIO_PA29B_TCLK2 (1u << 29) /**< \brief Tc0 signal: TCLK2 */ +#define PIO_PA0B_TIOA0 (1u << 0) /**< \brief Tc0 signal: TIOA0 */ +#define PIO_PA15B_TIOA1 (1u << 15) /**< \brief Tc0 signal: TIOA1 */ +#define PIO_PA26B_TIOA2 (1u << 26) /**< \brief Tc0 signal: TIOA2 */ +#define PIO_PA1B_TIOB0 (1u << 1) /**< \brief Tc0 signal: TIOB0 */ +#define PIO_PA16B_TIOB1 (1u << 16) /**< \brief Tc0 signal: TIOB1 */ +#define PIO_PA27B_TIOB2 (1u << 27) /**< \brief Tc0 signal: TIOB2 */ +/* ========== Pio definition for TC1 peripheral ========== */ +#define PIO_PC25B_TCLK3 (1u << 25) /**< \brief Tc1 signal: TCLK3 */ +#define PIO_PC28B_TCLK4 (1u << 28) /**< \brief Tc1 signal: TCLK4 */ +#define PIO_PC31B_TCLK5 (1u << 31) /**< \brief Tc1 signal: TCLK5 */ +#define PIO_PC23B_TIOA3 (1u << 23) /**< \brief Tc1 signal: TIOA3 */ +#define PIO_PC26B_TIOA4 (1u << 26) /**< \brief Tc1 signal: TIOA4 */ +#define PIO_PC29B_TIOA5 (1u << 29) /**< \brief Tc1 signal: TIOA5 */ +#define PIO_PC24B_TIOB3 (1u << 24) /**< \brief Tc1 signal: TIOB3 */ +#define PIO_PC27B_TIOB4 (1u << 27) /**< \brief Tc1 signal: TIOB4 */ +#define PIO_PC30B_TIOB5 (1u << 30) /**< \brief Tc1 signal: TIOB5 */ +/* ========== Pio definition for TC2 peripheral ========== */ +#define PIO_PC7B_TCLK6 (1u << 7) /**< \brief Tc2 signal: TCLK6 */ +#define PIO_PC10B_TCLK7 (1u << 10) /**< \brief Tc2 signal: TCLK7 */ +#define PIO_PC14B_TCLK8 (1u << 14) /**< \brief Tc2 signal: TCLK8 */ +#define PIO_PC5B_TIOA6 (1u << 5) /**< \brief Tc2 signal: TIOA6 */ +#define PIO_PC8B_TIOA7 (1u << 8) /**< \brief Tc2 signal: TIOA7 */ +#define PIO_PC11B_TIOA8 (1u << 11) /**< \brief Tc2 signal: TIOA8 */ +#define PIO_PC6B_TIOB6 (1u << 6) /**< \brief Tc2 signal: TIOB6 */ +#define PIO_PC9B_TIOB7 (1u << 9) /**< \brief Tc2 signal: TIOB7 */ +#define PIO_PC12B_TIOB8 (1u << 12) /**< \brief Tc2 signal: TIOB8 */ +/* ========== Pio definition for TWI0 peripheral ========== */ +#define PIO_PA4A_TWCK0 (1u << 4) /**< \brief Twi0 signal: TWCK0 */ +#define PIO_PA3A_TWD0 (1u << 3) /**< \brief Twi0 signal: TWD0 */ +/* ========== Pio definition for TWI1 peripheral ========== */ +#define PIO_PB5A_TWCK1 (1u << 5) /**< \brief Twi1 signal: TWCK1 */ +#define PIO_PB4A_TWD1 (1u << 4) /**< \brief Twi1 signal: TWD1 */ +/* ========== Pio definition for UART0 peripheral ========== */ +#define PIO_PA9A_URXD0 (1u << 9) /**< \brief Uart0 signal: URXD0 */ +#define PIO_PA10A_UTXD0 (1u << 10) /**< \brief Uart0 signal: UTXD0 */ +/* ========== Pio definition for UART1 peripheral ========== */ +#define PIO_PA5C_URXD1 (1u << 5) /**< \brief Uart1 signal: URXD1 */ +#define PIO_PA6C_UTXD1 (1u << 6) /**< \brief Uart1 signal: UTXD1 */ +/* ========== Pio definition for USART0 peripheral ========== */ +#define PIO_PB2C_CTS0 (1u << 2) /**< \brief Usart0 signal: CTS0 */ +#define PIO_PB3C_RTS0 (1u << 3) /**< \brief Usart0 signal: RTS0 */ +#define PIO_PB0C_RXD0 (1u << 0) /**< \brief Usart0 signal: RXD0 */ +#define PIO_PB13C_SCK0 (1u << 13) /**< \brief Usart0 signal: SCK0 */ +#define PIO_PB1C_TXD0 (1u << 1) /**< \brief Usart0 signal: TXD0 */ +/* ========== Pio definition for USART1 peripheral ========== */ +#define PIO_PA25A_CTS1 (1u << 25) /**< \brief Usart1 signal: CTS1 */ +#define PIO_PA26A_DCD1 (1u << 26) /**< \brief Usart1 signal: DCD1 */ +#define PIO_PA28A_DSR1 (1u << 28) /**< \brief Usart1 signal: DSR1 */ +#define PIO_PA27A_DTR1 (1u << 27) /**< \brief Usart1 signal: DTR1 */ +#define PIO_PA29A_RI1 (1u << 29) /**< \brief Usart1 signal: RI1 */ +#define PIO_PA24A_RTS1 (1u << 24) /**< \brief Usart1 signal: RTS1 */ +#define PIO_PA21A_RXD1 (1u << 21) /**< \brief Usart1 signal: RXD1 */ +#define PIO_PA23A_SCK1 (1u << 23) /**< \brief Usart1 signal: SCK1 */ +#define PIO_PA22A_TXD1 (1u << 22) /**< \brief Usart1 signal: TXD1 */ +/* ========== Pio indexes ========== */ +#define PIO_PA0_IDX 0 +#define PIO_PA1_IDX 1 +#define PIO_PA2_IDX 2 +#define PIO_PA3_IDX 3 +#define PIO_PA4_IDX 4 +#define PIO_PA5_IDX 5 +#define PIO_PA6_IDX 6 +#define PIO_PA7_IDX 7 +#define PIO_PA8_IDX 8 +#define PIO_PA9_IDX 9 +#define PIO_PA10_IDX 10 +#define PIO_PA11_IDX 11 +#define PIO_PA12_IDX 12 +#define PIO_PA13_IDX 13 +#define PIO_PA14_IDX 14 +#define PIO_PA15_IDX 15 +#define PIO_PA16_IDX 16 +#define PIO_PA17_IDX 17 +#define PIO_PA18_IDX 18 +#define PIO_PA19_IDX 19 +#define PIO_PA20_IDX 20 +#define PIO_PA21_IDX 21 +#define PIO_PA22_IDX 22 +#define PIO_PA23_IDX 23 +#define PIO_PA24_IDX 24 +#define PIO_PA25_IDX 25 +#define PIO_PA26_IDX 26 +#define PIO_PA27_IDX 27 +#define PIO_PA28_IDX 28 +#define PIO_PA29_IDX 29 +#define PIO_PA30_IDX 30 +#define PIO_PA31_IDX 31 +#define PIO_PB0_IDX 32 +#define PIO_PB1_IDX 33 +#define PIO_PB2_IDX 34 +#define PIO_PB3_IDX 35 +#define PIO_PB4_IDX 36 +#define PIO_PB5_IDX 37 +#define PIO_PB6_IDX 38 +#define PIO_PB7_IDX 39 +#define PIO_PB8_IDX 40 +#define PIO_PB9_IDX 41 +#define PIO_PB10_IDX 42 +#define PIO_PB11_IDX 43 +#define PIO_PB12_IDX 44 +#define PIO_PB13_IDX 45 +#define PIO_PB14_IDX 46 +#define PIO_PC0_IDX 64 +#define PIO_PC1_IDX 65 +#define PIO_PC2_IDX 66 +#define PIO_PC3_IDX 67 +#define PIO_PC4_IDX 68 +#define PIO_PC5_IDX 69 +#define PIO_PC6_IDX 70 +#define PIO_PC7_IDX 71 +#define PIO_PC8_IDX 72 +#define PIO_PC9_IDX 73 +#define PIO_PC10_IDX 74 +#define PIO_PC11_IDX 75 +#define PIO_PC12_IDX 76 +#define PIO_PC13_IDX 77 +#define PIO_PC14_IDX 78 +#define PIO_PC15_IDX 79 +#define PIO_PC16_IDX 80 +#define PIO_PC17_IDX 81 +#define PIO_PC18_IDX 82 +#define PIO_PC19_IDX 83 +#define PIO_PC20_IDX 84 +#define PIO_PC21_IDX 85 +#define PIO_PC22_IDX 86 +#define PIO_PC23_IDX 87 +#define PIO_PC24_IDX 88 +#define PIO_PC25_IDX 89 +#define PIO_PC26_IDX 90 +#define PIO_PC27_IDX 91 +#define PIO_PC28_IDX 92 +#define PIO_PC29_IDX 93 +#define PIO_PC30_IDX 94 +#define PIO_PC31_IDX 95 +#define PIO_PD0_IDX 96 +#define PIO_PD1_IDX 97 +#define PIO_PD2_IDX 98 +#define PIO_PD3_IDX 99 +#define PIO_PD4_IDX 100 +#define PIO_PD5_IDX 101 +#define PIO_PD6_IDX 102 +#define PIO_PD7_IDX 103 +#define PIO_PD8_IDX 104 +#define PIO_PD9_IDX 105 +#define PIO_PD10_IDX 106 +#define PIO_PD11_IDX 107 +#define PIO_PD12_IDX 108 +#define PIO_PD13_IDX 109 +#define PIO_PD14_IDX 110 +#define PIO_PD15_IDX 111 +#define PIO_PD16_IDX 112 +#define PIO_PD17_IDX 113 +#define PIO_PD18_IDX 114 +#define PIO_PD19_IDX 115 +#define PIO_PD20_IDX 116 +#define PIO_PD21_IDX 117 +#define PIO_PD22_IDX 118 +#define PIO_PD23_IDX 119 +#define PIO_PD24_IDX 120 +#define PIO_PD25_IDX 121 +#define PIO_PD26_IDX 122 +#define PIO_PD27_IDX 123 +#define PIO_PD28_IDX 124 +#define PIO_PD29_IDX 125 +#define PIO_PD30_IDX 126 +#define PIO_PD31_IDX 127 +#define PIO_PE0_IDX 128 +#define PIO_PE1_IDX 129 +#define PIO_PE2_IDX 130 +#define PIO_PE3_IDX 131 +#define PIO_PE4_IDX 132 +#define PIO_PE5_IDX 133 + +#endif /* _SAM4E8E_PIO_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e.h new file mode 100644 index 0000000..8c04108 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e.h @@ -0,0 +1,59 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ +#ifndef _SAM4E_ +#define _SAM4E_ + +#if defined (__SAM4E8E__) +#include "sam4e8e.h" +#elif defined (__SAM4E16E__) +#include "sam4e16e.h" +#elif defined (__SAM4E8C__) +#include "sam4e8c.h" +#elif defined (__SAM4E16C__) +#include "sam4e16c.h" +#else + #error Library does not support the specified device. +#endif + +#endif /* _SAM4E_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16c.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16c.h new file mode 100644 index 0000000..6920911 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16c.h @@ -0,0 +1,563 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E16C_ +#define _SAM4E16C_ + +/** \addtogroup SAM4E16C_definitions SAM4E16C definitions + This file defines all structures and symbols for SAM4E16C: + - registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#endif + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_cmsis CMSIS Definitions */ +/*@{*/ + +/**< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /**< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M4 System Tick Interrupt */ +/****** SAM4E16C specific Interrupt Numbers *********************************/ + + SUPC_IRQn = 0, /**< 0 SAM4E16C Supply Controller (SUPC) */ + RSTC_IRQn = 1, /**< 1 SAM4E16C Reset Controller (RSTC) */ + RTC_IRQn = 2, /**< 2 SAM4E16C Real Time Clock (RTC) */ + RTT_IRQn = 3, /**< 3 SAM4E16C Real Time Timer (RTT) */ + WDT_IRQn = 4, /**< 4 SAM4E16C Watchdog/Dual Watchdog Timer (WDT) */ + PMC_IRQn = 5, /**< 5 SAM4E16C Power Management Controller (PMC) */ + EFC_IRQn = 6, /**< 6 SAM4E16C Enhanced Embedded Flash Controller (EFC) */ + UART0_IRQn = 7, /**< 7 SAM4E16C UART 0 (UART0) */ + PIOA_IRQn = 9, /**< 9 SAM4E16C Parallel I/O Controller A (PIOA) */ + PIOB_IRQn = 10, /**< 10 SAM4E16C Parallel I/O Controller B (PIOB) */ + PIOD_IRQn = 12, /**< 12 SAM4E16C Parallel I/O Controller D (PIOD) */ + USART0_IRQn = 14, /**< 14 SAM4E16C USART 0 (USART0) */ + USART1_IRQn = 15, /**< 15 SAM4E16C USART 1 (USART1) */ + HSMCI_IRQn = 16, /**< 16 SAM4E16C Multimedia Card Interface (HSMCI) */ + TWI0_IRQn = 17, /**< 17 SAM4E16C Two Wire Interface 0 (TWI0) */ + TWI1_IRQn = 18, /**< 18 SAM4E16C Two Wire Interface 1 (TWI1) */ + SPI_IRQn = 19, /**< 19 SAM4E16C Serial Peripheral Interface (SPI) */ + DMAC_IRQn = 20, /**< 20 SAM4E16C DMAC (DMAC) */ + TC0_IRQn = 21, /**< 21 SAM4E16C Timer/Counter 0 (TC0) */ + TC1_IRQn = 22, /**< 22 SAM4E16C Timer/Counter 1 (TC1) */ + TC2_IRQn = 23, /**< 23 SAM4E16C Timer/Counter 2 (TC2) */ + AFEC0_IRQn = 30, /**< 30 SAM4E16C Analog Front End 0 (AFEC0) */ + AFEC1_IRQn = 31, /**< 31 SAM4E16C Analog Front End 1 (AFEC1) */ + DACC_IRQn = 32, /**< 32 SAM4E16C Digital To Analog Converter (DACC) */ + ACC_IRQn = 33, /**< 33 SAM4E16C Analog Comparator (ACC) */ + ARM_IRQn = 34, /**< 34 SAM4E16C FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ + UDP_IRQn = 35, /**< 35 SAM4E16C USB DEVICE (UDP) */ + PWM_IRQn = 36, /**< 36 SAM4E16C PWM (PWM) */ + CAN0_IRQn = 37, /**< 37 SAM4E16C CAN0 (CAN0) */ + AES_IRQn = 39, /**< 39 SAM4E16C AES (AES) */ + GMAC_IRQn = 44, /**< 44 SAM4E16C EMAC (GMAC) */ + UART1_IRQn = 45, /**< 45 SAM4E16C UART (UART1) */ + + PERIPH_COUNT_IRQn = 46 /**< 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* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pfnReserved5_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnSUPC_Handler; /* 0 Supply Controller */ + void* pfnRSTC_Handler; /* 1 Reset Controller */ + void* pfnRTC_Handler; /* 2 Real Time Clock */ + void* pfnRTT_Handler; /* 3 Real Time Timer */ + void* pfnWDT_Handler; /* 4 Watchdog/Dual Watchdog Timer */ + void* pfnPMC_Handler; /* 5 Power Management Controller */ + void* pfnEFC_Handler; /* 6 Enhanced Embedded Flash Controller */ + void* pfnUART0_Handler; /* 7 UART 0 */ + void* pvReserved8; + void* pfnPIOA_Handler; /* 9 Parallel I/O Controller A */ + void* pfnPIOB_Handler; /* 10 Parallel I/O Controller B */ + void* pvReserved11; + void* pfnPIOD_Handler; /* 12 Parallel I/O Controller D */ + void* pvReserved13; + void* pfnUSART0_Handler; /* 14 USART 0 */ + void* pfnUSART1_Handler; /* 15 USART 1 */ + void* pfnHSMCI_Handler; /* 16 Multimedia Card Interface */ + void* pfnTWI0_Handler; /* 17 Two Wire Interface 0 */ + void* pfnTWI1_Handler; /* 18 Two Wire Interface 1 */ + void* pfnSPI_Handler; /* 19 Serial Peripheral Interface */ + void* pfnDMAC_Handler; /* 20 DMAC */ + void* pfnTC0_Handler; /* 21 Timer/Counter 0 */ + void* pfnTC1_Handler; /* 22 Timer/Counter 1 */ + void* pfnTC2_Handler; /* 23 Timer/Counter 2 */ + void* pvReserved24; + void* pvReserved25; + void* pvReserved26; + void* pvReserved27; + void* pvReserved28; + void* pvReserved29; + void* pfnAFEC0_Handler; /* 30 Analog Front End 0 */ + void* pfnAFEC1_Handler; /* 31 Analog Front End 1 */ + void* pfnDACC_Handler; /* 32 Digital To Analog Converter */ + void* pfnACC_Handler; /* 33 Analog Comparator */ + void* pfnARM_Handler; /* 34 FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + void* pfnUDP_Handler; /* 35 USB DEVICE */ + void* pfnPWM_Handler; /* 36 PWM */ + void* pfnCAN0_Handler; /* 37 CAN0 */ + void* pvReserved38; + void* pfnAES_Handler; /* 39 AES */ + void* pvReserved40; + void* pvReserved41; + void* pvReserved42; + void* pvReserved43; + void* pfnGMAC_Handler; /* 44 EMAC */ + void* pfnUART1_Handler; /* 45 UART */ +} DeviceVectors; + +/* Cortex-M4 core handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void MemManage_Handler ( void ); +void BusFault_Handler ( void ); +void UsageFault_Handler ( void ); +void SVC_Handler ( void ); +void DebugMon_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void ACC_Handler ( void ); +void AES_Handler ( void ); +void AFEC0_Handler ( void ); +void AFEC1_Handler ( void ); +void ARM_Handler ( void ); +void CAN0_Handler ( void ); +void DACC_Handler ( void ); +void DMAC_Handler ( void ); +void EFC_Handler ( void ); +void GMAC_Handler ( void ); +void HSMCI_Handler ( void ); +void PIOA_Handler ( void ); +void PIOB_Handler ( void ); +void PIOD_Handler ( void ); +void PMC_Handler ( void ); +void PWM_Handler ( void ); +void RSTC_Handler ( void ); +void RTC_Handler ( void ); +void RTT_Handler ( void ); +void SPI_Handler ( void ); +void SUPC_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TWI0_Handler ( void ); +void TWI1_Handler ( void ); +void UART0_Handler ( void ); +void UART1_Handler ( void ); +void UDP_Handler ( void ); +void USART0_Handler ( void ); +void USART1_Handler ( void ); +void WDT_Handler ( void ); + +/** + * \brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ + +#define __CM4_REV 0x0001 /**< SAM4E16C core revision number ([15:8] revision number, [7:0] patch number) */ +#define __MPU_PRESENT 1 /**< SAM4E16C does provide a MPU */ +#define __FPU_PRESENT 1 /**< SAM4E16C does provide a FPU */ +#define __NVIC_PRIO_BITS 4 /**< SAM4E16C uses 4 Bits for the Priority Levels */ +#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_sam4e.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_api Peripheral Software API */ +/*@{*/ + +#include "component/acc.h" +#include "component/aes.h" +#include "component/afec.h" +#include "component/can.h" +#include "component/chipid.h" +#include "component/cmcc.h" +#include "component/dacc.h" +#include "component/dmac.h" +#include "component/efc.h" +#include "component/gmac.h" +#include "component/gpbr.h" +#include "component/hsmci.h" +#include "component/matrix.h" +#include "component/pdc.h" +#include "component/pio.h" +#include "component/pmc.h" +#include "component/pwm.h" +#include "component/rstc.h" +#include "component/rswdt.h" +#include "component/rtc.h" +#include "component/rtt.h" +#include "component/spi.h" +#include "component/supc.h" +#include "component/tc.h" +#include "component/twi.h" +#include "component/uart.h" +#include "component/udp.h" +#include "component/usart.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* REGISTER ACCESS DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/pwm.h" +#include "instance/aes.h" +#include "instance/can0.h" +#include "instance/gmac.h" +#include "instance/uart1.h" +#include "instance/hsmci.h" +#include "instance/udp.h" +#include "instance/spi.h" +#include "instance/tc0.h" +#include "instance/usart0.h" +#include "instance/usart1.h" +#include "instance/twi0.h" +#include "instance/twi1.h" +#include "instance/afec0.h" +#include "instance/afec1.h" +#include "instance/dacc.h" +#include "instance/acc.h" +#include "instance/dmac.h" +#include "instance/cmcc.h" +#include "instance/matrix.h" +#include "instance/pmc.h" +#include "instance/uart0.h" +#include "instance/chipid.h" +#include "instance/efc.h" +#include "instance/pioa.h" +#include "instance/piob.h" +#include "instance/piod.h" +#include "instance/rstc.h" +#include "instance/supc.h" +#include "instance/rtt.h" +#include "instance/wdt.h" +#include "instance/rtc.h" +#include "instance/gpbr.h" +#include "instance/rswdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_id Peripheral Ids Definitions */ +/*@{*/ + +#define ID_SUPC ( 0) /**< \brief Supply Controller (SUPC) */ +#define ID_RSTC ( 1) /**< \brief Reset Controller (RSTC) */ +#define ID_RTC ( 2) /**< \brief Real Time Clock (RTC) */ +#define ID_RTT ( 3) /**< \brief Real Time Timer (RTT) */ +#define ID_WDT ( 4) /**< \brief Watchdog/Dual Watchdog Timer (WDT) */ +#define ID_PMC ( 5) /**< \brief Power Management Controller (PMC) */ +#define ID_EFC ( 6) /**< \brief Enhanced Embedded Flash Controller (EFC) */ +#define ID_UART0 ( 7) /**< \brief UART 0 (UART0) */ +#define ID_PIOA ( 9) /**< \brief Parallel I/O Controller A (PIOA) */ +#define ID_PIOB (10) /**< \brief Parallel I/O Controller B (PIOB) */ +#define ID_PIOD (12) /**< \brief Parallel I/O Controller D (PIOD) */ +#define ID_USART0 (14) /**< \brief USART 0 (USART0) */ +#define ID_USART1 (15) /**< \brief USART 1 (USART1) */ +#define ID_HSMCI (16) /**< \brief Multimedia Card Interface (HSMCI) */ +#define ID_TWI0 (17) /**< \brief Two Wire Interface 0 (TWI0) */ +#define ID_TWI1 (18) /**< \brief Two Wire Interface 1 (TWI1) */ +#define ID_SPI (19) /**< \brief Serial Peripheral Interface (SPI) */ +#define ID_DMAC (20) /**< \brief DMAC (DMAC) */ +#define ID_TC0 (21) /**< \brief Timer/Counter 0 (TC0) */ +#define ID_TC1 (22) /**< \brief Timer/Counter 1 (TC1) */ +#define ID_TC2 (23) /**< \brief Timer/Counter 2 (TC2) */ +#define ID_AFEC0 (30) /**< \brief Analog Front End 0 (AFEC0) */ +#define ID_AFEC1 (31) /**< \brief Analog Front End 1 (AFEC1) */ +#define ID_DACC (32) /**< \brief Digital To Analog Converter (DACC) */ +#define ID_ACC (33) /**< \brief Analog Comparator (ACC) */ +#define ID_ARM (34) /**< \brief FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ +#define ID_UDP (35) /**< \brief USB DEVICE (UDP) */ +#define ID_PWM (36) /**< \brief PWM (PWM) */ +#define ID_CAN0 (37) /**< \brief CAN0 (CAN0) */ +#define ID_AES (39) /**< \brief AES (AES) */ +#define ID_GMAC (44) /**< \brief EMAC (GMAC) */ +#define ID_UART1 (45) /**< \brief UART (UART1) */ + +#define ID_PERIPH_COUNT (46) /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_base Peripheral Base Address Definitions */ +/*@{*/ + +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define PWM (0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM (0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES (0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 (0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define GMAC (0x40034000U) /**< \brief (GMAC ) Base Address */ +#define UART1 (0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 (0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI (0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI (0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP (0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI (0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI (0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 (0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 (0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define USART0 (0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 (0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 (0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 (0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 (0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 (0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 (0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 (0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 (0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 (0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 (0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 (0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC (0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC (0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC (0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC (0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC (0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX (0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC (0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 (0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 (0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID (0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC (0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA (0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA (0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB (0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOD (0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC (0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC (0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT (0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT (0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC (0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR (0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT (0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#else +#define PWM ((Pwm *)0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM ((Pdc *)0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES ((Aes *)0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 ((Can *)0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define GMAC ((Gmac *)0x40034000U) /**< \brief (GMAC ) Base Address */ +#define UART1 ((Uart *)0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 ((Pdc *)0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI ((Hsmci *)0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI ((Pdc *)0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP ((Udp *)0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI ((Spi *)0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI ((Pdc *)0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 ((Tc *)0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 ((Pdc *)0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define USART0 ((Usart *)0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 ((Pdc *)0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 ((Usart *)0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 ((Pdc *)0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 ((Twi *)0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 ((Pdc *)0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 ((Twi *)0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 ((Pdc *)0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 ((Afec *)0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 ((Pdc *)0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 ((Afec *)0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 ((Pdc *)0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC ((Dacc *)0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC ((Pdc *)0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC ((Acc *)0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC ((Dmac *)0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC ((Cmcc *)0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX ((Matrix *)0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC ((Pmc *)0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 ((Uart *)0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 ((Pdc *)0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID ((Chipid *)0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC ((Efc *)0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA ((Pio *)0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA ((Pdc *)0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB ((Pio *)0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOD ((Pio *)0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC ((Rstc *)0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC ((Supc *)0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT ((Rtt *)0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT ((Wdt *)0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC ((Rtc *)0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR ((Gpbr *)0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT ((Rswdt *)0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16C_pio Peripheral Pio Definitions */ +/*@{*/ + +#include "pio/sam4e16c.h" +/*@}*/ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ + +#define IFLASH_SIZE (0x100000u) +#define IFLASH_PAGE_SIZE (512u) +#define IFLASH_LOCK_REGION_SIZE (8192u) +#define IFLASH_NB_OF_PAGES (2048u) +#define IFLASH_NB_OF_LOCK_BITS (128u) +#define IRAM_SIZE (0x20000u) + +#define IFLASH_ADDR (0x00400000u) /**< Internal Flash base address */ +#define IROM_ADDR (0x00800000u) /**< Internal ROM base address */ +#define IRAM_ADDR (0x20000000u) /**< Internal RAM base address */ +#define EBI_CS0_ADDR (0x60000000u) /**< EBI Chip Select 0 base address */ +#define EBI_CS1_ADDR (0x61000000u) /**< EBI Chip Select 1 base address */ +#define EBI_CS2_ADDR (0x62000000u) /**< EBI Chip Select 2 base address */ +#define EBI_CS3_ADDR (0x63000000u) /**< EBI Chip Select 3 base address */ + +/* ************************************************************************** */ +/* MISCELLANEOUS DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ + +#define CHIP_JTAGID (0x05B3703FUL) +#define CHIP_CIDR (0xA3CC0CE0UL) +#define CHIP_EXID (0x00120201UL) +#define NB_CH_AFE0 (6UL) +#define NB_CH_AFE1 (4UL) +#define NB_CH_DAC (2UL) +#define USB_DEVICE_MAX_EP (8UL) + +/* ************************************************************************** */ +/* ELECTRICAL DEFINITIONS FOR SAM4E16C */ +/* ************************************************************************** */ + +/* Device characteristics */ +#define CHIP_FREQ_SLCK_RC_MIN (20000UL) +#define CHIP_FREQ_SLCK_RC (32000UL) +#define CHIP_FREQ_SLCK_RC_MAX (44000UL) +#define CHIP_FREQ_MAINCK_RC_4MHZ (4000000UL) +#define CHIP_FREQ_MAINCK_RC_8MHZ (8000000UL) +#define CHIP_FREQ_MAINCK_RC_12MHZ (12000000UL) +#define CHIP_FREQ_CPU_MAX (120000000UL) +#define CHIP_FREQ_XTAL_32K (32768UL) +#define CHIP_FREQ_XTAL_12M (12000000UL) + +/* Embedded Flash Write Wait State */ +#define CHIP_FLASH_WRITE_WAIT_STATE (6U) + +/* Embedded Flash Read Wait State (VDDCORE set at 1.20V) */ +#define CHIP_FREQ_FWS_0 (20000000UL) /**< \brief Maximum operating frequency when FWS is 0 */ +#define CHIP_FREQ_FWS_1 (40000000UL) /**< \brief Maximum operating frequency when FWS is 1 */ +#define CHIP_FREQ_FWS_2 (60000000UL) /**< \brief Maximum operating frequency when FWS is 2 */ +#define CHIP_FREQ_FWS_3 (80000000UL) /**< \brief Maximum operating frequency when FWS is 3 */ +#define CHIP_FREQ_FWS_4 (100000000UL) /**< \brief Maximum operating frequency when FWS is 4 */ +#define CHIP_FREQ_FWS_5 (123000000UL) /**< \brief Maximum operating frequency when FWS is 5 */ + +/* HYSTeresis levels: please refer to Electrical Characteristics */ +#define ACC_ACR_HYST_50MV_MAX (0x01UL) +#define ACC_ACR_HYST_90MV_MAX (0x11UL) + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _SAM4E16C_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16e.h new file mode 100644 index 0000000..6c77353 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e16e.h @@ -0,0 +1,612 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E16E_ +#define _SAM4E16E_ + +/** \addtogroup SAM4E16E_definitions SAM4E16E definitions + This file defines all structures and symbols for SAM4E16E: + - registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#endif + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_cmsis CMSIS Definitions */ +/*@{*/ + +/**< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /**< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M4 System Tick Interrupt */ +/****** SAM4E16E specific Interrupt Numbers *********************************/ + + SUPC_IRQn = 0, /**< 0 SAM4E16E Supply Controller (SUPC) */ + RSTC_IRQn = 1, /**< 1 SAM4E16E Reset Controller (RSTC) */ + RTC_IRQn = 2, /**< 2 SAM4E16E Real Time Clock (RTC) */ + RTT_IRQn = 3, /**< 3 SAM4E16E Real Time Timer (RTT) */ + WDT_IRQn = 4, /**< 4 SAM4E16E Watchdog/Dual Watchdog Timer (WDT) */ + PMC_IRQn = 5, /**< 5 SAM4E16E Power Management Controller (PMC) */ + EFC_IRQn = 6, /**< 6 SAM4E16E Enhanced Embedded Flash Controller (EFC) */ + UART0_IRQn = 7, /**< 7 SAM4E16E UART 0 (UART0) */ + PIOA_IRQn = 9, /**< 9 SAM4E16E Parallel I/O Controller A (PIOA) */ + PIOB_IRQn = 10, /**< 10 SAM4E16E Parallel I/O Controller B (PIOB) */ + PIOC_IRQn = 11, /**< 11 SAM4E16E Parallel I/O Controller C (PIOC) */ + PIOD_IRQn = 12, /**< 12 SAM4E16E Parallel I/O Controller D (PIOD) */ + PIOE_IRQn = 13, /**< 13 SAM4E16E Parallel I/O Controller E (PIOE) */ + USART0_IRQn = 14, /**< 14 SAM4E16E USART 0 (USART0) */ + USART1_IRQn = 15, /**< 15 SAM4E16E USART 1 (USART1) */ + HSMCI_IRQn = 16, /**< 16 SAM4E16E Multimedia Card Interface (HSMCI) */ + TWI0_IRQn = 17, /**< 17 SAM4E16E Two Wire Interface 0 (TWI0) */ + TWI1_IRQn = 18, /**< 18 SAM4E16E Two Wire Interface 1 (TWI1) */ + SPI_IRQn = 19, /**< 19 SAM4E16E Serial Peripheral Interface (SPI) */ + DMAC_IRQn = 20, /**< 20 SAM4E16E DMAC (DMAC) */ + TC0_IRQn = 21, /**< 21 SAM4E16E Timer/Counter 0 (TC0) */ + TC1_IRQn = 22, /**< 22 SAM4E16E Timer/Counter 1 (TC1) */ + TC2_IRQn = 23, /**< 23 SAM4E16E Timer/Counter 2 (TC2) */ + TC3_IRQn = 24, /**< 24 SAM4E16E Timer/Counter 3 (TC3) */ + TC4_IRQn = 25, /**< 25 SAM4E16E Timer/Counter 4 (TC4) */ + TC5_IRQn = 26, /**< 26 SAM4E16E Timer/Counter 5 (TC5) */ + TC6_IRQn = 27, /**< 27 SAM4E16E Timer/Counter 6 (TC6) */ + TC7_IRQn = 28, /**< 28 SAM4E16E Timer/Counter 7 (TC7) */ + TC8_IRQn = 29, /**< 29 SAM4E16E Timer/Counter 8 (TC8) */ + AFEC0_IRQn = 30, /**< 30 SAM4E16E Analog Front End 0 (AFEC0) */ + AFEC1_IRQn = 31, /**< 31 SAM4E16E Analog Front End 1 (AFEC1) */ + DACC_IRQn = 32, /**< 32 SAM4E16E Digital To Analog Converter (DACC) */ + ACC_IRQn = 33, /**< 33 SAM4E16E Analog Comparator (ACC) */ + ARM_IRQn = 34, /**< 34 SAM4E16E FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ + UDP_IRQn = 35, /**< 35 SAM4E16E USB DEVICE (UDP) */ + PWM_IRQn = 36, /**< 36 SAM4E16E PWM (PWM) */ + CAN0_IRQn = 37, /**< 37 SAM4E16E CAN0 (CAN0) */ + CAN1_IRQn = 38, /**< 38 SAM4E16E CAN1 (CAN1) */ + AES_IRQn = 39, /**< 39 SAM4E16E AES (AES) */ + GMAC_IRQn = 44, /**< 44 SAM4E16E EMAC (GMAC) */ + UART1_IRQn = 45, /**< 45 SAM4E16E UART (UART1) */ + + PERIPH_COUNT_IRQn = 46 /**< 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* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pfnReserved5_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnSUPC_Handler; /* 0 Supply Controller */ + void* pfnRSTC_Handler; /* 1 Reset Controller */ + void* pfnRTC_Handler; /* 2 Real Time Clock */ + void* pfnRTT_Handler; /* 3 Real Time Timer */ + void* pfnWDT_Handler; /* 4 Watchdog/Dual Watchdog Timer */ + void* pfnPMC_Handler; /* 5 Power Management Controller */ + void* pfnEFC_Handler; /* 6 Enhanced Embedded Flash Controller */ + void* pfnUART0_Handler; /* 7 UART 0 */ + void* pvReserved8; + void* pfnPIOA_Handler; /* 9 Parallel I/O Controller A */ + void* pfnPIOB_Handler; /* 10 Parallel I/O Controller B */ + void* pfnPIOC_Handler; /* 11 Parallel I/O Controller C */ + void* pfnPIOD_Handler; /* 12 Parallel I/O Controller D */ + void* pfnPIOE_Handler; /* 13 Parallel I/O Controller E */ + void* pfnUSART0_Handler; /* 14 USART 0 */ + void* pfnUSART1_Handler; /* 15 USART 1 */ + void* pfnHSMCI_Handler; /* 16 Multimedia Card Interface */ + void* pfnTWI0_Handler; /* 17 Two Wire Interface 0 */ + void* pfnTWI1_Handler; /* 18 Two Wire Interface 1 */ + void* pfnSPI_Handler; /* 19 Serial Peripheral Interface */ + void* pfnDMAC_Handler; /* 20 DMAC */ + void* pfnTC0_Handler; /* 21 Timer/Counter 0 */ + void* pfnTC1_Handler; /* 22 Timer/Counter 1 */ + void* pfnTC2_Handler; /* 23 Timer/Counter 2 */ + void* pfnTC3_Handler; /* 24 Timer/Counter 3 */ + void* pfnTC4_Handler; /* 25 Timer/Counter 4 */ + void* pfnTC5_Handler; /* 26 Timer/Counter 5 */ + void* pfnTC6_Handler; /* 27 Timer/Counter 6 */ + void* pfnTC7_Handler; /* 28 Timer/Counter 7 */ + void* pfnTC8_Handler; /* 29 Timer/Counter 8 */ + void* pfnAFEC0_Handler; /* 30 Analog Front End 0 */ + void* pfnAFEC1_Handler; /* 31 Analog Front End 1 */ + void* pfnDACC_Handler; /* 32 Digital To Analog Converter */ + void* pfnACC_Handler; /* 33 Analog Comparator */ + void* pfnARM_Handler; /* 34 FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + void* pfnUDP_Handler; /* 35 USB DEVICE */ + void* pfnPWM_Handler; /* 36 PWM */ + void* pfnCAN0_Handler; /* 37 CAN0 */ + void* pfnCAN1_Handler; /* 38 CAN1 */ + void* pfnAES_Handler; /* 39 AES */ + void* pvReserved40; + void* pvReserved41; + void* pvReserved42; + void* pvReserved43; + void* pfnGMAC_Handler; /* 44 EMAC */ + void* pfnUART1_Handler; /* 45 UART */ +} DeviceVectors; + +/* Cortex-M4 core handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void MemManage_Handler ( void ); +void BusFault_Handler ( void ); +void UsageFault_Handler ( void ); +void SVC_Handler ( void ); +void DebugMon_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void ACC_Handler ( void ); +void AES_Handler ( void ); +void AFEC0_Handler ( void ); +void AFEC1_Handler ( void ); +void ARM_Handler ( void ); +void CAN0_Handler ( void ); +void CAN1_Handler ( void ); +void DACC_Handler ( void ); +void DMAC_Handler ( void ); +void EFC_Handler ( void ); +void GMAC_Handler ( void ); +void HSMCI_Handler ( void ); +void PIOA_Handler ( void ); +void PIOB_Handler ( void ); +void PIOC_Handler ( void ); +void PIOD_Handler ( void ); +void PIOE_Handler ( void ); +void PMC_Handler ( void ); +void PWM_Handler ( void ); +void RSTC_Handler ( void ); +void RTC_Handler ( void ); +void RTT_Handler ( void ); +void SPI_Handler ( void ); +void SUPC_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 TC8_Handler ( void ); +void TWI0_Handler ( void ); +void TWI1_Handler ( void ); +void UART0_Handler ( void ); +void UART1_Handler ( void ); +void UDP_Handler ( void ); +void USART0_Handler ( void ); +void USART1_Handler ( void ); +void WDT_Handler ( void ); + +/** + * \brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ + +#define __CM4_REV 0x0001 /**< SAM4E16E core revision number ([15:8] revision number, [7:0] patch number) */ +#define __MPU_PRESENT 1 /**< SAM4E16E does provide a MPU */ +#define __FPU_PRESENT 1 /**< SAM4E16E does provide a FPU */ +#define __NVIC_PRIO_BITS 4 /**< SAM4E16E uses 4 Bits for the Priority Levels */ +#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_sam4e.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_api Peripheral Software API */ +/*@{*/ + +#include "component/acc.h" +#include "component/aes.h" +#include "component/afec.h" +#include "component/can.h" +#include "component/chipid.h" +#include "component/cmcc.h" +#include "component/dacc.h" +#include "component/dmac.h" +#include "component/efc.h" +#include "component/gmac.h" +#include "component/gpbr.h" +#include "component/hsmci.h" +#include "component/matrix.h" +#include "component/pdc.h" +#include "component/pio.h" +#include "component/pmc.h" +#include "component/pwm.h" +#include "component/rstc.h" +#include "component/rswdt.h" +#include "component/rtc.h" +#include "component/rtt.h" +#include "component/smc.h" +#include "component/spi.h" +#include "component/supc.h" +#include "component/tc.h" +#include "component/twi.h" +#include "component/uart.h" +#include "component/udp.h" +#include "component/usart.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* REGISTER ACCESS DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/pwm.h" +#include "instance/aes.h" +#include "instance/can0.h" +#include "instance/can1.h" +#include "instance/gmac.h" +#include "instance/smc.h" +#include "instance/uart1.h" +#include "instance/hsmci.h" +#include "instance/udp.h" +#include "instance/spi.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/usart0.h" +#include "instance/usart1.h" +#include "instance/twi0.h" +#include "instance/twi1.h" +#include "instance/afec0.h" +#include "instance/afec1.h" +#include "instance/dacc.h" +#include "instance/acc.h" +#include "instance/dmac.h" +#include "instance/cmcc.h" +#include "instance/matrix.h" +#include "instance/pmc.h" +#include "instance/uart0.h" +#include "instance/chipid.h" +#include "instance/efc.h" +#include "instance/pioa.h" +#include "instance/piob.h" +#include "instance/pioc.h" +#include "instance/piod.h" +#include "instance/pioe.h" +#include "instance/rstc.h" +#include "instance/supc.h" +#include "instance/rtt.h" +#include "instance/wdt.h" +#include "instance/rtc.h" +#include "instance/gpbr.h" +#include "instance/rswdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_id Peripheral Ids Definitions */ +/*@{*/ + +#define ID_SUPC ( 0) /**< \brief Supply Controller (SUPC) */ +#define ID_RSTC ( 1) /**< \brief Reset Controller (RSTC) */ +#define ID_RTC ( 2) /**< \brief Real Time Clock (RTC) */ +#define ID_RTT ( 3) /**< \brief Real Time Timer (RTT) */ +#define ID_WDT ( 4) /**< \brief Watchdog/Dual Watchdog Timer (WDT) */ +#define ID_PMC ( 5) /**< \brief Power Management Controller (PMC) */ +#define ID_EFC ( 6) /**< \brief Enhanced Embedded Flash Controller (EFC) */ +#define ID_UART0 ( 7) /**< \brief UART 0 (UART0) */ +#define ID_SMC ( 8) /**< \brief Static Memory Controller (SMC) */ +#define ID_PIOA ( 9) /**< \brief Parallel I/O Controller A (PIOA) */ +#define ID_PIOB (10) /**< \brief Parallel I/O Controller B (PIOB) */ +#define ID_PIOC (11) /**< \brief Parallel I/O Controller C (PIOC) */ +#define ID_PIOD (12) /**< \brief Parallel I/O Controller D (PIOD) */ +#define ID_PIOE (13) /**< \brief Parallel I/O Controller E (PIOE) */ +#define ID_USART0 (14) /**< \brief USART 0 (USART0) */ +#define ID_USART1 (15) /**< \brief USART 1 (USART1) */ +#define ID_HSMCI (16) /**< \brief Multimedia Card Interface (HSMCI) */ +#define ID_TWI0 (17) /**< \brief Two Wire Interface 0 (TWI0) */ +#define ID_TWI1 (18) /**< \brief Two Wire Interface 1 (TWI1) */ +#define ID_SPI (19) /**< \brief Serial Peripheral Interface (SPI) */ +#define ID_DMAC (20) /**< \brief DMAC (DMAC) */ +#define ID_TC0 (21) /**< \brief Timer/Counter 0 (TC0) */ +#define ID_TC1 (22) /**< \brief Timer/Counter 1 (TC1) */ +#define ID_TC2 (23) /**< \brief Timer/Counter 2 (TC2) */ +#define ID_TC3 (24) /**< \brief Timer/Counter 3 (TC3) */ +#define ID_TC4 (25) /**< \brief Timer/Counter 4 (TC4) */ +#define ID_TC5 (26) /**< \brief Timer/Counter 5 (TC5) */ +#define ID_TC6 (27) /**< \brief Timer/Counter 6 (TC6) */ +#define ID_TC7 (28) /**< \brief Timer/Counter 7 (TC7) */ +#define ID_TC8 (29) /**< \brief Timer/Counter 8 (TC8) */ +#define ID_AFEC0 (30) /**< \brief Analog Front End 0 (AFEC0) */ +#define ID_AFEC1 (31) /**< \brief Analog Front End 1 (AFEC1) */ +#define ID_DACC (32) /**< \brief Digital To Analog Converter (DACC) */ +#define ID_ACC (33) /**< \brief Analog Comparator (ACC) */ +#define ID_ARM (34) /**< \brief FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ +#define ID_UDP (35) /**< \brief USB DEVICE (UDP) */ +#define ID_PWM (36) /**< \brief PWM (PWM) */ +#define ID_CAN0 (37) /**< \brief CAN0 (CAN0) */ +#define ID_CAN1 (38) /**< \brief CAN1 (CAN1) */ +#define ID_AES (39) /**< \brief AES (AES) */ +#define ID_GMAC (44) /**< \brief EMAC (GMAC) */ +#define ID_UART1 (45) /**< \brief UART (UART1) */ + +#define ID_PERIPH_COUNT (46) /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_base Peripheral Base Address Definitions */ +/*@{*/ + +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define PWM (0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM (0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES (0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 (0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 (0x40014000U) /**< \brief (CAN1 ) Base Address */ +#define GMAC (0x40034000U) /**< \brief (GMAC ) Base Address */ +#define SMC (0x40060000U) /**< \brief (SMC ) Base Address */ +#define UART1 (0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 (0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI (0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI (0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP (0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI (0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI (0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 (0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 (0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define TC1 (0x40094000U) /**< \brief (TC1 ) Base Address */ +#define PDC_TC1 (0x40094100U) /**< \brief (PDC_TC1 ) Base Address */ +#define TC2 (0x40098000U) /**< \brief (TC2 ) Base Address */ +#define USART0 (0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 (0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 (0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 (0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 (0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 (0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 (0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 (0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 (0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 (0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 (0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 (0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC (0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC (0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC (0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC (0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC (0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX (0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC (0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 (0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 (0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID (0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC (0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA (0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA (0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB (0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC (0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD (0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define PIOE (0x400E1600U) /**< \brief (PIOE ) Base Address */ +#define RSTC (0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC (0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT (0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT (0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC (0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR (0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT (0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#else +#define PWM ((Pwm *)0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM ((Pdc *)0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES ((Aes *)0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 ((Can *)0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 ((Can *)0x40014000U) /**< \brief (CAN1 ) Base Address */ +#define GMAC ((Gmac *)0x40034000U) /**< \brief (GMAC ) Base Address */ +#define SMC ((Smc *)0x40060000U) /**< \brief (SMC ) Base Address */ +#define UART1 ((Uart *)0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 ((Pdc *)0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI ((Hsmci *)0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI ((Pdc *)0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP ((Udp *)0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI ((Spi *)0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI ((Pdc *)0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 ((Tc *)0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 ((Pdc *)0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define TC1 ((Tc *)0x40094000U) /**< \brief (TC1 ) Base Address */ +#define PDC_TC1 ((Pdc *)0x40094100U) /**< \brief (PDC_TC1 ) Base Address */ +#define TC2 ((Tc *)0x40098000U) /**< \brief (TC2 ) Base Address */ +#define USART0 ((Usart *)0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 ((Pdc *)0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 ((Usart *)0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 ((Pdc *)0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 ((Twi *)0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 ((Pdc *)0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 ((Twi *)0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 ((Pdc *)0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 ((Afec *)0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 ((Pdc *)0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 ((Afec *)0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 ((Pdc *)0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC ((Dacc *)0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC ((Pdc *)0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC ((Acc *)0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC ((Dmac *)0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC ((Cmcc *)0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX ((Matrix *)0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC ((Pmc *)0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 ((Uart *)0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 ((Pdc *)0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID ((Chipid *)0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC ((Efc *)0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA ((Pio *)0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA ((Pdc *)0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB ((Pio *)0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC ((Pio *)0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD ((Pio *)0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define PIOE ((Pio *)0x400E1600U) /**< \brief (PIOE ) Base Address */ +#define RSTC ((Rstc *)0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC ((Supc *)0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT ((Rtt *)0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT ((Wdt *)0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC ((Rtc *)0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR ((Gpbr *)0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT ((Rswdt *)0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E16E_pio Peripheral Pio Definitions */ +/*@{*/ + +#include "pio/sam4e16e.h" +/*@}*/ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ + +#define IFLASH_SIZE (0x100000u) +#define IFLASH_PAGE_SIZE (512u) +#define IFLASH_LOCK_REGION_SIZE (8192u) +#define IFLASH_NB_OF_PAGES (2048u) +#define IFLASH_NB_OF_LOCK_BITS (128u) +#define IRAM_SIZE (0x20000u) + +#define IFLASH_ADDR (0x00400000u) /**< Internal Flash base address */ +#define IROM_ADDR (0x00800000u) /**< Internal ROM base address */ +#define IRAM_ADDR (0x20000000u) /**< Internal RAM base address */ +#define EBI_CS0_ADDR (0x60000000u) /**< EBI Chip Select 0 base address */ +#define EBI_CS1_ADDR (0x61000000u) /**< EBI Chip Select 1 base address */ +#define EBI_CS2_ADDR (0x62000000u) /**< EBI Chip Select 2 base address */ +#define EBI_CS3_ADDR (0x63000000u) /**< EBI Chip Select 3 base address */ + +/* ************************************************************************** */ +/* MISCELLANEOUS DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ + +#define CHIP_JTAGID (0x05B3703FUL) +#define CHIP_CIDR (0xA3CC0CE0UL) +#define CHIP_EXID (0x00120200UL) +#define NB_CH_AFE0 (16UL) +#define NB_CH_AFE1 (8UL) +#define NB_CH_DAC (2UL) +#define USB_DEVICE_MAX_EP (8UL) + +/* ************************************************************************** */ +/* ELECTRICAL DEFINITIONS FOR SAM4E16E */ +/* ************************************************************************** */ + +/* Device characteristics */ +#define CHIP_FREQ_SLCK_RC_MIN (20000UL) +#define CHIP_FREQ_SLCK_RC (32000UL) +#define CHIP_FREQ_SLCK_RC_MAX (44000UL) +#define CHIP_FREQ_MAINCK_RC_4MHZ (4000000UL) +#define CHIP_FREQ_MAINCK_RC_8MHZ (8000000UL) +#define CHIP_FREQ_MAINCK_RC_12MHZ (12000000UL) +#define CHIP_FREQ_CPU_MAX (120000000UL) +#define CHIP_FREQ_XTAL_32K (32768UL) +#define CHIP_FREQ_XTAL_12M (12000000UL) + +/* Embedded Flash Write Wait State */ +#define CHIP_FLASH_WRITE_WAIT_STATE (6U) + +/* Embedded Flash Read Wait State (VDDCORE set at 1.20V) */ +#define CHIP_FREQ_FWS_0 (20000000UL) /**< \brief Maximum operating frequency when FWS is 0 */ +#define CHIP_FREQ_FWS_1 (40000000UL) /**< \brief Maximum operating frequency when FWS is 1 */ +#define CHIP_FREQ_FWS_2 (60000000UL) /**< \brief Maximum operating frequency when FWS is 2 */ +#define CHIP_FREQ_FWS_3 (80000000UL) /**< \brief Maximum operating frequency when FWS is 3 */ +#define CHIP_FREQ_FWS_4 (100000000UL) /**< \brief Maximum operating frequency when FWS is 4 */ +#define CHIP_FREQ_FWS_5 (123000000UL) /**< \brief Maximum operating frequency when FWS is 5 */ + +/* HYSTeresis levels: please refer to Electrical Characteristics */ +#define ACC_ACR_HYST_50MV_MAX (0x01UL) +#define ACC_ACR_HYST_90MV_MAX (0x11UL) + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _SAM4E16E_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8c.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8c.h new file mode 100644 index 0000000..c671aa3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8c.h @@ -0,0 +1,563 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E8C_ +#define _SAM4E8C_ + +/** \addtogroup SAM4E8C_definitions SAM4E8C definitions + This file defines all structures and symbols for SAM4E8C: + - registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#endif + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_cmsis CMSIS Definitions */ +/*@{*/ + +/**< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /**< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M4 System Tick Interrupt */ +/****** SAM4E8C specific Interrupt Numbers *********************************/ + + SUPC_IRQn = 0, /**< 0 SAM4E8C Supply Controller (SUPC) */ + RSTC_IRQn = 1, /**< 1 SAM4E8C Reset Controller (RSTC) */ + RTC_IRQn = 2, /**< 2 SAM4E8C Real Time Clock (RTC) */ + RTT_IRQn = 3, /**< 3 SAM4E8C Real Time Timer (RTT) */ + WDT_IRQn = 4, /**< 4 SAM4E8C Watchdog/Dual Watchdog Timer (WDT) */ + PMC_IRQn = 5, /**< 5 SAM4E8C Power Management Controller (PMC) */ + EFC_IRQn = 6, /**< 6 SAM4E8C Enhanced Embedded Flash Controller (EFC) */ + UART0_IRQn = 7, /**< 7 SAM4E8C UART 0 (UART0) */ + PIOA_IRQn = 9, /**< 9 SAM4E8C Parallel I/O Controller A (PIOA) */ + PIOB_IRQn = 10, /**< 10 SAM4E8C Parallel I/O Controller B (PIOB) */ + PIOD_IRQn = 12, /**< 12 SAM4E8C Parallel I/O Controller D (PIOD) */ + USART0_IRQn = 14, /**< 14 SAM4E8C USART 0 (USART0) */ + USART1_IRQn = 15, /**< 15 SAM4E8C USART 1 (USART1) */ + HSMCI_IRQn = 16, /**< 16 SAM4E8C Multimedia Card Interface (HSMCI) */ + TWI0_IRQn = 17, /**< 17 SAM4E8C Two Wire Interface 0 (TWI0) */ + TWI1_IRQn = 18, /**< 18 SAM4E8C Two Wire Interface 1 (TWI1) */ + SPI_IRQn = 19, /**< 19 SAM4E8C Serial Peripheral Interface (SPI) */ + DMAC_IRQn = 20, /**< 20 SAM4E8C DMAC (DMAC) */ + TC0_IRQn = 21, /**< 21 SAM4E8C Timer/Counter 0 (TC0) */ + TC1_IRQn = 22, /**< 22 SAM4E8C Timer/Counter 1 (TC1) */ + TC2_IRQn = 23, /**< 23 SAM4E8C Timer/Counter 2 (TC2) */ + AFEC0_IRQn = 30, /**< 30 SAM4E8C Analog Front End 0 (AFEC0) */ + AFEC1_IRQn = 31, /**< 31 SAM4E8C Analog Front End 1 (AFEC1) */ + DACC_IRQn = 32, /**< 32 SAM4E8C Digital To Analog Converter (DACC) */ + ACC_IRQn = 33, /**< 33 SAM4E8C Analog Comparator (ACC) */ + ARM_IRQn = 34, /**< 34 SAM4E8C FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ + UDP_IRQn = 35, /**< 35 SAM4E8C USB DEVICE (UDP) */ + PWM_IRQn = 36, /**< 36 SAM4E8C PWM (PWM) */ + CAN0_IRQn = 37, /**< 37 SAM4E8C CAN0 (CAN0) */ + AES_IRQn = 39, /**< 39 SAM4E8C AES (AES) */ + GMAC_IRQn = 44, /**< 44 SAM4E8C EMAC (GMAC) */ + UART1_IRQn = 45, /**< 45 SAM4E8C UART (UART1) */ + + PERIPH_COUNT_IRQn = 46 /**< 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* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pfnReserved5_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnSUPC_Handler; /* 0 Supply Controller */ + void* pfnRSTC_Handler; /* 1 Reset Controller */ + void* pfnRTC_Handler; /* 2 Real Time Clock */ + void* pfnRTT_Handler; /* 3 Real Time Timer */ + void* pfnWDT_Handler; /* 4 Watchdog/Dual Watchdog Timer */ + void* pfnPMC_Handler; /* 5 Power Management Controller */ + void* pfnEFC_Handler; /* 6 Enhanced Embedded Flash Controller */ + void* pfnUART0_Handler; /* 7 UART 0 */ + void* pvReserved8; + void* pfnPIOA_Handler; /* 9 Parallel I/O Controller A */ + void* pfnPIOB_Handler; /* 10 Parallel I/O Controller B */ + void* pvReserved11; + void* pfnPIOD_Handler; /* 12 Parallel I/O Controller D */ + void* pvReserved13; + void* pfnUSART0_Handler; /* 14 USART 0 */ + void* pfnUSART1_Handler; /* 15 USART 1 */ + void* pfnHSMCI_Handler; /* 16 Multimedia Card Interface */ + void* pfnTWI0_Handler; /* 17 Two Wire Interface 0 */ + void* pfnTWI1_Handler; /* 18 Two Wire Interface 1 */ + void* pfnSPI_Handler; /* 19 Serial Peripheral Interface */ + void* pfnDMAC_Handler; /* 20 DMAC */ + void* pfnTC0_Handler; /* 21 Timer/Counter 0 */ + void* pfnTC1_Handler; /* 22 Timer/Counter 1 */ + void* pfnTC2_Handler; /* 23 Timer/Counter 2 */ + void* pvReserved24; + void* pvReserved25; + void* pvReserved26; + void* pvReserved27; + void* pvReserved28; + void* pvReserved29; + void* pfnAFEC0_Handler; /* 30 Analog Front End 0 */ + void* pfnAFEC1_Handler; /* 31 Analog Front End 1 */ + void* pfnDACC_Handler; /* 32 Digital To Analog Converter */ + void* pfnACC_Handler; /* 33 Analog Comparator */ + void* pfnARM_Handler; /* 34 FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + void* pfnUDP_Handler; /* 35 USB DEVICE */ + void* pfnPWM_Handler; /* 36 PWM */ + void* pfnCAN0_Handler; /* 37 CAN0 */ + void* pvReserved38; + void* pfnAES_Handler; /* 39 AES */ + void* pvReserved40; + void* pvReserved41; + void* pvReserved42; + void* pvReserved43; + void* pfnGMAC_Handler; /* 44 EMAC */ + void* pfnUART1_Handler; /* 45 UART */ +} DeviceVectors; + +/* Cortex-M4 core handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void MemManage_Handler ( void ); +void BusFault_Handler ( void ); +void UsageFault_Handler ( void ); +void SVC_Handler ( void ); +void DebugMon_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void ACC_Handler ( void ); +void AES_Handler ( void ); +void AFEC0_Handler ( void ); +void AFEC1_Handler ( void ); +void ARM_Handler ( void ); +void CAN0_Handler ( void ); +void DACC_Handler ( void ); +void DMAC_Handler ( void ); +void EFC_Handler ( void ); +void GMAC_Handler ( void ); +void HSMCI_Handler ( void ); +void PIOA_Handler ( void ); +void PIOB_Handler ( void ); +void PIOD_Handler ( void ); +void PMC_Handler ( void ); +void PWM_Handler ( void ); +void RSTC_Handler ( void ); +void RTC_Handler ( void ); +void RTT_Handler ( void ); +void SPI_Handler ( void ); +void SUPC_Handler ( void ); +void TC0_Handler ( void ); +void TC1_Handler ( void ); +void TC2_Handler ( void ); +void TWI0_Handler ( void ); +void TWI1_Handler ( void ); +void UART0_Handler ( void ); +void UART1_Handler ( void ); +void UDP_Handler ( void ); +void USART0_Handler ( void ); +void USART1_Handler ( void ); +void WDT_Handler ( void ); + +/** + * \brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ + +#define __CM4_REV 0x0001 /**< SAM4E8C core revision number ([15:8] revision number, [7:0] patch number) */ +#define __MPU_PRESENT 1 /**< SAM4E8C does provide a MPU */ +#define __FPU_PRESENT 1 /**< SAM4E8C does provide a FPU */ +#define __NVIC_PRIO_BITS 4 /**< SAM4E8C uses 4 Bits for the Priority Levels */ +#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_sam4e.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_api Peripheral Software API */ +/*@{*/ + +#include "component/acc.h" +#include "component/aes.h" +#include "component/afec.h" +#include "component/can.h" +#include "component/chipid.h" +#include "component/cmcc.h" +#include "component/dacc.h" +#include "component/dmac.h" +#include "component/efc.h" +#include "component/gmac.h" +#include "component/gpbr.h" +#include "component/hsmci.h" +#include "component/matrix.h" +#include "component/pdc.h" +#include "component/pio.h" +#include "component/pmc.h" +#include "component/pwm.h" +#include "component/rstc.h" +#include "component/rswdt.h" +#include "component/rtc.h" +#include "component/rtt.h" +#include "component/spi.h" +#include "component/supc.h" +#include "component/tc.h" +#include "component/twi.h" +#include "component/uart.h" +#include "component/udp.h" +#include "component/usart.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* REGISTER ACCESS DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/pwm.h" +#include "instance/aes.h" +#include "instance/can0.h" +#include "instance/gmac.h" +#include "instance/uart1.h" +#include "instance/hsmci.h" +#include "instance/udp.h" +#include "instance/spi.h" +#include "instance/tc0.h" +#include "instance/usart0.h" +#include "instance/usart1.h" +#include "instance/twi0.h" +#include "instance/twi1.h" +#include "instance/afec0.h" +#include "instance/afec1.h" +#include "instance/dacc.h" +#include "instance/acc.h" +#include "instance/dmac.h" +#include "instance/cmcc.h" +#include "instance/matrix.h" +#include "instance/pmc.h" +#include "instance/uart0.h" +#include "instance/chipid.h" +#include "instance/efc.h" +#include "instance/pioa.h" +#include "instance/piob.h" +#include "instance/piod.h" +#include "instance/rstc.h" +#include "instance/supc.h" +#include "instance/rtt.h" +#include "instance/wdt.h" +#include "instance/rtc.h" +#include "instance/gpbr.h" +#include "instance/rswdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_id Peripheral Ids Definitions */ +/*@{*/ + +#define ID_SUPC ( 0) /**< \brief Supply Controller (SUPC) */ +#define ID_RSTC ( 1) /**< \brief Reset Controller (RSTC) */ +#define ID_RTC ( 2) /**< \brief Real Time Clock (RTC) */ +#define ID_RTT ( 3) /**< \brief Real Time Timer (RTT) */ +#define ID_WDT ( 4) /**< \brief Watchdog/Dual Watchdog Timer (WDT) */ +#define ID_PMC ( 5) /**< \brief Power Management Controller (PMC) */ +#define ID_EFC ( 6) /**< \brief Enhanced Embedded Flash Controller (EFC) */ +#define ID_UART0 ( 7) /**< \brief UART 0 (UART0) */ +#define ID_PIOA ( 9) /**< \brief Parallel I/O Controller A (PIOA) */ +#define ID_PIOB (10) /**< \brief Parallel I/O Controller B (PIOB) */ +#define ID_PIOD (12) /**< \brief Parallel I/O Controller D (PIOD) */ +#define ID_USART0 (14) /**< \brief USART 0 (USART0) */ +#define ID_USART1 (15) /**< \brief USART 1 (USART1) */ +#define ID_HSMCI (16) /**< \brief Multimedia Card Interface (HSMCI) */ +#define ID_TWI0 (17) /**< \brief Two Wire Interface 0 (TWI0) */ +#define ID_TWI1 (18) /**< \brief Two Wire Interface 1 (TWI1) */ +#define ID_SPI (19) /**< \brief Serial Peripheral Interface (SPI) */ +#define ID_DMAC (20) /**< \brief DMAC (DMAC) */ +#define ID_TC0 (21) /**< \brief Timer/Counter 0 (TC0) */ +#define ID_TC1 (22) /**< \brief Timer/Counter 1 (TC1) */ +#define ID_TC2 (23) /**< \brief Timer/Counter 2 (TC2) */ +#define ID_AFEC0 (30) /**< \brief Analog Front End 0 (AFEC0) */ +#define ID_AFEC1 (31) /**< \brief Analog Front End 1 (AFEC1) */ +#define ID_DACC (32) /**< \brief Digital To Analog Converter (DACC) */ +#define ID_ACC (33) /**< \brief Analog Comparator (ACC) */ +#define ID_ARM (34) /**< \brief FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ +#define ID_UDP (35) /**< \brief USB DEVICE (UDP) */ +#define ID_PWM (36) /**< \brief PWM (PWM) */ +#define ID_CAN0 (37) /**< \brief CAN0 (CAN0) */ +#define ID_AES (39) /**< \brief AES (AES) */ +#define ID_GMAC (44) /**< \brief EMAC (GMAC) */ +#define ID_UART1 (45) /**< \brief UART (UART1) */ + +#define ID_PERIPH_COUNT (46) /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_base Peripheral Base Address Definitions */ +/*@{*/ + +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define PWM (0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM (0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES (0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 (0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define GMAC (0x40034000U) /**< \brief (GMAC ) Base Address */ +#define UART1 (0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 (0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI (0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI (0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP (0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI (0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI (0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 (0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 (0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define USART0 (0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 (0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 (0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 (0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 (0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 (0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 (0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 (0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 (0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 (0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 (0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 (0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC (0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC (0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC (0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC (0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC (0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX (0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC (0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 (0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 (0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID (0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC (0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA (0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA (0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB (0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOD (0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC (0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC (0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT (0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT (0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC (0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR (0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT (0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#else +#define PWM ((Pwm *)0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM ((Pdc *)0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES ((Aes *)0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 ((Can *)0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define GMAC ((Gmac *)0x40034000U) /**< \brief (GMAC ) Base Address */ +#define UART1 ((Uart *)0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 ((Pdc *)0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI ((Hsmci *)0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI ((Pdc *)0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP ((Udp *)0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI ((Spi *)0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI ((Pdc *)0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 ((Tc *)0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 ((Pdc *)0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define USART0 ((Usart *)0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 ((Pdc *)0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 ((Usart *)0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 ((Pdc *)0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 ((Twi *)0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 ((Pdc *)0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 ((Twi *)0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 ((Pdc *)0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 ((Afec *)0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 ((Pdc *)0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 ((Afec *)0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 ((Pdc *)0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC ((Dacc *)0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC ((Pdc *)0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC ((Acc *)0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC ((Dmac *)0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC ((Cmcc *)0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX ((Matrix *)0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC ((Pmc *)0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 ((Uart *)0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 ((Pdc *)0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID ((Chipid *)0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC ((Efc *)0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA ((Pio *)0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA ((Pdc *)0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB ((Pio *)0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOD ((Pio *)0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define RSTC ((Rstc *)0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC ((Supc *)0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT ((Rtt *)0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT ((Wdt *)0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC ((Rtc *)0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR ((Gpbr *)0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT ((Rswdt *)0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8C_pio Peripheral Pio Definitions */ +/*@{*/ + +#include "pio/sam4e8c.h" +/*@}*/ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ + +#define IFLASH_SIZE (0x80000u) +#define IFLASH_PAGE_SIZE (512u) +#define IFLASH_LOCK_REGION_SIZE (8192u) +#define IFLASH_NB_OF_PAGES (1024u) +#define IFLASH_NB_OF_LOCK_BITS (128u) +#define IRAM_SIZE (0x20000u) + +#define IFLASH_ADDR (0x00400000u) /**< Internal Flash base address */ +#define IROM_ADDR (0x00800000u) /**< Internal ROM base address */ +#define IRAM_ADDR (0x20000000u) /**< Internal RAM base address */ +#define EBI_CS0_ADDR (0x60000000u) /**< EBI Chip Select 0 base address */ +#define EBI_CS1_ADDR (0x61000000u) /**< EBI Chip Select 1 base address */ +#define EBI_CS2_ADDR (0x62000000u) /**< EBI Chip Select 2 base address */ +#define EBI_CS3_ADDR (0x63000000u) /**< EBI Chip Select 3 base address */ + +/* ************************************************************************** */ +/* MISCELLANEOUS DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ + +#define CHIP_JTAGID (0x05B3703FUL) +#define CHIP_CIDR (0xA3CC0CE0UL) +#define CHIP_EXID (0x00120209UL) +#define NB_CH_AFE0 (6UL) +#define NB_CH_AFE1 (4UL) +#define NB_CH_DAC (2UL) +#define USB_DEVICE_MAX_EP (8UL) + +/* ************************************************************************** */ +/* ELECTRICAL DEFINITIONS FOR SAM4E8C */ +/* ************************************************************************** */ + +/* Device characteristics */ +#define CHIP_FREQ_SLCK_RC_MIN (20000UL) +#define CHIP_FREQ_SLCK_RC (32000UL) +#define CHIP_FREQ_SLCK_RC_MAX (44000UL) +#define CHIP_FREQ_MAINCK_RC_4MHZ (4000000UL) +#define CHIP_FREQ_MAINCK_RC_8MHZ (8000000UL) +#define CHIP_FREQ_MAINCK_RC_12MHZ (12000000UL) +#define CHIP_FREQ_CPU_MAX (120000000UL) +#define CHIP_FREQ_XTAL_32K (32768UL) +#define CHIP_FREQ_XTAL_12M (12000000UL) + +/* Embedded Flash Write Wait State */ +#define CHIP_FLASH_WRITE_WAIT_STATE (6U) + +/* Embedded Flash Read Wait State (VDDCORE set at 1.20V) */ +#define CHIP_FREQ_FWS_0 (20000000UL) /**< \brief Maximum operating frequency when FWS is 0 */ +#define CHIP_FREQ_FWS_1 (40000000UL) /**< \brief Maximum operating frequency when FWS is 1 */ +#define CHIP_FREQ_FWS_2 (60000000UL) /**< \brief Maximum operating frequency when FWS is 2 */ +#define CHIP_FREQ_FWS_3 (80000000UL) /**< \brief Maximum operating frequency when FWS is 3 */ +#define CHIP_FREQ_FWS_4 (100000000UL) /**< \brief Maximum operating frequency when FWS is 4 */ +#define CHIP_FREQ_FWS_5 (123000000UL) /**< \brief Maximum operating frequency when FWS is 5 */ + +/* HYSTeresis levels: please refer to Electrical Characteristics */ +#define ACC_ACR_HYST_50MV_MAX (0x01UL) +#define ACC_ACR_HYST_90MV_MAX (0x11UL) + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _SAM4E8C_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8e.h new file mode 100644 index 0000000..ecd4ae4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/include/sam4e8e.h @@ -0,0 +1,612 @@ +/** + * \file + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM4E8E_ +#define _SAM4E8E_ + +/** \addtogroup SAM4E8E_definitions SAM4E8E definitions + This file defines all structures and symbols for SAM4E8E: + - registers and bitfields + - peripheral base address + - peripheral ID + - PIO definitions +*/ +/*@{*/ + +#ifdef __cplusplus + extern "C" { +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#include +#endif + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_cmsis CMSIS Definitions */ +/*@{*/ + +/**< Interrupt Number Definition */ +typedef enum IRQn +{ +/****** Cortex-M4 Processor Exceptions Numbers ******************************/ + NonMaskableInt_IRQn = -14, /**< 2 Non Maskable Interrupt */ + MemoryManagement_IRQn = -12, /**< 4 Cortex-M4 Memory Management Interrupt */ + BusFault_IRQn = -11, /**< 5 Cortex-M4 Bus Fault Interrupt */ + UsageFault_IRQn = -10, /**< 6 Cortex-M4 Usage Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 Cortex-M4 SV Call Interrupt */ + DebugMonitor_IRQn = -4, /**< 12 Cortex-M4 Debug Monitor Interrupt */ + PendSV_IRQn = -2, /**< 14 Cortex-M4 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 Cortex-M4 System Tick Interrupt */ +/****** SAM4E8E specific Interrupt Numbers *********************************/ + + SUPC_IRQn = 0, /**< 0 SAM4E8E Supply Controller (SUPC) */ + RSTC_IRQn = 1, /**< 1 SAM4E8E Reset Controller (RSTC) */ + RTC_IRQn = 2, /**< 2 SAM4E8E Real Time Clock (RTC) */ + RTT_IRQn = 3, /**< 3 SAM4E8E Real Time Timer (RTT) */ + WDT_IRQn = 4, /**< 4 SAM4E8E Watchdog/Dual Watchdog Timer (WDT) */ + PMC_IRQn = 5, /**< 5 SAM4E8E Power Management Controller (PMC) */ + EFC_IRQn = 6, /**< 6 SAM4E8E Enhanced Embedded Flash Controller (EFC) */ + UART0_IRQn = 7, /**< 7 SAM4E8E UART 0 (UART0) */ + PIOA_IRQn = 9, /**< 9 SAM4E8E Parallel I/O Controller A (PIOA) */ + PIOB_IRQn = 10, /**< 10 SAM4E8E Parallel I/O Controller B (PIOB) */ + PIOC_IRQn = 11, /**< 11 SAM4E8E Parallel I/O Controller C (PIOC) */ + PIOD_IRQn = 12, /**< 12 SAM4E8E Parallel I/O Controller D (PIOD) */ + PIOE_IRQn = 13, /**< 13 SAM4E8E Parallel I/O Controller E (PIOE) */ + USART0_IRQn = 14, /**< 14 SAM4E8E USART 0 (USART0) */ + USART1_IRQn = 15, /**< 15 SAM4E8E USART 1 (USART1) */ + HSMCI_IRQn = 16, /**< 16 SAM4E8E Multimedia Card Interface (HSMCI) */ + TWI0_IRQn = 17, /**< 17 SAM4E8E Two Wire Interface 0 (TWI0) */ + TWI1_IRQn = 18, /**< 18 SAM4E8E Two Wire Interface 1 (TWI1) */ + SPI_IRQn = 19, /**< 19 SAM4E8E Serial Peripheral Interface (SPI) */ + DMAC_IRQn = 20, /**< 20 SAM4E8E DMAC (DMAC) */ + TC0_IRQn = 21, /**< 21 SAM4E8E Timer/Counter 0 (TC0) */ + TC1_IRQn = 22, /**< 22 SAM4E8E Timer/Counter 1 (TC1) */ + TC2_IRQn = 23, /**< 23 SAM4E8E Timer/Counter 2 (TC2) */ + TC3_IRQn = 24, /**< 24 SAM4E8E Timer/Counter 3 (TC3) */ + TC4_IRQn = 25, /**< 25 SAM4E8E Timer/Counter 4 (TC4) */ + TC5_IRQn = 26, /**< 26 SAM4E8E Timer/Counter 5 (TC5) */ + TC6_IRQn = 27, /**< 27 SAM4E8E Timer/Counter 6 (TC6) */ + TC7_IRQn = 28, /**< 28 SAM4E8E Timer/Counter 7 (TC7) */ + TC8_IRQn = 29, /**< 29 SAM4E8E Timer/Counter 8 (TC8) */ + AFEC0_IRQn = 30, /**< 30 SAM4E8E Analog Front End 0 (AFEC0) */ + AFEC1_IRQn = 31, /**< 31 SAM4E8E Analog Front End 1 (AFEC1) */ + DACC_IRQn = 32, /**< 32 SAM4E8E Digital To Analog Converter (DACC) */ + ACC_IRQn = 33, /**< 33 SAM4E8E Analog Comparator (ACC) */ + ARM_IRQn = 34, /**< 34 SAM4E8E FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ + UDP_IRQn = 35, /**< 35 SAM4E8E USB DEVICE (UDP) */ + PWM_IRQn = 36, /**< 36 SAM4E8E PWM (PWM) */ + CAN0_IRQn = 37, /**< 37 SAM4E8E CAN0 (CAN0) */ + CAN1_IRQn = 38, /**< 38 SAM4E8E CAN1 (CAN1) */ + AES_IRQn = 39, /**< 39 SAM4E8E AES (AES) */ + GMAC_IRQn = 44, /**< 44 SAM4E8E EMAC (GMAC) */ + UART1_IRQn = 45, /**< 45 SAM4E8E UART (UART1) */ + + PERIPH_COUNT_IRQn = 46 /**< 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* pfnMemManage_Handler; + void* pfnBusFault_Handler; + void* pfnUsageFault_Handler; + void* pfnReserved1_Handler; + void* pfnReserved2_Handler; + void* pfnReserved3_Handler; + void* pfnReserved4_Handler; + void* pfnSVC_Handler; + void* pfnDebugMon_Handler; + void* pfnReserved5_Handler; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnSUPC_Handler; /* 0 Supply Controller */ + void* pfnRSTC_Handler; /* 1 Reset Controller */ + void* pfnRTC_Handler; /* 2 Real Time Clock */ + void* pfnRTT_Handler; /* 3 Real Time Timer */ + void* pfnWDT_Handler; /* 4 Watchdog/Dual Watchdog Timer */ + void* pfnPMC_Handler; /* 5 Power Management Controller */ + void* pfnEFC_Handler; /* 6 Enhanced Embedded Flash Controller */ + void* pfnUART0_Handler; /* 7 UART 0 */ + void* pvReserved8; + void* pfnPIOA_Handler; /* 9 Parallel I/O Controller A */ + void* pfnPIOB_Handler; /* 10 Parallel I/O Controller B */ + void* pfnPIOC_Handler; /* 11 Parallel I/O Controller C */ + void* pfnPIOD_Handler; /* 12 Parallel I/O Controller D */ + void* pfnPIOE_Handler; /* 13 Parallel I/O Controller E */ + void* pfnUSART0_Handler; /* 14 USART 0 */ + void* pfnUSART1_Handler; /* 15 USART 1 */ + void* pfnHSMCI_Handler; /* 16 Multimedia Card Interface */ + void* pfnTWI0_Handler; /* 17 Two Wire Interface 0 */ + void* pfnTWI1_Handler; /* 18 Two Wire Interface 1 */ + void* pfnSPI_Handler; /* 19 Serial Peripheral Interface */ + void* pfnDMAC_Handler; /* 20 DMAC */ + void* pfnTC0_Handler; /* 21 Timer/Counter 0 */ + void* pfnTC1_Handler; /* 22 Timer/Counter 1 */ + void* pfnTC2_Handler; /* 23 Timer/Counter 2 */ + void* pfnTC3_Handler; /* 24 Timer/Counter 3 */ + void* pfnTC4_Handler; /* 25 Timer/Counter 4 */ + void* pfnTC5_Handler; /* 26 Timer/Counter 5 */ + void* pfnTC6_Handler; /* 27 Timer/Counter 6 */ + void* pfnTC7_Handler; /* 28 Timer/Counter 7 */ + void* pfnTC8_Handler; /* 29 Timer/Counter 8 */ + void* pfnAFEC0_Handler; /* 30 Analog Front End 0 */ + void* pfnAFEC1_Handler; /* 31 Analog Front End 1 */ + void* pfnDACC_Handler; /* 32 Digital To Analog Converter */ + void* pfnACC_Handler; /* 33 Analog Comparator */ + void* pfnARM_Handler; /* 34 FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + void* pfnUDP_Handler; /* 35 USB DEVICE */ + void* pfnPWM_Handler; /* 36 PWM */ + void* pfnCAN0_Handler; /* 37 CAN0 */ + void* pfnCAN1_Handler; /* 38 CAN1 */ + void* pfnAES_Handler; /* 39 AES */ + void* pvReserved40; + void* pvReserved41; + void* pvReserved42; + void* pvReserved43; + void* pfnGMAC_Handler; /* 44 EMAC */ + void* pfnUART1_Handler; /* 45 UART */ +} DeviceVectors; + +/* Cortex-M4 core handlers */ +void Reset_Handler ( void ); +void NMI_Handler ( void ); +void HardFault_Handler ( void ); +void MemManage_Handler ( void ); +void BusFault_Handler ( void ); +void UsageFault_Handler ( void ); +void SVC_Handler ( void ); +void DebugMon_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void ACC_Handler ( void ); +void AES_Handler ( void ); +void AFEC0_Handler ( void ); +void AFEC1_Handler ( void ); +void ARM_Handler ( void ); +void CAN0_Handler ( void ); +void CAN1_Handler ( void ); +void DACC_Handler ( void ); +void DMAC_Handler ( void ); +void EFC_Handler ( void ); +void GMAC_Handler ( void ); +void HSMCI_Handler ( void ); +void PIOA_Handler ( void ); +void PIOB_Handler ( void ); +void PIOC_Handler ( void ); +void PIOD_Handler ( void ); +void PIOE_Handler ( void ); +void PMC_Handler ( void ); +void PWM_Handler ( void ); +void RSTC_Handler ( void ); +void RTC_Handler ( void ); +void RTT_Handler ( void ); +void SPI_Handler ( void ); +void SUPC_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 TC8_Handler ( void ); +void TWI0_Handler ( void ); +void TWI1_Handler ( void ); +void UART0_Handler ( void ); +void UART1_Handler ( void ); +void UDP_Handler ( void ); +void USART0_Handler ( void ); +void USART1_Handler ( void ); +void WDT_Handler ( void ); + +/** + * \brief Configuration of the Cortex-M4 Processor and Core Peripherals + */ + +#define __CM4_REV 0x0001 /**< SAM4E8E core revision number ([15:8] revision number, [7:0] patch number) */ +#define __MPU_PRESENT 1 /**< SAM4E8E does provide a MPU */ +#define __FPU_PRESENT 1 /**< SAM4E8E does provide a FPU */ +#define __NVIC_PRIO_BITS 4 /**< SAM4E8E uses 4 Bits for the Priority Levels */ +#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_sam4e.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_api Peripheral Software API */ +/*@{*/ + +#include "component/acc.h" +#include "component/aes.h" +#include "component/afec.h" +#include "component/can.h" +#include "component/chipid.h" +#include "component/cmcc.h" +#include "component/dacc.h" +#include "component/dmac.h" +#include "component/efc.h" +#include "component/gmac.h" +#include "component/gpbr.h" +#include "component/hsmci.h" +#include "component/matrix.h" +#include "component/pdc.h" +#include "component/pio.h" +#include "component/pmc.h" +#include "component/pwm.h" +#include "component/rstc.h" +#include "component/rswdt.h" +#include "component/rtc.h" +#include "component/rtt.h" +#include "component/smc.h" +#include "component/spi.h" +#include "component/supc.h" +#include "component/tc.h" +#include "component/twi.h" +#include "component/uart.h" +#include "component/udp.h" +#include "component/usart.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* REGISTER ACCESS DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/pwm.h" +#include "instance/aes.h" +#include "instance/can0.h" +#include "instance/can1.h" +#include "instance/gmac.h" +#include "instance/smc.h" +#include "instance/uart1.h" +#include "instance/hsmci.h" +#include "instance/udp.h" +#include "instance/spi.h" +#include "instance/tc0.h" +#include "instance/tc1.h" +#include "instance/tc2.h" +#include "instance/usart0.h" +#include "instance/usart1.h" +#include "instance/twi0.h" +#include "instance/twi1.h" +#include "instance/afec0.h" +#include "instance/afec1.h" +#include "instance/dacc.h" +#include "instance/acc.h" +#include "instance/dmac.h" +#include "instance/cmcc.h" +#include "instance/matrix.h" +#include "instance/pmc.h" +#include "instance/uart0.h" +#include "instance/chipid.h" +#include "instance/efc.h" +#include "instance/pioa.h" +#include "instance/piob.h" +#include "instance/pioc.h" +#include "instance/piod.h" +#include "instance/pioe.h" +#include "instance/rstc.h" +#include "instance/supc.h" +#include "instance/rtt.h" +#include "instance/wdt.h" +#include "instance/rtc.h" +#include "instance/gpbr.h" +#include "instance/rswdt.h" +/*@}*/ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_id Peripheral Ids Definitions */ +/*@{*/ + +#define ID_SUPC ( 0) /**< \brief Supply Controller (SUPC) */ +#define ID_RSTC ( 1) /**< \brief Reset Controller (RSTC) */ +#define ID_RTC ( 2) /**< \brief Real Time Clock (RTC) */ +#define ID_RTT ( 3) /**< \brief Real Time Timer (RTT) */ +#define ID_WDT ( 4) /**< \brief Watchdog/Dual Watchdog Timer (WDT) */ +#define ID_PMC ( 5) /**< \brief Power Management Controller (PMC) */ +#define ID_EFC ( 6) /**< \brief Enhanced Embedded Flash Controller (EFC) */ +#define ID_UART0 ( 7) /**< \brief UART 0 (UART0) */ +#define ID_SMC ( 8) /**< \brief Static Memory Controller (SMC) */ +#define ID_PIOA ( 9) /**< \brief Parallel I/O Controller A (PIOA) */ +#define ID_PIOB (10) /**< \brief Parallel I/O Controller B (PIOB) */ +#define ID_PIOC (11) /**< \brief Parallel I/O Controller C (PIOC) */ +#define ID_PIOD (12) /**< \brief Parallel I/O Controller D (PIOD) */ +#define ID_PIOE (13) /**< \brief Parallel I/O Controller E (PIOE) */ +#define ID_USART0 (14) /**< \brief USART 0 (USART0) */ +#define ID_USART1 (15) /**< \brief USART 1 (USART1) */ +#define ID_HSMCI (16) /**< \brief Multimedia Card Interface (HSMCI) */ +#define ID_TWI0 (17) /**< \brief Two Wire Interface 0 (TWI0) */ +#define ID_TWI1 (18) /**< \brief Two Wire Interface 1 (TWI1) */ +#define ID_SPI (19) /**< \brief Serial Peripheral Interface (SPI) */ +#define ID_DMAC (20) /**< \brief DMAC (DMAC) */ +#define ID_TC0 (21) /**< \brief Timer/Counter 0 (TC0) */ +#define ID_TC1 (22) /**< \brief Timer/Counter 1 (TC1) */ +#define ID_TC2 (23) /**< \brief Timer/Counter 2 (TC2) */ +#define ID_TC3 (24) /**< \brief Timer/Counter 3 (TC3) */ +#define ID_TC4 (25) /**< \brief Timer/Counter 4 (TC4) */ +#define ID_TC5 (26) /**< \brief Timer/Counter 5 (TC5) */ +#define ID_TC6 (27) /**< \brief Timer/Counter 6 (TC6) */ +#define ID_TC7 (28) /**< \brief Timer/Counter 7 (TC7) */ +#define ID_TC8 (29) /**< \brief Timer/Counter 8 (TC8) */ +#define ID_AFEC0 (30) /**< \brief Analog Front End 0 (AFEC0) */ +#define ID_AFEC1 (31) /**< \brief Analog Front End 1 (AFEC1) */ +#define ID_DACC (32) /**< \brief Digital To Analog Converter (DACC) */ +#define ID_ACC (33) /**< \brief Analog Comparator (ACC) */ +#define ID_ARM (34) /**< \brief FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC (ARM) */ +#define ID_UDP (35) /**< \brief USB DEVICE (UDP) */ +#define ID_PWM (36) /**< \brief PWM (PWM) */ +#define ID_CAN0 (37) /**< \brief CAN0 (CAN0) */ +#define ID_CAN1 (38) /**< \brief CAN1 (CAN1) */ +#define ID_AES (39) /**< \brief AES (AES) */ +#define ID_GMAC (44) /**< \brief EMAC (GMAC) */ +#define ID_UART1 (45) /**< \brief UART (UART1) */ + +#define ID_PERIPH_COUNT (46) /**< \brief Number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_base Peripheral Base Address Definitions */ +/*@{*/ + +#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#define PWM (0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM (0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES (0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 (0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 (0x40014000U) /**< \brief (CAN1 ) Base Address */ +#define GMAC (0x40034000U) /**< \brief (GMAC ) Base Address */ +#define SMC (0x40060000U) /**< \brief (SMC ) Base Address */ +#define UART1 (0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 (0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI (0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI (0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP (0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI (0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI (0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 (0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 (0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define TC1 (0x40094000U) /**< \brief (TC1 ) Base Address */ +#define PDC_TC1 (0x40094100U) /**< \brief (PDC_TC1 ) Base Address */ +#define TC2 (0x40098000U) /**< \brief (TC2 ) Base Address */ +#define USART0 (0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 (0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 (0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 (0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 (0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 (0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 (0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 (0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 (0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 (0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 (0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 (0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC (0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC (0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC (0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC (0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC (0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX (0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC (0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 (0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 (0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID (0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC (0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA (0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA (0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB (0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC (0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD (0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define PIOE (0x400E1600U) /**< \brief (PIOE ) Base Address */ +#define RSTC (0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC (0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT (0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT (0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC (0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR (0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT (0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#else +#define PWM ((Pwm *)0x40000000U) /**< \brief (PWM ) Base Address */ +#define PDC_PWM ((Pdc *)0x40000100U) /**< \brief (PDC_PWM ) Base Address */ +#define AES ((Aes *)0x40004000U) /**< \brief (AES ) Base Address */ +#define CAN0 ((Can *)0x40010000U) /**< \brief (CAN0 ) Base Address */ +#define CAN1 ((Can *)0x40014000U) /**< \brief (CAN1 ) Base Address */ +#define GMAC ((Gmac *)0x40034000U) /**< \brief (GMAC ) Base Address */ +#define SMC ((Smc *)0x40060000U) /**< \brief (SMC ) Base Address */ +#define UART1 ((Uart *)0x40060600U) /**< \brief (UART1 ) Base Address */ +#define PDC_UART1 ((Pdc *)0x40060700U) /**< \brief (PDC_UART1 ) Base Address */ +#define HSMCI ((Hsmci *)0x40080000U) /**< \brief (HSMCI ) Base Address */ +#define PDC_HSMCI ((Pdc *)0x40080100U) /**< \brief (PDC_HSMCI ) Base Address */ +#define UDP ((Udp *)0x40084000U) /**< \brief (UDP ) Base Address */ +#define SPI ((Spi *)0x40088000U) /**< \brief (SPI ) Base Address */ +#define PDC_SPI ((Pdc *)0x40088100U) /**< \brief (PDC_SPI ) Base Address */ +#define TC0 ((Tc *)0x40090000U) /**< \brief (TC0 ) Base Address */ +#define PDC_TC0 ((Pdc *)0x40090100U) /**< \brief (PDC_TC0 ) Base Address */ +#define TC1 ((Tc *)0x40094000U) /**< \brief (TC1 ) Base Address */ +#define PDC_TC1 ((Pdc *)0x40094100U) /**< \brief (PDC_TC1 ) Base Address */ +#define TC2 ((Tc *)0x40098000U) /**< \brief (TC2 ) Base Address */ +#define USART0 ((Usart *)0x400A0000U) /**< \brief (USART0 ) Base Address */ +#define PDC_USART0 ((Pdc *)0x400A0100U) /**< \brief (PDC_USART0) Base Address */ +#define USART1 ((Usart *)0x400A4000U) /**< \brief (USART1 ) Base Address */ +#define PDC_USART1 ((Pdc *)0x400A4100U) /**< \brief (PDC_USART1) Base Address */ +#define TWI0 ((Twi *)0x400A8000U) /**< \brief (TWI0 ) Base Address */ +#define PDC_TWI0 ((Pdc *)0x400A8100U) /**< \brief (PDC_TWI0 ) Base Address */ +#define TWI1 ((Twi *)0x400AC000U) /**< \brief (TWI1 ) Base Address */ +#define PDC_TWI1 ((Pdc *)0x400AC100U) /**< \brief (PDC_TWI1 ) Base Address */ +#define AFEC0 ((Afec *)0x400B0000U) /**< \brief (AFEC0 ) Base Address */ +#define PDC_AFEC0 ((Pdc *)0x400B0100U) /**< \brief (PDC_AFEC0 ) Base Address */ +#define AFEC1 ((Afec *)0x400B4000U) /**< \brief (AFEC1 ) Base Address */ +#define PDC_AFEC1 ((Pdc *)0x400B4100U) /**< \brief (PDC_AFEC1 ) Base Address */ +#define DACC ((Dacc *)0x400B8000U) /**< \brief (DACC ) Base Address */ +#define PDC_DACC ((Pdc *)0x400B8100U) /**< \brief (PDC_DACC ) Base Address */ +#define ACC ((Acc *)0x400BC000U) /**< \brief (ACC ) Base Address */ +#define DMAC ((Dmac *)0x400C0000U) /**< \brief (DMAC ) Base Address */ +#define CMCC ((Cmcc *)0x400C4000U) /**< \brief (CMCC ) Base Address */ +#define MATRIX ((Matrix *)0x400E0200U) /**< \brief (MATRIX ) Base Address */ +#define PMC ((Pmc *)0x400E0400U) /**< \brief (PMC ) Base Address */ +#define UART0 ((Uart *)0x400E0600U) /**< \brief (UART0 ) Base Address */ +#define PDC_UART0 ((Pdc *)0x400E0700U) /**< \brief (PDC_UART0 ) Base Address */ +#define CHIPID ((Chipid *)0x400E0740U) /**< \brief (CHIPID ) Base Address */ +#define EFC ((Efc *)0x400E0A00U) /**< \brief (EFC ) Base Address */ +#define PIOA ((Pio *)0x400E0E00U) /**< \brief (PIOA ) Base Address */ +#define PDC_PIOA ((Pdc *)0x400E0F68U) /**< \brief (PDC_PIOA ) Base Address */ +#define PIOB ((Pio *)0x400E1000U) /**< \brief (PIOB ) Base Address */ +#define PIOC ((Pio *)0x400E1200U) /**< \brief (PIOC ) Base Address */ +#define PIOD ((Pio *)0x400E1400U) /**< \brief (PIOD ) Base Address */ +#define PIOE ((Pio *)0x400E1600U) /**< \brief (PIOE ) Base Address */ +#define RSTC ((Rstc *)0x400E1800U) /**< \brief (RSTC ) Base Address */ +#define SUPC ((Supc *)0x400E1810U) /**< \brief (SUPC ) Base Address */ +#define RTT ((Rtt *)0x400E1830U) /**< \brief (RTT ) Base Address */ +#define WDT ((Wdt *)0x400E1850U) /**< \brief (WDT ) Base Address */ +#define RTC ((Rtc *)0x400E1860U) /**< \brief (RTC ) Base Address */ +#define GPBR ((Gpbr *)0x400E1890U) /**< \brief (GPBR ) Base Address */ +#define RSWDT ((Rswdt *)0x400E1900U) /**< \brief (RSWDT ) Base Address */ +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ +/** \addtogroup SAM4E8E_pio Peripheral Pio Definitions */ +/*@{*/ + +#include "pio/sam4e8e.h" +/*@}*/ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ + +#define IFLASH_SIZE (0x80000u) +#define IFLASH_PAGE_SIZE (512u) +#define IFLASH_LOCK_REGION_SIZE (8192u) +#define IFLASH_NB_OF_PAGES (1024u) +#define IFLASH_NB_OF_LOCK_BITS (128u) +#define IRAM_SIZE (0x20000u) + +#define IFLASH_ADDR (0x00400000u) /**< Internal Flash base address */ +#define IROM_ADDR (0x00800000u) /**< Internal ROM base address */ +#define IRAM_ADDR (0x20000000u) /**< Internal RAM base address */ +#define EBI_CS0_ADDR (0x60000000u) /**< EBI Chip Select 0 base address */ +#define EBI_CS1_ADDR (0x61000000u) /**< EBI Chip Select 1 base address */ +#define EBI_CS2_ADDR (0x62000000u) /**< EBI Chip Select 2 base address */ +#define EBI_CS3_ADDR (0x63000000u) /**< EBI Chip Select 3 base address */ + +/* ************************************************************************** */ +/* MISCELLANEOUS DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ + +#define CHIP_JTAGID (0x05B3703FUL) +#define CHIP_CIDR (0xA3CC0CE0UL) +#define CHIP_EXID (0x00120208UL) +#define NB_CH_AFE0 (16UL) +#define NB_CH_AFE1 (8UL) +#define NB_CH_DAC (2UL) +#define USB_DEVICE_MAX_EP (8UL) + +/* ************************************************************************** */ +/* ELECTRICAL DEFINITIONS FOR SAM4E8E */ +/* ************************************************************************** */ + +/* Device characteristics */ +#define CHIP_FREQ_SLCK_RC_MIN (20000UL) +#define CHIP_FREQ_SLCK_RC (32000UL) +#define CHIP_FREQ_SLCK_RC_MAX (44000UL) +#define CHIP_FREQ_MAINCK_RC_4MHZ (4000000UL) +#define CHIP_FREQ_MAINCK_RC_8MHZ (8000000UL) +#define CHIP_FREQ_MAINCK_RC_12MHZ (12000000UL) +#define CHIP_FREQ_CPU_MAX (120000000UL) +#define CHIP_FREQ_XTAL_32K (32768UL) +#define CHIP_FREQ_XTAL_12M (12000000UL) + +/* Embedded Flash Write Wait State */ +#define CHIP_FLASH_WRITE_WAIT_STATE (6U) + +/* Embedded Flash Read Wait State (VDDCORE set at 1.20V) */ +#define CHIP_FREQ_FWS_0 (20000000UL) /**< \brief Maximum operating frequency when FWS is 0 */ +#define CHIP_FREQ_FWS_1 (40000000UL) /**< \brief Maximum operating frequency when FWS is 1 */ +#define CHIP_FREQ_FWS_2 (60000000UL) /**< \brief Maximum operating frequency when FWS is 2 */ +#define CHIP_FREQ_FWS_3 (80000000UL) /**< \brief Maximum operating frequency when FWS is 3 */ +#define CHIP_FREQ_FWS_4 (100000000UL) /**< \brief Maximum operating frequency when FWS is 4 */ +#define CHIP_FREQ_FWS_5 (123000000UL) /**< \brief Maximum operating frequency when FWS is 5 */ + +/* HYSTeresis levels: please refer to Electrical Characteristics */ +#define ACC_ACR_HYST_50MV_MAX (0x01UL) +#define ACC_ACR_HYST_90MV_MAX (0x11UL) + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* _SAM4E8E_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.c new file mode 100644 index 0000000..9c21242 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.c @@ -0,0 +1,218 @@ +/** + * \file + * + * \brief This file contains the default exception handlers. + * + * 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 + * + * \par Purpose + * + * This file provides basic support for Cortex-M processor based + * microcontrollers. + * + * \note + * The exception handler has weak aliases. + * As they are weak aliases, any function with the same name will override + * this definition. + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "exceptions.h" + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/* @endcond */ + +#ifdef __GNUC__ +/* Cortex-M4 core handlers */ +void Reset_Handler (void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NMI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void MemManage_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void BusFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void UsageFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DebugMon_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 SUPC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RSTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EFC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void UART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SMC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PIOA_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PIOB_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef _SAM4E_PIOC_INSTANCE_ +void PIOC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif /* _SAM4E_PIOC_INSTANCE_ */ +void PIOD_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef _SAM4E_PIOE_INSTANCE_ +void PIOE_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif /* _SAM4E_PIOE_INSTANCE_ */ +void USART0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void USART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HSMCI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TWI0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TWI1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SPI_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_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"))); +#ifdef _SAM4E_TC1_INSTANCE_ +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"))); +#endif /* _SAM4E_TC1_INSTANCE_ */ +#ifdef _SAM4E_TC2_INSTANCE_ +void TC6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC8_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif /* _SAM4E_TC2_INSTANCE_ */ +void AFEC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void AFEC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DACC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ACC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void ARM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void UDP_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PWM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void CAN0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef _SAM4E_CAN1_INSTANCE_ +void CAN1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif /* _SAM4E_CAN1_INSTANCE_ */ +void AES_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void GMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void UART1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif /* __GNUC__ */ + +#ifdef __ICCARM__ +/* Cortex-M4 core handlers */ +#pragma weak Reset_Handler=Dummy_Handler +#pragma weak NMI_Handler=Dummy_Handler +#pragma weak HardFault_Handler=Dummy_Handler +#pragma weak MemManage_Handler=Dummy_Handler +#pragma weak BusFault_Handler=Dummy_Handler +#pragma weak UsageFault_Handler=Dummy_Handler +#pragma weak SVC_Handler=Dummy_Handler +#pragma weak DebugMon_Handler=Dummy_Handler +#pragma weak PendSV_Handler=Dummy_Handler +#pragma weak SysTick_Handler=Dummy_Handler + +/* Peripherals handlers */ +#pragma weak SUPC_Handler=Dummy_Handler +#pragma weak RSTC_Handler=Dummy_Handler +#pragma weak RTC_Handler=Dummy_Handler +#pragma weak RTT_Handler=Dummy_Handler +#pragma weak WDT_Handler=Dummy_Handler +#pragma weak PMC_Handler=Dummy_Handler +#pragma weak EFC_Handler=Dummy_Handler +#pragma weak UART0_Handler=Dummy_Handler +#pragma weak SMC_Handler=Dummy_Handler +#pragma weak PIOA_Handler=Dummy_Handler +#pragma weak PIOB_Handler=Dummy_Handler +#ifdef _SAM4E_PIOC_INSTANCE_ +#pragma weak PIOC_Handler=Dummy_Handler +#endif /* _SAM4E_PIOC_INSTANCE_ */ +#pragma weak PIOD_Handler=Dummy_Handler +#ifdef _SAM4E_PIOE_INSTANCE_ +#pragma weak PIOE_Handler=Dummy_Handler +#endif /* _SAM4E_PIOE_INSTANCE_ */ +#pragma weak USART0_Handler=Dummy_Handler +#pragma weak USART1_Handler=Dummy_Handler +#pragma weak HSMCI_Handler=Dummy_Handler +#pragma weak TWI0_Handler=Dummy_Handler +#pragma weak TWI1_Handler=Dummy_Handler +#pragma weak SPI_Handler=Dummy_Handler +#pragma weak DMAC_Handler=Dummy_Handler +#pragma weak TC0_Handler=Dummy_Handler +#pragma weak TC1_Handler=Dummy_Handler +#pragma weak TC2_Handler=Dummy_Handler +#ifdef _SAM4E_TC1_INSTANCE_ +#pragma weak TC3_Handler=Dummy_Handler +#pragma weak TC4_Handler=Dummy_Handler +#pragma weak TC5_Handler=Dummy_Handler +#endif /* _SAM4E_TC1_INSTANCE_ */ +#ifdef _SAM4E_TC2_INSTANCE_ +#pragma weak TC6_Handler=Dummy_Handler +#pragma weak TC7_Handler=Dummy_Handler +#pragma weak TC8_Handler=Dummy_Handler +#endif /* _SAM4E_TC2_INSTANCE_ */ +#pragma weak AFEC0_Handler=Dummy_Handler +#pragma weak AFEC1_Handler=Dummy_Handler +#pragma weak DACC_Handler=Dummy_Handler +#pragma weak ACC_Handler=Dummy_Handler +#pragma weak ARM_Handler=Dummy_Handler +#pragma weak UDP_Handler=Dummy_Handler +#pragma weak PWM_Handler=Dummy_Handler +#pragma weak CAN0_Handler=Dummy_Handler +#ifdef _SAM4E_CAN1_INSTANCE_ +#pragma weak CAN1_Handler=Dummy_Handler +#endif /* _SAM4E_CAN1_INSTANCE_ */ +#pragma weak AES_Handler=Dummy_Handler +#pragma weak GMAC_Handler=Dummy_Handler +#pragma weak UART1_Handler=Dummy_Handler +#endif /* __ICCARM__ */ + +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Dummy_Handler(void) +{ + while (1) { + } +} + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/* @endcond */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.h new file mode 100644 index 0000000..f23e907 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/exceptions.h @@ -0,0 +1,74 @@ +/** + * \file + * + * \brief This file contains the interface for default exception handlers. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef EXCEPTIONS_H_INCLUDED +#define EXCEPTIONS_H_INCLUDED + +#include "sam4e.h" + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/* @endcond */ + +/* Function prototype for exception table items (interrupt handler). */ +typedef void (*IntFunc) (void); + +/* Default empty handler */ +void Dummy_Handler(void); + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/* @endcond */ + +#endif /* EXCEPTIONS_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/gcc/startup_sam4e.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/gcc/startup_sam4e.c new file mode 100644 index 0000000..97729e5 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/gcc/startup_sam4e.c @@ -0,0 +1,206 @@ +/** + * \file + * + * \brief Startup file for SAM4E. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "sam4e.h" +#include "exceptions.h" +#include "system_sam4e.h" +#if __FPU_USED /* CMSIS defined value to indicate usage of FPU */ +#include "fpu.h" +#endif + +/* Initialize segments */ +extern uint32_t _sfixed; +extern uint32_t _efixed; +extern uint32_t _etext; +extern uint32_t _srelocate; +extern uint32_t _erelocate; +extern uint32_t _szero; +extern uint32_t _ezero; +extern uint32_t _sstack; +extern uint32_t _estack; + +/** \cond DOXYGEN_SHOULD_SKIP_THIS */ +int main(void); +/** \endcond */ + +void __libc_init_array(void); + +/* Exception Table */ +__attribute__ ((section(".vectors"))) +const DeviceVectors exception_table = { + + /* Configure Initial Stack Pointer, using linker-generated symbols */ + (void*) (&_estack), + + (void*) Reset_Handler, + (void*) NMI_Handler, + (void*) HardFault_Handler, + (void*) MemManage_Handler, + (void*) BusFault_Handler, + (void*) UsageFault_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) SVC_Handler, + (void*) DebugMon_Handler, + (void*) (0UL), /* Reserved */ + (void*) PendSV_Handler, + (void*) SysTick_Handler, + + /* Configurable interrupts */ + (void*) SUPC_Handler, /* 0 Supply Controller */ + (void*) RSTC_Handler, /* 1 Reset Controller */ + (void*) RTC_Handler, /* 2 Real Time Clock */ + (void*) RTT_Handler, /* 3 Real Time Timer */ + (void*) WDT_Handler, /* 4 Watchdog/Dual Watchdog Timer */ + (void*) PMC_Handler, /* 5 Power Management Controller */ + (void*) EFC_Handler, /* 6 Enhanced Embedded Flash Controller */ + (void*) UART0_Handler, /* 7 UART 0 */ + (void*) Dummy_Handler, + (void*) PIOA_Handler, /* 9 Parallel I/O Controller A */ + (void*) PIOB_Handler, /* 10 Parallel I/O Controller B */ +#ifdef _SAM4E_PIOC_INSTANCE_ + (void*) PIOC_Handler, /* 11 Parallel I/O Controller C */ +#else + (void*) Dummy_Handler, +#endif + (void*) PIOD_Handler, /* 12 Parallel I/O Controller D */ +#ifdef _SAM4E_PIOE_INSTANCE_ + (void*) PIOE_Handler, /* 13 Parallel I/O Controller E */ +#else + (void*) Dummy_Handler, +#endif + (void*) USART0_Handler, /* 14 USART 0 */ + (void*) USART1_Handler, /* 15 USART 1 */ + (void*) HSMCI_Handler, /* 16 Multimedia Card Interface */ + (void*) TWI0_Handler, /* 17 Two Wire Interface 0 */ + (void*) TWI1_Handler, /* 18 Two Wire Interface 1 */ + (void*) SPI_Handler, /* 19 Serial Peripheral Interface */ + (void*) DMAC_Handler, /* 20 DMAC */ + (void*) TC0_Handler, /* 21 Timer/Counter 0 */ + (void*) TC1_Handler, /* 22 Timer/Counter 1 */ + (void*) TC2_Handler, /* 23 Timer/Counter 2 */ +#ifdef _SAM4E_TC1_INSTANCE_ + (void*) TC3_Handler, /* 24 Timer/Counter 3 */ + (void*) TC4_Handler, /* 25 Timer/Counter 4 */ + (void*) TC5_Handler, /* 26 Timer/Counter 5 */ +#else + (void*) Dummy_Handler, + (void*) Dummy_Handler, + (void*) Dummy_Handler, +#endif /* _SAM4E_TC1_INSTANCE_ */ +#ifdef _SAM4E_TC2_INSTANCE_ + (void*) TC6_Handler, /* 27 Timer/Counter 6 */ + (void*) TC7_Handler, /* 28 Timer/Counter 7 */ + (void*) TC8_Handler, /* 29 Timer/Counter 8 */ +#else + (void*) Dummy_Handler, + (void*) Dummy_Handler, + (void*) Dummy_Handler, +#endif /* _SAM4E_TC2_INSTANCE_ */ + (void*) AFEC0_Handler, /* 30 Analog Front End 0 */ + (void*) AFEC1_Handler, /* 31 Analog Front End 1 */ + (void*) DACC_Handler, /* 32 Digital To Analog Converter */ + (void*) ACC_Handler, /* 33 Analog Comparator */ + (void*) ARM_Handler, /* 34 FPU signals : FPIXC, FPOFC, FPUFC, FPIOC, FPDZC, FPIDC, FPIXC */ + (void*) UDP_Handler, /* 35 USB DEVICE */ + (void*) PWM_Handler, /* 36 PWM */ + (void*) CAN0_Handler, /* 37 CAN0 */ +#ifdef _SAM4E_CAN1_INSTANCE_ + (void*) CAN1_Handler, /* 38 CAN1 */ +#else + (void*) Dummy_Handler, +#endif /* _SAM4E_CAN1_INSTANCE_ */ + (void*) AES_Handler, /* 39 AES */ + (void*) Dummy_Handler, + (void*) Dummy_Handler, + (void*) Dummy_Handler, + (void*) Dummy_Handler, + (void*) GMAC_Handler, /* 44 EMAC */ + (void*) UART1_Handler /* 45 UART */ +}; + +/** + * \brief This is the code that gets called on processor reset. + * To initialize the device, and call the main() routine. + */ +void Reset_Handler(void) +{ + uint32_t *pSrc, *pDest; + + /* Initialize the relocate segment */ + pSrc = &_etext; + pDest = &_srelocate; + + if (pSrc != pDest) { + for (; pDest < &_erelocate;) { + *pDest++ = *pSrc++; + } + } + + /* Clear the zero segment */ + for (pDest = &_szero; pDest < &_ezero;) { + *pDest++ = 0; + } + + /* Set the vector table base address */ + pSrc = (uint32_t *) & _sfixed; + SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk); + +#if __FPU_USED + fpu_enable(); +#endif + + /* Initialize the C library */ + __libc_init_array(); + + /* Branch to main function */ + main(); + + /* Infinite loop */ + while (1); +} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.c new file mode 100644 index 0000000..1be9e31 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.c @@ -0,0 +1,234 @@ +/** + * \file + * + * \brief Provides the low-level initialization functions that called + * on chip startup. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include "sam4e.h" + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/* @endcond */ + +/* Clock Settings (120MHz) */ +#define SYS_BOARD_OSCOUNT (CKGR_MOR_MOSCXTST(0x8U)) +#define SYS_BOARD_PLLAR (CKGR_PLLAR_ONE \ + | CKGR_PLLAR_MULA(0x13U) \ + | CKGR_PLLAR_PLLACOUNT(0x3fU) \ + | CKGR_PLLAR_DIVA(0x1U)) +#define SYS_BOARD_MCKR (PMC_MCKR_PRES_CLK_2 | PMC_MCKR_CSS_PLLA_CLK) + +#define SYS_CKGR_MOR_KEY_VALUE CKGR_MOR_KEY_PASSWD/* Key to unlock MOR register */ + +uint32_t SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ; + +/** + * \brief Setup the microcontroller system. + * Initialize the System and update the SystemFrequency variable. + */ +void SystemInit( void ) +{ + /* Set FWS according to SYS_BOARD_MCKR configuration */ + EFC->EEFC_FMR = EEFC_FMR_FWS(5)|EEFC_FMR_CLOE; + + /* Initialize main oscillator */ + if ( !(PMC->CKGR_MOR & CKGR_MOR_MOSCSEL) ) { + PMC->CKGR_MOR = SYS_CKGR_MOR_KEY_VALUE | SYS_BOARD_OSCOUNT | + CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN; + + while ( !(PMC->PMC_SR & PMC_SR_MOSCXTS) ) { + } + } + + /* Switch to 3-20MHz Xtal oscillator */ + PMC->CKGR_MOR = SYS_CKGR_MOR_KEY_VALUE | SYS_BOARD_OSCOUNT | + CKGR_MOR_MOSCRCEN | CKGR_MOR_MOSCXTEN | + CKGR_MOR_MOSCSEL; + + while ( !(PMC->PMC_SR & PMC_SR_MOSCSELS) ) { + } + + PMC->PMC_MCKR = (PMC->PMC_MCKR & ~(uint32_t)PMC_MCKR_CSS_Msk) | + PMC_MCKR_CSS_MAIN_CLK; + + while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) { + } + + /* Initialize PLLA */ + PMC->CKGR_PLLAR = SYS_BOARD_PLLAR; + while ( !(PMC->PMC_SR & PMC_SR_LOCKA) ) { + } + + /* Switch to main clock */ + PMC->PMC_MCKR = (SYS_BOARD_MCKR & ~PMC_MCKR_CSS_Msk) | + PMC_MCKR_CSS_MAIN_CLK; + while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) { + } + + /* Switch to PLLA */ + PMC->PMC_MCKR = SYS_BOARD_MCKR; + while ( !(PMC->PMC_SR & PMC_SR_MCKRDY) ) { + } + + SystemCoreClock = CHIP_FREQ_CPU_MAX; +} + +void SystemCoreClockUpdate( void ) +{ + /* Determine clock frequency according to clock register values */ + switch (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) { + case PMC_MCKR_CSS_SLOW_CLK: /* Slow clock */ + if ( SUPC->SUPC_SR & SUPC_SR_OSCSEL ) { + SystemCoreClock = CHIP_FREQ_XTAL_32K; + } else { + SystemCoreClock = CHIP_FREQ_SLCK_RC; + } + break; + + case PMC_MCKR_CSS_MAIN_CLK: /* Main clock */ + if ( PMC->CKGR_MOR & CKGR_MOR_MOSCSEL ) { + SystemCoreClock = CHIP_FREQ_XTAL_12M; + } else { + SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ; + + switch ( PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk ) { + case CKGR_MOR_MOSCRCF_4_MHz: + break; + + case CKGR_MOR_MOSCRCF_8_MHz: + SystemCoreClock *= 2U; + break; + + case CKGR_MOR_MOSCRCF_12_MHz: + SystemCoreClock *= 3U; + break; + + default: + break; + } + } + break; + + case PMC_MCKR_CSS_PLLA_CLK: /* PLLA clock */ + if ( PMC->CKGR_MOR & CKGR_MOR_MOSCSEL ) { + SystemCoreClock = CHIP_FREQ_XTAL_12M ; + } else { + SystemCoreClock = CHIP_FREQ_MAINCK_RC_4MHZ; + + switch ( PMC->CKGR_MOR & CKGR_MOR_MOSCRCF_Msk ) { + case CKGR_MOR_MOSCRCF_4_MHz: + break; + + case CKGR_MOR_MOSCRCF_8_MHz: + SystemCoreClock *= 2U; + break; + + case CKGR_MOR_MOSCRCF_12_MHz: + SystemCoreClock *= 3U; + break; + + default: + break; + } + } + + if ((uint32_t) (PMC->PMC_MCKR & (uint32_t) PMC_MCKR_CSS_Msk) == PMC_MCKR_CSS_PLLA_CLK) + { + SystemCoreClock *= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_MULA_Msk) >> CKGR_PLLAR_MULA_Pos) + 1U); + SystemCoreClock /= ((((PMC->CKGR_PLLAR) & CKGR_PLLAR_DIVA_Msk) >> CKGR_PLLAR_DIVA_Pos)); + } + break; + + default: + break; + } + + if ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) == PMC_MCKR_PRES_CLK_3) { + SystemCoreClock /= 3U; + } else { + SystemCoreClock >>= ((PMC->PMC_MCKR & PMC_MCKR_PRES_Msk) >> + PMC_MCKR_PRES_Pos); + } +} + +/** + * Initialize flash. + */ +void system_init_flash( uint32_t ul_clk ) +{ + /* Set FWS for embedded Flash access according to operating frequency */ + if ( ul_clk < CHIP_FREQ_FWS_0 ) { + EFC->EEFC_FMR = EEFC_FMR_FWS(0)|EEFC_FMR_CLOE; + } else { + if (ul_clk < CHIP_FREQ_FWS_1) { + EFC->EEFC_FMR = EEFC_FMR_FWS(1)|EEFC_FMR_CLOE; + } else { + if (ul_clk < CHIP_FREQ_FWS_2) { + EFC->EEFC_FMR = EEFC_FMR_FWS(2)|EEFC_FMR_CLOE; + } else { + if ( ul_clk < CHIP_FREQ_FWS_3 ) { + EFC->EEFC_FMR = EEFC_FMR_FWS(3)|EEFC_FMR_CLOE; + } else { + if ( ul_clk < CHIP_FREQ_FWS_4 ) { + EFC->EEFC_FMR = EEFC_FMR_FWS(4)|EEFC_FMR_CLOE; + } else { + EFC->EEFC_FMR = EEFC_FMR_FWS(5)|EEFC_FMR_CLOE; + } + } + } + } + } +} + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/* @endcond */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.h new file mode 100644 index 0000000..a756bff --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/cmsis/sam4e/source/templates/system_sam4e.h @@ -0,0 +1,88 @@ +/** + * \file + * + * \brief Provides the low-level initialization functions that called + * on chip startup. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef SYSTEM_SAM4E_H_INCLUDED +#define SYSTEM_SAM4E_H_INCLUDED + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/* @endcond */ + +#include + +extern uint32_t SystemCoreClock; /* System Clock Frequency (Core Clock) */ + +/** + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +void SystemInit(void); + +/** + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void); + +/** + * Initialize flash. + */ +void system_init_flash(uint32_t dw_clk); + +/* @cond 0 */ +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/* @endcond */ + +#endif /* SYSTEM_SAM4E_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/compiler.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/compiler.h new file mode 100644 index 0000000..cb568cf --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/compiler.h @@ -0,0 +1,1197 @@ +/** + * \file + * + * \brief Commonly used includes, types and macros. + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef UTILS_COMPILER_H +#define UTILS_COMPILER_H + +/** + * \defgroup group_sam_utils Compiler abstraction layer and code utilities + * + * Compiler abstraction layer and code utilities for AT91SAM. + * This module provides various abstraction layers and utilities to make code compatible between different compilers. + * + * \{ + */ +#include + +#if (defined __ICCARM__) +# include +#endif + +#include +#include "preprocessor.h" + +#include + +//_____ D E C L A R A T I O N S ____________________________________________ + +#ifndef __ASSEMBLY__ // Not defined for assembling. + +#include +#include +#include +#include + +#ifdef __ICCARM__ +/*! \name Compiler Keywords + * + * Port of some keywords from GCC to IAR Embedded Workbench. + */ +//! @{ +#define __asm__ asm +#define __inline__ inline +#define __volatile__ +//! @} + +#endif + +#define FUNC_PTR void * +/** + * \def UNUSED + * \brief Marking \a v as a unused parameter or value. + */ +#define UNUSED(v) (void)(v) + +/** + * \def unused + * \brief Marking \a v as a unused parameter or value. + */ +#define unused(v) do { (void)(v); } while(0) + +/** + * \def barrier + * \brief Memory barrier + */ +#define barrier() __DMB() + +/** + * \brief Emit the compiler pragma \a arg. + * + * \param arg The pragma directive as it would appear after \e \#pragma + * (i.e. not stringified). + */ +#define COMPILER_PRAGMA(arg) _Pragma(#arg) + +/** + * \def COMPILER_PACK_SET(alignment) + * \brief Set maximum alignment for subsequent struct and union + * definitions to \a alignment. + */ +#define COMPILER_PACK_SET(alignment) COMPILER_PRAGMA(pack(alignment)) + +/** + * \def COMPILER_PACK_RESET() + * \brief Set default alignment for subsequent struct and union + * definitions. + */ +#define COMPILER_PACK_RESET() COMPILER_PRAGMA(pack()) + + +/** + * \brief Set aligned boundary. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define COMPILER_ALIGNED(a) __attribute__((__aligned__(a))) +#elif (defined __ICCARM__) +# define COMPILER_ALIGNED(a) COMPILER_PRAGMA(data_alignment = a) +#endif + +/** + * \brief Set word-aligned boundary. + */ +#if (defined __GNUC__) || defined(__CC_ARM) +#define COMPILER_WORD_ALIGNED __attribute__((__aligned__(4))) +#elif (defined __ICCARM__) +#define COMPILER_WORD_ALIGNED COMPILER_PRAGMA(data_alignment = 4) +#endif + +#undef __always_inline + +/** + * \def __always_inline + * \brief The function should always be inlined. + * + * This annotation instructs the compiler to ignore its inlining + * heuristics and inline the function no matter how big it thinks it + * becomes. + */ +#if defined(__CC_ARM) +# define __always_inline __forceinline +#elif (defined __GNUC__) +# define __always_inline inline __attribute__((__always_inline__)) +#elif (defined __ICCARM__) +# define __always_inline _Pragma("inline=forced") +#endif + +/** + * \def __no_inline + * \brief The function should not be inlined. + * + * This annotation instructs the compiler to ignore its inlining + * heuristics and not inline the function. + */ +#if defined(__CC_ARM) +# define __no_inline __attribute__((noinline)) +#elif (defined __GNUC__) +# define __no_inline __attribute__((__noinline__)) +#elif (defined __ICCARM__) +# define __no_inline _Pragma("inline=never") +#endif + +/*! \brief This macro is used to test fatal errors. + * + * The macro tests if the expression is false. If it is, a fatal error is + * detected and the application hangs up. If TEST_SUITE_DEFINE_ASSERT_MACRO + * is defined, a unit test version of the macro is used, to allow execution + * of further tests after a false expression. + * + * \param expr Expression to evaluate and supposed to be nonzero. + */ +#if defined(_ASSERT_ENABLE_) +# if defined(TEST_SUITE_DEFINE_ASSERT_MACRO) + // Assert() is defined in unit_test/suite.h +# include "unit_test/suite.h" +# else +#undef TEST_SUITE_DEFINE_ASSERT_MACRO +# define Assert(expr) \ + {\ + if (!(expr)) while (true);\ + } +# endif +#else +# define Assert(expr) ((void) 0) +#endif + +/* Define WEAK attribute */ +#if defined ( __CC_ARM ) /* Keil 礦ision 4 */ +# define WEAK __attribute__ ((weak)) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +# define WEAK __weak +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ +# define WEAK __attribute__ ((weak)) +#endif + +/* Define NO_INIT attribute */ +#if defined ( __CC_ARM ) +# define NO_INIT __attribute__((zero_init)) +#elif defined ( __ICCARM__ ) +# define NO_INIT __no_init +#elif defined ( __GNUC__ ) +# define NO_INIT __attribute__((section(".no_init"))) +#endif + +/* Define RAMFUNC attribute */ +#if defined ( __CC_ARM ) /* Keil 礦ision 4 */ +# define RAMFUNC __attribute__ ((section(".ramfunc"))) +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +# define RAMFUNC __ramfunc +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ +# define RAMFUNC __attribute__ ((section(".ramfunc"))) +#endif + +/* Define OPTIMIZE_HIGH attribute */ +#if defined ( __CC_ARM ) /* Keil 礦ision 4 */ +# define OPTIMIZE_HIGH _Pragma("O3") +#elif defined ( __ICCARM__ ) /* IAR Ewarm 5.41+ */ +# define OPTIMIZE_HIGH _Pragma("optimize=high") +#elif defined ( __GNUC__ ) /* GCC CS3 2009q3-68 */ +# define OPTIMIZE_HIGH __attribute__((optimize(s))) +#endif + +#include "interrupt.h" + +/*! \name Usual Types + */ +//! @{ +typedef unsigned char Bool; //!< Boolean. +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +typedef unsigned char bool; //!< Boolean. +#endif +#endif +typedef int8_t S8 ; //!< 8-bit signed integer. +typedef uint8_t U8 ; //!< 8-bit unsigned integer. +typedef int16_t S16; //!< 16-bit signed integer. +typedef uint16_t U16; //!< 16-bit unsigned integer. +typedef uint16_t le16_t; +typedef uint16_t be16_t; +typedef int32_t S32; //!< 32-bit signed integer. +typedef uint32_t U32; //!< 32-bit unsigned integer. +typedef uint32_t le32_t; +typedef uint32_t be32_t; +typedef int64_t S64; //!< 64-bit signed integer. +typedef uint64_t U64; //!< 64-bit unsigned integer. +typedef float F32; //!< 32-bit floating-point number. +typedef double F64; //!< 64-bit floating-point number. +typedef uint32_t iram_size_t; +//! @} + + +/*! \name Status Types + */ +//! @{ +typedef bool Status_bool_t; //!< Boolean status. +typedef U8 Status_t; //!< 8-bit-coded status. +//! @} + + +/*! \name Aliasing Aggregate Types + */ +//! @{ + +//! 16-bit union. +typedef union +{ + S16 s16 ; + U16 u16 ; + S8 s8 [2]; + U8 u8 [2]; +} Union16; + +//! 32-bit union. +typedef union +{ + S32 s32 ; + U32 u32 ; + S16 s16[2]; + U16 u16[2]; + S8 s8 [4]; + U8 u8 [4]; +} Union32; + +//! 64-bit union. +typedef union +{ + S64 s64 ; + U64 u64 ; + S32 s32[2]; + U32 u32[2]; + S16 s16[4]; + U16 u16[4]; + S8 s8 [8]; + U8 u8 [8]; +} Union64; + +//! Union of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} UnionPtr; + +//! Union of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} UnionVPtr; + +//! Union of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} UnionCPtr; + +//! Union of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef union +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} UnionCVPtr; + +//! Structure of pointers to 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + S64 *s64ptr; + U64 *u64ptr; + S32 *s32ptr; + U32 *u32ptr; + S16 *s16ptr; + U16 *u16ptr; + S8 *s8ptr ; + U8 *u8ptr ; +} StructPtr; + +//! Structure of pointers to volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + volatile S64 *s64ptr; + volatile U64 *u64ptr; + volatile S32 *s32ptr; + volatile U32 *u32ptr; + volatile S16 *s16ptr; + volatile U16 *u16ptr; + volatile S8 *s8ptr ; + volatile U8 *u8ptr ; +} StructVPtr; + +//! Structure of pointers to constant 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const S64 *s64ptr; + const U64 *u64ptr; + const S32 *s32ptr; + const U32 *u32ptr; + const S16 *s16ptr; + const U16 *u16ptr; + const S8 *s8ptr ; + const U8 *u8ptr ; +} StructCPtr; + +//! Structure of pointers to constant volatile 64-, 32-, 16- and 8-bit unsigned integers. +typedef struct +{ + const volatile S64 *s64ptr; + const volatile U64 *u64ptr; + const volatile S32 *s32ptr; + const volatile U32 *u32ptr; + const volatile S16 *s16ptr; + const volatile U16 *u16ptr; + const volatile S8 *s8ptr ; + const volatile U8 *u8ptr ; +} StructCVPtr; + +//! @} + +#endif // #ifndef __ASSEMBLY__ + +/*! \name Usual Constants + */ +//! @{ +#define DISABLE 0 +#define ENABLE 1 +#ifndef __cplusplus +#if !defined(__bool_true_false_are_defined) +#define false 0 +#define true 1 +#endif +#endif +#define PASS 0 +#define FAIL 1 +#define LOW 0 +#define HIGH 1 +//! @} + + +#ifndef __ASSEMBLY__ // not for assembling. + +//! \name Optimization Control +//@{ + +/** + * \def likely(exp) + * \brief The expression \a exp is likely to be true + */ +#ifndef likely +# define likely(exp) (exp) +#endif + +/** + * \def unlikely(exp) + * \brief The expression \a exp is unlikely to be true + */ +#ifndef unlikely +# define unlikely(exp) (exp) +#endif + +/** + * \def is_constant(exp) + * \brief Determine if an expression evaluates to a constant value. + * + * \param exp Any expression + * + * \return true if \a exp is constant, false otherwise. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define is_constant(exp) __builtin_constant_p(exp) +#else +# define is_constant(exp) (0) +#endif + +//! @} + +/*! \name Bit-Field Handling + */ +//! @{ + +/*! \brief Reads the bits of a value specified by a given bit-mask. + * + * \param value Value to read bits from. + * \param mask Bit-mask indicating bits to read. + * + * \return Read bits. + */ +#define Rd_bits( value, mask) ((value) & (mask)) + +/*! \brief Writes the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write bits to. + * \param mask Bit-mask indicating bits to write. + * \param bits Bits to write. + * + * \return Resulting value with written bits. + */ +#define Wr_bits(lvalue, mask, bits) ((lvalue) = ((lvalue) & ~(mask)) |\ + ((bits ) & (mask))) + +/*! \brief Tests the bits of a value specified by a given bit-mask. + * + * \param value Value of which to test bits. + * \param mask Bit-mask indicating bits to test. + * + * \return \c 1 if at least one of the tested bits is set, else \c 0. + */ +#define Tst_bits( value, mask) (Rd_bits(value, mask) != 0) + +/*! \brief Clears the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to clear bits. + * \param mask Bit-mask indicating bits to clear. + * + * \return Resulting value with cleared bits. + */ +#define Clr_bits(lvalue, mask) ((lvalue) &= ~(mask)) + +/*! \brief Sets the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to set bits. + * \param mask Bit-mask indicating bits to set. + * + * \return Resulting value with set bits. + */ +#define Set_bits(lvalue, mask) ((lvalue) |= (mask)) + +/*! \brief Toggles the bits of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue of which to toggle bits. + * \param mask Bit-mask indicating bits to toggle. + * + * \return Resulting value with toggled bits. + */ +#define Tgl_bits(lvalue, mask) ((lvalue) ^= (mask)) + +/*! \brief Reads the bit-field of a value specified by a given bit-mask. + * + * \param value Value to read a bit-field from. + * \param mask Bit-mask indicating the bit-field to read. + * + * \return Read bit-field. + */ +#define Rd_bitfield( value, mask) (Rd_bits( value, mask) >> ctz(mask)) + +/*! \brief Writes the bit-field of a C lvalue specified by a given bit-mask. + * + * \param lvalue C lvalue to write a bit-field to. + * \param mask Bit-mask indicating the bit-field to write. + * \param bitfield Bit-field to write. + * + * \return Resulting value with written bit-field. + */ +#define Wr_bitfield(lvalue, mask, bitfield) (Wr_bits(lvalue, mask, (U32)(bitfield) << ctz(mask))) + +//! @} + + +/*! \name Zero-Bit Counting + * + * Under GCC, __builtin_clz and __builtin_ctz behave like macros when + * applied to constant expressions (values known at compile time), so they are + * more optimized than the use of the corresponding assembly instructions and + * they can be used as constant expressions e.g. to initialize objects having + * static storage duration, and like the corresponding assembly instructions + * when applied to non-constant expressions (values unknown at compile time), so + * they are more optimized than an assembly periphrasis. Hence, clz and ctz + * ensure a possible and optimized behavior for both constant and non-constant + * expressions. + */ +//! @{ + +/*! \brief Counts the leading zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the leading zero bits. + * + * \return The count of leading zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define clz(u) __builtin_clz(u) +#elif (defined __ICCARM__) +# define clz(u) __CLZ(u) +#else +# define clz(u) (((u) == 0) ? 32 : \ + ((u) & (1ul << 31)) ? 0 : \ + ((u) & (1ul << 30)) ? 1 : \ + ((u) & (1ul << 29)) ? 2 : \ + ((u) & (1ul << 28)) ? 3 : \ + ((u) & (1ul << 27)) ? 4 : \ + ((u) & (1ul << 26)) ? 5 : \ + ((u) & (1ul << 25)) ? 6 : \ + ((u) & (1ul << 24)) ? 7 : \ + ((u) & (1ul << 23)) ? 8 : \ + ((u) & (1ul << 22)) ? 9 : \ + ((u) & (1ul << 21)) ? 10 : \ + ((u) & (1ul << 20)) ? 11 : \ + ((u) & (1ul << 19)) ? 12 : \ + ((u) & (1ul << 18)) ? 13 : \ + ((u) & (1ul << 17)) ? 14 : \ + ((u) & (1ul << 16)) ? 15 : \ + ((u) & (1ul << 15)) ? 16 : \ + ((u) & (1ul << 14)) ? 17 : \ + ((u) & (1ul << 13)) ? 18 : \ + ((u) & (1ul << 12)) ? 19 : \ + ((u) & (1ul << 11)) ? 20 : \ + ((u) & (1ul << 10)) ? 21 : \ + ((u) & (1ul << 9)) ? 22 : \ + ((u) & (1ul << 8)) ? 23 : \ + ((u) & (1ul << 7)) ? 24 : \ + ((u) & (1ul << 6)) ? 25 : \ + ((u) & (1ul << 5)) ? 26 : \ + ((u) & (1ul << 4)) ? 27 : \ + ((u) & (1ul << 3)) ? 28 : \ + ((u) & (1ul << 2)) ? 29 : \ + ((u) & (1ul << 1)) ? 30 : \ + 31) +#endif + +/*! \brief Counts the trailing zero bits of the given value considered as a 32-bit integer. + * + * \param u Value of which to count the trailing zero bits. + * + * \return The count of trailing zero bits in \a u. + */ +#if (defined __GNUC__) || (defined __CC_ARM) +# define ctz(u) __builtin_ctz(u) +#else +# define ctz(u) ((u) & (1ul << 0) ? 0 : \ + (u) & (1ul << 1) ? 1 : \ + (u) & (1ul << 2) ? 2 : \ + (u) & (1ul << 3) ? 3 : \ + (u) & (1ul << 4) ? 4 : \ + (u) & (1ul << 5) ? 5 : \ + (u) & (1ul << 6) ? 6 : \ + (u) & (1ul << 7) ? 7 : \ + (u) & (1ul << 8) ? 8 : \ + (u) & (1ul << 9) ? 9 : \ + (u) & (1ul << 10) ? 10 : \ + (u) & (1ul << 11) ? 11 : \ + (u) & (1ul << 12) ? 12 : \ + (u) & (1ul << 13) ? 13 : \ + (u) & (1ul << 14) ? 14 : \ + (u) & (1ul << 15) ? 15 : \ + (u) & (1ul << 16) ? 16 : \ + (u) & (1ul << 17) ? 17 : \ + (u) & (1ul << 18) ? 18 : \ + (u) & (1ul << 19) ? 19 : \ + (u) & (1ul << 20) ? 20 : \ + (u) & (1ul << 21) ? 21 : \ + (u) & (1ul << 22) ? 22 : \ + (u) & (1ul << 23) ? 23 : \ + (u) & (1ul << 24) ? 24 : \ + (u) & (1ul << 25) ? 25 : \ + (u) & (1ul << 26) ? 26 : \ + (u) & (1ul << 27) ? 27 : \ + (u) & (1ul << 28) ? 28 : \ + (u) & (1ul << 29) ? 29 : \ + (u) & (1ul << 30) ? 30 : \ + (u) & (1ul << 31) ? 31 : \ + 32) +#endif + +//! @} + + +/*! \name Bit Reversing + */ +//! @{ + +/*! \brief Reverses the bits of \a u8. + * + * \param u8 U8 of which to reverse the bits. + * + * \return Value resulting from \a u8 with reversed bits. + */ +#define bit_reverse8(u8) ((U8)(bit_reverse32((U8)(u8)) >> 24)) + +/*! \brief Reverses the bits of \a u16. + * + * \param u16 U16 of which to reverse the bits. + * + * \return Value resulting from \a u16 with reversed bits. + */ +#define bit_reverse16(u16) ((U16)(bit_reverse32((U16)(u16)) >> 16)) + +/*! \brief Reverses the bits of \a u32. + * + * \param u32 U32 of which to reverse the bits. + * + * \return Value resulting from \a u32 with reversed bits. + */ +#define bit_reverse32(u32) __RBIT(u32) + +/*! \brief Reverses the bits of \a u64. + * + * \param u64 U64 of which to reverse the bits. + * + * \return Value resulting from \a u64 with reversed bits. + */ +#define bit_reverse64(u64) ((U64)(((U64)bit_reverse32((U64)(u64) >> 32)) |\ + ((U64)bit_reverse32((U64)(u64)) << 32))) + +//! @} + + +/*! \name Alignment + */ +//! @{ + +/*! \brief Tests alignment of the number \a val with the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return \c 1 if the number \a val is aligned with the \a n boundary, else \c 0. + */ +#define Test_align(val, n ) (!Tst_bits( val, (n) - 1 ) ) + +/*! \brief Gets alignment of the number \a val with respect to the \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Alignment of the number \a val with respect to the \a n boundary. + */ +#define Get_align( val, n ) ( Rd_bits( val, (n) - 1 ) ) + +/*! \brief Sets alignment of the lvalue number \a lval to \a alg with respect to the \a n boundary. + * + * \param lval Input/output lvalue. + * \param n Boundary. + * \param alg Alignment. + * + * \return New value of \a lval resulting from its alignment set to \a alg with respect to the \a n boundary. + */ +#define Set_align(lval, n, alg) ( Wr_bits(lval, (n) - 1, alg) ) + +/*! \brief Aligns the number \a val with the upper \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the upper \a n boundary. + */ +#define Align_up( val, n ) (((val) + ((n) - 1)) & ~((n) - 1)) + +/*! \brief Aligns the number \a val with the lower \a n boundary. + * + * \param val Input value. + * \param n Boundary. + * + * \return Value resulting from the number \a val aligned with the lower \a n boundary. + */ +#define Align_down(val, n ) ( (val) & ~((n) - 1)) + +//! @} + + +/*! \name Mathematics + * + * The same considerations as for clz and ctz apply here but GCC does not + * provide built-in functions to access the assembly instructions abs, min and + * max and it does not produce them by itself in most cases, so two sets of + * macros are defined here: + * - Abs, Min and Max to apply to constant expressions (values known at + * compile time); + * - abs, min and max to apply to non-constant expressions (values unknown at + * compile time), abs is found in stdlib.h. + */ +//! @{ + +/*! \brief Takes the absolute value of \a a. + * + * \param a Input value. + * + * \return Absolute value of \a a. + * + * \note More optimized if only used with values known at compile time. + */ +#define Abs(a) (((a) < 0 ) ? -(a) : (a)) + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Min(a, b) (((a) < (b)) ? (a) : (b)) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values known at compile time. + */ +#define Max(a, b) (((a) > (b)) ? (a) : (b)) + +// abs() is already defined by stdlib.h + +/*! \brief Takes the minimal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Minimal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define min(a, b) Min(a, b) + +/*! \brief Takes the maximal value of \a a and \a b. + * + * \param a Input value. + * \param b Input value. + * + * \return Maximal value of \a a and \a b. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define max(a, b) Max(a, b) + +//! @} + + +/*! \brief Calls the routine at address \a addr. + * + * It generates a long call opcode. + * + * For example, `Long_call(0x80000000)' generates a software reset on a UC3 if + * it is invoked from the CPU supervisor mode. + * + * \param addr Address of the routine to call. + * + * \note It may be used as a long jump opcode in some special cases. + */ +#define Long_call(addr) ((*(void (*)(void))(addr))()) + + +/*! \name MCU Endianism Handling + * ARM is MCU little endianism. + */ +//! @{ +#define MSB(u16) (((U8 *)&(u16))[1]) //!< Most significant byte of \a u16. +#define LSB(u16) (((U8 *)&(u16))[0]) //!< Least significant byte of \a u16. + +#define MSH(u32) (((U16 *)&(u32))[1]) //!< Most significant half-word of \a u32. +#define LSH(u32) (((U16 *)&(u32))[0]) //!< Least significant half-word of \a u32. +#define MSB0W(u32) (((U8 *)&(u32))[3]) //!< Most significant byte of 1st rank of \a u32. +#define MSB1W(u32) (((U8 *)&(u32))[2]) //!< Most significant byte of 2nd rank of \a u32. +#define MSB2W(u32) (((U8 *)&(u32))[1]) //!< Most significant byte of 3rd rank of \a u32. +#define MSB3W(u32) (((U8 *)&(u32))[0]) //!< Most significant byte of 4th rank of \a u32. +#define LSB3W(u32) MSB0W(u32) //!< Least significant byte of 4th rank of \a u32. +#define LSB2W(u32) MSB1W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB1W(u32) MSB2W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB0W(u32) MSB3W(u32) //!< Least significant byte of 1st rank of \a u32. + +#define MSW(u64) (((U32 *)&(u64))[1]) //!< Most significant word of \a u64. +#define LSW(u64) (((U32 *)&(u64))[0]) //!< Least significant word of \a u64. +#define MSH0(u64) (((U16 *)&(u64))[3]) //!< Most significant half-word of 1st rank of \a u64. +#define MSH1(u64) (((U16 *)&(u64))[2]) //!< Most significant half-word of 2nd rank of \a u64. +#define MSH2(u64) (((U16 *)&(u64))[1]) //!< Most significant half-word of 3rd rank of \a u64. +#define MSH3(u64) (((U16 *)&(u64))[0]) //!< Most significant half-word of 4th rank of \a u64. +#define LSH3(u64) MSH0(u64) //!< Least significant half-word of 4th rank of \a u64. +#define LSH2(u64) MSH1(u64) //!< Least significant half-word of 3rd rank of \a u64. +#define LSH1(u64) MSH2(u64) //!< Least significant half-word of 2nd rank of \a u64. +#define LSH0(u64) MSH3(u64) //!< Least significant half-word of 1st rank of \a u64. +#define MSB0D(u64) (((U8 *)&(u64))[7]) //!< Most significant byte of 1st rank of \a u64. +#define MSB1D(u64) (((U8 *)&(u64))[6]) //!< Most significant byte of 2nd rank of \a u64. +#define MSB2D(u64) (((U8 *)&(u64))[5]) //!< Most significant byte of 3rd rank of \a u64. +#define MSB3D(u64) (((U8 *)&(u64))[4]) //!< Most significant byte of 4th rank of \a u64. +#define MSB4D(u64) (((U8 *)&(u64))[3]) //!< Most significant byte of 5th rank of \a u64. +#define MSB5D(u64) (((U8 *)&(u64))[2]) //!< Most significant byte of 6th rank of \a u64. +#define MSB6D(u64) (((U8 *)&(u64))[1]) //!< Most significant byte of 7th rank of \a u64. +#define MSB7D(u64) (((U8 *)&(u64))[0]) //!< Most significant byte of 8th rank of \a u64. +#define LSB7D(u64) MSB0D(u64) //!< Least significant byte of 8th rank of \a u64. +#define LSB6D(u64) MSB1D(u64) //!< Least significant byte of 7th rank of \a u64. +#define LSB5D(u64) MSB2D(u64) //!< Least significant byte of 6th rank of \a u64. +#define LSB4D(u64) MSB3D(u64) //!< Least significant byte of 5th rank of \a u64. +#define LSB3D(u64) MSB4D(u64) //!< Least significant byte of 4th rank of \a u64. +#define LSB2D(u64) MSB5D(u64) //!< Least significant byte of 3rd rank of \a u64. +#define LSB1D(u64) MSB6D(u64) //!< Least significant byte of 2nd rank of \a u64. +#define LSB0D(u64) MSB7D(u64) //!< Least significant byte of 1st rank of \a u64. + +#define BE16(x) Swap16(x) +#define LE16(x) (x) + +#define le16_to_cpu(x) (x) +#define cpu_to_le16(x) (x) +#define LE16_TO_CPU(x) (x) +#define CPU_TO_LE16(x) (x) + +#define be16_to_cpu(x) Swap16(x) +#define cpu_to_be16(x) Swap16(x) +#define BE16_TO_CPU(x) Swap16(x) +#define CPU_TO_BE16(x) Swap16(x) + +#define le32_to_cpu(x) (x) +#define cpu_to_le32(x) (x) +#define LE32_TO_CPU(x) (x) +#define CPU_TO_LE32(x) (x) + +#define be32_to_cpu(x) swap32(x) +#define cpu_to_be32(x) swap32(x) +#define BE32_TO_CPU(x) swap32(x) +#define CPU_TO_BE32(x) swap32(x) +//! @} + + +/*! \name Endianism Conversion + * + * The same considerations as for clz and ctz apply here but GCC's + * __builtin_bswap_32 and __builtin_bswap_64 do not behave like macros when + * applied to constant expressions, so two sets of macros are defined here: + * - Swap16, Swap32 and Swap64 to apply to constant expressions (values known + * at compile time); + * - swap16, swap32 and swap64 to apply to non-constant expressions (values + * unknown at compile time). + */ +//! @{ + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap16(u16) ((U16)(((U16)(u16) >> 8) |\ + ((U16)(u16) << 8))) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap32(u32) ((U32)(((U32)Swap16((U32)(u32) >> 16)) |\ + ((U32)Swap16((U32)(u32)) << 16))) + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values known at compile time. + */ +#define Swap64(u64) ((U64)(((U64)Swap32((U64)(u64) >> 32)) |\ + ((U64)Swap32((U64)(u64)) << 32))) + +/*! \brief Toggles the endianism of \a u16 (by swapping its bytes). + * + * \param u16 U16 of which to toggle the endianism. + * + * \return Value resulting from \a u16 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#define swap16(u16) Swap16(u16) + +/*! \brief Toggles the endianism of \a u32 (by swapping its bytes). + * + * \param u32 U32 of which to toggle the endianism. + * + * \return Value resulting from \a u32 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) +# define swap32(u32) ((U32)__builtin_bswap32((U32)(u32))) +#else +# define swap32(u32) Swap32(u32) +#endif + +/*! \brief Toggles the endianism of \a u64 (by swapping its bytes). + * + * \param u64 U64 of which to toggle the endianism. + * + * \return Value resulting from \a u64 with toggled endianism. + * + * \note More optimized if only used with values unknown at compile time. + */ +#if (defined __GNUC__) +# define swap64(u64) ((U64)__builtin_bswap64((U64)(u64))) +#else +# define swap64(u64) ((U64)(((U64)swap32((U64)(u64) >> 32)) |\ + ((U64)swap32((U64)(u64)) << 32))) +#endif + +//! @} + + +/*! \name Target Abstraction + */ +//! @{ + +#define _GLOBEXT_ extern //!< extern storage-class specifier. +#define _CONST_TYPE_ const //!< const type qualifier. +#define _MEM_TYPE_SLOW_ //!< Slow memory type. +#define _MEM_TYPE_MEDFAST_ //!< Fairly fast memory type. +#define _MEM_TYPE_FAST_ //!< Fast memory type. + +typedef U8 Byte; //!< 8-bit unsigned integer. + +#define memcmp_ram2ram memcmp //!< Target-specific memcmp of RAM to RAM. +#define memcmp_code2ram memcmp //!< Target-specific memcmp of RAM to NVRAM. +#define memcpy_ram2ram memcpy //!< Target-specific memcpy from RAM to RAM. +#define memcpy_code2ram memcpy //!< Target-specific memcpy from NVRAM to RAM. + +#define LSB0(u32) LSB0W(u32) //!< Least significant byte of 1st rank of \a u32. +#define LSB1(u32) LSB1W(u32) //!< Least significant byte of 2nd rank of \a u32. +#define LSB2(u32) LSB2W(u32) //!< Least significant byte of 3rd rank of \a u32. +#define LSB3(u32) LSB3W(u32) //!< Least significant byte of 4th rank of \a u32. +#define MSB3(u32) MSB3W(u32) //!< Most significant byte of 4th rank of \a u32. +#define MSB2(u32) MSB2W(u32) //!< Most significant byte of 3rd rank of \a u32. +#define MSB1(u32) MSB1W(u32) //!< Most significant byte of 2nd rank of \a u32. +#define MSB0(u32) MSB0W(u32) //!< Most significant byte of 1st rank of \a u32. + +//! @} + +/** + * \brief Calculate \f$ \left\lceil \frac{a}{b} \right\rceil \f$ using + * integer arithmetic. + * + * \param a An integer + * \param b Another integer + * + * \return (\a a / \a b) rounded up to the nearest integer. + */ +#define div_ceil(a, b) (((a) + (b) - 1) / (b)) + +#endif // #ifndef __ASSEMBLY__ + + +#if defined(__ICCARM__) +#define SHORTENUM __packed +#elif defined(__GNUC__) +#define SHORTENUM __attribute__((packed)) +#endif + +/* No operation */ +#if defined(__ICCARM__) +#define nop() __no_operation() +#elif defined(__GNUC__) +#define nop() (__NOP()) +#endif + +#define FLASH_DECLARE(x) const x +#define FLASH_EXTERN(x) extern const x +#define PGM_READ_BYTE(x) *(x) +#define PGM_READ_WORD(x) *(x) +#define MEMCPY_ENDIAN memcpy +#define PGM_READ_BLOCK(dst, src, len) memcpy((dst), (src), (len)) + +/*Defines the Flash Storage for the request and response of MAC*/ +#define CMD_ID_OCTET (0) + +/* Converting of values from CPU endian to little endian. */ +#define CPU_ENDIAN_TO_LE16(x) (x) +#define CPU_ENDIAN_TO_LE32(x) (x) +#define CPU_ENDIAN_TO_LE64(x) (x) + +/* Converting of values from little endian to CPU endian. */ +#define LE16_TO_CPU_ENDIAN(x) (x) +#define LE32_TO_CPU_ENDIAN(x) (x) +#define LE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from little endian to CPU endian. */ +#define CLE16_TO_CPU_ENDIAN(x) (x) +#define CLE32_TO_CPU_ENDIAN(x) (x) +#define CLE64_TO_CPU_ENDIAN(x) (x) + +/* Converting of constants from CPU endian to little endian. */ +#define CCPU_ENDIAN_TO_LE16(x) (x) +#define CCPU_ENDIAN_TO_LE32(x) (x) +#define CCPU_ENDIAN_TO_LE64(x) (x) + +#define ADDR_COPY_DST_SRC_16(dst, src) ((dst) = (src)) +#define ADDR_COPY_DST_SRC_64(dst, src) ((dst) = (src)) + +/** + * @brief Converts a 64-Bit value into a 8 Byte array + * + * @param[in] value 64-Bit value + * @param[out] data Pointer to the 8 Byte array to be updated with 64-Bit value + * @ingroup apiPalApi + */ +static inline void convert_64_bit_to_byte_array(uint64_t value, uint8_t *data) +{ + uint8_t val_index = 0; + + while (val_index < 8) + { + data[val_index++] = value & 0xFF; + value = value >> 8; + } +} + +/** + * @brief Converts a 16-Bit value into a 2 Byte array + * + * @param[in] value 16-Bit value + * @param[out] data Pointer to the 2 Byte array to be updated with 16-Bit value + * @ingroup apiPalApi + */ +static inline void convert_16_bit_to_byte_array(uint16_t value, uint8_t *data) +{ + data[0] = value & 0xFF; + data[1] = (value >> 8) & 0xFF; +} + +/* Converts a 16-Bit value into a 2 Byte array */ +static inline void convert_spec_16_bit_to_byte_array(uint16_t value, uint8_t *data) +{ + data[0] = value & 0xFF; + data[1] = (value >> 8) & 0xFF; +} + +/* Converts a 16-Bit value into a 2 Byte array */ +static inline void convert_16_bit_to_byte_address(uint16_t value, uint8_t *data) +{ + data[0] = value & 0xFF; + data[1] = (value >> 8) & 0xFF; +} + +/* + * @brief Converts a 2 Byte array into a 16-Bit value + * + * @param data Specifies the pointer to the 2 Byte array + * + * @return 16-Bit value + * @ingroup apiPalApi + */ +static inline uint16_t convert_byte_array_to_16_bit(uint8_t *data) +{ + return (data[0] | ((uint16_t)data[1] << 8)); +} + +/* Converts a 8 Byte array into a 32-Bit value */ +static inline uint32_t convert_byte_array_to_32_bit(uint8_t *data) +{ + union + { + uint32_t u32; + uint8_t u8[8]; + }long_addr; + uint8_t index; + for (index = 0; index < 4; index++) + { + long_addr.u8[index] = *data++; + } + return long_addr.u32; +} + +/** + * @brief Converts a 8 Byte array into a 64-Bit value + * + * @param data Specifies the pointer to the 8 Byte array + * + * @return 64-Bit value + * @ingroup apiPalApi + */ +static inline uint64_t convert_byte_array_to_64_bit(uint8_t *data) +{ + union + { + uint64_t u64; + uint8_t u8[8]; + } long_addr; + + uint8_t val_index; + + for (val_index = 0; val_index < 8; val_index++) + { + long_addr.u8[val_index] = *data++; + } + + return long_addr.u64; +} +/** + * \} + */ + +#endif /* UTILS_COMPILER_H */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/fpu/fpu.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/fpu/fpu.h new file mode 100644 index 0000000..e4f73b8 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/fpu/fpu.h @@ -0,0 +1,94 @@ +/** + * \file + * + * \brief FPU support for SAM. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _FPU_H_INCLUDED_ +#define _FPU_H_INCLUDED_ + +#include + +/** Address for ARM CPACR */ +#define ADDR_CPACR 0xE000ED88 + +/** CPACR Register */ +#define REG_CPACR (*((volatile uint32_t *)ADDR_CPACR)) + +/** + * \brief Enable FPU + */ +__always_inline static void fpu_enable(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + REG_CPACR |= (0xFu << 20); + __DSB(); + __ISB(); + cpu_irq_restore(flags); +} + +/** + * \brief Disable FPU + */ +__always_inline static void fpu_disable(void) +{ + irqflags_t flags; + flags = cpu_irq_save(); + REG_CPACR &= ~(0xFu << 20); + __DSB(); + __ISB(); + cpu_irq_restore(flags); +} + +/** + * \brief Check if FPU is enabled + * + * \return Return ture if FPU is enabled, otherwise return false. + */ +__always_inline static bool fpu_is_enabled(void) +{ + return (REG_CPACR & (0xFu << 20)); +} + +#endif /* _FPU_H_INCLUDED_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/header_files/io.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/header_files/io.h new file mode 100644 index 0000000..9ca5fd7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/header_files/io.h @@ -0,0 +1,137 @@ +/** + * \file + * + * \brief Arch file for SAM. + * + * This file defines common SAM series. + * + * Copyright (c) 2011 - 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _SAM_IO_ +#define _SAM_IO_ + +/* SAM3 family */ + +/* SAM3S series */ +#if (SAM3S) +# if (SAM3S8 || SAM3SD8) +# include "sam3s8.h" +# else +# include "sam3s.h" +# endif +#endif + +/* SAM3U series */ +#if (SAM3U) +# include "sam3u.h" +#endif + +/* SAM3N series */ +#if (SAM3N) +# include "sam3n.h" +#endif + +/* SAM3XA series */ +#if (SAM3XA) +# include "sam3xa.h" +#endif + +/* SAM4S series */ +#if (SAM4S) +# include "sam4s.h" +#endif + +/* SAM4L series */ +#if (SAM4L) +# include "sam4l.h" +#endif + +/* SAM4E series */ +#if (SAM4E) +# include "sam4e.h" +#endif + +/* SAM4N series */ +#if (SAM4N) +# include "sam4n.h" +#endif + +/* SAM4C series */ +#if (SAM4C) +# include "sam4c.h" +#endif + +/* SAM4CM series */ +#if (SAM4CM) +# if (SAM4CMP32 || SAM4CMS32) +# include "sam4cm32.h" +# else +# include "sam4cm.h" +# endif +#endif + +/* SAM4CP series */ +#if (SAM4CP) +# include "sam4cp.h" +#endif + +/* SAMG51 series */ +#if (SAMG51) +# include "samg51.h" +#endif + +/* SAMG53 series */ +#if (SAMG53) +# include "samg53.h" +#endif + +/* SAMG54 series */ +#if (SAMG54) +# include "samg54.h" +#endif + +/* SAMG55 series */ +#if (SAMG55) +# include "samg55.h" +#endif + +#endif /* _SAM_IO_ */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld new file mode 100644 index 0000000..c5b04b3 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/linker_scripts/sam4e/sam4e16/gcc/flash.ld @@ -0,0 +1,156 @@ +/** + * \file + * + * \brief Flash Linker script for SAM. + * + * 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 + * + */ + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00400000, LENGTH = 0x00100000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00020000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +__stack_size__ = DEFINED(__stack_size__) ? __stack_size__ : 0x3000; +__ram_end__ = ORIGIN(ram) + LENGTH(ram) - 4; + +SECTIONS +{ + .text : + { + . = ALIGN(4); + _sfixed = .; + KEEP(*(.vectors .vectors.*)) + *(.text .text.* .gnu.linkonce.t.*) + *(.glue_7t) *(.glue_7) + *(.rodata .rodata* .gnu.linkonce.r.*) + *(.ARM.extab* .gnu.linkonce.armextab.*) + + /* 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(0x4); + 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); + _efixed = .; /* End of text section */ + } > rom + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > rom + PROVIDE_HIDDEN (__exidx_end = .); + + . = ALIGN(4); + _etext = .; + + .relocate : AT (_etext) + { + . = ALIGN(4); + _srelocate = .; + *(.ramfunc .ramfunc.*); + *(.data .data.*); + . = ALIGN(4); + _erelocate = .; + } > ram + + /* .bss section which is used for uninitialized data */ + .bss (NOLOAD) : + { + . = ALIGN(4); + _sbss = . ; + _szero = .; + *(.bss .bss.*) + *(COMMON) + . = ALIGN(4); + _ebss = . ; + _ezero = .; + } > ram + + /* stack section */ + .stack (NOLOAD): + { + . = ALIGN(8); + _sstack = .; + . = . + __stack_size__; + . = ALIGN(8); + _estack = .; + } > ram + + . = ALIGN(4); + _end = . ; +} diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/make/Makefile.sam.in b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/make/Makefile.sam.in new file mode 100644 index 0000000..23c6697 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/make/Makefile.sam.in @@ -0,0 +1,496 @@ +# List of available make goals: +# +# all Default target, builds the project +# clean Clean up the project +# rebuild Rebuild the project +# debug_flash Builds the project and debug in flash +# debug_sram Builds the project and debug in sram +# +# doc Build the documentation +# cleandoc Clean up the documentation +# rebuilddoc Rebuild the documentation +# +# \file +# +# Copyright (c) 2011 - 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 the config.mk file from the current working path, e.g., where the +# user called make. +include config.mk + +# Tool to use to generate documentation from the source code +DOCGEN ?= doxygen + +# Look for source files relative to the top-level source directory +VPATH := $(PRJ_PATH) + +# Output target file +project_type := $(PROJECT_TYPE) + +# Output target file +ifeq ($(project_type),flash) +target := $(TARGET_FLASH) +linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_FLASH) +debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH) +else +target := $(TARGET_SRAM) +linker_script := $(PRJ_PATH)/$(LINKER_SCRIPT_SRAM) +debug_script := $(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM) +endif + +# Output project name (target name minus suffix) +project := $(basename $(target)) + +# Output target file (typically ELF or static library) +ifeq ($(suffix $(target)),.a) +target_type := lib +else +ifeq ($(suffix $(target)),.elf) +target_type := elf +else +$(error "Target type $(target_type) is not supported") +endif +endif + +# Allow override of operating system detection. The user can add OS=Linux or +# OS=Windows on the command line to explicit set the host OS. +# +# This allows to work around broken uname utility on certain systems. +ifdef OS + ifeq ($(strip $(OS)), Linux) + os_type := Linux + endif + ifeq ($(strip $(OS)), Windows) + os_type := windows32_64 + endif +endif + +os_type ?= $(strip $(shell uname)) + +ifeq ($(os_type),windows32) +os := Windows +else +ifeq ($(os_type),windows64) +os := Windows +else +ifeq ($(os_type),windows32_64) +os ?= Windows +else +ifeq ($(os_type),) +os := Windows +else +# Default to Linux style operating system. Both Cygwin and mingw are fully +# compatible (for this Makefile) with Linux. +os := Linux +endif +endif +endif +endif + +# Output documentation directory and configuration file. +docdir := ../doxygen/html +doccfg := ../doxygen/doxyfile.doxygen + +CROSS ?= arm-none-eabi- +AR := $(CROSS)ar +AS := $(CROSS)as +CC := $(CROSS)gcc +CPP := $(CROSS)gcc -E +CXX := $(CROSS)g++ +LD := $(CROSS)g++ +NM := $(CROSS)nm +OBJCOPY := $(CROSS)objcopy +OBJDUMP := $(CROSS)objdump +SIZE := $(CROSS)size +GDB := $(CROSS)gdb + +RM := rm +ifeq ($(os),Windows) +RMDIR := rmdir /S /Q +else +RMDIR := rmdir -p --ignore-fail-on-non-empty +endif + +# On Windows, we need to override the shell to force the use of cmd.exe +ifeq ($(os),Windows) +SHELL := cmd +endif + +# Strings for beautifying output +MSG_CLEAN_FILES = "RM *.o *.d" +MSG_CLEAN_DIRS = "RMDIR $(strip $(clean-dirs))" +MSG_CLEAN_DOC = "RMDIR $(docdir)" +MSG_MKDIR = "MKDIR $(dir $@)" + +MSG_INFO = "INFO " +MSG_PREBUILD = "PREBUILD $(PREBUILD_CMD)" +MSG_POSTBUILD = "POSTBUILD $(POSTBUILD_CMD)" + +MSG_ARCHIVING = "AR $@" +MSG_ASSEMBLING = "AS $@" +MSG_BINARY_IMAGE = "OBJCOPY $@" +MSG_COMPILING = "CC $@" +MSG_COMPILING_CXX = "CXX $@" +MSG_EXTENDED_LISTING = "OBJDUMP $@" +MSG_IHEX_IMAGE = "OBJCOPY $@" +MSG_LINKING = "LN $@" +MSG_PREPROCESSING = "CPP $@" +MSG_SIZE = "SIZE $@" +MSG_SYMBOL_TABLE = "NM $@" + +MSG_GENERATING_DOC = "DOXYGEN $(docdir)" + +# Don't use make's built-in rules and variables +MAKEFLAGS += -rR + +# Don't print 'Entering directory ...' +MAKEFLAGS += --no-print-directory + +# Function for reversing the order of a list +reverse = $(if $(1),$(call reverse,$(wordlist 2,$(words $(1)),$(1)))) $(firstword $(1)) + +# Hide command output by default, but allow the user to override this +# by adding V=1 on the command line. +# +# This is inspired by the Kbuild system used by the Linux kernel. +ifdef V + ifeq ("$(origin V)", "command line") + VERBOSE = $(V) + endif +endif +ifndef VERBOSE + VERBOSE = 0 +endif + +ifeq ($(VERBOSE), 1) + Q = +else + Q = @ +endif + +arflags-gnu-y := $(ARFLAGS) +asflags-gnu-y := $(ASFLAGS) +cflags-gnu-y := $(CFLAGS) +cxxflags-gnu-y := $(CXXFLAGS) +cppflags-gnu-y := $(CPPFLAGS) +cpuflags-gnu-y := +dbgflags-gnu-y := $(DBGFLAGS) +libflags-gnu-y := $(foreach LIB,$(LIBS),-l$(LIB)) +ldflags-gnu-y := $(LDFLAGS) +flashflags-gnu-y := +clean-files := +clean-dirs := + +clean-files += $(wildcard $(target) $(project).map) +clean-files += $(wildcard $(project).hex $(project).bin) +clean-files += $(wildcard $(project).lss $(project).sym) +clean-files += $(wildcard $(build)) + +# Use pipes instead of temporary files for communication between processes +cflags-gnu-y += -pipe +asflags-gnu-y += -pipe +ldflags-gnu-y += -pipe + +# Archiver flags. +arflags-gnu-y += rcs + +# Always enable warnings. And be very careful about implicit +# declarations. +cflags-gnu-y += -Wall -Wstrict-prototypes -Wmissing-prototypes +cflags-gnu-y += -Werror-implicit-function-declaration +cxxflags-gnu-y += -Wall +# IAR doesn't allow arithmetic on void pointers, so warn about that. +cflags-gnu-y += -Wpointer-arith +cxxflags-gnu-y += -Wpointer-arith + +# Preprocessor flags. +cppflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),-I$(INC)) +asflags-gnu-y += $(foreach INC,$(addprefix $(PRJ_PATH)/,$(INC_PATH)),'-Wa,-I$(INC)') + +# CPU specific flags. +cpuflags-gnu-y += -mcpu=$(ARCH) -mthumb -D=__$(PART)__ + +# Dependency file flags. +depflags = -MD -MP -MQ $@ + +# Debug specific flags. +ifdef BUILD_DEBUG_LEVEL +dbgflags-gnu-y += -g$(BUILD_DEBUG_LEVEL) +else +dbgflags-gnu-y += -g3 +endif + +# Optimization specific flags. +ifdef BUILD_OPTIMIZATION +optflags-gnu-y = -O$(BUILD_OPTIMIZATION) +else +optflags-gnu-y = $(OPTIMIZATION) +endif + +# Always preprocess assembler files. +asflags-gnu-y += -x assembler-with-cpp +# Compile C files using the GNU99 standard. +cflags-gnu-y += -std=gnu99 +# Compile C++ files using the GNU++98 standard. +cxxflags-gnu-y += -std=gnu++98 + +# Don't use strict aliasing (very common in embedded applications). +cflags-gnu-y += -fno-strict-aliasing +cxxflags-gnu-y += -fno-strict-aliasing + +# Separate each function and data into its own separate section to allow +# garbage collection of unused sections. +cflags-gnu-y += -ffunction-sections -fdata-sections +cxxflags-gnu-y += -ffunction-sections -fdata-sections + +# Various cflags. +cflags-gnu-y += -Wchar-subscripts -Wcomment -Wformat=2 -Wimplicit-int +cflags-gnu-y += -Wmain -Wparentheses +cflags-gnu-y += -Wsequence-point -Wreturn-type -Wswitch -Wtrigraphs -Wunused +cflags-gnu-y += -Wuninitialized -Wunknown-pragmas -Wfloat-equal -Wundef +cflags-gnu-y += -Wshadow -Wbad-function-cast -Wwrite-strings +cflags-gnu-y += -Wsign-compare -Waggregate-return +cflags-gnu-y += -Wmissing-declarations +cflags-gnu-y += -Wformat -Wmissing-format-attribute -Wno-deprecated-declarations +cflags-gnu-y += -Wpacked -Wredundant-decls -Wnested-externs -Winline -Wlong-long +cflags-gnu-y += -Wunreachable-code +cflags-gnu-y += -Wcast-align +cflags-gnu-y += --param max-inline-insns-single=500 + +# Garbage collect unreferred sections when linking. +ldflags-gnu-y += -Wl,--gc-sections + +# Use the linker script if provided by the project. +ifneq ($(strip $(linker_script)),) +ldflags-gnu-y += -Wl,-T $(linker_script) +endif + +# Output a link map file and a cross reference table +ldflags-gnu-y += -Wl,-Map=$(project).map,--cref + +# Add library search paths relative to the top level directory. +ldflags-gnu-y += $(foreach _LIB_PATH,$(addprefix $(PRJ_PATH)/,$(LIB_PATH)),-L$(_LIB_PATH)) + +a_flags = $(cpuflags-gnu-y) $(depflags) $(cppflags-gnu-y) $(asflags-gnu-y) -D__ASSEMBLY__ +c_flags = $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cflags-gnu-y) +cxx_flags= $(cpuflags-gnu-y) $(dbgflags-gnu-y) $(depflags) $(optflags-gnu-y) $(cppflags-gnu-y) $(cxxflags-gnu-y) +l_flags = -Wl,--entry=Reset_Handler -Wl,--cref $(cpuflags-gnu-y) $(optflags-gnu-y) $(ldflags-gnu-y) +ar_flags = $(arflags-gnu-y) + +# Source files list and part informations must already be included before +# running this makefile + +# If a custom build directory is specified, use it -- force trailing / in directory name. +ifdef BUILD_DIR + build-dir := $(dir $(BUILD_DIR))$(if $(notdir $(BUILD_DIR)),$(notdir $(BUILD_DIR))/) +else + build-dir = +endif + +# Create object files list from source files list. +obj-y := $(addprefix $(build-dir), $(addsuffix .o,$(basename $(CSRCS) $(ASSRCS)))) +# Create dependency files list from source files list. +dep-files := $(wildcard $(foreach f,$(obj-y),$(basename $(f)).d)) + +clean-files += $(wildcard $(obj-y)) +clean-files += $(dep-files) + +clean-dirs += $(call reverse,$(sort $(wildcard $(dir $(obj-y))))) + +# Default target. +.PHONY: all +ifeq ($(project_type),all) +all: + $(MAKE) all PROJECT_TYPE=flash + $(MAKE) all PROJECT_TYPE=sram +else +ifeq ($(target_type),lib) +all: $(target) $(project).lss $(project).sym +else +ifeq ($(target_type),elf) +all: prebuild $(target) $(project).lss $(project).sym $(project).hex $(project).bin postbuild +endif +endif +endif + +prebuild: +ifneq ($(strip $(PREBUILD_CMD)),) + @echo $(MSG_PREBUILD) + $(Q)$(PREBUILD_CMD) +endif + +postbuild: +ifneq ($(strip $(POSTBUILD_CMD)),) + @echo $(MSG_POSTBUILD) + $(Q)$(POSTBUILD_CMD) +endif + +# Clean up the project. +.PHONY: clean +clean: + @$(if $(strip $(clean-files)),echo $(MSG_CLEAN_FILES)) + $(if $(strip $(clean-files)),$(Q)$(RM) $(clean-files),) + @$(if $(strip $(clean-dirs)),echo $(MSG_CLEAN_DIRS)) +# Remove created directories, and make sure we only remove existing +# directories, since recursive rmdir might help us a bit on the way. +ifeq ($(os),Windows) + $(Q)$(if $(strip $(clean-dirs)), \ + $(RMDIR) $(strip $(subst /,\,$(clean-dirs)))) +else + $(Q)$(if $(strip $(clean-dirs)), \ + for directory in $(strip $(clean-dirs)); do \ + if [ -d "$$directory" ]; then \ + $(RMDIR) $$directory; \ + fi \ + done \ + ) +endif + +# Rebuild the project. +.PHONY: rebuild +rebuild: clean all + +# Debug the project in flash. +.PHONY: debug_flash +debug_flash: all + $(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_FLASH)" -ex "reset" -readnow -se $(TARGET_FLASH) + +# Debug the project in sram. +.PHONY: debug_sram +debug_sram: all + $(GDB) -x "$(PRJ_PATH)/$(DEBUG_SCRIPT_SRAM)" -ex "reset" -readnow -se $(TARGET_SRAM) + +.PHONY: objfiles +objfiles: $(obj-y) + +# Create object files from C source files. +$(build-dir)%.o: %.c $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING) + $(Q)$(CC) $(c_flags) -c $< -o $@ + +# Create object files from C++ source files. +$(build-dir)%.o: %.cpp $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_COMPILING_CXX) + $(Q)$(CXX) $(cxx_flags) -c $< -o $@ + +# Preprocess and assemble: create object files from assembler source files. +$(build-dir)%.o: %.S $(MAKEFILE_PATH) config.mk + $(Q)test -d $(dir $@) || echo $(MSG_MKDIR) +ifeq ($(os),Windows) + $(Q)test -d $(patsubst %/,%,$(dir $@)) || mkdir $(subst /,\,$(dir $@)) +else + $(Q)test -d $(dir $@) || mkdir -p $(dir $@) +endif + @echo $(MSG_ASSEMBLING) + $(Q)$(CC) $(a_flags) -c $< -o $@ + +# Include all dependency files to add depedency to all header files in use. +include $(dep-files) + +ifeq ($(target_type),lib) +# Archive object files into an archive +$(target): $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_ARCHIVING) + $(Q)$(AR) $(ar_flags) $@ $(obj-y) + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Bxt $@ +else +ifeq ($(target_type),elf) +# Link the object files into an ELF file. Also make sure the target is rebuilt +# if the common Makefile.sam.in or project config.mk is changed. +$(target): $(linker_script) $(MAKEFILE_PATH) config.mk $(obj-y) + @echo $(MSG_LINKING) + $(Q)$(LD) $(l_flags) $(obj-y) $(libflags-gnu-y) -o $@ + @echo $(MSG_SIZE) + $(Q)$(SIZE) -Ax $@ + $(Q)$(SIZE) -Bx $@ +endif +endif + +# Create extended function listing from target output file. +%.lss: $(target) + @echo $(MSG_EXTENDED_LISTING) + $(Q)$(OBJDUMP) -h -S $< > $@ + +# Create symbol table from target output file. +%.sym: $(target) + @echo $(MSG_SYMBOL_TABLE) + $(Q)$(NM) -n $< > $@ + +# Create Intel HEX image from ELF output file. +%.hex: $(target) + @echo $(MSG_IHEX_IMAGE) + $(Q)$(OBJCOPY) -O ihex $(flashflags-gnu-y) $< $@ + +# Create binary image from ELF output file. +%.bin: $(target) + @echo $(MSG_BINARY_IMAGE) + $(Q)$(OBJCOPY) -O binary $< $@ + +# Provide information about the detected host operating system. +.SECONDARY: info-os +info-os: + @echo $(MSG_INFO)$(os) build host detected + +# Build Doxygen generated documentation. +.PHONY: doc +doc: + @echo $(MSG_GENERATING_DOC) + $(Q)cd $(dir $(doccfg)) && $(DOCGEN) $(notdir $(doccfg)) + +# Clean Doxygen generated documentation. +.PHONY: cleandoc +cleandoc: + @$(if $(wildcard $(docdir)),echo $(MSG_CLEAN_DOC)) + $(Q)$(if $(wildcard $(docdir)),$(RM) --recursive $(docdir)) + +# Rebuild the Doxygen generated documentation. +.PHONY: rebuilddoc +rebuilddoc: cleandoc doc diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/mrepeat.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/mrepeat.h new file mode 100644 index 0000000..4247f2f --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/mrepeat.h @@ -0,0 +1,339 @@ +/** + * \file + * + * \brief Preprocessor macro repeating utils. + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _MREPEAT_H_ +#define _MREPEAT_H_ + +/** + * \defgroup group_sam_utils_mrepeat Preprocessor - Macro Repeat + * + * \ingroup group_sam_utils + * + * \{ + */ + +#include "preprocessor.h" + + +//! Maximal number of repetitions supported by MREPEAT. +#define MREPEAT_LIMIT 256 + +/*! \brief Macro repeat. + * + * This macro represents a horizontal repetition construct. + * + * \param count The number of repetitious calls to macro. Valid values range from 0 to MREPEAT_LIMIT. + * \param macro A binary operation of the form macro(n, data). This macro is expanded by MREPEAT with + * the current repetition number and the auxiliary data argument. + * \param data Auxiliary data passed to macro. + * + * \return macro(0, data) macro(1, data) ... macro(count - 1, data) + */ +#define MREPEAT(count, macro, data) TPASTE2(MREPEAT, count)(macro, data) + +#define MREPEAT0( macro, data) +#define MREPEAT1( macro, data) MREPEAT0( macro, data) macro( 0, data) +#define MREPEAT2( macro, data) MREPEAT1( macro, data) macro( 1, data) +#define MREPEAT3( macro, data) MREPEAT2( macro, data) macro( 2, data) +#define MREPEAT4( macro, data) MREPEAT3( macro, data) macro( 3, data) +#define MREPEAT5( macro, data) MREPEAT4( macro, data) macro( 4, data) +#define MREPEAT6( macro, data) MREPEAT5( macro, data) macro( 5, data) +#define MREPEAT7( macro, data) MREPEAT6( macro, data) macro( 6, data) +#define MREPEAT8( macro, data) MREPEAT7( macro, data) macro( 7, data) +#define MREPEAT9( macro, data) MREPEAT8( macro, data) macro( 8, data) +#define MREPEAT10( macro, data) MREPEAT9( macro, data) macro( 9, data) +#define MREPEAT11( macro, data) MREPEAT10( macro, data) macro( 10, data) +#define MREPEAT12( macro, data) MREPEAT11( macro, data) macro( 11, data) +#define MREPEAT13( macro, data) MREPEAT12( macro, data) macro( 12, data) +#define MREPEAT14( macro, data) MREPEAT13( macro, data) macro( 13, data) +#define MREPEAT15( macro, data) MREPEAT14( macro, data) macro( 14, data) +#define MREPEAT16( macro, data) MREPEAT15( macro, data) macro( 15, data) +#define MREPEAT17( macro, data) MREPEAT16( macro, data) macro( 16, data) +#define MREPEAT18( macro, data) MREPEAT17( macro, data) macro( 17, data) +#define MREPEAT19( macro, data) MREPEAT18( macro, data) macro( 18, data) +#define MREPEAT20( macro, data) MREPEAT19( macro, data) macro( 19, data) +#define MREPEAT21( macro, data) MREPEAT20( macro, data) macro( 20, data) +#define MREPEAT22( macro, data) MREPEAT21( macro, data) macro( 21, data) +#define MREPEAT23( macro, data) MREPEAT22( macro, data) macro( 22, data) +#define MREPEAT24( macro, data) MREPEAT23( macro, data) macro( 23, data) +#define MREPEAT25( macro, data) MREPEAT24( macro, data) macro( 24, data) +#define MREPEAT26( macro, data) MREPEAT25( macro, data) macro( 25, data) +#define MREPEAT27( macro, data) MREPEAT26( macro, data) macro( 26, data) +#define MREPEAT28( macro, data) MREPEAT27( macro, data) macro( 27, data) +#define MREPEAT29( macro, data) MREPEAT28( macro, data) macro( 28, data) +#define MREPEAT30( macro, data) MREPEAT29( macro, data) macro( 29, data) +#define MREPEAT31( macro, data) MREPEAT30( macro, data) macro( 30, data) +#define MREPEAT32( macro, data) MREPEAT31( macro, data) macro( 31, data) +#define MREPEAT33( macro, data) MREPEAT32( macro, data) macro( 32, data) +#define MREPEAT34( macro, data) MREPEAT33( macro, data) macro( 33, data) +#define MREPEAT35( macro, data) MREPEAT34( macro, data) macro( 34, data) +#define MREPEAT36( macro, data) MREPEAT35( macro, data) macro( 35, data) +#define MREPEAT37( macro, data) MREPEAT36( macro, data) macro( 36, data) +#define MREPEAT38( macro, data) MREPEAT37( macro, data) macro( 37, data) +#define MREPEAT39( macro, data) MREPEAT38( macro, data) macro( 38, data) +#define MREPEAT40( macro, data) MREPEAT39( macro, data) macro( 39, data) +#define MREPEAT41( macro, data) MREPEAT40( macro, data) macro( 40, data) +#define MREPEAT42( macro, data) MREPEAT41( macro, data) macro( 41, data) +#define MREPEAT43( macro, data) MREPEAT42( macro, data) macro( 42, data) +#define MREPEAT44( macro, data) MREPEAT43( macro, data) macro( 43, data) +#define MREPEAT45( macro, data) MREPEAT44( macro, data) macro( 44, data) +#define MREPEAT46( macro, data) MREPEAT45( macro, data) macro( 45, data) +#define MREPEAT47( macro, data) MREPEAT46( macro, data) macro( 46, data) +#define MREPEAT48( macro, data) MREPEAT47( macro, data) macro( 47, data) +#define MREPEAT49( macro, data) MREPEAT48( macro, data) macro( 48, data) +#define MREPEAT50( macro, data) MREPEAT49( macro, data) macro( 49, data) +#define MREPEAT51( macro, data) MREPEAT50( macro, data) macro( 50, data) +#define MREPEAT52( macro, data) MREPEAT51( macro, data) macro( 51, data) +#define MREPEAT53( macro, data) MREPEAT52( macro, data) macro( 52, data) +#define MREPEAT54( macro, data) MREPEAT53( macro, data) macro( 53, data) +#define MREPEAT55( macro, data) MREPEAT54( macro, data) macro( 54, data) +#define MREPEAT56( macro, data) MREPEAT55( macro, data) macro( 55, data) +#define MREPEAT57( macro, data) MREPEAT56( macro, data) macro( 56, data) +#define MREPEAT58( macro, data) MREPEAT57( macro, data) macro( 57, data) +#define MREPEAT59( macro, data) MREPEAT58( macro, data) macro( 58, data) +#define MREPEAT60( macro, data) MREPEAT59( macro, data) macro( 59, data) +#define MREPEAT61( macro, data) MREPEAT60( macro, data) macro( 60, data) +#define MREPEAT62( macro, data) MREPEAT61( macro, data) macro( 61, data) +#define MREPEAT63( macro, data) MREPEAT62( macro, data) macro( 62, data) +#define MREPEAT64( macro, data) MREPEAT63( macro, data) macro( 63, data) +#define MREPEAT65( macro, data) MREPEAT64( macro, data) macro( 64, data) +#define MREPEAT66( macro, data) MREPEAT65( macro, data) macro( 65, data) +#define MREPEAT67( macro, data) MREPEAT66( macro, data) macro( 66, data) +#define MREPEAT68( macro, data) MREPEAT67( macro, data) macro( 67, data) +#define MREPEAT69( macro, data) MREPEAT68( macro, data) macro( 68, data) +#define MREPEAT70( macro, data) MREPEAT69( macro, data) macro( 69, data) +#define MREPEAT71( macro, data) MREPEAT70( macro, data) macro( 70, data) +#define MREPEAT72( macro, data) MREPEAT71( macro, data) macro( 71, data) +#define MREPEAT73( macro, data) MREPEAT72( macro, data) macro( 72, data) +#define MREPEAT74( macro, data) MREPEAT73( macro, data) macro( 73, data) +#define MREPEAT75( macro, data) MREPEAT74( macro, data) macro( 74, data) +#define MREPEAT76( macro, data) MREPEAT75( macro, data) macro( 75, data) +#define MREPEAT77( macro, data) MREPEAT76( macro, data) macro( 76, data) +#define MREPEAT78( macro, data) MREPEAT77( macro, data) macro( 77, data) +#define MREPEAT79( macro, data) MREPEAT78( macro, data) macro( 78, data) +#define MREPEAT80( macro, data) MREPEAT79( macro, data) macro( 79, data) +#define MREPEAT81( macro, data) MREPEAT80( macro, data) macro( 80, data) +#define MREPEAT82( macro, data) MREPEAT81( macro, data) macro( 81, data) +#define MREPEAT83( macro, data) MREPEAT82( macro, data) macro( 82, data) +#define MREPEAT84( macro, data) MREPEAT83( macro, data) macro( 83, data) +#define MREPEAT85( macro, data) MREPEAT84( macro, data) macro( 84, data) +#define MREPEAT86( macro, data) MREPEAT85( macro, data) macro( 85, data) +#define MREPEAT87( macro, data) MREPEAT86( macro, data) macro( 86, data) +#define MREPEAT88( macro, data) MREPEAT87( macro, data) macro( 87, data) +#define MREPEAT89( macro, data) MREPEAT88( macro, data) macro( 88, data) +#define MREPEAT90( macro, data) MREPEAT89( macro, data) macro( 89, data) +#define MREPEAT91( macro, data) MREPEAT90( macro, data) macro( 90, data) +#define MREPEAT92( macro, data) MREPEAT91( macro, data) macro( 91, data) +#define MREPEAT93( macro, data) MREPEAT92( macro, data) macro( 92, data) +#define MREPEAT94( macro, data) MREPEAT93( macro, data) macro( 93, data) +#define MREPEAT95( macro, data) MREPEAT94( macro, data) macro( 94, data) +#define MREPEAT96( macro, data) MREPEAT95( macro, data) macro( 95, data) +#define MREPEAT97( macro, data) MREPEAT96( macro, data) macro( 96, data) +#define MREPEAT98( macro, data) MREPEAT97( macro, data) macro( 97, data) +#define MREPEAT99( macro, data) MREPEAT98( macro, data) macro( 98, data) +#define MREPEAT100(macro, data) MREPEAT99( macro, data) macro( 99, data) +#define MREPEAT101(macro, data) MREPEAT100(macro, data) macro(100, data) +#define MREPEAT102(macro, data) MREPEAT101(macro, data) macro(101, data) +#define MREPEAT103(macro, data) MREPEAT102(macro, data) macro(102, data) +#define MREPEAT104(macro, data) MREPEAT103(macro, data) macro(103, data) +#define MREPEAT105(macro, data) MREPEAT104(macro, data) macro(104, data) +#define MREPEAT106(macro, data) MREPEAT105(macro, data) macro(105, data) +#define MREPEAT107(macro, data) MREPEAT106(macro, data) macro(106, data) +#define MREPEAT108(macro, data) MREPEAT107(macro, data) macro(107, data) +#define MREPEAT109(macro, data) MREPEAT108(macro, data) macro(108, data) +#define MREPEAT110(macro, data) MREPEAT109(macro, data) macro(109, data) +#define MREPEAT111(macro, data) MREPEAT110(macro, data) macro(110, data) +#define MREPEAT112(macro, data) MREPEAT111(macro, data) macro(111, data) +#define MREPEAT113(macro, data) MREPEAT112(macro, data) macro(112, data) +#define MREPEAT114(macro, data) MREPEAT113(macro, data) macro(113, data) +#define MREPEAT115(macro, data) MREPEAT114(macro, data) macro(114, data) +#define MREPEAT116(macro, data) MREPEAT115(macro, data) macro(115, data) +#define MREPEAT117(macro, data) MREPEAT116(macro, data) macro(116, data) +#define MREPEAT118(macro, data) MREPEAT117(macro, data) macro(117, data) +#define MREPEAT119(macro, data) MREPEAT118(macro, data) macro(118, data) +#define MREPEAT120(macro, data) MREPEAT119(macro, data) macro(119, data) +#define MREPEAT121(macro, data) MREPEAT120(macro, data) macro(120, data) +#define MREPEAT122(macro, data) MREPEAT121(macro, data) macro(121, data) +#define MREPEAT123(macro, data) MREPEAT122(macro, data) macro(122, data) +#define MREPEAT124(macro, data) MREPEAT123(macro, data) macro(123, data) +#define MREPEAT125(macro, data) MREPEAT124(macro, data) macro(124, data) +#define MREPEAT126(macro, data) MREPEAT125(macro, data) macro(125, data) +#define MREPEAT127(macro, data) MREPEAT126(macro, data) macro(126, data) +#define MREPEAT128(macro, data) MREPEAT127(macro, data) macro(127, data) +#define MREPEAT129(macro, data) MREPEAT128(macro, data) macro(128, data) +#define MREPEAT130(macro, data) MREPEAT129(macro, data) macro(129, data) +#define MREPEAT131(macro, data) MREPEAT130(macro, data) macro(130, data) +#define MREPEAT132(macro, data) MREPEAT131(macro, data) macro(131, data) +#define MREPEAT133(macro, data) MREPEAT132(macro, data) macro(132, data) +#define MREPEAT134(macro, data) MREPEAT133(macro, data) macro(133, data) +#define MREPEAT135(macro, data) MREPEAT134(macro, data) macro(134, data) +#define MREPEAT136(macro, data) MREPEAT135(macro, data) macro(135, data) +#define MREPEAT137(macro, data) MREPEAT136(macro, data) macro(136, data) +#define MREPEAT138(macro, data) MREPEAT137(macro, data) macro(137, data) +#define MREPEAT139(macro, data) MREPEAT138(macro, data) macro(138, data) +#define MREPEAT140(macro, data) MREPEAT139(macro, data) macro(139, data) +#define MREPEAT141(macro, data) MREPEAT140(macro, data) macro(140, data) +#define MREPEAT142(macro, data) MREPEAT141(macro, data) macro(141, data) +#define MREPEAT143(macro, data) MREPEAT142(macro, data) macro(142, data) +#define MREPEAT144(macro, data) MREPEAT143(macro, data) macro(143, data) +#define MREPEAT145(macro, data) MREPEAT144(macro, data) macro(144, data) +#define MREPEAT146(macro, data) MREPEAT145(macro, data) macro(145, data) +#define MREPEAT147(macro, data) MREPEAT146(macro, data) macro(146, data) +#define MREPEAT148(macro, data) MREPEAT147(macro, data) macro(147, data) +#define MREPEAT149(macro, data) MREPEAT148(macro, data) macro(148, data) +#define MREPEAT150(macro, data) MREPEAT149(macro, data) macro(149, data) +#define MREPEAT151(macro, data) MREPEAT150(macro, data) macro(150, data) +#define MREPEAT152(macro, data) MREPEAT151(macro, data) macro(151, data) +#define MREPEAT153(macro, data) MREPEAT152(macro, data) macro(152, data) +#define MREPEAT154(macro, data) MREPEAT153(macro, data) macro(153, data) +#define MREPEAT155(macro, data) MREPEAT154(macro, data) macro(154, data) +#define MREPEAT156(macro, data) MREPEAT155(macro, data) macro(155, data) +#define MREPEAT157(macro, data) MREPEAT156(macro, data) macro(156, data) +#define MREPEAT158(macro, data) MREPEAT157(macro, data) macro(157, data) +#define MREPEAT159(macro, data) MREPEAT158(macro, data) macro(158, data) +#define MREPEAT160(macro, data) MREPEAT159(macro, data) macro(159, data) +#define MREPEAT161(macro, data) MREPEAT160(macro, data) macro(160, data) +#define MREPEAT162(macro, data) MREPEAT161(macro, data) macro(161, data) +#define MREPEAT163(macro, data) MREPEAT162(macro, data) macro(162, data) +#define MREPEAT164(macro, data) MREPEAT163(macro, data) macro(163, data) +#define MREPEAT165(macro, data) MREPEAT164(macro, data) macro(164, data) +#define MREPEAT166(macro, data) MREPEAT165(macro, data) macro(165, data) +#define MREPEAT167(macro, data) MREPEAT166(macro, data) macro(166, data) +#define MREPEAT168(macro, data) MREPEAT167(macro, data) macro(167, data) +#define MREPEAT169(macro, data) MREPEAT168(macro, data) macro(168, data) +#define MREPEAT170(macro, data) MREPEAT169(macro, data) macro(169, data) +#define MREPEAT171(macro, data) MREPEAT170(macro, data) macro(170, data) +#define MREPEAT172(macro, data) MREPEAT171(macro, data) macro(171, data) +#define MREPEAT173(macro, data) MREPEAT172(macro, data) macro(172, data) +#define MREPEAT174(macro, data) MREPEAT173(macro, data) macro(173, data) +#define MREPEAT175(macro, data) MREPEAT174(macro, data) macro(174, data) +#define MREPEAT176(macro, data) MREPEAT175(macro, data) macro(175, data) +#define MREPEAT177(macro, data) MREPEAT176(macro, data) macro(176, data) +#define MREPEAT178(macro, data) MREPEAT177(macro, data) macro(177, data) +#define MREPEAT179(macro, data) MREPEAT178(macro, data) macro(178, data) +#define MREPEAT180(macro, data) MREPEAT179(macro, data) macro(179, data) +#define MREPEAT181(macro, data) MREPEAT180(macro, data) macro(180, data) +#define MREPEAT182(macro, data) MREPEAT181(macro, data) macro(181, data) +#define MREPEAT183(macro, data) MREPEAT182(macro, data) macro(182, data) +#define MREPEAT184(macro, data) MREPEAT183(macro, data) macro(183, data) +#define MREPEAT185(macro, data) MREPEAT184(macro, data) macro(184, data) +#define MREPEAT186(macro, data) MREPEAT185(macro, data) macro(185, data) +#define MREPEAT187(macro, data) MREPEAT186(macro, data) macro(186, data) +#define MREPEAT188(macro, data) MREPEAT187(macro, data) macro(187, data) +#define MREPEAT189(macro, data) MREPEAT188(macro, data) macro(188, data) +#define MREPEAT190(macro, data) MREPEAT189(macro, data) macro(189, data) +#define MREPEAT191(macro, data) MREPEAT190(macro, data) macro(190, data) +#define MREPEAT192(macro, data) MREPEAT191(macro, data) macro(191, data) +#define MREPEAT193(macro, data) MREPEAT192(macro, data) macro(192, data) +#define MREPEAT194(macro, data) MREPEAT193(macro, data) macro(193, data) +#define MREPEAT195(macro, data) MREPEAT194(macro, data) macro(194, data) +#define MREPEAT196(macro, data) MREPEAT195(macro, data) macro(195, data) +#define MREPEAT197(macro, data) MREPEAT196(macro, data) macro(196, data) +#define MREPEAT198(macro, data) MREPEAT197(macro, data) macro(197, data) +#define MREPEAT199(macro, data) MREPEAT198(macro, data) macro(198, data) +#define MREPEAT200(macro, data) MREPEAT199(macro, data) macro(199, data) +#define MREPEAT201(macro, data) MREPEAT200(macro, data) macro(200, data) +#define MREPEAT202(macro, data) MREPEAT201(macro, data) macro(201, data) +#define MREPEAT203(macro, data) MREPEAT202(macro, data) macro(202, data) +#define MREPEAT204(macro, data) MREPEAT203(macro, data) macro(203, data) +#define MREPEAT205(macro, data) MREPEAT204(macro, data) macro(204, data) +#define MREPEAT206(macro, data) MREPEAT205(macro, data) macro(205, data) +#define MREPEAT207(macro, data) MREPEAT206(macro, data) macro(206, data) +#define MREPEAT208(macro, data) MREPEAT207(macro, data) macro(207, data) +#define MREPEAT209(macro, data) MREPEAT208(macro, data) macro(208, data) +#define MREPEAT210(macro, data) MREPEAT209(macro, data) macro(209, data) +#define MREPEAT211(macro, data) MREPEAT210(macro, data) macro(210, data) +#define MREPEAT212(macro, data) MREPEAT211(macro, data) macro(211, data) +#define MREPEAT213(macro, data) MREPEAT212(macro, data) macro(212, data) +#define MREPEAT214(macro, data) MREPEAT213(macro, data) macro(213, data) +#define MREPEAT215(macro, data) MREPEAT214(macro, data) macro(214, data) +#define MREPEAT216(macro, data) MREPEAT215(macro, data) macro(215, data) +#define MREPEAT217(macro, data) MREPEAT216(macro, data) macro(216, data) +#define MREPEAT218(macro, data) MREPEAT217(macro, data) macro(217, data) +#define MREPEAT219(macro, data) MREPEAT218(macro, data) macro(218, data) +#define MREPEAT220(macro, data) MREPEAT219(macro, data) macro(219, data) +#define MREPEAT221(macro, data) MREPEAT220(macro, data) macro(220, data) +#define MREPEAT222(macro, data) MREPEAT221(macro, data) macro(221, data) +#define MREPEAT223(macro, data) MREPEAT222(macro, data) macro(222, data) +#define MREPEAT224(macro, data) MREPEAT223(macro, data) macro(223, data) +#define MREPEAT225(macro, data) MREPEAT224(macro, data) macro(224, data) +#define MREPEAT226(macro, data) MREPEAT225(macro, data) macro(225, data) +#define MREPEAT227(macro, data) MREPEAT226(macro, data) macro(226, data) +#define MREPEAT228(macro, data) MREPEAT227(macro, data) macro(227, data) +#define MREPEAT229(macro, data) MREPEAT228(macro, data) macro(228, data) +#define MREPEAT230(macro, data) MREPEAT229(macro, data) macro(229, data) +#define MREPEAT231(macro, data) MREPEAT230(macro, data) macro(230, data) +#define MREPEAT232(macro, data) MREPEAT231(macro, data) macro(231, data) +#define MREPEAT233(macro, data) MREPEAT232(macro, data) macro(232, data) +#define MREPEAT234(macro, data) MREPEAT233(macro, data) macro(233, data) +#define MREPEAT235(macro, data) MREPEAT234(macro, data) macro(234, data) +#define MREPEAT236(macro, data) MREPEAT235(macro, data) macro(235, data) +#define MREPEAT237(macro, data) MREPEAT236(macro, data) macro(236, data) +#define MREPEAT238(macro, data) MREPEAT237(macro, data) macro(237, data) +#define MREPEAT239(macro, data) MREPEAT238(macro, data) macro(238, data) +#define MREPEAT240(macro, data) MREPEAT239(macro, data) macro(239, data) +#define MREPEAT241(macro, data) MREPEAT240(macro, data) macro(240, data) +#define MREPEAT242(macro, data) MREPEAT241(macro, data) macro(241, data) +#define MREPEAT243(macro, data) MREPEAT242(macro, data) macro(242, data) +#define MREPEAT244(macro, data) MREPEAT243(macro, data) macro(243, data) +#define MREPEAT245(macro, data) MREPEAT244(macro, data) macro(244, data) +#define MREPEAT246(macro, data) MREPEAT245(macro, data) macro(245, data) +#define MREPEAT247(macro, data) MREPEAT246(macro, data) macro(246, data) +#define MREPEAT248(macro, data) MREPEAT247(macro, data) macro(247, data) +#define MREPEAT249(macro, data) MREPEAT248(macro, data) macro(248, data) +#define MREPEAT250(macro, data) MREPEAT249(macro, data) macro(249, data) +#define MREPEAT251(macro, data) MREPEAT250(macro, data) macro(250, data) +#define MREPEAT252(macro, data) MREPEAT251(macro, data) macro(251, data) +#define MREPEAT253(macro, data) MREPEAT252(macro, data) macro(252, data) +#define MREPEAT254(macro, data) MREPEAT253(macro, data) macro(253, data) +#define MREPEAT255(macro, data) MREPEAT254(macro, data) macro(254, data) +#define MREPEAT256(macro, data) MREPEAT255(macro, data) macro(255, data) + +/** + * \} + */ + +#endif // _MREPEAT_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/preprocessor.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/preprocessor.h new file mode 100644 index 0000000..b0f796f --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/preprocessor.h @@ -0,0 +1,55 @@ +/** + * \file + * + * \brief Preprocessor utils. + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _PREPROCESSOR_H_ +#define _PREPROCESSOR_H_ + +#include "tpaste.h" +#include "stringz.h" +#include "mrepeat.h" + + +#endif // _PREPROCESSOR_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/stringz.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/stringz.h new file mode 100644 index 0000000..bd2ba46 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/stringz.h @@ -0,0 +1,85 @@ +/** + * \file + * + * \brief Preprocessor stringizing utils. + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _STRINGZ_H_ +#define _STRINGZ_H_ + +/** + * \defgroup group_sam_utils_stringz Preprocessor - Stringize + * + * \ingroup group_sam_utils + * + * \{ + */ + +/*! \brief Stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * May be used only within macros with the token passed as an argument if the token is \#defined. + * + * For example, writing STRINGZ(PIN) within a macro \#defined by PIN_NAME(PIN) + * and invoked as PIN_NAME(PIN0) with PIN0 \#defined as A0 is equivalent to + * writing "A0". + */ +#define STRINGZ(x) #x + +/*! \brief Absolute stringize. + * + * Stringize a preprocessing token, this token being allowed to be \#defined. + * + * No restriction of use if the token is \#defined. + * + * For example, writing ASTRINGZ(PIN0) anywhere with PIN0 \#defined as A0 is + * equivalent to writing "A0". + */ +#define ASTRINGZ(x) STRINGZ(x) + +/** + * \} + */ + +#endif // _STRINGZ_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/tpaste.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/tpaste.h new file mode 100644 index 0000000..a061ffd --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/preprocessor/tpaste.h @@ -0,0 +1,105 @@ +/** + * \file + * + * \brief Preprocessor token pasting utils. + * + * Copyright (c) 2010-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef _TPASTE_H_ +#define _TPASTE_H_ + +/** + * \defgroup group_sam_utils_tpaste Preprocessor - Token Paste + * + * \ingroup group_sam_utils + * + * \{ + */ + +/*! \name Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * May be used only within macros with the tokens passed as arguments if the tokens are \#defined. + * + * For example, writing TPASTE2(U, WIDTH) within a macro \#defined by + * UTYPE(WIDTH) and invoked as UTYPE(UL_WIDTH) with UL_WIDTH \#defined as 32 is + * equivalent to writing U32. + */ +//! @{ +#define TPASTE2( a, b) a##b +#define TPASTE3( a, b, c) a##b##c +#define TPASTE4( a, b, c, d) a##b##c##d +#define TPASTE5( a, b, c, d, e) a##b##c##d##e +#define TPASTE6( a, b, c, d, e, f) a##b##c##d##e##f +#define TPASTE7( a, b, c, d, e, f, g) a##b##c##d##e##f##g +#define TPASTE8( a, b, c, d, e, f, g, h) a##b##c##d##e##f##g##h +#define TPASTE9( a, b, c, d, e, f, g, h, i) a##b##c##d##e##f##g##h##i +#define TPASTE10(a, b, c, d, e, f, g, h, i, j) a##b##c##d##e##f##g##h##i##j +//! @} + +/*! \name Absolute Token Paste + * + * Paste N preprocessing tokens together, these tokens being allowed to be \#defined. + * + * No restriction of use if the tokens are \#defined. + * + * For example, writing ATPASTE2(U, UL_WIDTH) anywhere with UL_WIDTH \#defined + * as 32 is equivalent to writing U32. + */ +//! @{ +#define ATPASTE2( a, b) TPASTE2( a, b) +#define ATPASTE3( a, b, c) TPASTE3( a, b, c) +#define ATPASTE4( a, b, c, d) TPASTE4( a, b, c, d) +#define ATPASTE5( a, b, c, d, e) TPASTE5( a, b, c, d, e) +#define ATPASTE6( a, b, c, d, e, f) TPASTE6( a, b, c, d, e, f) +#define ATPASTE7( a, b, c, d, e, f, g) TPASTE7( a, b, c, d, e, f, g) +#define ATPASTE8( a, b, c, d, e, f, g, h) TPASTE8( a, b, c, d, e, f, g, h) +#define ATPASTE9( a, b, c, d, e, f, g, h, i) TPASTE9( a, b, c, d, e, f, g, h, i) +#define ATPASTE10(a, b, c, d, e, f, g, h, i, j) TPASTE10(a, b, c, d, e, f, g, h, i, j) +//! @} + +/** + * \} + */ + +#endif // _TPASTE_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/status_codes.h b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/status_codes.h new file mode 100644 index 0000000..8cfc7a6 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/status_codes.h @@ -0,0 +1,113 @@ +/** + * \file + * + * \brief Status code definitions. + * + * This file defines various status codes returned by functions, + * indicating success or failure as well as what kind of failure. + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef STATUS_CODES_H_INCLUDED +#define STATUS_CODES_H_INCLUDED + +/* Note: this is a local workaround to avoid a pre-processor clash due to the + * lwIP macro ERR_TIMEOUT. */ +#if defined(__LWIP_ERR_H__) && defined(ERR_TIMEOUT) +#if (ERR_TIMEOUT != -3) + +/* Internal check to make sure that the later restore of lwIP's ERR_TIMEOUT + * macro is set to the correct value. Note that it is highly improbable that + * this value ever changes in lwIP. */ +#error ASF developers: check lwip err.h new value for ERR_TIMEOUT +#endif +#undef ERR_TIMEOUT +#endif + +/** + * Status code that may be returned by shell commands and protocol + * implementations. + * + * \note Any change to these status codes and the corresponding + * message strings is strictly forbidden. New codes can be added, + * however, but make sure that any message string tables are updated + * at the same time. + */ +enum status_code { + STATUS_OK = 0, //!< Success + STATUS_ERR_BUSY = 0x19, + STATUS_ERR_DENIED = 0x1C, + STATUS_ERR_TIMEOUT = 0x12, + ERR_IO_ERROR = -1, //!< I/O error + ERR_FLUSHED = -2, //!< Request flushed from queue + ERR_TIMEOUT = -3, //!< Operation timed out + ERR_BAD_DATA = -4, //!< Data integrity check failed + ERR_PROTOCOL = -5, //!< Protocol error + ERR_UNSUPPORTED_DEV = -6, //!< Unsupported device + ERR_NO_MEMORY = -7, //!< Insufficient memory + ERR_INVALID_ARG = -8, //!< Invalid argument + ERR_BAD_ADDRESS = -9, //!< Bad address + ERR_BUSY = -10, //!< Resource is busy + ERR_BAD_FORMAT = -11, //!< Data format not recognized + ERR_NO_TIMER = -12, //!< No timer available + ERR_TIMER_ALREADY_RUNNING = -13, //!< Timer already running + ERR_TIMER_NOT_RUNNING = -14, //!< Timer not running + ERR_ABORTED = -15, //!< Operation aborted by user + /** + * \brief Operation in progress + * + * This status code is for driver-internal use when an operation + * is currently being performed. + * + * \note Drivers should never return this status code to any + * callers. It is strictly for internal use. + */ + OPERATION_IN_PROGRESS = -128, +}; + +typedef enum status_code status_code_t; + +#if defined(__LWIP_ERR_H__) +#define ERR_TIMEOUT -3 +#endif + +#endif /* STATUS_CODES_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/syscalls/gcc/syscalls.c b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/syscalls/gcc/syscalls.c new file mode 100644 index 0000000..d807d98 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/sam/utils/syscalls/gcc/syscalls.c @@ -0,0 +1,145 @@ +/** + * \file + * + * \brief Syscalls for SAM (GCC). + * + * Copyright (c) 2011-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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include +#include +#include +#include + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +extern "C" { +#endif +/**INDENT-ON**/ +/// @endcond + +#undef errno +extern int errno; +extern int _end; +extern int __ram_end__; + +extern caddr_t _sbrk(int incr); +extern int link(char *old, char *new); +extern int _close(int file); +extern int _fstat(int file, struct stat *st); +extern int _isatty(int file); +extern int _lseek(int file, int ptr, int dir); +extern void _exit(int status); +extern void _kill(int pid, int sig); +extern int _getpid(void); + +extern caddr_t _sbrk(int incr) +{ + static unsigned char *heap = NULL; + unsigned char *prev_heap; + int ramend = (int)&__ram_end__; + + if (heap == NULL) { + heap = (unsigned char *)&_end; + } + prev_heap = heap; + + if (((int)prev_heap + incr) > ramend) { + return (caddr_t) -1; + } + + heap += incr; + + return (caddr_t) prev_heap; +} + +extern int link(char *old, char *new) +{ + return -1; +} + +extern int _close(int file) +{ + return -1; +} + +extern int _fstat(int file, struct stat *st) +{ + st->st_mode = S_IFCHR; + + return 0; +} + +extern int _isatty(int file) +{ + return 1; +} + +extern int _lseek(int file, int ptr, int dir) +{ + return 0; +} + +extern void _exit(int status) +{ + printf("Exiting with status %d.\n", status); + + for (;;); +} + +extern void _kill(int pid, int sig) +{ + return; +} + +extern int _getpid(void) +{ + return -1; +} + +/// @cond 0 +/**INDENT-OFF**/ +#ifdef __cplusplus +} +#endif +/**INDENT-ON**/ +/// @endcond diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/ATMEL-disclaimer.txt b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/ATMEL-disclaimer.txt new file mode 100644 index 0000000..92a70e9 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/ATMEL-disclaimer.txt @@ -0,0 +1,6 @@ +/* + * Only the CMSIS required parts for ASF are included here, go to the below + * address for the full package: + * http://www.arm.com/products/processors/cortex-m/cortex-microcontroller-software-interface-standard.php + * + */ diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/CMSIS END USER LICENCE AGREEMENT.pdf b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/CMSIS END USER LICENCE AGREEMENT.pdf new file mode 100644 index 0000000000000000000000000000000000000000..c8feab483c7aee07b235b93666803151e052e8c7 GIT binary patch literal 46999 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 QQc9AHn2Sr@P=oA$0ObL?h5!Hn literal 0 HcmV?d00001 diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/arm_math.h b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/arm_math.h new file mode 100644 index 0000000..93dc03c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/arm_math.h @@ -0,0 +1,7062 @@ +/* ---------------------------------------------------------------------- + * 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 + */ + /** + * Support and FAQ: visit Atmel Support + */ +#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/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4.h b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4.h new file mode 100644 index 0000000..cf4e910 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4.h @@ -0,0 +1,1692 @@ +/**************************************************************************//** + * @file core_cm4.h + * @brief CMSIS Cortex-M4 Core Peripheral Access Layer Header File + * @version V3.00 + * @date 03. 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. + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_H_GENERIC +#define __CORE_CM4_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_M4 + @{ + */ + +/* CMSIS CM4 definitions */ +#define __CM4_CMSIS_VERSION_MAIN (0x03) /*!< [31:16] CMSIS HAL main version */ +#define __CM4_CMSIS_VERSION_SUB (0x00) /*!< [15:0] CMSIS HAL sub version */ +#define __CM4_CMSIS_VERSION ((__CM4_CMSIS_VERSION_MAIN << 16) | \ + __CM4_CMSIS_VERSION_SUB ) /*!< CMSIS HAL version number */ + +#define __CORTEX_M (0x04) /*!< 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 ( __TMS470__ ) + #define __ASM __asm /*!< asm keyword for TI CCS Compiler */ + #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. For this, __FPU_PRESENT has to be checked prior to making use of FPU specific registers and functions. +*/ +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1 + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0 + #endif + #else + #define __FPU_USED 0 + #endif + +#elif defined ( __TASKING__ ) + /* add preprocessor checks to define __FPU_USED */ + #define __FPU_USED 0 +#endif + +#include /* standard types definitions */ +#include /* Core Instruction Access */ +#include /* Core Function Access */ +#include /* Compiler specific SIMD Intrinsics */ + +#endif /* __CORE_CM4_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM4_H_DEPENDANT +#define __CORE_CM4_H_DEPENDANT + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM4_REV + #define __CM4_REV 0x0000 + #warning "__CM4_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0 + #warning "__FPU_PRESENT 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 __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 4 + #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_M4 */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core Debug Register + - Core MPU Register + - Core FPU 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[8]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[24]; + __IO uint32_t ICER[8]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[24]; + __IO uint32_t ISPR[8]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[24]; + __IO uint32_t ICPR[8]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[24]; + __IO uint32_t IABR[8]; /*!< Offset: 0x200 (R/W) Interrupt Active bit Register */ + uint32_t RESERVED4[56]; + __IO uint8_t IP[240]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register (8Bit wide) */ + uint32_t RESERVED5[644]; + __O uint32_t STIR; /*!< Offset: 0xE00 ( /W) Software Trigger Interrupt Register */ +} NVIC_Type; + +/* Software Triggered Interrupt Register Definitions */ +#define NVIC_STIR_INTID_Pos 0 /*!< STIR: INTLINESNUM Position */ +#define NVIC_STIR_INTID_Msk (0x1FFUL << NVIC_STIR_INTID_Pos) /*!< STIR: INTLINESNUM Mask */ + +/*@} 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 */ + __IO uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ + __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 */ + __IO uint8_t SHP[12]; /*!< Offset: 0x018 (R/W) System Handlers Priority Registers (4-7, 8-11, 12-15) */ + __IO uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ + __IO uint32_t CFSR; /*!< Offset: 0x028 (R/W) Configurable Fault Status Register */ + __IO uint32_t HFSR; /*!< Offset: 0x02C (R/W) HardFault Status Register */ + __IO uint32_t DFSR; /*!< Offset: 0x030 (R/W) Debug Fault Status Register */ + __IO uint32_t MMFAR; /*!< Offset: 0x034 (R/W) MemManage Fault Address Register */ + __IO uint32_t BFAR; /*!< Offset: 0x038 (R/W) BusFault Address Register */ + __IO uint32_t AFSR; /*!< Offset: 0x03C (R/W) Auxiliary Fault Status Register */ + __I uint32_t PFR[2]; /*!< Offset: 0x040 (R/ ) Processor Feature Register */ + __I uint32_t DFR; /*!< Offset: 0x048 (R/ ) Debug Feature Register */ + __I uint32_t ADR; /*!< Offset: 0x04C (R/ ) Auxiliary Feature Register */ + __I uint32_t MMFR[4]; /*!< Offset: 0x050 (R/ ) Memory Model Feature Register */ + __I uint32_t ISAR[5]; /*!< Offset: 0x060 (R/ ) Instruction Set Attributes Register */ + uint32_t RESERVED0[5]; + __IO uint32_t CPACR; /*!< Offset: 0x088 (R/W) Coprocessor Access Control 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_RETTOBASE_Pos 11 /*!< SCB ICSR: RETTOBASE Position */ +#define SCB_ICSR_RETTOBASE_Msk (1UL << SCB_ICSR_RETTOBASE_Pos) /*!< SCB ICSR: RETTOBASE 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 */ + +/* SCB Vector Table Offset 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 */ + +/* 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_PRIGROUP_Pos 8 /*!< SCB AIRCR: PRIGROUP Position */ +#define SCB_AIRCR_PRIGROUP_Msk (7UL << SCB_AIRCR_PRIGROUP_Pos) /*!< SCB AIRCR: PRIGROUP 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 */ + +#define SCB_AIRCR_VECTRESET_Pos 0 /*!< SCB AIRCR: VECTRESET Position */ +#define SCB_AIRCR_VECTRESET_Msk (1UL << SCB_AIRCR_VECTRESET_Pos) /*!< SCB AIRCR: VECTRESET 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_BFHFNMIGN_Pos 8 /*!< SCB CCR: BFHFNMIGN Position */ +#define SCB_CCR_BFHFNMIGN_Msk (1UL << SCB_CCR_BFHFNMIGN_Pos) /*!< SCB CCR: BFHFNMIGN Mask */ + +#define SCB_CCR_DIV_0_TRP_Pos 4 /*!< SCB CCR: DIV_0_TRP Position */ +#define SCB_CCR_DIV_0_TRP_Msk (1UL << SCB_CCR_DIV_0_TRP_Pos) /*!< SCB CCR: DIV_0_TRP 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 */ + +#define SCB_CCR_USERSETMPEND_Pos 1 /*!< SCB CCR: USERSETMPEND Position */ +#define SCB_CCR_USERSETMPEND_Msk (1UL << SCB_CCR_USERSETMPEND_Pos) /*!< SCB CCR: USERSETMPEND Mask */ + +#define SCB_CCR_NONBASETHRDENA_Pos 0 /*!< SCB CCR: NONBASETHRDENA Position */ +#define SCB_CCR_NONBASETHRDENA_Msk (1UL << SCB_CCR_NONBASETHRDENA_Pos) /*!< SCB CCR: NONBASETHRDENA Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_USGFAULTENA_Pos 18 /*!< SCB SHCSR: USGFAULTENA Position */ +#define SCB_SHCSR_USGFAULTENA_Msk (1UL << SCB_SHCSR_USGFAULTENA_Pos) /*!< SCB SHCSR: USGFAULTENA Mask */ + +#define SCB_SHCSR_BUSFAULTENA_Pos 17 /*!< SCB SHCSR: BUSFAULTENA Position */ +#define SCB_SHCSR_BUSFAULTENA_Msk (1UL << SCB_SHCSR_BUSFAULTENA_Pos) /*!< SCB SHCSR: BUSFAULTENA Mask */ + +#define SCB_SHCSR_MEMFAULTENA_Pos 16 /*!< SCB SHCSR: MEMFAULTENA Position */ +#define SCB_SHCSR_MEMFAULTENA_Msk (1UL << SCB_SHCSR_MEMFAULTENA_Pos) /*!< SCB SHCSR: MEMFAULTENA Mask */ + +#define SCB_SHCSR_SVCALLPENDED_Pos 15 /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +#define SCB_SHCSR_BUSFAULTPENDED_Pos 14 /*!< SCB SHCSR: BUSFAULTPENDED Position */ +#define SCB_SHCSR_BUSFAULTPENDED_Msk (1UL << SCB_SHCSR_BUSFAULTPENDED_Pos) /*!< SCB SHCSR: BUSFAULTPENDED Mask */ + +#define SCB_SHCSR_MEMFAULTPENDED_Pos 13 /*!< SCB SHCSR: MEMFAULTPENDED Position */ +#define SCB_SHCSR_MEMFAULTPENDED_Msk (1UL << SCB_SHCSR_MEMFAULTPENDED_Pos) /*!< SCB SHCSR: MEMFAULTPENDED Mask */ + +#define SCB_SHCSR_USGFAULTPENDED_Pos 12 /*!< SCB SHCSR: USGFAULTPENDED Position */ +#define SCB_SHCSR_USGFAULTPENDED_Msk (1UL << SCB_SHCSR_USGFAULTPENDED_Pos) /*!< SCB SHCSR: USGFAULTPENDED Mask */ + +#define SCB_SHCSR_SYSTICKACT_Pos 11 /*!< SCB SHCSR: SYSTICKACT Position */ +#define SCB_SHCSR_SYSTICKACT_Msk (1UL << SCB_SHCSR_SYSTICKACT_Pos) /*!< SCB SHCSR: SYSTICKACT Mask */ + +#define SCB_SHCSR_PENDSVACT_Pos 10 /*!< SCB SHCSR: PENDSVACT Position */ +#define SCB_SHCSR_PENDSVACT_Msk (1UL << SCB_SHCSR_PENDSVACT_Pos) /*!< SCB SHCSR: PENDSVACT Mask */ + +#define SCB_SHCSR_MONITORACT_Pos 8 /*!< SCB SHCSR: MONITORACT Position */ +#define SCB_SHCSR_MONITORACT_Msk (1UL << SCB_SHCSR_MONITORACT_Pos) /*!< SCB SHCSR: MONITORACT Mask */ + +#define SCB_SHCSR_SVCALLACT_Pos 7 /*!< SCB SHCSR: SVCALLACT Position */ +#define SCB_SHCSR_SVCALLACT_Msk (1UL << SCB_SHCSR_SVCALLACT_Pos) /*!< SCB SHCSR: SVCALLACT Mask */ + +#define SCB_SHCSR_USGFAULTACT_Pos 3 /*!< SCB SHCSR: USGFAULTACT Position */ +#define SCB_SHCSR_USGFAULTACT_Msk (1UL << SCB_SHCSR_USGFAULTACT_Pos) /*!< SCB SHCSR: USGFAULTACT Mask */ + +#define SCB_SHCSR_BUSFAULTACT_Pos 1 /*!< SCB SHCSR: BUSFAULTACT Position */ +#define SCB_SHCSR_BUSFAULTACT_Msk (1UL << SCB_SHCSR_BUSFAULTACT_Pos) /*!< SCB SHCSR: BUSFAULTACT Mask */ + +#define SCB_SHCSR_MEMFAULTACT_Pos 0 /*!< SCB SHCSR: MEMFAULTACT Position */ +#define SCB_SHCSR_MEMFAULTACT_Msk (1UL << SCB_SHCSR_MEMFAULTACT_Pos) /*!< SCB SHCSR: MEMFAULTACT Mask */ + +/* SCB Configurable Fault Status Registers Definitions */ +#define SCB_CFSR_USGFAULTSR_Pos 16 /*!< SCB CFSR: Usage Fault Status Register Position */ +#define SCB_CFSR_USGFAULTSR_Msk (0xFFFFUL << SCB_CFSR_USGFAULTSR_Pos) /*!< SCB CFSR: Usage Fault Status Register Mask */ + +#define SCB_CFSR_BUSFAULTSR_Pos 8 /*!< SCB CFSR: Bus Fault Status Register Position */ +#define SCB_CFSR_BUSFAULTSR_Msk (0xFFUL << SCB_CFSR_BUSFAULTSR_Pos) /*!< SCB CFSR: Bus Fault Status Register Mask */ + +#define SCB_CFSR_MEMFAULTSR_Pos 0 /*!< SCB CFSR: Memory Manage Fault Status Register Position */ +#define SCB_CFSR_MEMFAULTSR_Msk (0xFFUL << SCB_CFSR_MEMFAULTSR_Pos) /*!< SCB CFSR: Memory Manage Fault Status Register Mask */ + +/* SCB Hard Fault Status Registers Definitions */ +#define SCB_HFSR_DEBUGEVT_Pos 31 /*!< SCB HFSR: DEBUGEVT Position */ +#define SCB_HFSR_DEBUGEVT_Msk (1UL << SCB_HFSR_DEBUGEVT_Pos) /*!< SCB HFSR: DEBUGEVT Mask */ + +#define SCB_HFSR_FORCED_Pos 30 /*!< SCB HFSR: FORCED Position */ +#define SCB_HFSR_FORCED_Msk (1UL << SCB_HFSR_FORCED_Pos) /*!< SCB HFSR: FORCED Mask */ + +#define SCB_HFSR_VECTTBL_Pos 1 /*!< SCB HFSR: VECTTBL Position */ +#define SCB_HFSR_VECTTBL_Msk (1UL << SCB_HFSR_VECTTBL_Pos) /*!< SCB HFSR: VECTTBL Mask */ + +/* SCB Debug Fault Status Register Definitions */ +#define SCB_DFSR_EXTERNAL_Pos 4 /*!< SCB DFSR: EXTERNAL Position */ +#define SCB_DFSR_EXTERNAL_Msk (1UL << SCB_DFSR_EXTERNAL_Pos) /*!< SCB DFSR: EXTERNAL Mask */ + +#define SCB_DFSR_VCATCH_Pos 3 /*!< SCB DFSR: VCATCH Position */ +#define SCB_DFSR_VCATCH_Msk (1UL << SCB_DFSR_VCATCH_Pos) /*!< SCB DFSR: VCATCH Mask */ + +#define SCB_DFSR_DWTTRAP_Pos 2 /*!< SCB DFSR: DWTTRAP Position */ +#define SCB_DFSR_DWTTRAP_Msk (1UL << SCB_DFSR_DWTTRAP_Pos) /*!< SCB DFSR: DWTTRAP Mask */ + +#define SCB_DFSR_BKPT_Pos 1 /*!< SCB DFSR: BKPT Position */ +#define SCB_DFSR_BKPT_Msk (1UL << SCB_DFSR_BKPT_Pos) /*!< SCB DFSR: BKPT Mask */ + +#define SCB_DFSR_HALTED_Pos 0 /*!< SCB DFSR: HALTED Position */ +#define SCB_DFSR_HALTED_Msk (1UL << SCB_DFSR_HALTED_Pos) /*!< SCB DFSR: HALTED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_SCnSCB System Controls not in SCB (SCnSCB) + \brief Type definitions for the System Control and ID Register not in the SCB + @{ + */ + +/** \brief Structure type to access the System Control and ID Register not in the SCB. + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __I uint32_t ICTR; /*!< Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IO uint32_t ACTLR; /*!< Offset: 0x008 (R/W) Auxiliary Control Register */ +} SCnSCB_Type; + +/* Interrupt Controller Type Register Definitions */ +#define SCnSCB_ICTR_INTLINESNUM_Pos 0 /*!< ICTR: INTLINESNUM Position */ +#define SCnSCB_ICTR_INTLINESNUM_Msk (0xFUL << SCnSCB_ICTR_INTLINESNUM_Pos) /*!< ICTR: INTLINESNUM Mask */ + +/* Auxiliary Control Register Definitions */ +#define SCnSCB_ACTLR_DISOOFP_Pos 9 /*!< ACTLR: DISOOFP Position */ +#define SCnSCB_ACTLR_DISOOFP_Msk (1UL << SCnSCB_ACTLR_DISOOFP_Pos) /*!< ACTLR: DISOOFP Mask */ + +#define SCnSCB_ACTLR_DISFPCA_Pos 8 /*!< ACTLR: DISFPCA Position */ +#define SCnSCB_ACTLR_DISFPCA_Msk (1UL << SCnSCB_ACTLR_DISFPCA_Pos) /*!< ACTLR: DISFPCA Mask */ + +#define SCnSCB_ACTLR_DISFOLD_Pos 2 /*!< ACTLR: DISFOLD Position */ +#define SCnSCB_ACTLR_DISFOLD_Msk (1UL << SCnSCB_ACTLR_DISFOLD_Pos) /*!< ACTLR: DISFOLD Mask */ + +#define SCnSCB_ACTLR_DISDEFWBUF_Pos 1 /*!< ACTLR: DISDEFWBUF Position */ +#define SCnSCB_ACTLR_DISDEFWBUF_Msk (1UL << SCnSCB_ACTLR_DISDEFWBUF_Pos) /*!< ACTLR: DISDEFWBUF Mask */ + +#define SCnSCB_ACTLR_DISMCYCINT_Pos 0 /*!< ACTLR: DISMCYCINT Position */ +#define SCnSCB_ACTLR_DISMCYCINT_Msk (1UL << SCnSCB_ACTLR_DISMCYCINT_Pos) /*!< ACTLR: DISMCYCINT Mask */ + +/*@} end of group CMSIS_SCnotSCB */ + + +/** \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 */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_ITM Instrumentation Trace Macrocell (ITM) + \brief Type definitions for the Instrumentation Trace Macrocell (ITM) + @{ + */ + +/** \brief Structure type to access the Instrumentation Trace Macrocell Register (ITM). + */ +typedef struct +{ + __O union + { + __O uint8_t u8; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 8-bit */ + __O uint16_t u16; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 16-bit */ + __O uint32_t u32; /*!< Offset: 0x000 ( /W) ITM Stimulus Port 32-bit */ + } PORT [32]; /*!< Offset: 0x000 ( /W) ITM Stimulus Port Registers */ + uint32_t RESERVED0[864]; + __IO uint32_t TER; /*!< Offset: 0xE00 (R/W) ITM Trace Enable Register */ + uint32_t RESERVED1[15]; + __IO uint32_t TPR; /*!< Offset: 0xE40 (R/W) ITM Trace Privilege Register */ + uint32_t RESERVED2[15]; + __IO uint32_t TCR; /*!< Offset: 0xE80 (R/W) ITM Trace Control Register */ +} ITM_Type; + +/* ITM Trace Privilege Register Definitions */ +#define ITM_TPR_PRIVMASK_Pos 0 /*!< ITM TPR: PRIVMASK Position */ +#define ITM_TPR_PRIVMASK_Msk (0xFUL << ITM_TPR_PRIVMASK_Pos) /*!< ITM TPR: PRIVMASK Mask */ + +/* ITM Trace Control Register Definitions */ +#define ITM_TCR_BUSY_Pos 23 /*!< ITM TCR: BUSY Position */ +#define ITM_TCR_BUSY_Msk (1UL << ITM_TCR_BUSY_Pos) /*!< ITM TCR: BUSY Mask */ + +#define ITM_TCR_TraceBusID_Pos 16 /*!< ITM TCR: ATBID Position */ +#define ITM_TCR_TraceBusID_Msk (0x7FUL << ITM_TCR_TraceBusID_Pos) /*!< ITM TCR: ATBID Mask */ + +#define ITM_TCR_GTSFREQ_Pos 10 /*!< ITM TCR: Global timestamp frequency Position */ +#define ITM_TCR_GTSFREQ_Msk (3UL << ITM_TCR_GTSFREQ_Pos) /*!< ITM TCR: Global timestamp frequency Mask */ + +#define ITM_TCR_TSPrescale_Pos 8 /*!< ITM TCR: TSPrescale Position */ +#define ITM_TCR_TSPrescale_Msk (3UL << ITM_TCR_TSPrescale_Pos) /*!< ITM TCR: TSPrescale Mask */ + +#define ITM_TCR_SWOENA_Pos 4 /*!< ITM TCR: SWOENA Position */ +#define ITM_TCR_SWOENA_Msk (1UL << ITM_TCR_SWOENA_Pos) /*!< ITM TCR: SWOENA Mask */ + +#define ITM_TCR_TXENA_Pos 3 /*!< ITM TCR: TXENA Position */ +#define ITM_TCR_TXENA_Msk (1UL << ITM_TCR_TXENA_Pos) /*!< ITM TCR: TXENA Mask */ + +#define ITM_TCR_SYNCENA_Pos 2 /*!< ITM TCR: SYNCENA Position */ +#define ITM_TCR_SYNCENA_Msk (1UL << ITM_TCR_SYNCENA_Pos) /*!< ITM TCR: SYNCENA Mask */ + +#define ITM_TCR_TSENA_Pos 1 /*!< ITM TCR: TSENA Position */ +#define ITM_TCR_TSENA_Msk (1UL << ITM_TCR_TSENA_Pos) /*!< ITM TCR: TSENA Mask */ + +#define ITM_TCR_ITMENA_Pos 0 /*!< ITM TCR: ITM Enable bit Position */ +#define ITM_TCR_ITMENA_Msk (1UL << ITM_TCR_ITMENA_Pos) /*!< ITM TCR: ITM Enable bit Mask */ + +/*@}*/ /* end of group CMSIS_ITM */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_DWT Data Watchpoint and Trace (DWT) + \brief Type definitions for the Data Watchpoint and Trace (DWT) + @{ + */ + +/** \brief Structure type to access the Data Watchpoint and Trace Register (DWT). + */ +typedef struct +{ + __IO uint32_t CTRL; /*!< Offset: 0x000 (R/W) Control Register */ + __IO uint32_t CYCCNT; /*!< Offset: 0x004 (R/W) Cycle Count Register */ + __IO uint32_t CPICNT; /*!< Offset: 0x008 (R/W) CPI Count Register */ + __IO uint32_t EXCCNT; /*!< Offset: 0x00C (R/W) Exception Overhead Count Register */ + __IO uint32_t SLEEPCNT; /*!< Offset: 0x010 (R/W) Sleep Count Register */ + __IO uint32_t LSUCNT; /*!< Offset: 0x014 (R/W) LSU Count Register */ + __IO uint32_t FOLDCNT; /*!< Offset: 0x018 (R/W) Folded-instruction Count Register */ + __I uint32_t PCSR; /*!< Offset: 0x01C (R/ ) Program Counter Sample Register */ + __IO uint32_t COMP0; /*!< Offset: 0x020 (R/W) Comparator Register 0 */ + __IO uint32_t MASK0; /*!< Offset: 0x024 (R/W) Mask Register 0 */ + __IO uint32_t FUNCTION0; /*!< Offset: 0x028 (R/W) Function Register 0 */ + uint32_t RESERVED0[1]; + __IO uint32_t COMP1; /*!< Offset: 0x030 (R/W) Comparator Register 1 */ + __IO uint32_t MASK1; /*!< Offset: 0x034 (R/W) Mask Register 1 */ + __IO uint32_t FUNCTION1; /*!< Offset: 0x038 (R/W) Function Register 1 */ + uint32_t RESERVED1[1]; + __IO uint32_t COMP2; /*!< Offset: 0x040 (R/W) Comparator Register 2 */ + __IO uint32_t MASK2; /*!< Offset: 0x044 (R/W) Mask Register 2 */ + __IO uint32_t FUNCTION2; /*!< Offset: 0x048 (R/W) Function Register 2 */ + uint32_t RESERVED2[1]; + __IO uint32_t COMP3; /*!< Offset: 0x050 (R/W) Comparator Register 3 */ + __IO uint32_t MASK3; /*!< Offset: 0x054 (R/W) Mask Register 3 */ + __IO uint32_t FUNCTION3; /*!< Offset: 0x058 (R/W) Function Register 3 */ +} DWT_Type; + +/* DWT Control Register Definitions */ +#define DWT_CTRL_NUMCOMP_Pos 28 /*!< DWT CTRL: NUMCOMP Position */ +#define DWT_CTRL_NUMCOMP_Msk (0xFUL << DWT_CTRL_NUMCOMP_Pos) /*!< DWT CTRL: NUMCOMP Mask */ + +#define DWT_CTRL_NOTRCPKT_Pos 27 /*!< DWT CTRL: NOTRCPKT Position */ +#define DWT_CTRL_NOTRCPKT_Msk (0x1UL << DWT_CTRL_NOTRCPKT_Pos) /*!< DWT CTRL: NOTRCPKT Mask */ + +#define DWT_CTRL_NOEXTTRIG_Pos 26 /*!< DWT CTRL: NOEXTTRIG Position */ +#define DWT_CTRL_NOEXTTRIG_Msk (0x1UL << DWT_CTRL_NOEXTTRIG_Pos) /*!< DWT CTRL: NOEXTTRIG Mask */ + +#define DWT_CTRL_NOCYCCNT_Pos 25 /*!< DWT CTRL: NOCYCCNT Position */ +#define DWT_CTRL_NOCYCCNT_Msk (0x1UL << DWT_CTRL_NOCYCCNT_Pos) /*!< DWT CTRL: NOCYCCNT Mask */ + +#define DWT_CTRL_NOPRFCNT_Pos 24 /*!< DWT CTRL: NOPRFCNT Position */ +#define DWT_CTRL_NOPRFCNT_Msk (0x1UL << DWT_CTRL_NOPRFCNT_Pos) /*!< DWT CTRL: NOPRFCNT Mask */ + +#define DWT_CTRL_CYCEVTENA_Pos 22 /*!< DWT CTRL: CYCEVTENA Position */ +#define DWT_CTRL_CYCEVTENA_Msk (0x1UL << DWT_CTRL_CYCEVTENA_Pos) /*!< DWT CTRL: CYCEVTENA Mask */ + +#define DWT_CTRL_FOLDEVTENA_Pos 21 /*!< DWT CTRL: FOLDEVTENA Position */ +#define DWT_CTRL_FOLDEVTENA_Msk (0x1UL << DWT_CTRL_FOLDEVTENA_Pos) /*!< DWT CTRL: FOLDEVTENA Mask */ + +#define DWT_CTRL_LSUEVTENA_Pos 20 /*!< DWT CTRL: LSUEVTENA Position */ +#define DWT_CTRL_LSUEVTENA_Msk (0x1UL << DWT_CTRL_LSUEVTENA_Pos) /*!< DWT CTRL: LSUEVTENA Mask */ + +#define DWT_CTRL_SLEEPEVTENA_Pos 19 /*!< DWT CTRL: SLEEPEVTENA Position */ +#define DWT_CTRL_SLEEPEVTENA_Msk (0x1UL << DWT_CTRL_SLEEPEVTENA_Pos) /*!< DWT CTRL: SLEEPEVTENA Mask */ + +#define DWT_CTRL_EXCEVTENA_Pos 18 /*!< DWT CTRL: EXCEVTENA Position */ +#define DWT_CTRL_EXCEVTENA_Msk (0x1UL << DWT_CTRL_EXCEVTENA_Pos) /*!< DWT CTRL: EXCEVTENA Mask */ + +#define DWT_CTRL_CPIEVTENA_Pos 17 /*!< DWT CTRL: CPIEVTENA Position */ +#define DWT_CTRL_CPIEVTENA_Msk (0x1UL << DWT_CTRL_CPIEVTENA_Pos) /*!< DWT CTRL: CPIEVTENA Mask */ + +#define DWT_CTRL_EXCTRCENA_Pos 16 /*!< DWT CTRL: EXCTRCENA Position */ +#define DWT_CTRL_EXCTRCENA_Msk (0x1UL << DWT_CTRL_EXCTRCENA_Pos) /*!< DWT CTRL: EXCTRCENA Mask */ + +#define DWT_CTRL_PCSAMPLENA_Pos 12 /*!< DWT CTRL: PCSAMPLENA Position */ +#define DWT_CTRL_PCSAMPLENA_Msk (0x1UL << DWT_CTRL_PCSAMPLENA_Pos) /*!< DWT CTRL: PCSAMPLENA Mask */ + +#define DWT_CTRL_SYNCTAP_Pos 10 /*!< DWT CTRL: SYNCTAP Position */ +#define DWT_CTRL_SYNCTAP_Msk (0x3UL << DWT_CTRL_SYNCTAP_Pos) /*!< DWT CTRL: SYNCTAP Mask */ + +#define DWT_CTRL_CYCTAP_Pos 9 /*!< DWT CTRL: CYCTAP Position */ +#define DWT_CTRL_CYCTAP_Msk (0x1UL << DWT_CTRL_CYCTAP_Pos) /*!< DWT CTRL: CYCTAP Mask */ + +#define DWT_CTRL_POSTINIT_Pos 5 /*!< DWT CTRL: POSTINIT Position */ +#define DWT_CTRL_POSTINIT_Msk (0xFUL << DWT_CTRL_POSTINIT_Pos) /*!< DWT CTRL: POSTINIT Mask */ + +#define DWT_CTRL_POSTPRESET_Pos 1 /*!< DWT CTRL: POSTPRESET Position */ +#define DWT_CTRL_POSTPRESET_Msk (0xFUL << DWT_CTRL_POSTPRESET_Pos) /*!< DWT CTRL: POSTPRESET Mask */ + +#define DWT_CTRL_CYCCNTENA_Pos 0 /*!< DWT CTRL: CYCCNTENA Position */ +#define DWT_CTRL_CYCCNTENA_Msk (0x1UL << DWT_CTRL_CYCCNTENA_Pos) /*!< DWT CTRL: CYCCNTENA Mask */ + +/* DWT CPI Count Register Definitions */ +#define DWT_CPICNT_CPICNT_Pos 0 /*!< DWT CPICNT: CPICNT Position */ +#define DWT_CPICNT_CPICNT_Msk (0xFFUL << DWT_CPICNT_CPICNT_Pos) /*!< DWT CPICNT: CPICNT Mask */ + +/* DWT Exception Overhead Count Register Definitions */ +#define DWT_EXCCNT_EXCCNT_Pos 0 /*!< DWT EXCCNT: EXCCNT Position */ +#define DWT_EXCCNT_EXCCNT_Msk (0xFFUL << DWT_EXCCNT_EXCCNT_Pos) /*!< DWT EXCCNT: EXCCNT Mask */ + +/* DWT Sleep Count Register Definitions */ +#define DWT_SLEEPCNT_SLEEPCNT_Pos 0 /*!< DWT SLEEPCNT: SLEEPCNT Position */ +#define DWT_SLEEPCNT_SLEEPCNT_Msk (0xFFUL << DWT_SLEEPCNT_SLEEPCNT_Pos) /*!< DWT SLEEPCNT: SLEEPCNT Mask */ + +/* DWT LSU Count Register Definitions */ +#define DWT_LSUCNT_LSUCNT_Pos 0 /*!< DWT LSUCNT: LSUCNT Position */ +#define DWT_LSUCNT_LSUCNT_Msk (0xFFUL << DWT_LSUCNT_LSUCNT_Pos) /*!< DWT LSUCNT: LSUCNT Mask */ + +/* DWT Folded-instruction Count Register Definitions */ +#define DWT_FOLDCNT_FOLDCNT_Pos 0 /*!< DWT FOLDCNT: FOLDCNT Position */ +#define DWT_FOLDCNT_FOLDCNT_Msk (0xFFUL << DWT_FOLDCNT_FOLDCNT_Pos) /*!< DWT FOLDCNT: FOLDCNT Mask */ + +/* DWT Comparator Mask Register Definitions */ +#define DWT_MASK_MASK_Pos 0 /*!< DWT MASK: MASK Position */ +#define DWT_MASK_MASK_Msk (0x1FUL << DWT_MASK_MASK_Pos) /*!< DWT MASK: MASK Mask */ + +/* DWT Comparator Function Register Definitions */ +#define DWT_FUNCTION_MATCHED_Pos 24 /*!< DWT FUNCTION: MATCHED Position */ +#define DWT_FUNCTION_MATCHED_Msk (0x1UL << DWT_FUNCTION_MATCHED_Pos) /*!< DWT FUNCTION: MATCHED Mask */ + +#define DWT_FUNCTION_DATAVADDR1_Pos 16 /*!< DWT FUNCTION: DATAVADDR1 Position */ +#define DWT_FUNCTION_DATAVADDR1_Msk (0xFUL << DWT_FUNCTION_DATAVADDR1_Pos) /*!< DWT FUNCTION: DATAVADDR1 Mask */ + +#define DWT_FUNCTION_DATAVADDR0_Pos 12 /*!< DWT FUNCTION: DATAVADDR0 Position */ +#define DWT_FUNCTION_DATAVADDR0_Msk (0xFUL << DWT_FUNCTION_DATAVADDR0_Pos) /*!< DWT FUNCTION: DATAVADDR0 Mask */ + +#define DWT_FUNCTION_DATAVSIZE_Pos 10 /*!< DWT FUNCTION: DATAVSIZE Position */ +#define DWT_FUNCTION_DATAVSIZE_Msk (0x3UL << DWT_FUNCTION_DATAVSIZE_Pos) /*!< DWT FUNCTION: DATAVSIZE Mask */ + +#define DWT_FUNCTION_LNK1ENA_Pos 9 /*!< DWT FUNCTION: LNK1ENA Position */ +#define DWT_FUNCTION_LNK1ENA_Msk (0x1UL << DWT_FUNCTION_LNK1ENA_Pos) /*!< DWT FUNCTION: LNK1ENA Mask */ + +#define DWT_FUNCTION_DATAVMATCH_Pos 8 /*!< DWT FUNCTION: DATAVMATCH Position */ +#define DWT_FUNCTION_DATAVMATCH_Msk (0x1UL << DWT_FUNCTION_DATAVMATCH_Pos) /*!< DWT FUNCTION: DATAVMATCH Mask */ + +#define DWT_FUNCTION_CYCMATCH_Pos 7 /*!< DWT FUNCTION: CYCMATCH Position */ +#define DWT_FUNCTION_CYCMATCH_Msk (0x1UL << DWT_FUNCTION_CYCMATCH_Pos) /*!< DWT FUNCTION: CYCMATCH Mask */ + +#define DWT_FUNCTION_EMITRANGE_Pos 5 /*!< DWT FUNCTION: EMITRANGE Position */ +#define DWT_FUNCTION_EMITRANGE_Msk (0x1UL << DWT_FUNCTION_EMITRANGE_Pos) /*!< DWT FUNCTION: EMITRANGE Mask */ + +#define DWT_FUNCTION_FUNCTION_Pos 0 /*!< DWT FUNCTION: FUNCTION Position */ +#define DWT_FUNCTION_FUNCTION_Msk (0xFUL << DWT_FUNCTION_FUNCTION_Pos) /*!< DWT FUNCTION: FUNCTION Mask */ + +/*@}*/ /* end of group CMSIS_DWT */ + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_TPI Trace Port Interface (TPI) + \brief Type definitions for the Trace Port Interface (TPI) + @{ + */ + +/** \brief Structure type to access the Trace Port Interface Register (TPI). + */ +typedef struct +{ + __IO uint32_t SSPSR; /*!< Offset: 0x000 (R/ ) Supported Parallel Port Size Register */ + __IO uint32_t CSPSR; /*!< Offset: 0x004 (R/W) Current Parallel Port Size Register */ + uint32_t RESERVED0[2]; + __IO uint32_t ACPR; /*!< Offset: 0x010 (R/W) Asynchronous Clock Prescaler Register */ + uint32_t RESERVED1[55]; + __IO uint32_t SPPR; /*!< Offset: 0x0F0 (R/W) Selected Pin Protocol Register */ + uint32_t RESERVED2[131]; + __I uint32_t FFSR; /*!< Offset: 0x300 (R/ ) Formatter and Flush Status Register */ + __IO uint32_t FFCR; /*!< Offset: 0x304 (R/W) Formatter and Flush Control Register */ + __I uint32_t FSCR; /*!< Offset: 0x308 (R/ ) Formatter Synchronization Counter Register */ + uint32_t RESERVED3[759]; + __I uint32_t TRIGGER; /*!< Offset: 0xEE8 (R/ ) TRIGGER */ + __I uint32_t FIFO0; /*!< Offset: 0xEEC (R/ ) Integration ETM Data */ + __I uint32_t ITATBCTR2; /*!< Offset: 0xEF0 (R/ ) ITATBCTR2 */ + uint32_t RESERVED4[1]; + __I uint32_t ITATBCTR0; /*!< Offset: 0xEF8 (R/ ) ITATBCTR0 */ + __I uint32_t FIFO1; /*!< Offset: 0xEFC (R/ ) Integration ITM Data */ + __IO uint32_t ITCTRL; /*!< Offset: 0xF00 (R/W) Integration Mode Control */ + uint32_t RESERVED5[39]; + __IO uint32_t CLAIMSET; /*!< Offset: 0xFA0 (R/W) Claim tag set */ + __IO uint32_t CLAIMCLR; /*!< Offset: 0xFA4 (R/W) Claim tag clear */ + uint32_t RESERVED7[8]; + __I uint32_t DEVID; /*!< Offset: 0xFC8 (R/ ) TPIU_DEVID */ + __I uint32_t DEVTYPE; /*!< Offset: 0xFCC (R/ ) TPIU_DEVTYPE */ +} TPI_Type; + +/* TPI Asynchronous Clock Prescaler Register Definitions */ +#define TPI_ACPR_PRESCALER_Pos 0 /*!< TPI ACPR: PRESCALER Position */ +#define TPI_ACPR_PRESCALER_Msk (0x1FFFUL << TPI_ACPR_PRESCALER_Pos) /*!< TPI ACPR: PRESCALER Mask */ + +/* TPI Selected Pin Protocol Register Definitions */ +#define TPI_SPPR_TXMODE_Pos 0 /*!< TPI SPPR: TXMODE Position */ +#define TPI_SPPR_TXMODE_Msk (0x3UL << TPI_SPPR_TXMODE_Pos) /*!< TPI SPPR: TXMODE Mask */ + +/* TPI Formatter and Flush Status Register Definitions */ +#define TPI_FFSR_FtNonStop_Pos 3 /*!< TPI FFSR: FtNonStop Position */ +#define TPI_FFSR_FtNonStop_Msk (0x1UL << TPI_FFSR_FtNonStop_Pos) /*!< TPI FFSR: FtNonStop Mask */ + +#define TPI_FFSR_TCPresent_Pos 2 /*!< TPI FFSR: TCPresent Position */ +#define TPI_FFSR_TCPresent_Msk (0x1UL << TPI_FFSR_TCPresent_Pos) /*!< TPI FFSR: TCPresent Mask */ + +#define TPI_FFSR_FtStopped_Pos 1 /*!< TPI FFSR: FtStopped Position */ +#define TPI_FFSR_FtStopped_Msk (0x1UL << TPI_FFSR_FtStopped_Pos) /*!< TPI FFSR: FtStopped Mask */ + +#define TPI_FFSR_FlInProg_Pos 0 /*!< TPI FFSR: FlInProg Position */ +#define TPI_FFSR_FlInProg_Msk (0x1UL << TPI_FFSR_FlInProg_Pos) /*!< TPI FFSR: FlInProg Mask */ + +/* TPI Formatter and Flush Control Register Definitions */ +#define TPI_FFCR_TrigIn_Pos 8 /*!< TPI FFCR: TrigIn Position */ +#define TPI_FFCR_TrigIn_Msk (0x1UL << TPI_FFCR_TrigIn_Pos) /*!< TPI FFCR: TrigIn Mask */ + +#define TPI_FFCR_EnFCont_Pos 1 /*!< TPI FFCR: EnFCont Position */ +#define TPI_FFCR_EnFCont_Msk (0x1UL << TPI_FFCR_EnFCont_Pos) /*!< TPI FFCR: EnFCont Mask */ + +/* TPI TRIGGER Register Definitions */ +#define TPI_TRIGGER_TRIGGER_Pos 0 /*!< TPI TRIGGER: TRIGGER Position */ +#define TPI_TRIGGER_TRIGGER_Msk (0x1UL << TPI_TRIGGER_TRIGGER_Pos) /*!< TPI TRIGGER: TRIGGER Mask */ + +/* TPI Integration ETM Data Register Definitions (FIFO0) */ +#define TPI_FIFO0_ITM_ATVALID_Pos 29 /*!< TPI FIFO0: ITM_ATVALID Position */ +#define TPI_FIFO0_ITM_ATVALID_Msk (0x3UL << TPI_FIFO0_ITM_ATVALID_Pos) /*!< TPI FIFO0: ITM_ATVALID Mask */ + +#define TPI_FIFO0_ITM_bytecount_Pos 27 /*!< TPI FIFO0: ITM_bytecount Position */ +#define TPI_FIFO0_ITM_bytecount_Msk (0x3UL << TPI_FIFO0_ITM_bytecount_Pos) /*!< TPI FIFO0: ITM_bytecount Mask */ + +#define TPI_FIFO0_ETM_ATVALID_Pos 26 /*!< TPI FIFO0: ETM_ATVALID Position */ +#define TPI_FIFO0_ETM_ATVALID_Msk (0x3UL << TPI_FIFO0_ETM_ATVALID_Pos) /*!< TPI FIFO0: ETM_ATVALID Mask */ + +#define TPI_FIFO0_ETM_bytecount_Pos 24 /*!< TPI FIFO0: ETM_bytecount Position */ +#define TPI_FIFO0_ETM_bytecount_Msk (0x3UL << TPI_FIFO0_ETM_bytecount_Pos) /*!< TPI FIFO0: ETM_bytecount Mask */ + +#define TPI_FIFO0_ETM2_Pos 16 /*!< TPI FIFO0: ETM2 Position */ +#define TPI_FIFO0_ETM2_Msk (0xFFUL << TPI_FIFO0_ETM2_Pos) /*!< TPI FIFO0: ETM2 Mask */ + +#define TPI_FIFO0_ETM1_Pos 8 /*!< TPI FIFO0: ETM1 Position */ +#define TPI_FIFO0_ETM1_Msk (0xFFUL << TPI_FIFO0_ETM1_Pos) /*!< TPI FIFO0: ETM1 Mask */ + +#define TPI_FIFO0_ETM0_Pos 0 /*!< TPI FIFO0: ETM0 Position */ +#define TPI_FIFO0_ETM0_Msk (0xFFUL << TPI_FIFO0_ETM0_Pos) /*!< TPI FIFO0: ETM0 Mask */ + +/* TPI ITATBCTR2 Register Definitions */ +#define TPI_ITATBCTR2_ATREADY_Pos 0 /*!< TPI ITATBCTR2: ATREADY Position */ +#define TPI_ITATBCTR2_ATREADY_Msk (0x1UL << TPI_ITATBCTR2_ATREADY_Pos) /*!< TPI ITATBCTR2: ATREADY Mask */ + +/* TPI Integration ITM Data Register Definitions (FIFO1) */ +#define TPI_FIFO1_ITM_ATVALID_Pos 29 /*!< TPI FIFO1: ITM_ATVALID Position */ +#define TPI_FIFO1_ITM_ATVALID_Msk (0x3UL << TPI_FIFO1_ITM_ATVALID_Pos) /*!< TPI FIFO1: ITM_ATVALID Mask */ + +#define TPI_FIFO1_ITM_bytecount_Pos 27 /*!< TPI FIFO1: ITM_bytecount Position */ +#define TPI_FIFO1_ITM_bytecount_Msk (0x3UL << TPI_FIFO1_ITM_bytecount_Pos) /*!< TPI FIFO1: ITM_bytecount Mask */ + +#define TPI_FIFO1_ETM_ATVALID_Pos 26 /*!< TPI FIFO1: ETM_ATVALID Position */ +#define TPI_FIFO1_ETM_ATVALID_Msk (0x3UL << TPI_FIFO1_ETM_ATVALID_Pos) /*!< TPI FIFO1: ETM_ATVALID Mask */ + +#define TPI_FIFO1_ETM_bytecount_Pos 24 /*!< TPI FIFO1: ETM_bytecount Position */ +#define TPI_FIFO1_ETM_bytecount_Msk (0x3UL << TPI_FIFO1_ETM_bytecount_Pos) /*!< TPI FIFO1: ETM_bytecount Mask */ + +#define TPI_FIFO1_ITM2_Pos 16 /*!< TPI FIFO1: ITM2 Position */ +#define TPI_FIFO1_ITM2_Msk (0xFFUL << TPI_FIFO1_ITM2_Pos) /*!< TPI FIFO1: ITM2 Mask */ + +#define TPI_FIFO1_ITM1_Pos 8 /*!< TPI FIFO1: ITM1 Position */ +#define TPI_FIFO1_ITM1_Msk (0xFFUL << TPI_FIFO1_ITM1_Pos) /*!< TPI FIFO1: ITM1 Mask */ + +#define TPI_FIFO1_ITM0_Pos 0 /*!< TPI FIFO1: ITM0 Position */ +#define TPI_FIFO1_ITM0_Msk (0xFFUL << TPI_FIFO1_ITM0_Pos) /*!< TPI FIFO1: ITM0 Mask */ + +/* TPI ITATBCTR0 Register Definitions */ +#define TPI_ITATBCTR0_ATREADY_Pos 0 /*!< TPI ITATBCTR0: ATREADY Position */ +#define TPI_ITATBCTR0_ATREADY_Msk (0x1UL << TPI_ITATBCTR0_ATREADY_Pos) /*!< TPI ITATBCTR0: ATREADY Mask */ + +/* TPI Integration Mode Control Register Definitions */ +#define TPI_ITCTRL_Mode_Pos 0 /*!< TPI ITCTRL: Mode Position */ +#define TPI_ITCTRL_Mode_Msk (0x1UL << TPI_ITCTRL_Mode_Pos) /*!< TPI ITCTRL: Mode Mask */ + +/* TPI DEVID Register Definitions */ +#define TPI_DEVID_NRZVALID_Pos 11 /*!< TPI DEVID: NRZVALID Position */ +#define TPI_DEVID_NRZVALID_Msk (0x1UL << TPI_DEVID_NRZVALID_Pos) /*!< TPI DEVID: NRZVALID Mask */ + +#define TPI_DEVID_MANCVALID_Pos 10 /*!< TPI DEVID: MANCVALID Position */ +#define TPI_DEVID_MANCVALID_Msk (0x1UL << TPI_DEVID_MANCVALID_Pos) /*!< TPI DEVID: MANCVALID Mask */ + +#define TPI_DEVID_PTINVALID_Pos 9 /*!< TPI DEVID: PTINVALID Position */ +#define TPI_DEVID_PTINVALID_Msk (0x1UL << TPI_DEVID_PTINVALID_Pos) /*!< TPI DEVID: PTINVALID Mask */ + +#define TPI_DEVID_MinBufSz_Pos 6 /*!< TPI DEVID: MinBufSz Position */ +#define TPI_DEVID_MinBufSz_Msk (0x7UL << TPI_DEVID_MinBufSz_Pos) /*!< TPI DEVID: MinBufSz Mask */ + +#define TPI_DEVID_AsynClkIn_Pos 5 /*!< TPI DEVID: AsynClkIn Position */ +#define TPI_DEVID_AsynClkIn_Msk (0x1UL << TPI_DEVID_AsynClkIn_Pos) /*!< TPI DEVID: AsynClkIn Mask */ + +#define TPI_DEVID_NrTraceInput_Pos 0 /*!< TPI DEVID: NrTraceInput Position */ +#define TPI_DEVID_NrTraceInput_Msk (0x1FUL << TPI_DEVID_NrTraceInput_Pos) /*!< TPI DEVID: NrTraceInput Mask */ + +/* TPI DEVTYPE Register Definitions */ +#define TPI_DEVTYPE_SubType_Pos 0 /*!< TPI DEVTYPE: SubType Position */ +#define TPI_DEVTYPE_SubType_Msk (0xFUL << TPI_DEVTYPE_SubType_Pos) /*!< TPI DEVTYPE: SubType Mask */ + +#define TPI_DEVTYPE_MajorType_Pos 4 /*!< TPI DEVTYPE: MajorType Position */ +#define TPI_DEVTYPE_MajorType_Msk (0xFUL << TPI_DEVTYPE_MajorType_Pos) /*!< TPI DEVTYPE: MajorType Mask */ + +/*@}*/ /* end of group CMSIS_TPI */ + + +#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 */ + __IO uint32_t RBAR_A1; /*!< Offset: 0x014 (R/W) MPU Alias 1 Region Base Address Register */ + __IO uint32_t RASR_A1; /*!< Offset: 0x018 (R/W) MPU Alias 1 Region Attribute and Size Register */ + __IO uint32_t RBAR_A2; /*!< Offset: 0x01C (R/W) MPU Alias 2 Region Base Address Register */ + __IO uint32_t RASR_A2; /*!< Offset: 0x020 (R/W) MPU Alias 2 Region Attribute and Size Register */ + __IO uint32_t RBAR_A3; /*!< Offset: 0x024 (R/W) MPU Alias 3 Region Base Address Register */ + __IO uint32_t RASR_A3; /*!< Offset: 0x028 (R/W) MPU Alias 3 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 5 /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0x7FFFFFFUL << 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_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 + + +#if (__FPU_PRESENT == 1) +/** \ingroup CMSIS_core_register + \defgroup CMSIS_FPU Floating Point Unit (FPU) + \brief Type definitions for the Floating Point Unit (FPU) + @{ + */ + +/** \brief Structure type to access the Floating Point Unit (FPU). + */ +typedef struct +{ + uint32_t RESERVED0[1]; + __IO uint32_t FPCCR; /*!< Offset: 0x004 (R/W) Floating-Point Context Control Register */ + __IO uint32_t FPCAR; /*!< Offset: 0x008 (R/W) Floating-Point Context Address Register */ + __IO uint32_t FPDSCR; /*!< Offset: 0x00C (R/W) Floating-Point Default Status Control Register */ + __I uint32_t MVFR0; /*!< Offset: 0x010 (R/ ) Media and FP Feature Register 0 */ + __I uint32_t MVFR1; /*!< Offset: 0x014 (R/ ) Media and FP Feature Register 1 */ +} FPU_Type; + +/* Floating-Point Context Control Register */ +#define FPU_FPCCR_ASPEN_Pos 31 /*!< FPCCR: ASPEN bit Position */ +#define FPU_FPCCR_ASPEN_Msk (1UL << FPU_FPCCR_ASPEN_Pos) /*!< FPCCR: ASPEN bit Mask */ + +#define FPU_FPCCR_LSPEN_Pos 30 /*!< FPCCR: LSPEN Position */ +#define FPU_FPCCR_LSPEN_Msk (1UL << FPU_FPCCR_LSPEN_Pos) /*!< FPCCR: LSPEN bit Mask */ + +#define FPU_FPCCR_MONRDY_Pos 8 /*!< FPCCR: MONRDY Position */ +#define FPU_FPCCR_MONRDY_Msk (1UL << FPU_FPCCR_MONRDY_Pos) /*!< FPCCR: MONRDY bit Mask */ + +#define FPU_FPCCR_BFRDY_Pos 6 /*!< FPCCR: BFRDY Position */ +#define FPU_FPCCR_BFRDY_Msk (1UL << FPU_FPCCR_BFRDY_Pos) /*!< FPCCR: BFRDY bit Mask */ + +#define FPU_FPCCR_MMRDY_Pos 5 /*!< FPCCR: MMRDY Position */ +#define FPU_FPCCR_MMRDY_Msk (1UL << FPU_FPCCR_MMRDY_Pos) /*!< FPCCR: MMRDY bit Mask */ + +#define FPU_FPCCR_HFRDY_Pos 4 /*!< FPCCR: HFRDY Position */ +#define FPU_FPCCR_HFRDY_Msk (1UL << FPU_FPCCR_HFRDY_Pos) /*!< FPCCR: HFRDY bit Mask */ + +#define FPU_FPCCR_THREAD_Pos 3 /*!< FPCCR: processor mode bit Position */ +#define FPU_FPCCR_THREAD_Msk (1UL << FPU_FPCCR_THREAD_Pos) /*!< FPCCR: processor mode active bit Mask */ + +#define FPU_FPCCR_USER_Pos 1 /*!< FPCCR: privilege level bit Position */ +#define FPU_FPCCR_USER_Msk (1UL << FPU_FPCCR_USER_Pos) /*!< FPCCR: privilege level bit Mask */ + +#define FPU_FPCCR_LSPACT_Pos 0 /*!< FPCCR: Lazy state preservation active bit Position */ +#define FPU_FPCCR_LSPACT_Msk (1UL << FPU_FPCCR_LSPACT_Pos) /*!< FPCCR: Lazy state preservation active bit Mask */ + +/* Floating-Point Context Address Register */ +#define FPU_FPCAR_ADDRESS_Pos 3 /*!< FPCAR: ADDRESS bit Position */ +#define FPU_FPCAR_ADDRESS_Msk (0x1FFFFFFFUL << FPU_FPCAR_ADDRESS_Pos) /*!< FPCAR: ADDRESS bit Mask */ + +/* Floating-Point Default Status Control Register */ +#define FPU_FPDSCR_AHP_Pos 26 /*!< FPDSCR: AHP bit Position */ +#define FPU_FPDSCR_AHP_Msk (1UL << FPU_FPDSCR_AHP_Pos) /*!< FPDSCR: AHP bit Mask */ + +#define FPU_FPDSCR_DN_Pos 25 /*!< FPDSCR: DN bit Position */ +#define FPU_FPDSCR_DN_Msk (1UL << FPU_FPDSCR_DN_Pos) /*!< FPDSCR: DN bit Mask */ + +#define FPU_FPDSCR_FZ_Pos 24 /*!< FPDSCR: FZ bit Position */ +#define FPU_FPDSCR_FZ_Msk (1UL << FPU_FPDSCR_FZ_Pos) /*!< FPDSCR: FZ bit Mask */ + +#define FPU_FPDSCR_RMode_Pos 22 /*!< FPDSCR: RMode bit Position */ +#define FPU_FPDSCR_RMode_Msk (3UL << FPU_FPDSCR_RMode_Pos) /*!< FPDSCR: RMode bit Mask */ + +/* Media and FP Feature Register 0 */ +#define FPU_MVFR0_FP_rounding_modes_Pos 28 /*!< MVFR0: FP rounding modes bits Position */ +#define FPU_MVFR0_FP_rounding_modes_Msk (0xFUL << FPU_MVFR0_FP_rounding_modes_Pos) /*!< MVFR0: FP rounding modes bits Mask */ + +#define FPU_MVFR0_Short_vectors_Pos 24 /*!< MVFR0: Short vectors bits Position */ +#define FPU_MVFR0_Short_vectors_Msk (0xFUL << FPU_MVFR0_Short_vectors_Pos) /*!< MVFR0: Short vectors bits Mask */ + +#define FPU_MVFR0_Square_root_Pos 20 /*!< MVFR0: Square root bits Position */ +#define FPU_MVFR0_Square_root_Msk (0xFUL << FPU_MVFR0_Square_root_Pos) /*!< MVFR0: Square root bits Mask */ + +#define FPU_MVFR0_Divide_Pos 16 /*!< MVFR0: Divide bits Position */ +#define FPU_MVFR0_Divide_Msk (0xFUL << FPU_MVFR0_Divide_Pos) /*!< MVFR0: Divide bits Mask */ + +#define FPU_MVFR0_FP_excep_trapping_Pos 12 /*!< MVFR0: FP exception trapping bits Position */ +#define FPU_MVFR0_FP_excep_trapping_Msk (0xFUL << FPU_MVFR0_FP_excep_trapping_Pos) /*!< MVFR0: FP exception trapping bits Mask */ + +#define FPU_MVFR0_Double_precision_Pos 8 /*!< MVFR0: Double-precision bits Position */ +#define FPU_MVFR0_Double_precision_Msk (0xFUL << FPU_MVFR0_Double_precision_Pos) /*!< MVFR0: Double-precision bits Mask */ + +#define FPU_MVFR0_Single_precision_Pos 4 /*!< MVFR0: Single-precision bits Position */ +#define FPU_MVFR0_Single_precision_Msk (0xFUL << FPU_MVFR0_Single_precision_Pos) /*!< MVFR0: Single-precision bits Mask */ + +#define FPU_MVFR0_A_SIMD_registers_Pos 0 /*!< MVFR0: A_SIMD registers bits Position */ +#define FPU_MVFR0_A_SIMD_registers_Msk (0xFUL << FPU_MVFR0_A_SIMD_registers_Pos) /*!< MVFR0: A_SIMD registers bits Mask */ + +/* Media and FP Feature Register 1 */ +#define FPU_MVFR1_FP_fused_MAC_Pos 28 /*!< MVFR1: FP fused MAC bits Position */ +#define FPU_MVFR1_FP_fused_MAC_Msk (0xFUL << FPU_MVFR1_FP_fused_MAC_Pos) /*!< MVFR1: FP fused MAC bits Mask */ + +#define FPU_MVFR1_FP_HPFP_Pos 24 /*!< MVFR1: FP HPFP bits Position */ +#define FPU_MVFR1_FP_HPFP_Msk (0xFUL << FPU_MVFR1_FP_HPFP_Pos) /*!< MVFR1: FP HPFP bits Mask */ + +#define FPU_MVFR1_D_NaN_mode_Pos 4 /*!< MVFR1: D_NaN mode bits Position */ +#define FPU_MVFR1_D_NaN_mode_Msk (0xFUL << FPU_MVFR1_D_NaN_mode_Pos) /*!< MVFR1: D_NaN mode bits Mask */ + +#define FPU_MVFR1_FtZ_mode_Pos 0 /*!< MVFR1: FtZ mode bits Position */ +#define FPU_MVFR1_FtZ_mode_Msk (0xFUL << FPU_MVFR1_FtZ_mode_Pos) /*!< MVFR1: FtZ mode bits Mask */ + +/*@} end of group CMSIS_FPU */ +#endif + + +/** \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Type definitions for the Core Debug Registers + @{ + */ + +/** \brief Structure type to access the Core Debug Register (CoreDebug). + */ +typedef struct +{ + __IO uint32_t DHCSR; /*!< Offset: 0x000 (R/W) Debug Halting Control and Status Register */ + __O uint32_t DCRSR; /*!< Offset: 0x004 ( /W) Debug Core Register Selector Register */ + __IO uint32_t DCRDR; /*!< Offset: 0x008 (R/W) Debug Core Register Data Register */ + __IO uint32_t DEMCR; /*!< Offset: 0x00C (R/W) Debug Exception and Monitor Control Register */ +} CoreDebug_Type; + +/* Debug Halting Control and Status Register */ +#define CoreDebug_DHCSR_DBGKEY_Pos 16 /*!< CoreDebug DHCSR: DBGKEY Position */ +#define CoreDebug_DHCSR_DBGKEY_Msk (0xFFFFUL << CoreDebug_DHCSR_DBGKEY_Pos) /*!< CoreDebug DHCSR: DBGKEY Mask */ + +#define CoreDebug_DHCSR_S_RESET_ST_Pos 25 /*!< CoreDebug DHCSR: S_RESET_ST Position */ +#define CoreDebug_DHCSR_S_RESET_ST_Msk (1UL << CoreDebug_DHCSR_S_RESET_ST_Pos) /*!< CoreDebug DHCSR: S_RESET_ST Mask */ + +#define CoreDebug_DHCSR_S_RETIRE_ST_Pos 24 /*!< CoreDebug DHCSR: S_RETIRE_ST Position */ +#define CoreDebug_DHCSR_S_RETIRE_ST_Msk (1UL << CoreDebug_DHCSR_S_RETIRE_ST_Pos) /*!< CoreDebug DHCSR: S_RETIRE_ST Mask */ + +#define CoreDebug_DHCSR_S_LOCKUP_Pos 19 /*!< CoreDebug DHCSR: S_LOCKUP Position */ +#define CoreDebug_DHCSR_S_LOCKUP_Msk (1UL << CoreDebug_DHCSR_S_LOCKUP_Pos) /*!< CoreDebug DHCSR: S_LOCKUP Mask */ + +#define CoreDebug_DHCSR_S_SLEEP_Pos 18 /*!< CoreDebug DHCSR: S_SLEEP Position */ +#define CoreDebug_DHCSR_S_SLEEP_Msk (1UL << CoreDebug_DHCSR_S_SLEEP_Pos) /*!< CoreDebug DHCSR: S_SLEEP Mask */ + +#define CoreDebug_DHCSR_S_HALT_Pos 17 /*!< CoreDebug DHCSR: S_HALT Position */ +#define CoreDebug_DHCSR_S_HALT_Msk (1UL << CoreDebug_DHCSR_S_HALT_Pos) /*!< CoreDebug DHCSR: S_HALT Mask */ + +#define CoreDebug_DHCSR_S_REGRDY_Pos 16 /*!< CoreDebug DHCSR: S_REGRDY Position */ +#define CoreDebug_DHCSR_S_REGRDY_Msk (1UL << CoreDebug_DHCSR_S_REGRDY_Pos) /*!< CoreDebug DHCSR: S_REGRDY Mask */ + +#define CoreDebug_DHCSR_C_SNAPSTALL_Pos 5 /*!< CoreDebug DHCSR: C_SNAPSTALL Position */ +#define CoreDebug_DHCSR_C_SNAPSTALL_Msk (1UL << CoreDebug_DHCSR_C_SNAPSTALL_Pos) /*!< CoreDebug DHCSR: C_SNAPSTALL Mask */ + +#define CoreDebug_DHCSR_C_MASKINTS_Pos 3 /*!< CoreDebug DHCSR: C_MASKINTS Position */ +#define CoreDebug_DHCSR_C_MASKINTS_Msk (1UL << CoreDebug_DHCSR_C_MASKINTS_Pos) /*!< CoreDebug DHCSR: C_MASKINTS Mask */ + +#define CoreDebug_DHCSR_C_STEP_Pos 2 /*!< CoreDebug DHCSR: C_STEP Position */ +#define CoreDebug_DHCSR_C_STEP_Msk (1UL << CoreDebug_DHCSR_C_STEP_Pos) /*!< CoreDebug DHCSR: C_STEP Mask */ + +#define CoreDebug_DHCSR_C_HALT_Pos 1 /*!< CoreDebug DHCSR: C_HALT Position */ +#define CoreDebug_DHCSR_C_HALT_Msk (1UL << CoreDebug_DHCSR_C_HALT_Pos) /*!< CoreDebug DHCSR: C_HALT Mask */ + +#define CoreDebug_DHCSR_C_DEBUGEN_Pos 0 /*!< CoreDebug DHCSR: C_DEBUGEN Position */ +#define CoreDebug_DHCSR_C_DEBUGEN_Msk (1UL << CoreDebug_DHCSR_C_DEBUGEN_Pos) /*!< CoreDebug DHCSR: C_DEBUGEN Mask */ + +/* Debug Core Register Selector Register */ +#define CoreDebug_DCRSR_REGWnR_Pos 16 /*!< CoreDebug DCRSR: REGWnR Position */ +#define CoreDebug_DCRSR_REGWnR_Msk (1UL << CoreDebug_DCRSR_REGWnR_Pos) /*!< CoreDebug DCRSR: REGWnR Mask */ + +#define CoreDebug_DCRSR_REGSEL_Pos 0 /*!< CoreDebug DCRSR: REGSEL Position */ +#define CoreDebug_DCRSR_REGSEL_Msk (0x1FUL << CoreDebug_DCRSR_REGSEL_Pos) /*!< CoreDebug DCRSR: REGSEL Mask */ + +/* Debug Exception and Monitor Control Register */ +#define CoreDebug_DEMCR_TRCENA_Pos 24 /*!< CoreDebug DEMCR: TRCENA Position */ +#define CoreDebug_DEMCR_TRCENA_Msk (1UL << CoreDebug_DEMCR_TRCENA_Pos) /*!< CoreDebug DEMCR: TRCENA Mask */ + +#define CoreDebug_DEMCR_MON_REQ_Pos 19 /*!< CoreDebug DEMCR: MON_REQ Position */ +#define CoreDebug_DEMCR_MON_REQ_Msk (1UL << CoreDebug_DEMCR_MON_REQ_Pos) /*!< CoreDebug DEMCR: MON_REQ Mask */ + +#define CoreDebug_DEMCR_MON_STEP_Pos 18 /*!< CoreDebug DEMCR: MON_STEP Position */ +#define CoreDebug_DEMCR_MON_STEP_Msk (1UL << CoreDebug_DEMCR_MON_STEP_Pos) /*!< CoreDebug DEMCR: MON_STEP Mask */ + +#define CoreDebug_DEMCR_MON_PEND_Pos 17 /*!< CoreDebug DEMCR: MON_PEND Position */ +#define CoreDebug_DEMCR_MON_PEND_Msk (1UL << CoreDebug_DEMCR_MON_PEND_Pos) /*!< CoreDebug DEMCR: MON_PEND Mask */ + +#define CoreDebug_DEMCR_MON_EN_Pos 16 /*!< CoreDebug DEMCR: MON_EN Position */ +#define CoreDebug_DEMCR_MON_EN_Msk (1UL << CoreDebug_DEMCR_MON_EN_Pos) /*!< CoreDebug DEMCR: MON_EN Mask */ + +#define CoreDebug_DEMCR_VC_HARDERR_Pos 10 /*!< CoreDebug DEMCR: VC_HARDERR Position */ +#define CoreDebug_DEMCR_VC_HARDERR_Msk (1UL << CoreDebug_DEMCR_VC_HARDERR_Pos) /*!< CoreDebug DEMCR: VC_HARDERR Mask */ + +#define CoreDebug_DEMCR_VC_INTERR_Pos 9 /*!< CoreDebug DEMCR: VC_INTERR Position */ +#define CoreDebug_DEMCR_VC_INTERR_Msk (1UL << CoreDebug_DEMCR_VC_INTERR_Pos) /*!< CoreDebug DEMCR: VC_INTERR Mask */ + +#define CoreDebug_DEMCR_VC_BUSERR_Pos 8 /*!< CoreDebug DEMCR: VC_BUSERR Position */ +#define CoreDebug_DEMCR_VC_BUSERR_Msk (1UL << CoreDebug_DEMCR_VC_BUSERR_Pos) /*!< CoreDebug DEMCR: VC_BUSERR Mask */ + +#define CoreDebug_DEMCR_VC_STATERR_Pos 7 /*!< CoreDebug DEMCR: VC_STATERR Position */ +#define CoreDebug_DEMCR_VC_STATERR_Msk (1UL << CoreDebug_DEMCR_VC_STATERR_Pos) /*!< CoreDebug DEMCR: VC_STATERR Mask */ + +#define CoreDebug_DEMCR_VC_CHKERR_Pos 6 /*!< CoreDebug DEMCR: VC_CHKERR Position */ +#define CoreDebug_DEMCR_VC_CHKERR_Msk (1UL << CoreDebug_DEMCR_VC_CHKERR_Pos) /*!< CoreDebug DEMCR: VC_CHKERR Mask */ + +#define CoreDebug_DEMCR_VC_NOCPERR_Pos 5 /*!< CoreDebug DEMCR: VC_NOCPERR Position */ +#define CoreDebug_DEMCR_VC_NOCPERR_Msk (1UL << CoreDebug_DEMCR_VC_NOCPERR_Pos) /*!< CoreDebug DEMCR: VC_NOCPERR Mask */ + +#define CoreDebug_DEMCR_VC_MMERR_Pos 4 /*!< CoreDebug DEMCR: VC_MMERR Position */ +#define CoreDebug_DEMCR_VC_MMERR_Msk (1UL << CoreDebug_DEMCR_VC_MMERR_Pos) /*!< CoreDebug DEMCR: VC_MMERR Mask */ + +#define CoreDebug_DEMCR_VC_CORERESET_Pos 0 /*!< CoreDebug DEMCR: VC_CORERESET Position */ +#define CoreDebug_DEMCR_VC_CORERESET_Msk (1UL << CoreDebug_DEMCR_VC_CORERESET_Pos) /*!< CoreDebug DEMCR: VC_CORERESET Mask */ + +/*@} 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-M4 Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define ITM_BASE (0xE0000000UL) /*!< ITM Base Address */ +#define DWT_BASE (0xE0001000UL) /*!< DWT Base Address */ +#define TPI_BASE (0xE0040000UL) /*!< TPI Base Address */ +#define CoreDebug_BASE (0xE000EDF0UL) /*!< Core Debug 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 SCnSCB ((SCnSCB_Type *) SCS_BASE ) /*!< System control Register not in SCB */ +#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 */ +#define ITM ((ITM_Type *) ITM_BASE ) /*!< ITM configuration struct */ +#define DWT ((DWT_Type *) DWT_BASE ) /*!< DWT configuration struct */ +#define TPI ((TPI_Type *) TPI_BASE ) /*!< TPI configuration struct */ +#define CoreDebug ((CoreDebug_Type *) CoreDebug_BASE) /*!< Core Debug 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 + +#if (__FPU_PRESENT == 1) + #define FPU_BASE (SCS_BASE + 0x0F30UL) /*!< Floating Point Unit */ + #define FPU ((FPU_Type *) FPU_BASE ) /*!< Floating Point Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Debug 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. + @{ + */ + +/** \brief Set Priority Grouping + + The function sets the priority grouping field using the required unlock sequence. + The parameter PriorityGroup is assigned to the field SCB->AIRCR [10:8] PRIGROUP field. + Only values from 0..7 are used. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the smallest possible priority group is set. + + \param [in] PriorityGroup Priority grouping field. + */ +__STATIC_INLINE void NVIC_SetPriorityGrouping(uint32_t PriorityGroup) +{ + uint32_t reg_value; + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07); /* only values 0..7 are used */ + + reg_value = SCB->AIRCR; /* read old register configuration */ + reg_value &= ~(SCB_AIRCR_VECTKEY_Msk | SCB_AIRCR_PRIGROUP_Msk); /* clear bits to change */ + reg_value = (reg_value | + ((uint32_t)0x5FA << SCB_AIRCR_VECTKEY_Pos) | + (PriorityGroupTmp << 8)); /* Insert write key and priorty group */ + SCB->AIRCR = reg_value; +} + + +/** \brief Get Priority Grouping + + The function reads the priority grouping field from the NVIC Interrupt Controller. + + \return Priority grouping field (SCB->AIRCR [10:8] PRIGROUP field). + */ +__STATIC_INLINE uint32_t NVIC_GetPriorityGrouping(void) +{ + return ((SCB->AIRCR & SCB_AIRCR_PRIGROUP_Msk) >> SCB_AIRCR_PRIGROUP_Pos); /* read priority grouping field */ +} + + +/** \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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); enable interrupt */ + NVIC->ISER[(uint32_t)((int32_t)IRQn) >> 5] = (uint32_t)(1 << ((uint32_t)((int32_t)IRQn) & (uint32_t)0x1F)); /* enable interrupt */ +} + + +/** \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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* disable interrupt */ +} + + +/** \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[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if pending else 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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* set interrupt pending */ +} + + +/** \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[((uint32_t)(IRQn) >> 5)] = (1 << ((uint32_t)(IRQn) & 0x1F)); /* Clear pending interrupt */ +} + + +/** \brief Get Active Interrupt + + The function reads the active register in NVIC and returns the active bit. + + \param [in] IRQn Interrupt number. + + \return 0 Interrupt status is not active. + \return 1 Interrupt status is active. + */ +__STATIC_INLINE uint32_t NVIC_GetActive(IRQn_Type IRQn) +{ + return((uint32_t)((NVIC->IABR[(uint32_t)(IRQn) >> 5] & (1 << ((uint32_t)(IRQn) & 0x1F)))?1:0)); /* Return 1 if active else 0 */ +} + + +/** \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[((uint32_t)(IRQn) & 0xF)-4] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for Cortex-M System Interrupts */ + else { + NVIC->IP[(uint32_t)(IRQn)] = ((priority << (8 - __NVIC_PRIO_BITS)) & 0xff); } /* set Priority for device specific Interrupts */ +} + + +/** \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[((uint32_t)(IRQn) & 0xF)-4] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for Cortex-M system interrupts */ + else { + return((uint32_t)(NVIC->IP[(uint32_t)(IRQn)] >> (8 - __NVIC_PRIO_BITS))); } /* get priority for device specific interrupts */ +} + + +/** \brief Encode Priority + + The function encodes the priority for an interrupt with the given priority group, + preemptive priority value, and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS), the samllest possible priority group is set. + + \param [in] PriorityGroup Used priority group. + \param [in] PreemptPriority Preemptive priority value (starting from 0). + \param [in] SubPriority Subpriority value (starting from 0). + \return Encoded priority. Value can be used in the function \ref NVIC_SetPriority(). + */ +__STATIC_INLINE uint32_t NVIC_EncodePriority (uint32_t PriorityGroup, uint32_t PreemptPriority, uint32_t SubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + return ( + ((PreemptPriority & ((1 << (PreemptPriorityBits)) - 1)) << SubPriorityBits) | + ((SubPriority & ((1 << (SubPriorityBits )) - 1))) + ); +} + + +/** \brief Decode Priority + + The function decodes an interrupt priority value with a given priority group to + preemptive priority value and subpriority value. + In case of a conflict between priority grouping and available + priority bits (__NVIC_PRIO_BITS) the samllest possible priority group is set. + + \param [in] Priority Priority value, which can be retrieved with the function \ref NVIC_GetPriority(). + \param [in] PriorityGroup Used priority group. + \param [out] pPreemptPriority Preemptive priority value (starting from 0). + \param [out] pSubPriority Subpriority value (starting from 0). + */ +__STATIC_INLINE void NVIC_DecodePriority (uint32_t Priority, uint32_t PriorityGroup, uint32_t* pPreemptPriority, uint32_t* pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & 0x07); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7 - PriorityGroupTmp) > __NVIC_PRIO_BITS) ? __NVIC_PRIO_BITS : 7 - PriorityGroupTmp; + SubPriorityBits = ((PriorityGroupTmp + __NVIC_PRIO_BITS) < 7) ? 0 : PriorityGroupTmp - 7 + __NVIC_PRIO_BITS; + + *pPreemptPriority = (Priority >> SubPriorityBits) & ((1 << (PreemptPriorityBits)) - 1); + *pSubPriority = (Priority ) & ((1 << (SubPriorityBits )) - 1); +} + + +/** \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 & SCB_AIRCR_PRIGROUP_Msk) | + SCB_AIRCR_SYSRESETREQ_Msk); /* Keep priority group unchanged */ + __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 */ + + + +/* ##################################### Debug In/Output function ########################################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_core_DebugFunctions ITM Functions + \brief Functions that access the ITM debug interface. + @{ + */ + +extern volatile int32_t ITM_RxBuffer; /*!< External variable to receive characters. */ +#define ITM_RXBUFFER_EMPTY 0x5AA55AA5 /*!< Value identifying \ref ITM_RxBuffer is ready for next character. */ + + +/** \brief ITM Send Character + + The function transmits a character via the ITM channel 0, and + \li Just returns when no debugger is connected that has booked the output. + \li Is blocking when a debugger is connected, but the previous character sent has not been transmitted. + + \param [in] ch Character to transmit. + + \returns Character to transmit. + */ +__STATIC_INLINE uint32_t ITM_SendChar (uint32_t ch) +{ + if ((ITM->TCR & ITM_TCR_ITMENA_Msk) && /* ITM enabled */ + (ITM->TER & (1UL << 0) ) ) /* ITM Port #0 enabled */ + { + while (ITM->PORT[0].u32 == 0); + ITM->PORT[0].u8 = (uint8_t) ch; + } + return (ch); +} + + +/** \brief ITM Receive Character + + The function inputs a character via the external variable \ref ITM_RxBuffer. + + \return Received character. + \return -1 No character pending. + */ +__STATIC_INLINE int32_t ITM_ReceiveChar (void) { + int32_t ch = -1; /* no character available */ + + if (ITM_RxBuffer != ITM_RXBUFFER_EMPTY) { + ch = ITM_RxBuffer; + ITM_RxBuffer = ITM_RXBUFFER_EMPTY; /* ready for next character */ + } + + return (ch); +} + + +/** \brief ITM Check Character + + The function checks whether a character is pending for reading in the variable \ref ITM_RxBuffer. + + \return 0 No character available. + \return 1 Character available. + */ +__STATIC_INLINE int32_t ITM_CheckChar (void) { + + if (ITM_RxBuffer == ITM_RXBUFFER_EMPTY) { + return (0); /* no character available */ + } else { + return (1); /* character available */ + } +} + +/*@} end of CMSIS_core_DebugFunctions */ + +#endif /* __CORE_CM4_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ + +#ifdef __cplusplus +} +#endif diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4_simd.h b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4_simd.h new file mode 100644 index 0000000..42e0b8a --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cm4_simd.h @@ -0,0 +1,652 @@ +/**************************************************************************//** + * @file core_cm4_simd.h + * @brief CMSIS Cortex-M4 SIMD Header File + * @version V3.00 + * @date 19. January 2012 + * + * @note + * Copyright (C) 2010-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. + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CM4_SIMD_H +#define __CORE_CM4_SIMD_H + + +/******************************************************************************* + * Hardware Abstraction Layer + ******************************************************************************/ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if defined ( __CC_ARM ) /*------------------RealView Compiler -----------------*/ +/* ARM armcc specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#define __SADD8 __sadd8 +#define __QADD8 __qadd8 +#define __SHADD8 __shadd8 +#define __UADD8 __uadd8 +#define __UQADD8 __uqadd8 +#define __UHADD8 __uhadd8 +#define __SSUB8 __ssub8 +#define __QSUB8 __qsub8 +#define __SHSUB8 __shsub8 +#define __USUB8 __usub8 +#define __UQSUB8 __uqsub8 +#define __UHSUB8 __uhsub8 +#define __SADD16 __sadd16 +#define __QADD16 __qadd16 +#define __SHADD16 __shadd16 +#define __UADD16 __uadd16 +#define __UQADD16 __uqadd16 +#define __UHADD16 __uhadd16 +#define __SSUB16 __ssub16 +#define __QSUB16 __qsub16 +#define __SHSUB16 __shsub16 +#define __USUB16 __usub16 +#define __UQSUB16 __uqsub16 +#define __UHSUB16 __uhsub16 +#define __SASX __sasx +#define __QASX __qasx +#define __SHASX __shasx +#define __UASX __uasx +#define __UQASX __uqasx +#define __UHASX __uhasx +#define __SSAX __ssax +#define __QSAX __qsax +#define __SHSAX __shsax +#define __USAX __usax +#define __UQSAX __uqsax +#define __UHSAX __uhsax +#define __USAD8 __usad8 +#define __USADA8 __usada8 +#define __SSAT16 __ssat16 +#define __USAT16 __usat16 +#define __UXTB16 __uxtb16 +#define __UXTAB16 __uxtab16 +#define __SXTB16 __sxtb16 +#define __SXTAB16 __sxtab16 +#define __SMUAD __smuad +#define __SMUADX __smuadx +#define __SMLAD __smlad +#define __SMLADX __smladx +#define __SMLALD __smlald +#define __SMLALDX __smlaldx +#define __SMUSD __smusd +#define __SMUSDX __smusdx +#define __SMLSD __smlsd +#define __SMLSDX __smlsdx +#define __SMLSLD __smlsld +#define __SMLSLDX __smlsldx +#define __SEL __sel +#define __QADD __qadd +#define __QSUB __qsub + +#define __PKHBT(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0x0000FFFFUL) | \ + ((((uint32_t)(ARG2)) << (ARG3)) & 0xFFFF0000UL) ) + +#define __PKHTB(ARG1,ARG2,ARG3) ( ((((uint32_t)(ARG1)) ) & 0xFFFF0000UL) | \ + ((((uint32_t)(ARG2)) >> (ARG3)) & 0x0000FFFFUL) ) + + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __ICCARM__ ) /*------------------ ICC Compiler -------------------*/ +/* IAR iccarm specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#include + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TMS470__ ) /*---------------- TI CCS Compiler ------------------*/ +/* TI CCS specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +#include + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __GNUC__ ) /*------------------ GNU Compiler ---------------------*/ +/* GNU gcc specific functions */ + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHADD16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhadd16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSUB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsub16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHASX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhasx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("ssax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("shsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UQSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uqsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UHSAX(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uhsax %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USAD8(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("usad8 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __USADA8(uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("usada8 %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SSAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +#define __USAT16(ARG1,ARG2) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat16 %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __UXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("uxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SXTAB16(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sxtab16 %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUAD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuad %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUADX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smuadx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLAD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlad %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLADX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smladx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SMLALD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLALDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((uint64_t)(ARG3) >> 32), __ARG3_L = (uint32_t)((uint64_t)(ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSD (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMUSDX (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("smusdx %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSD (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsd %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SMLSDX (uint32_t op1, uint32_t op2, uint32_t op3) +{ + uint32_t result; + + __ASM volatile ("smlsdx %0, %1, %2, %3" : "=r" (result) : "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#define __SMLSLD(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +#define __SMLSLDX(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __ARG1 = (ARG1), __ARG2 = (ARG2), __ARG3_H = (uint32_t)((ARG3) >> 32), __ARG3_L = (uint32_t)((ARG3) & 0xFFFFFFFFUL); \ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (__ARG3_L), "=r" (__ARG3_H) : "r" (__ARG1), "r" (__ARG2), "0" (__ARG3_L), "1" (__ARG3_H) ); \ + (uint64_t)(((uint64_t)__ARG3_H << 32) | __ARG3_L); \ + }) + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __SEL (uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("sel %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QADD(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__attribute__( ( always_inline ) ) __STATIC_INLINE uint32_t __QSUB(uint32_t op1, uint32_t op2) +{ + uint32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#define __PKHBT(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + __ASM ("pkhbt %0, %1, %2, lsl %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +#define __PKHTB(ARG1,ARG2,ARG3) \ +({ \ + uint32_t __RES, __ARG1 = (ARG1), __ARG2 = (ARG2); \ + if (ARG3 == 0) \ + __ASM ("pkhtb %0, %1, %2" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2) ); \ + else \ + __ASM ("pkhtb %0, %1, %2, asr %3" : "=r" (__RES) : "r" (__ARG1), "r" (__ARG2), "I" (ARG3) ); \ + __RES; \ + }) + +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + + +#elif defined ( __TASKING__ ) /*------------------ TASKING Compiler --------------*/ +/* TASKING carm specific functions */ + + +/*------ CM4 SIMD Intrinsics -----------------------------------------------------*/ +/* not yet supported */ +/*-- End CM4 SIMD Intrinsics -----------------------------------------------------*/ + + +#endif + +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CORE_CM4_SIMD_H */ + +#ifdef __cplusplus +} +#endif diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmFunc.h b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmFunc.h new file mode 100644 index 0000000..093dc76 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmFunc.h @@ -0,0 +1,619 @@ +/**************************************************************************//** + * @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. + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + +#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/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmInstr.h b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmInstr.h new file mode 100644 index 0000000..11f7624 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Include/core_cmInstr.h @@ -0,0 +1,621 @@ +/**************************************************************************//** + * @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. + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + +#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/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/Lib/GCC/libarm_cortexM4lf_math.a new file mode 100644 index 0000000000000000000000000000000000000000..ceaf7bfc5c2bc8ddbcdb2417d450c6a508f206a1 GIT binary patch literal 2270540 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

Bl<-Umvy^a2344_AMF~R` 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

XPL)&J2^?AF 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%0A>ft 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 jm6jc5Sy<%m58z8%p3 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ℑ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 z

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

!_IBzcva=L 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

YfbGnYZ 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%0AkkI@#@iN5&2AA6~f{w4flw{+A| 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

NCQ;70A} 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�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Ν$ae8?LFDJOx-Y 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 Hyax5ZuL@a6 literal 0 HcmV?d00001 diff --git a/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/README.txt b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/README.txt new file mode 100644 index 0000000..41cede7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/ASF/thirdparty/CMSIS/README.txt @@ -0,0 +1,37 @@ +* ------------------------------------------------------------------- +* Copyright (C) 2011 ARM Limited. All rights reserved. +* +* Date: 11 October 2011 +* Revision: V3.00 +* +* Project: Cortex Microcontroller Software Interface Standard (CMSIS) +* Title: Release Note for CMSIS +* +* ------------------------------------------------------------------- + + +NOTE - Open the index.html file to access CMSIS documentation + + +The Cortex Microcontroller Software Interface Standard (CMSIS) provides a single standard across all +Cortex-Mx processor series vendors. It enables code re-use and code sharing across software projects +and reduces time-to-market for new embedded applications. + +CMSIS is released under the terms of the end user license agreement ("CMSIS END USER LICENCE AGREEMENT.pdf"). +Any user of the software package is bound to the terms and conditions of the end user license agreement. + + +You will find the following sub-directories: + +Documentation - Contains CMSIS documentation. + +DSP_Lib - MDK project files, Examples and source files etc.. to build the + CMSIS DSP Software Library for Cortex-M0, Cortex-M3, Cortex-M4 processors. + +Include - CMSIS Core Support and CMSIS DSP Include Files. + +Lib - CMSIS DSP Libraries. + +RTOS - CMSIS RTOS API template header file. + +SVD - CMSIS SVD Schema files and Conversion Utility. diff --git a/projects/freertos/atmel/sam4e-ek/src/asf.h b/projects/freertos/atmel/sam4e-ek/src/asf.h new file mode 100644 index 0000000..1450c39 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/asf.h @@ -0,0 +1,117 @@ +/** + * \file + * + * \brief Autogenerated API include file for the Atmel Software Framework (ASF) + * + * Copyright (c) 2012 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 ASF_H +#define ASF_H + +/* + * This file includes all API header files for the selected drivers from ASF. + * Note: There might be duplicate includes required by more than one driver. + * + * The file is automatically generated and will be re-written when + * running the ASF driver selector tool. Any changes will be discarded. + */ + +// From module: Common SAM compiler driver +#include +#include + +// From module: Delay routines +#include + +// From module: Generic board support +#include + +// From module: High Speed Multimedia Card Interface +#include + +// From module: IOPORT - General purpose I/O service +#include + +// From module: Interrupt management - SAM implementation +#include + +// From module: Memory Control Access Interface +#include + +// From module: PDC - Peripheral DMA Controller Example +#include + +// From module: PMC - Power Management Controller +#include +#include + +// From module: Part identification macros +#include + +// From module: SAM FPU driver +#include + +// From module: SAM4E EK LED support enabled +#include + +// From module: SAM4E startup code +#include + +// From module: SD/MMC Memory Control Access - Enable +#include + +// From module: SD/MMC stack on Multimedia Card interface +#include + +// From module: Standard serial I/O (stdio) - SAM implementation +#include + +// From module: System Clock Control - SAM4E implementation +#include + +// From module: UART - Univ. Async Rec/Trans +#include + +// From module: USART - Serial interface - SAM implementation for devices with both UART and USART +#include + +// From module: USART - Univ. Syn Async Rec/Trans +#include + +#endif // ASF_H diff --git a/projects/freertos/atmel/sam4e-ek/src/config/FreeRTOSConfig.h b/projects/freertos/atmel/sam4e-ek/src/config/FreeRTOSConfig.h new file mode 100644 index 0000000..a1f0cd7 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/FreeRTOSConfig.h @@ -0,0 +1,251 @@ +/* + FreeRTOS V8.2.0 - Copyright (C) 2015 Real Time Engineers Ltd. + All rights reserved + + VISIT http://www.FreeRTOS.org TO ENSURE YOU ARE USING THE LATEST VERSION. + + This file is part of the FreeRTOS distribution. + + FreeRTOS is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License (version 2) as published by the + Free Software Foundation >>!AND MODIFIED BY!<< the FreeRTOS exception. + + *************************************************************************** + >>! NOTE: The modification to the GPL is included to allow you to !<< + >>! distribute a combined work that includes FreeRTOS without being !<< + >>! obliged to provide the source code for proprietary components !<< + >>! outside of the FreeRTOS kernel. !<< + *************************************************************************** + + FreeRTOS is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + FOR A PARTICULAR PURPOSE. Full license text is available on the following + link: http://www.freertos.org/a00114.html + + *************************************************************************** + * * + * FreeRTOS provides completely free yet professionally developed, * + * robust, strictly quality controlled, supported, and cross * + * platform software that is more than just the market leader, it * + * is the industry's de facto standard. * + * * + * Help yourself get started quickly while simultaneously helping * + * to support the FreeRTOS project by purchasing a FreeRTOS * + * tutorial book, reference manual, or both: * + * http://www.FreeRTOS.org/Documentation * + * * + *************************************************************************** + + http://www.FreeRTOS.org/FAQHelp.html - Having a problem? Start by reading + the FAQ page "My application does not run, what could be wrong?". Have you + defined configASSERT()? + + http://www.FreeRTOS.org/support - In return for receiving this top quality + embedded software for free we request you assist our global community by + participating in the support forum. + + http://www.FreeRTOS.org/training - Investing in training allows your team to + be as productive as possible as early as possible. Now you can receive + FreeRTOS training directly from Richard Barry, CEO of Real Time Engineers + Ltd, and the world's leading authority on the world's leading RTOS. + + http://www.FreeRTOS.org/plus - A selection of FreeRTOS ecosystem products, + including FreeRTOS+Trace - an indispensable productivity tool, a DOS + compatible FAT file system, and our tiny thread aware UDP/IP stack. + + http://www.FreeRTOS.org/labs - Where new FreeRTOS products go to incubate. + Come and try FreeRTOS+TCP, our new open source TCP/IP stack for FreeRTOS. + + http://www.OpenRTOS.com - Real Time Engineers ltd. license FreeRTOS to High + Integrity Systems ltd. to sell under the OpenRTOS brand. Low cost OpenRTOS + licenses offer ticketed support, indemnification and commercial middleware. + + http://www.SafeRTOS.com - High Integrity Systems also provide a safety + engineered and independently SIL3 certified version for use in safety and + mission critical applications that require provable dependability. + + 1 tab == 4 spaces! +*/ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* Atmel library includes. */ +#include + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +extern uint32_t SystemCoreClock; + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_QUEUE_SETS 1 +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configCPU_CLOCK_HZ ( SystemCoreClock ) +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 120 ) +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 47 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 10 ) +#define configUSE_TRACE_FACILITY 1 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 8 +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_MALLOC_FAILED_HOOK 0 +#define configUSE_APPLICATION_TASK_TAG 0 +#define configUSE_COUNTING_SEMAPHORES 1 + +/* The full demo always has tasks to run so the tick will never be turned off. +The blinky demo will use the default tickless idle implementation to turn the +tick off. */ +#define configUSE_TICKLESS_IDLE 1 + +/* Run time stats gathering definitions. */ +#define configGENERATE_RUN_TIME_STATS 1 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() (void)0 +#define portGET_RUN_TIME_COUNTER_VALUE() 0U + +/* This demo makes use of one or more example stats formatting functions. These +format the raw data provided by the uxTaskGetSystemState() function in to human +readable ASCII form. See the notes in the implementation of vTaskList() within +FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 1 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* Software timer definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( 2 ) +#define configTIMER_QUEUE_LENGTH 5 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE ) + +/* Set the following definitions to 1 to include the API function, or zero +to exclude the API function. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 1 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 + +/* Cortex-M specific definitions. */ +#ifdef __NVIC_PRIO_BITS + /* __BVIC_PRIO_BITS will be specified when CMSIS is being used. */ + #define configPRIO_BITS __NVIC_PRIO_BITS +#else + #define configPRIO_BITS 4 /* 15 priority levels */ +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" +function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY 0xf + +/* The highest interrupt priority that can be used by any interrupt service +routine that makes calls to interrupt safe FreeRTOS API functions. DO NOT CALL +INTERRUPT SAFE FREERTOS API FUNCTIONS FROM ANY INTERRUPT THAT HAS A HIGHER +PRIORITY THAN THIS! (higher priorities are lower numeric values. */ +#define configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY 5 + +/* Interrupt priorities used by the kernel port layer itself. These are generic +to all Cortex-M ports, and do not rely on any particular library functions. */ +#define configKERNEL_INTERRUPT_PRIORITY ( configLIBRARY_LOWEST_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) +/* !!!! configMAX_SYSCALL_INTERRUPT_PRIORITY must not be set to zero !!!! +See http://www.FreeRTOS.org/RTOS-Cortex-M3-M4.html. */ +#define configMAX_SYSCALL_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY << (8 - configPRIO_BITS) ) + +/* Normal assert() semantics without relying on the provision of an assert.h +header file. */ +extern void vAssertCalled( uint32_t ulLine, const char *pcFile ); +#define configASSERT( x ) if( ( x ) == 0 ) vAssertCalled( __LINE__, __FILE__ ) + +/* Definitions that map the FreeRTOS port interrupt handlers to their CMSIS +standard names. */ +#define xPortPendSVHandler PendSV_Handler +#define vPortSVCHandler SVC_Handler +#define xPortSysTickHandler SysTick_Handler + +/* MAC address configuration. In a deployed production system this would +probably be read from an EEPROM. In the demo it is just hard coded. Make sure +each node on the network has a unique MAC address. */ +#define configMAC_ADDR0 0x00 +#define configMAC_ADDR1 0x11 +#define configMAC_ADDR2 0x22 +#define configMAC_ADDR3 0x33 +#define configMAC_ADDR4 0x44 +#define configMAC_ADDR5 0x45 + +/* Default IP address configuration. Used in ipconfigUSE_DNS is set to 0, or +ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configIP_ADDR0 172 +#define configIP_ADDR1 25 +#define configIP_ADDR2 218 +#define configIP_ADDR3 200 + +/* Default gateway IP address configuration. Used in ipconfigUSE_DNS is set to +0, or ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configGATEWAY_ADDR0 172 +#define configGATEWAY_ADDR1 25 +#define configGATEWAY_ADDR2 218 +#define configGATEWAY_ADDR3 2 + +/* Default DNS server configuration. OpenDNS addresses are 208.67.222.222 and +208.67.220.220. Used in ipconfigUSE_DNS is set to 0, or ipconfigUSE_DNS is set +to 1 but a DNS server cannot be contacted.*/ +#define configDNS_SERVER_ADDR0 208 +#define configDNS_SERVER_ADDR1 67 +#define configDNS_SERVER_ADDR2 222 +#define configDNS_SERVER_ADDR3 222 + +/* Default netmask configuration. Used in ipconfigUSE_DNS is set to 0, or +ipconfigUSE_DNS is set to 1 but a DNS server cannot be contacted. */ +#define configNET_MASK0 255 +#define configNET_MASK1 255 +#define configNET_MASK2 255 +#define configNET_MASK3 0 + +/* The address of the echo server. Used when the demo is build to include the +UDP echo tasks (when mainINCLUDE_ECHO_CLIENT_TASKS is set to 1 in +FreeRTOSConfig.h. +http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_UDP/Embedded_Ethernet_Examples/Common_Echo_Clients.shtml */ +#define configECHO_SERVER_ADDR0 172 +#define configECHO_SERVER_ADDR1 25 +#define configECHO_SERVER_ADDR2 218 +#define configECHO_SERVER_ADDR3 100 + + +/* The priority used by the Ethernet MAC driver interrupt. */ +#define configMAC_INTERRUPT_PRIORITY ( configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ) + +/* Dimensions a buffer that can be used by the FreeRTOS+CLI command +interpreter. See the FreeRTOS+CLI documentation for more information: +http://www.FreeRTOS.org/FreeRTOS-Plus/FreeRTOS_Plus_CLI/ */ +#define configCOMMAND_INT_MAX_OUTPUT_SIZE 1024 + +/* If configINCLUDE_DEMO_DEBUG_STATS is set to one, then a few basic IP trace +macros are defined to gather some UDP stack statistics that can then be viewed +through the CLI interface. */ +#define configINCLUDE_DEMO_DEBUG_STATS 1 + +#endif /* FREERTOS_CONFIG_H */ + diff --git a/projects/freertos/atmel/sam4e-ek/src/config/conf_access.h b/projects/freertos/atmel/sam4e-ek/src/config/conf_access.h new file mode 100644 index 0000000..da9963c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/conf_access.h @@ -0,0 +1,183 @@ +/***************************************************************************** + * + * \file + * + * \brief Memory access control configuration file. + * + * This file contains the possible external configuration of the memory access + * control. + * + * Copyright (c) 2009 - 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 + * + ******************************************************************************/ + /** + * Support and FAQ: visit Atmel Support + */ + + + //! Configuration of ctrl_access which is an abstraction layer for memory interfaces (common/services/storage/ctrl_access) + +#ifndef _CONF_ACCESS_H_ +#define _CONF_ACCESS_H_ + +#include "compiler.h" +#include "board.h" + + +/*! \name Activation of Logical Unit Numbers + */ +//! @{ +#define LUN_0 DISABLE //!< On-Chip Virtual Memory. +#define LUN_1 DISABLE //!< AT45DBX Data Flash. +#define LUN_2 ENABLE //!< SD/MMC Card over Slot 0 +#define LUN_3 DISABLE //!< Spare +#define LUN_4 DISABLE //!< Spare +#define LUN_5 DISABLE //!< Spare +#define LUN_6 DISABLE //!< Spare +#define LUN_7 DISABLE //!< Spare +#define LUN_USB DISABLE //!< Host Mass-Storage Memory. +//! @} + +/*! \name LUN 0 Definitions + */ +//! @{ +#define VIRTUAL_MEM LUN_0 +#define LUN_ID_VIRTUAL_MEM LUN_ID_0 +#define LUN_0_INCLUDE "virtual_mem.h" +#define Lun_0_test_unit_ready virtual_test_unit_ready +#define Lun_0_read_capacity virtual_read_capacity +#define Lun_0_unload NULL /* Can not be unloaded */ +#define Lun_0_wr_protect virtual_wr_protect +#define Lun_0_removal virtual_removal +#define Lun_0_usb_read_10 virtual_usb_read_10 +#define Lun_0_usb_write_10 virtual_usb_write_10 +#define Lun_0_mem_2_ram virtual_mem_2_ram +#define Lun_0_ram_2_mem virtual_ram_2_mem +#define LUN_0_NAME "\"On-Chip Virtual Memory\"" +//! @} + +/*! \name LUN 1 Definitions + */ +//! @{ +#define AT45DBX_MEM LUN_1 +#define LUN_ID_AT45DBX_MEM LUN_ID_1 +#define LUN_1_INCLUDE "at45dbx_mem.h" +#define Lun_1_test_unit_ready at45dbx_test_unit_ready +#define Lun_1_read_capacity at45dbx_read_capacity +#define Lun_1_unload NULL /* Can not be unloaded */ +#define Lun_1_wr_protect at45dbx_wr_protect +#define Lun_1_removal at45dbx_removal +#define Lun_1_usb_read_10 at45dbx_usb_read_10 +#define Lun_1_usb_write_10 at45dbx_usb_write_10 +#define Lun_1_mem_2_ram at45dbx_df_2_ram +#define Lun_1_ram_2_mem at45dbx_ram_2_df +#define LUN_1_NAME "\"AT45DBX Data Flash\"" +//! @} + +/*! \name LUN 2 Definitions + */ +//! @{ +#define SD_MMC_0_MEM LUN_2 +#define LUN_ID_SD_MMC_0_MEM LUN_ID_2 +#define LUN_2_INCLUDE "sd_mmc_mem.h" +#define Lun_2_test_unit_ready sd_mmc_test_unit_ready_0 +#define Lun_2_read_capacity sd_mmc_read_capacity_0 +#define Lun_2_unload sd_mmc_unload_0 +#define Lun_2_wr_protect sd_mmc_wr_protect_0 +#define Lun_2_removal sd_mmc_removal_0 +#define Lun_2_usb_read_10 sd_mmc_usb_read_10_0 +#define Lun_2_usb_write_10 sd_mmc_usb_write_10_0 +#define Lun_2_mem_2_ram sd_mmc_mem_2_ram_0 +#define Lun_2_ram_2_mem sd_mmc_ram_2_mem_0 +#define LUN_2_NAME "\"SD/MMC Card Slot 0\"" +//! @} + +/*! \name USB LUNs Definitions + */ +//! @{ +#define MEM_USB LUN_USB +#define LUN_ID_MEM_USB LUN_ID_USB +#define LUN_USB_INCLUDE "uhi_msc_mem.h" +#define Lun_usb_get_lun() uhi_msc_mem_get_lun() +#define Lun_usb_test_unit_ready(lun) uhi_msc_mem_test_unit_ready(lun) +#define Lun_usb_read_capacity(lun, nb_sect) uhi_msc_mem_read_capacity(lun, nb_sect) +#define Lun_usb_read_sector_size(lun) uhi_msc_mem_read_sector_size(lun) +#define Lun_usb_unload NULL +#define Lun_usb_wr_protect(lun) uhi_msc_mem_wr_protect(lun) +#define Lun_usb_removal() uhi_msc_mem_removal() +#define Lun_usb_mem_2_ram(addr, ram) uhi_msc_mem_read_10_ram(addr, ram) +#define Lun_usb_ram_2_mem(addr, ram) uhi_msc_mem_write_10_ram(addr, ram) +#define LUN_USB_NAME "\"Host Mass-Storage Memory\"" +//! @} + +/*! \name Actions Associated with Memory Accesses + * + * Write here the action to associate with each memory access. + * + * \warning Be careful not to waste time in order not to disturb the functions. + */ +//! @{ +#define memory_start_read_action(nb_sectors) +#define memory_stop_read_action() +#define memory_start_write_action(nb_sectors) +#define memory_stop_write_action() +//! @} + +/*! \name Activation of Interface Features + */ +//! @{ +#define ACCESS_USB false //!< MEM <-> USB interface. +#define ACCESS_MEM_TO_RAM true //!< MEM <-> RAM interface. +#define ACCESS_STREAM false //!< Streaming MEM <-> MEM interface. +#define ACCESS_STREAM_RECORD false //!< Streaming MEM <-> MEM interface in record mode. +#define ACCESS_MEM_TO_MEM false //!< MEM <-> MEM interface. +#define ACCESS_CODEC false //!< Codec interface. +//! @} + +/*! \name Specific Options for Access Control + */ +//! @{ +#define GLOBAL_WR_PROTECT false //!< Management of a global write protection. +//! @} + +/*! \name Sector size option for different storage media. + */ +//! @{ +#define SECTOR_SIZE 512 +//! @} + +#endif // _CONF_ACCESS_H_ diff --git a/projects/freertos/atmel/sam4e-ek/src/config/conf_board.h b/projects/freertos/atmel/sam4e-ek/src/config/conf_board.h new file mode 100644 index 0000000..f83183c --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/conf_board.h @@ -0,0 +1,62 @@ +/** + * \file + * + * \brief Board configuration + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_BOARD_H_INCLUDED +#define CONF_BOARD_H_INCLUDED + +/** Define to avoid disabling the watchdog at startup. */ +//#define CONF_BOARD_KEEP_WATCHDOG_AT_INIT + +/** Enable COM Port. */ +#define CONF_BOARD_UART_CONSOLE + +/** USART Hw ID used by the console (UART0). */ +#define CONSOLE_UART_ID ID_UART0 + +/** Enable SD MMC interface pins through HSMCI */ +#define CONF_BOARD_SD_MMC_HSMCI + +#endif /* CONF_BOARD_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/config/conf_clock.h b/projects/freertos/atmel/sam4e-ek/src/config/conf_clock.h new file mode 100644 index 0000000..9924b15 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/conf_clock.h @@ -0,0 +1,86 @@ +/** + * \file + * + * \brief SAM4E clock configuration. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_CLOCK_H_INCLUDED +#define CONF_CLOCK_H_INCLUDED + +// ===== System Clock (MCK) Source Options +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_SLCK_BYPASS +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_4M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_8M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_12M_RC +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_XTAL +//#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_MAINCK_BYPASS +#define CONFIG_SYSCLK_SOURCE SYSCLK_SRC_PLLACK + +// ===== System Clock (MCK) Prescaler Options (Fmck = Fsys / (SYSCLK_PRES)) +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_1 +#define CONFIG_SYSCLK_PRES SYSCLK_PRES_2 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_4 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_8 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_16 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_32 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_64 +//#define CONFIG_SYSCLK_PRES SYSCLK_PRES_3 + +// ===== PLL0 (A) Options (Fpll = (Fclk * PLL_mul) / PLL_div) +// Use mul and div effective values here. +#define CONFIG_PLL0_SOURCE PLL_SRC_MAINCK_XTAL +#define CONFIG_PLL0_MUL 20 +#define CONFIG_PLL0_DIV 1 + +// ===== Target frequency (System clock) +// - XTAL frequency: 12MHz +// - System clock source: PLLA +// - System clock prescaler: 2 (divided by 2) +// - PLLA source: XTAL +// - PLLA output: XTAL * 20 / 1 +// - System clock: 12 * 20 / 1 / 2 = 120MHz + + +#endif /* CONF_CLOCK_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/config/conf_sd_mmc.h b/projects/freertos/atmel/sam4e-ek/src/config/conf_sd_mmc.h new file mode 100644 index 0000000..5ace042 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/conf_sd_mmc.h @@ -0,0 +1,60 @@ +/** + * \file + * + * \brief SD/MMC stack configuration file. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_SD_MMC_H_INCLUDED +#define CONF_SD_MMC_H_INCLUDED + +/* Define it to enable the SPI mode instead of Multimedia Card interface mode */ +//#define SD_MMC_SPI_MODE + +/* Define it to enable the SDIO support */ +#define SDIO_SUPPORT_ENABLE + +/* Define it to enable the debug trace to the current standard output (stdio) */ +//#define SD_MMC_DEBUG + +#endif /* CONF_SD_MMC_H_INCLUDED */ + diff --git a/projects/freertos/atmel/sam4e-ek/src/config/conf_uart_serial.h b/projects/freertos/atmel/sam4e-ek/src/config/conf_uart_serial.h new file mode 100644 index 0000000..00d261e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/conf_uart_serial.h @@ -0,0 +1,51 @@ +/*! \file + * + * \brief Serial USART service configuration. + * + * 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 + * + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#ifndef CONF_USART_SERIAL_H_INCLUDED +#define CONF_USART_SERIAL_H_INCLUDED + +/* Intentionally empty */ + +#endif/* CONF_USART_SERIAL_H_INCLUDED */ diff --git a/projects/freertos/atmel/sam4e-ek/src/config/redconf.c b/projects/freertos/atmel/sam4e-ek/src/config/redconf.c new file mode 100644 index 0000000..a35b158 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/redconf.c @@ -0,0 +1,15 @@ +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + UTILITY. DO NOT MODIFY. +*/ +/** @file +*/ +#include +#include +#include +#include + + +const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] = +{ + { 512U, 3862528U, false, 1000U, ""} +}; diff --git a/projects/freertos/atmel/sam4e-ek/src/config/redconf.h b/projects/freertos/atmel/sam4e-ek/src/config/redconf.h new file mode 100644 index 0000000..0a5c7e4 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/redconf.h @@ -0,0 +1,102 @@ +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + UTILITY. DO NOT MODIFY. +*/ +/** @file +*/ +#ifndef REDCONF_H +#define REDCONF_H + + +#include + +#define REDCONF_READ_ONLY 0 + +#define REDCONF_API_POSIX 1 + +#define REDCONF_API_FSE 0 + +#define REDCONF_API_POSIX_FORMAT 1 + +#define REDCONF_API_POSIX_LINK 1 + +#define REDCONF_API_POSIX_UNLINK 1 + +#define REDCONF_API_POSIX_MKDIR 1 + +#define REDCONF_API_POSIX_RMDIR 1 + +#define REDCONF_API_POSIX_RENAME 1 + +#define REDCONF_RENAME_ATOMIC 1 + +#define REDCONF_API_POSIX_FTRUNCATE 1 + +#define REDCONF_API_POSIX_READDIR 1 + +#define REDCONF_NAME_MAX 12U + +#define REDCONF_PATH_SEPARATOR '/' + +#define REDCONF_TASK_COUNT 10U + +#define REDCONF_HANDLE_COUNT 10U + +#define REDCONF_API_FSE_TRUNCATE 0 + +#define REDCONF_API_FSE_TRANSMASKGET 0 + +#define REDCONF_API_FSE_TRANSMASKSET 0 + +#define REDCONF_OUTPUT 1 + +#define REDCONF_ASSERTS 1 + +#define REDCONF_BLOCK_SIZE 512U + +#define REDCONF_VOLUME_COUNT 1U + +#define REDCONF_ENDIAN_BIG 0 + +#define REDCONF_ALIGNMENT_SIZE 4U + +#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8 + +#define REDCONF_INODE_BLOCKS 1 + +#define REDCONF_INODE_TIMESTAMPS 1 + +#define REDCONF_ATIME 0 + +#define REDCONF_DIRECT_POINTERS 4U + +#define REDCONF_INDIRECT_POINTERS 32U + +#define REDCONF_BUFFER_COUNT 12U + +#define RedMemCpy memcpy + +#define RedMemMove memmove + +#define RedMemSet memset + +#define RedMemCmp memcmp + +#define RedStrLen (uint32_t)strlen + +#define RedStrCmp strcmp + +#define RedStrNCmp strncmp + +#define RedStrNCpy strncpy + +#define REDCONF_TRANSACT_DEFAULT (( RED_TRANSACT_CREAT | RED_TRANSACT_MKDIR | RED_TRANSACT_RENAME | RED_TRANSACT_LINK | RED_TRANSACT_UNLINK | RED_TRANSACT_FSYNC | RED_TRANSACT_CLOSE | RED_TRANSACT_VOLFULL | RED_TRANSACT_UMOUNT ) & RED_TRANSACT_MASK) + +#define REDCONF_IMAP_INLINE 0 + +#define REDCONF_IMAP_EXTERNAL 1 + +#define REDCONF_IMAGE_BUILDER 0 + +#define REDCONF_CHECKER 0 + +#endif diff --git a/projects/freertos/atmel/sam4e-ek/src/config/redtypes.h b/projects/freertos/atmel/sam4e-ek/src/config/redtypes.h new file mode 100644 index 0000000..3192e38 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/config/redtypes.h @@ -0,0 +1,97 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +/* Defines bool. +*/ +#include + +/* Defines uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, + int64_t, and uintptr_t. +*/ +#include + + +#endif + diff --git a/projects/freertos/atmel/sam4e-ek/src/hooks.c b/projects/freertos/atmel/sam4e-ek/src/hooks.c new file mode 100644 index 0000000..d4d24ca --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/hooks.c @@ -0,0 +1,111 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include + +#include +#include + +#include + + +/** @brief Handler for Atmel SAM4E-EK hard faults. + + The hard fault handler has been observed to be invoked when attempts are + made to dynamically allocate a large amount of memory. The default handler + simply loops forever, resulting in a silent hang. Overriding the default + handler at least makes it obvious that something has gone wrong. +*/ +void HardFault_Handler(void) +{ + /* Produce output even if asserts are disabled. + */ + fprintf(stderr, "Hard fault handler invoked!\n\r"); + + REDERROR(); + + /* Don't return. After a hard fault, things are possibly in a bad state. + Even when we get here from malloc(), if we return from here malloc() + returns a bogus pointer instead of a NULL pointer, so error recovery is + not possible. + */ + while(true) + { + } +} + + +/** @brief Handler for asserts firing from the FreeRTOS code. +*/ +void vAssertCalled( + uint32_t ulLine, + const char *pcFile) +{ + /* The following two variables are just to ensure the parameters are not + optimized away and therefore unavailable when viewed in the debugger. + */ + volatile uint32_t ulLineNumber = ulLine, ulSetNonZeroInDebuggerToReturn = 0; + volatile const char * const pcFileName = pcFile; + + /* Invoke Reliance Edge assertion handler if available. + */ + RedOsAssertFail(pcFile, ulLine); + + taskENTER_CRITICAL(); + while( ulSetNonZeroInDebuggerToReturn == 0 ) + { + /* If you want to get out of this function in the debugger to see the + assert() location then set ulSetNonZeroInDebuggerToReturn to a + non-zero value. + */ + } + taskEXIT_CRITICAL(); + + (void)pcFileName; + (void)ulLineNumber; +} + + +#if configCHECK_FOR_STACK_OVERFLOW > 0 +/* Prototype to quiet a warning. +*/ +void vApplicationStackOverflowHook(TaskHandle_t pxTask, char *pcTaskName); + + +/** @brief Handler for stack overflows. +*/ +void vApplicationStackOverflowHook( + TaskHandle_t pxTask, + char *pcTaskName) +{ + (void)pcTaskName; + (void)pxTask; + + /* Run time stack overflow checking is performed if + configCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook + function is called if a stack overflow is detected. + */ + vAssertCalled(__LINE__, __FILE__); +} +#endif diff --git a/projects/freertos/atmel/sam4e-ek/src/main.c b/projects/freertos/atmel/sam4e-ek/src/main.c new file mode 100644 index 0000000..864825e --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/main.c @@ -0,0 +1,176 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Example application entry point for using Reliance Edge. +*/ +#include +#include +#include "conf_board.h" +#include "conf_clock.h" +#include "conf_example.h" +#include "sd_mmc_protocol.h" +#include "memtest.h" + +#include +#include + +#include + + +#define RUN_ATMEL_MEMTEST 0 + + +static void vRedTestTask(void *pParam); + + +/** + * \brief Application entry point. + * + * \return Unused (ANSI-C compatibility). + */ +int main(void) +{ + TaskHandle_t vTask; + + const usart_serial_options_t usart_serial_options = + { + .baudrate = CONF_TEST_BAUDRATE, + .charlength = CONF_TEST_CHARLENGTH, + .paritytype = CONF_TEST_PARITY, + .stopbits = CONF_TEST_STOPBITS, + }; + + irq_initialize_vectors(); + cpu_irq_enable(); + + sysclk_init(); + board_init(); + stdio_serial_init(CONF_TEST_USART, &usart_serial_options); + + // Initialize SD MMC stack + sd_mmc_init(); + + if(xTaskCreate(vRedTestTask, "REDTEST", (1024U * 3U) / sizeof(StackType_t), NULL, tskIDLE_PRIORITY + 1U, &vTask) != pdPASS) + { + fprintf(stderr, "Failed to create Reliance Edge test task\n\r"); + return 1; + } + + /* Start the FreeRTOS task scheduler. + */ + vTaskStartScheduler(); + + /* vTaskStartScheduler() never returns unless there was not enough RAM to + start the scheduler. + */ + fprintf(stderr, "Failed to start FreeRTOS task scheduler: insufficient RAM\n\r"); + return 1; +} + + +/** @brief FreeRTOS task which runs Reliance Edge file system tests. + + @param pParam Unused, for prototype compatibility with TaskFunction_t. +*/ +static void vRedTestTask( + void *pParam) +{ + /* We don't use the parameter. + */ + (void)pParam; + + printf("\n\rReliance Edge example task started...\n\r"); + + #if RUN_ATMEL_MEMTEST == 1 + AtmelMemTest(); + #endif + + #if REDCONF_API_POSIX == 1 + { + int32_t ret; + int32_t ret2; + + ret = red_init(); + if(ret == 0) + { + #if REDCONF_API_POSIX_FORMAT == 1 + ret = red_format(""); + if(ret == 0) + #endif + { + ret = red_mount(""); + if(ret == 0) + { + /* Add test code here. + */ + ;; + + ret2 = red_umount(""); + if(ret == 0) + { + ret = ret2; + } + } + } + + (void)red_uninit(); + } + } + #elif REDCONF_API_FSE == 1 + { + REDSTATUS ret; + REDSTATUS ret2; + + ret = RedFseInit(); + if(ret == 0) + { + ret = RedFseMount(0U); + if(ret == 0) + { + /* Add test code here. + */ + ;; + + ret2 = RedFseUnmount(0U); + if(ret == 0) + { + ret = ret2; + } + } + + (void)RedFseUninit(); + } + } + #endif + + printf("Reliance Edge example task complete.\n\r"); + + /* FreeRTOS tasks must never return. + */ + while(true) + { + } +} + diff --git a/projects/freertos/atmel/sam4e-ek/src/memtest.c b/projects/freertos/atmel/sam4e-ek/src/memtest.c new file mode 100644 index 0000000..1cb6319 --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/memtest.c @@ -0,0 +1,521 @@ +/** + * \file + * + * \brief SD/MMC card example + * + * 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 + * + */ + +/** + * \mainpage SD/MMC/SDIO Card Example + * + * \section Purpose + * + * This example demonstrates basic functions of SD/MMC/SDIO stack. + * It will read and write an SD, MMC or SDIO card over MCI or SPI interface. + * It is a development base for a SDIO application or a specific SD/MMC + * application which does not require a file system. + * + * \section Description + * + * The example executes the following sequences: + * - For each card slot available on board: + * - Wait for a card insertion + * - Initialize an SD, MMC or SDIO card. + * - If the inserted card is an SD or MMC card, test read/write access. + * - Write data into the card + * - Read data from the card + * - Verify the written data. + * - If the inserted card is a SDIO card: + * - Iniltialize a SDIO card. + * - Read and write test on CIA. + * + * The example outputs the information through the standard output (stdio). + * To know the output used on the board, look in the conf_example.h file + * and connect a terminal to the correct stdio port. + * + * While using SAM4L Xplained Pro or SAM4L8 Xplained Pro, please attach IO1 + * Xplained Pro extension board to EXT1. + * + * While using Xplained Pro evaluation kits, please attach I/O1 Xplained Pro + * extension board to EXT1. + * + * \section Usage + * + * -# Build the program and download it into the board. + * -# On the computer, open and configure a terminal application. + * Refer to conf_example.h file. + * -# Start the application. + * -# In the terminal window, the following text should appear: + * \code + -- SD/MMC/SDIO Card Example -- + -- Compiled: xxx xx xxxx xx:xx:xx -- + Please plug an SD, MMC or SDIO card in slot 1. + !!Warning, the data contained will be lost!! +\endcode + * -# If the inserted card is a SD or MMC card, the following text should appear: + * \code + A card has been connected. + Card information: + xxxx + xxxx MB + Write pattern... XXXXKBps [OK] + Read... XXXXKBps [OK] + Read and check pattern... [OK] + Test finished, please unplugged card. +\endcode + * -# If inserted card is a SDIO card, similar following text should appear: + * \code + A card has been connected. + Card information: + SDIO + 0MB + --- Test with direct read and write command of CIA: + Dump buffer (length=22): + 0: 11 00 00 00 00 00 00 00 17 00 10 00 00 00 00 00 + 10: 00 00 01 00 00 00 + Write 0x02 to IEN(CIA.4). + Check IEN after write:0x02 + Test OK + + --- Test with extended read and write command of CIA: + Dump buffer (length=22): + 0: 11 00 00 00 00 00 00 00 17 00 10 00 00 00 00 00 + 10: 00 00 01 00 00 00 + Modify Some R/W bytes (2,4) for FN0 and write: + Check CIA after write: + Dump buffer (length=22): + 0: 11 00 00 00 03 00 00 00 17 00 10 00 00 00 00 00 + 10: 00 00 01 00 00 00 + test OK + All test done. +\endcode + */ + /** + * Support and FAQ: visit Atmel Support + */ + +#include +#include +#include "sd_mmc_protocol.h" +#include +#include "memtest.h" + +/* For the timestamp OS service. This test originally used a custom + SysTick_Handler() for its timestamps, but FreeRTOS needs SysTick_Handler() + for its own purposes. +*/ +#include + +//! \name Read/write access configurations +//! @{ + +//! Offset before the end of memory card to start the test +#define TEST_MEM_START_OFFSET (1024lu * 1024lu * 4lu) // 4MB + +//! Memory area size dedicated for the read/write test +#define TEST_MEM_AREA_SIZE (1024lu * 1024lu * 1lu) // 1MB +/** + * Size of each read or write access. + * Increasing this number can get higher R/W performance. + */ +#define TEST_MEM_ACCESS_SIZE (8lu * SD_MMC_BLOCK_SIZE) + +#if TEST_MEM_START_OFFSET < TEST_MEM_AREA_SIZE +# error TEST_MEM_START_OFFSET must be higher than TEST_MEM_AREA_SIZE +#endif +#if TEST_MEM_ACCESS_SIZE > TEST_MEM_AREA_SIZE +# error TEST_MEM_AREA_SIZE must be higher than TEST_MEM_ACCESS_SIZE +#endif + +//! The value used to generate test data +#define TEST_FILL_VALUE_U32 (0x5500AAFFU) + +//! Buffer used by read/write tests +COMPILER_WORD_ALIGNED +static uint8_t buf_test[TEST_MEM_ACCESS_SIZE]; + +//! Read and write test length of CIA in bytes +#define TEST_CIA_SIZE (0x16) + +//! Buffer for test SDIO data +static uint8_t buf_cia[TEST_CIA_SIZE]; +//! @} + +static void main_display_info_card(uint8_t slot); +static void main_test_memory(uint8_t slot); +static void main_test_sdio(uint8_t slot); +static void main_dump_buffer(uint8_t *data_buffer, uint32_t length); + +void AtmelMemTest(void) +{ + uint8_t slot = 0; + sd_mmc_err_t err; + REDSTATUS ret; + + printf("\x0C\n\r-- SD/MMC/SDIO Card Example --\n\r"); + printf("-- Compiled: %s %s --\n\r", __DATE__, __TIME__); + + printf("Please plug an SD, MMC or SDIO card in slot %d.\n\r", slot+1); + + // Wait for a card and ready + do { + err = sd_mmc_check(slot); + if ((SD_MMC_ERR_NO_CARD != err) + && (SD_MMC_INIT_ONGOING != err) + && (SD_MMC_OK != err)) { + printf("Card install FAILED\n\r"); + printf("Please unplug and re-plug the card.\n\r"); + while(SD_MMC_ERR_NO_CARD != sd_mmc_check(slot)) { + } + } + } while (SD_MMC_OK != err); + + // Display basic card information + main_display_info_card(slot); + + ret = RedOsTimestampInit(); + if (ret != 0) { + printf("Unable to initialize timestamps, err=%d\n\r", (int)ret); + return; + } + + /* Test the card */ + if (sd_mmc_get_type(slot) & CARD_TYPE_SDIO) { + // Test CIA of SDIO card + main_test_sdio(slot); + } + if (sd_mmc_get_type(slot) & (CARD_TYPE_SD | CARD_TYPE_MMC)) { + // SD/MMC Card R/W + main_test_memory(slot); + } + + (void)RedOsTimestampUninit(); + + printf("SD/MMC card test finished.\n\r"); +} + +/** + * \brief Display basic information of the card. + * \note This function should be called only after the card has been + * initialized successfully. + * + * \param slot SD/MMC slot to test + */ +static void main_display_info_card(uint8_t slot) +{ + printf("Card information:\n\r"); + + printf(" "); + switch (sd_mmc_get_type(slot)) { + case CARD_TYPE_SD | CARD_TYPE_HC: + printf("SDHC"); + break; + case CARD_TYPE_SD: + printf("SD"); + break; + case CARD_TYPE_MMC | CARD_TYPE_HC: + printf("MMC High Density"); + break; + case CARD_TYPE_MMC: + printf("MMC"); + break; + case CARD_TYPE_SDIO: + printf("SDIO\n\r"); + return; + case CARD_TYPE_SD_COMBO: + printf("SD COMBO"); + break; + case CARD_TYPE_UNKNOWN: + default: + printf("Unknown\n\r"); + return; + } + printf("\n\r %d MB\n\r", (uint16_t)(sd_mmc_get_capacity(slot)/1024)); +} + +/** + * \brief Card R/W tests + * + * \param slot SD/MMC slot to test + */ +static void main_test_memory(uint8_t slot) +{ + uint32_t last_blocks_addr, i, nb_trans; + REDTIMESTAMP tick_start; + uint32_t time_ms; + + // Compute the last address + last_blocks_addr = sd_mmc_get_capacity(slot) * + (1024 / SD_MMC_BLOCK_SIZE); + if (last_blocks_addr < (TEST_MEM_START_OFFSET / 512lu)) { + printf("[Memory is too small.]\n\r"); + return; + } + last_blocks_addr -= (TEST_MEM_START_OFFSET / SD_MMC_BLOCK_SIZE); + + printf("Card R/W test:\n\r"); + + // Read the last block + printf(" Read... "); + tick_start = RedOsTimestamp(); + if (SD_MMC_OK != sd_mmc_init_read_blocks(slot, + last_blocks_addr, + TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("[FAIL]\n\r"); + return; + } + for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE); + nb_trans++) { + if (SD_MMC_OK != sd_mmc_start_read_blocks(buf_test, + TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("[FAIL]\n\r"); + return; + } + if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) { + printf("[FAIL]\n\r"); + return; + } + } + time_ms = RedOsTimePassed(tick_start) / 1000U; + if (time_ms) { // Valid time_ms + printf(" %d KBps ", (int)(((TEST_MEM_AREA_SIZE + * 1000lu) / 1024lu) / time_ms)); + } + printf("[OK]\n\r"); + + if (sd_mmc_is_write_protected(slot)) { + printf("Card is write protected [WRITE TEST SKIPPED]\n\r"); + return; + } + + // Fill buffer with a pattern + for (i = 0; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) { + ((uint32_t*)buf_test)[i] = TEST_FILL_VALUE_U32; + } + + printf(" Write pattern... "); + if (SD_MMC_OK != sd_mmc_init_write_blocks(slot, + last_blocks_addr, + TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("[FAIL]\n\r"); + return; + } + tick_start = RedOsTimestamp(); + for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE); + nb_trans++) { + ((uint32_t*)buf_test)[0] = nb_trans; // Unique value for each area + if (SD_MMC_OK != sd_mmc_start_write_blocks(buf_test, + TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("[FAIL]\n\r"); + return; + } + if (SD_MMC_OK != sd_mmc_wait_end_of_write_blocks(false)) { + printf("[FAIL]\n\r"); + return; + } + } + time_ms = RedOsTimePassed(tick_start) / 1000U; + if (time_ms) { // Valid time_ms + printf(" %d KBps ", (int)(((TEST_MEM_AREA_SIZE + * 1000lu) / 1024lu) / time_ms)); + } + printf("[OK]\n\r"); + + printf(" Read and check pattern... "); + if (SD_MMC_OK != sd_mmc_init_read_blocks(slot, + last_blocks_addr, + TEST_MEM_AREA_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("Read [FAIL]\n\r"); + return; + } + for (nb_trans = 0; nb_trans < (TEST_MEM_AREA_SIZE / TEST_MEM_ACCESS_SIZE); + nb_trans++) { + // Clear buffer + for (i = 0; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) { + ((uint32_t*)buf_test)[i] = 0xFFFFFFFF; + } + // Fill buffer + if (SD_MMC_OK != sd_mmc_start_read_blocks(buf_test, + TEST_MEM_ACCESS_SIZE / SD_MMC_BLOCK_SIZE)) { + printf("Read [FAIL]\n\r"); + return; + } + if (SD_MMC_OK != sd_mmc_wait_end_of_read_blocks(false)) { + printf("Read [FAIL]\n\r"); + return; + } + // Check the unique value of the area + if (((uint32_t*)buf_test)[0] != nb_trans) { + printf("Check [FAIL]\n\r"); + return; + } + // Check buffer + for (i = 1; i < (TEST_MEM_ACCESS_SIZE / sizeof(uint32_t)); i++) { + if (((uint32_t*)buf_test)[i] != TEST_FILL_VALUE_U32) { + printf("Check [FAIL]\n\r"); + return; + } + } + } + printf("[OK]\n\r"); +} + +/** + * \brief Perform test on CIA (Common I/O Area) of SDIO card. + * + * \note The Common I/O Area (CIA) shall be implemented on all SDIO cards. + * + * \param slot SD/MMC slot to test + */ +static void main_test_sdio(uint8_t slot) +{ + uint32_t i; + uint32_t err; + + /* + * Test with direct read and write command. + */ + printf("\n\r--- Test with direct read and write command of CIA:\n\r"); + /* Read */ + for (i = 0; i < TEST_CIA_SIZE; i++) { + err = sdio_read_direct(slot, SDIO_CIA, i, &buf_cia[i]); + if (err) { + printf("Error: SDIO direct read failed.\n\r"); + return; + } + } + main_dump_buffer(buf_cia, TEST_CIA_SIZE); + + /* Write */ + printf("Write 0x02 to IEN(CIA.4).\n\r"); + err = sdio_write_direct(slot, SDIO_CIA, SDIO_CCCR_IEN, 0x02); + if (err) { + printf("Error: SDIO direct write failed.\n\r"); + return; + } + + /* Check */ + printf("Check IEN after write:"); + err = sdio_read_direct(slot, SDIO_CIA, SDIO_CCCR_IEN, + &buf_cia[SDIO_CCCR_IEN]); + if (err) { + printf("Error: SDIO direct read failed.\n\r"); + return; + } + + printf("0x%02x\n\r", buf_cia[SDIO_CCCR_IEN]); + if (0x02 == buf_cia[SDIO_CCCR_IEN]) { + printf("Test OK.\n\r"); + } else { + printf("Test failed.\n\r"); + } + + /* Restore data to 0 */ + sdio_write_direct(slot, SDIO_CIA, SDIO_CCCR_IEN, 0); + + /* Clear the buffer. */ + memset(buf_cia, 0x0, sizeof(buf_cia)); + + /* + * Test with extended read and write command. + */ + printf("\n\r--- Test with extended read and write command of CIA:\n\r"); + /* Read */ + err = sdio_read_extended(slot, SDIO_CIA, 0, 1, &buf_cia[0], + TEST_CIA_SIZE); + if (err) { + printf("Error: SDIO extended read failed.\n\r"); + return; + } + + main_dump_buffer(buf_cia, TEST_CIA_SIZE); + + /* Write */ + printf("Modify Some R/W bytes for FN0 and write:\n\r"); + buf_cia[SDIO_CCCR_IEN] = 0x3; + err = sdio_write_extended(slot, SDIO_CIA, SDIO_CCCR_IEN, 1, + &buf_cia[SDIO_CCCR_IEN], 1); + if (err) { + printf("Error: SDIO extended write failed.\n\r"); + return; + } + + /* Read and check */ + printf("Check CIA after write:\n\r"); + err = sdio_read_extended(slot, SDIO_CIA, 0, 1, &buf_cia[0], + TEST_CIA_SIZE); + if (err) { + printf("Error: SDIO extended read failed.\n\r"); + return; + } + + main_dump_buffer(buf_cia, TEST_CIA_SIZE); + + if (buf_cia[SDIO_CCCR_IEN] != 0x3) { + printf("CIA.4 Fail\n\r"); + } else { + printf("Test OK\n\r"); + } + + /* Restore data to 0 */ + sdio_write_direct(slot, SDIO_CIA, SDIO_CCCR_IEN, 0); + + return; +} + +/** + * \brief Dump and print buffer. + * + * \param data_buffer Pointer to data buffer. + * \param length Buffer length. + */ +static void main_dump_buffer(uint8_t *data_buffer, uint32_t length) +{ + uint32_t i; + + printf("Dump buffer (length=%d):", (int)length); + for (i = 0; i < length; i++) { + if ((i % 16) == 0) { /* Display 16 data per line */ + printf("\n\r%3x:", (int)i); + } + + printf(" %02x", data_buffer[i]); + } + printf("\n\r"); +} diff --git a/projects/freertos/atmel/sam4e-ek/src/memtest.h b/projects/freertos/atmel/sam4e-ek/src/memtest.h new file mode 100644 index 0000000..010e7bd --- /dev/null +++ b/projects/freertos/atmel/sam4e-ek/src/memtest.h @@ -0,0 +1,33 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Interface to the Atmel SD/MMC memory card test. +*/ +#ifndef MEMTEST_H +#define MEMTEST_H + +void AtmelMemTest(void); + +#endif diff --git a/projects/newproj/host/Makefile b/projects/newproj/host/Makefile new file mode 100644 index 0000000..6ed45c3 --- /dev/null +++ b/projects/newproj/host/Makefile @@ -0,0 +1,9 @@ +# +# Makefile for a Reliance Edge Win32 host tools project +# +P_BASEDIR ?= ../../.. +P_PROJDIR ?= $(P_BASEDIR)/projects/newproj/host +B_DEBUG ?= 1 + +include $(P_BASEDIR)/os/win32/build/host.mk + diff --git a/projects/newproj/host/redconf.c b/projects/newproj/host/redconf.c new file mode 100644 index 0000000..e099597 --- /dev/null +++ b/projects/newproj/host/redconf.c @@ -0,0 +1,7 @@ +/** @file +*/ + +/* The host tools use the same volume configuration as the target. +*/ +#include "../redconf.c" + diff --git a/projects/newproj/host/redconf.h b/projects/newproj/host/redconf.h new file mode 100644 index 0000000..2d86ba9 --- /dev/null +++ b/projects/newproj/host/redconf.h @@ -0,0 +1,94 @@ +/** @file +*/ + +/* Inherit most settings from the target configuration. +*/ +#include "../redconf.h" + + +#ifndef HOST_REDCONF_H +#define HOST_REDCONF_H + +#if REDCONF_ENDIAN_BIG == 1 +#define REDCONF_ENDIAN_SWAP +#endif + +#undef REDCONF_ENDIAN_BIG +#define REDCONF_ENDIAN_BIG 0 + +/* Ignore the target system memory alignment. For Windows, 4 bytes works well. +*/ +#undef REDCONF_ALIGNMENT_SIZE +#define REDCONF_ALIGNMENT_SIZE 4U + +/* Host tools always have output. +*/ +#undef REDCONF_OUTPUT +#define REDCONF_OUTPUT 1 + +/* Read-only must be disabled for the image builder. +*/ +#undef REDCONF_READ_ONLY +#define REDCONF_READ_ONLY 0 + +/* Enable the checker host tool. +*/ +#undef REDCONF_CHECKER +#define REDCONF_CHECKER 1 + +/* Enable the formatter code in POSIX-like API configurations for the image + builder and formatter host tools. +*/ +#undef REDCONF_API_POSIX_FORMAT +#define REDCONF_API_POSIX_FORMAT 1 + +/* Enable the image builder host tool. +*/ +#undef REDCONF_IMAGE_BUILDER +#define REDCONF_IMAGE_BUILDER 1 + +/* The image builder needs red_mkdir(). +*/ +#undef REDCONF_API_POSIX_MKDIR +#define REDCONF_API_POSIX_MKDIR 1 + +/* The image copier utility needs red_readdir(). +*/ +#undef REDCONF_API_POSIX_READDIR +#define REDCONF_API_POSIX_READDIR 1 + +/* The image copier utility needs a handle for every level of directory depth. + While Reliance Edge has no maximum directory depth or path depth, Windows + limits paths to 260 bytes, and each level of depth eats up at least two + characters, 130 handles will be sufficient for all images that can be + copied. +*/ +#undef REDCONF_HANDLE_COUNT +#define REDCONF_HANDLE_COUNT 130U + +/* The target redconf.h may have configured the memory and string functions to + use custom implementations that are only available on the target system. So + for the host, we just use the C library versions. +*/ +#include + +#undef RedMemCpy +#define RedMemCpy memcpy +#undef RedMemMove +#define RedMemMove memmove +#undef RedMemSet +#define RedMemSet memset +#undef RedMemCmp +#define RedMemCmp memcmp + +#undef RedStrLen +#define RedStrLen (uint32_t)strlen +#undef RedStrCmp +#define RedStrCmp strcmp +#undef RedStrNCmp +#define RedStrNCmp strncmp +#undef RedStrNCpy +#define RedStrNCpy strncpy + +#endif + diff --git a/projects/newproj/host/redtypes.h b/projects/newproj/host/redtypes.h new file mode 100644 index 0000000..9ec53cc --- /dev/null +++ b/projects/newproj/host/redtypes.h @@ -0,0 +1,110 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +typedef int bool; /**< @brief Boolean type; either true or false. */ + +typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ +typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ + +typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ +typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ + +typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ +typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ + +typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ +typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ + +/** @brief Unsigned integer capable of storing a pointer. +*/ +#ifdef _WIN64 +typedef uint64_t uintptr_t; +#else +typedef uint32_t uintptr_t; +#endif + + +#endif + diff --git a/projects/newproj/redtypes.h b/projects/newproj/redtypes.h new file mode 100644 index 0000000..3192e38 --- /dev/null +++ b/projects/newproj/redtypes.h @@ -0,0 +1,97 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +/* Defines bool. +*/ +#include + +/* Defines uint8_t, int8_t, uint16_t, int16_t, uint32_t, int32_t, uint64_t, + int64_t, and uintptr_t. +*/ +#include + + +#endif + diff --git a/projects/win32/Makefile b/projects/win32/Makefile new file mode 100644 index 0000000..32f4a78 --- /dev/null +++ b/projects/win32/Makefile @@ -0,0 +1,47 @@ +P_BASEDIR ?= ../.. +P_PROJDIR ?= $(P_BASEDIR)/projects/win32 +B_DEBUG ?= 1 + +CC=cl +P_OS ?= win32 +B_OBJEXT ?= obj + +INCLUDES= \ + /I $(P_BASEDIR)/include \ + /I $(P_BASEDIR)/core/include \ + /I $(P_BASEDIR)/tests/testfw \ + /I $(P_BASEDIR)/tests/stochposix \ + /I $(P_BASEDIR)/os/win32/include \ + /I $(P_BASEDIR)/os/win32/tools \ + /I $(P_PROJDIR) + +EXTRA_CFLAGS += /W3 /D_CRT_SECURE_NO_WARNINGS +ifeq ($(B_DEBUG),0) +EXTRA_CFLAGS += /O2 /Ot /Ox +else +EXTRA_CFLAGS += /Od /DD_DEBUG /MTd /Od /Zi /RTC1 +endif + +all: fsstress + +%.$(B_OBJEXT): %.c + $(CC) $(EXTRA_CFLAGS) -DD_DEBUG=$(B_DEBUG) $(INCLUDES) $< /c /Fo$@ + +include $(P_BASEDIR)/build/reliance.mk + +REDPROJOBJ= \ + $(P_BASEDIR)/os/win32/tools/wintlcmn.$(B_OBJEXT) +REDPROJOBJ += \ + $(P_PROJDIR)/fsstress_main.$(B_OBJEXT) + +$(P_PROJDIR)/fsstress_main.$(B_OBJEXT): $(P_PROJDIR)/fsstress_main.c $(REDHDR) +$(P_BASEDIR)/os/win32/tools/wintlcmn.$(B_OBJEXT): $(P_BASEDIR)/os/win32/tools/wintlcmn.c $(P_BASEDIR)/os/win32/tools/wintlcmn.h + +fsstress: $(P_PROJDIR)/fsstress_main.$(B_OBJEXT) $(P_BASEDIR)/os/win32/tools/wintlcmn.$(B_OBJEXT) $(REDALLOBJ) + $(CC) $(EXTRA_CFLAGS) $^ /Fe$@.exe + +.phony: clean +clean: + -cmd /c del /Q/F *.$(B_OBJEXT) *.pdb *.ilk *.exe *.suo *.sln + -cmd /c del /Q/F $(subst /,\,$(REDALLOBJ) $(REDPROJOBJ)) + diff --git a/projects/win32/fsstress_main.c b/projects/win32/fsstress_main.c new file mode 100644 index 0000000..e21cd39 --- /dev/null +++ b/projects/win32/fsstress_main.c @@ -0,0 +1,183 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +#include +#include +#include + +#include +#include + +#if FSSTRESS_SUPPORTED && (REDCONF_API_POSIX_FORMAT == 1) + +#include +#include +#include + + +static void Usage(bool fError); + + +static const char *gpszProgramName; + + +/** @brief Entry point for the fsstress test. +*/ +int main( + int argc, + char *argv[]) +{ + int iRet = 0; + + gpszProgramName = argv[0U]; + + if((argc > 1) && IsHelpRequest(argv[1U])) + { + Usage(false); + } + else if(argc < 3) + { + Usage(true); + } + else + { + REDSTATUS ret; + int32_t iErr; + uint8_t bVolNum; + const char *pszVolume; + const char *pszDrive; + + iErr = red_init(); + if(iErr == -1) + { + fprintf(stderr, "Unexpected error %d from red_init()\n", (int)red_errno); + exit(red_errno); + } + + /* Parse the command line arguments. + */ + pszVolume = argv[1U]; + pszDrive = argv[2U]; + + bVolNum = FindVolumeNumber(pszVolume); + if(bVolNum == REDCONF_VOLUME_COUNT) + { + #if REDCONF_API_POSIX == 1 + fprintf(stderr, "Error: \"%s\" is not a valid volume number or path prefix.\n", pszVolume); + #else + fprintf(stderr, "Error: \"%s\" is not a valid volume number.\n", pszVolume); + #endif + Usage(true); + } + + pszVolume = gaRedVolConf[bVolNum].pszPathPrefix; + + if(_stricmp(pszDrive, "ram") != 0) + { + /* Let the Win32 block device layer know the path/drive to be used + for this volume's block device. + */ + pszDrive = MassageDriveName(pszDrive); + ret = RedOsBDevConfig(bVolNum, pszDrive); + if(ret != 0) + { + fprintf(stderr, "Unexpected error %d from RedOsBDevConfig()\n", (int)ret); + exit(ret); + } + } + + iErr = red_format(pszVolume); + if(iErr == -1) + { + fprintf(stderr, "Unexpected error %d from red_mount()\n", (int)red_errno); + exit(red_errno); + } + + iErr = red_mount(pszVolume); + if(iErr == -1) + { + fprintf(stderr, "Unexpected error %d from red_mount()\n", (int)red_errno); + exit(red_errno); + } + + /* Remove volume and drive from the arguments. + */ + RedMemMove(&argv[1U], &argv[3U], (argc - 3) * sizeof(argv[0U])); + argc -= 2; + + printf("fsstress begin...\n"); + iRet = fsstress_main(argc, argv); + printf("fsstress end, return %d\n", iRet); + } + + return iRet; +} + + +/** @brief Print usage information and exit. + + @param fError Whether this function is being invoked due to an invocation + error. +*/ +static void Usage( + bool fError) +{ + static const char szUsage[] = +"usage: %s \n" +"Run fsstress, a stress test for the POSIX-like API.\n" +"\n" +"Arguments:\n" +" A volume number (e.g., 2) or a volume path prefix (e.g., VOL1:\n" +" or /data) of the volume to test.\n" +" The block device underlying the volume. This can be:\n" +" 1) The string \"ram\" to test on a RAM disk;\n" +" 2) The path and name of a file disk (e.g., relrt.bin);\n" +" 3) A drive letter (e.g., G:); or\n" +" 4) A Win32 device name (e.g., \\\\.\\PhysicalDrive7).\n" +" The numerous arguments to the fsstress test. For usage information,\n" +" run this program with just the and arguments.\n"; + + if(fError) + { + fprintf(stderr, szUsage, gpszProgramName); + exit(1); + } + else + { + fprintf(stdout, szUsage, gpszProgramName); + exit(0); + } +} + +#else + +int main(void) +{ + fprintf(stderr, "fsstress test is not supported in this configuration.\n"); + return 1; +} + +#endif + + diff --git a/projects/win32/host/Makefile b/projects/win32/host/Makefile new file mode 100644 index 0000000..9204d79 --- /dev/null +++ b/projects/win32/host/Makefile @@ -0,0 +1,10 @@ +# +# Makefile for a Reliance Edge Win32 host tools project +# +P_BASEDIR ?= ../../.. +P_PROJDIR ?= $(P_BASEDIR)/projects/win32/host +P_CONFDIR ?= $(P_PROJDIR)/.. +B_DEBUG ?= 1 + +include $(P_BASEDIR)/os/win32/build/host.mk + diff --git a/projects/win32/host/redconf.c b/projects/win32/host/redconf.c new file mode 100644 index 0000000..e099597 --- /dev/null +++ b/projects/win32/host/redconf.c @@ -0,0 +1,7 @@ +/** @file +*/ + +/* The host tools use the same volume configuration as the target. +*/ +#include "../redconf.c" + diff --git a/projects/win32/host/redconf.h b/projects/win32/host/redconf.h new file mode 100644 index 0000000..2d86ba9 --- /dev/null +++ b/projects/win32/host/redconf.h @@ -0,0 +1,94 @@ +/** @file +*/ + +/* Inherit most settings from the target configuration. +*/ +#include "../redconf.h" + + +#ifndef HOST_REDCONF_H +#define HOST_REDCONF_H + +#if REDCONF_ENDIAN_BIG == 1 +#define REDCONF_ENDIAN_SWAP +#endif + +#undef REDCONF_ENDIAN_BIG +#define REDCONF_ENDIAN_BIG 0 + +/* Ignore the target system memory alignment. For Windows, 4 bytes works well. +*/ +#undef REDCONF_ALIGNMENT_SIZE +#define REDCONF_ALIGNMENT_SIZE 4U + +/* Host tools always have output. +*/ +#undef REDCONF_OUTPUT +#define REDCONF_OUTPUT 1 + +/* Read-only must be disabled for the image builder. +*/ +#undef REDCONF_READ_ONLY +#define REDCONF_READ_ONLY 0 + +/* Enable the checker host tool. +*/ +#undef REDCONF_CHECKER +#define REDCONF_CHECKER 1 + +/* Enable the formatter code in POSIX-like API configurations for the image + builder and formatter host tools. +*/ +#undef REDCONF_API_POSIX_FORMAT +#define REDCONF_API_POSIX_FORMAT 1 + +/* Enable the image builder host tool. +*/ +#undef REDCONF_IMAGE_BUILDER +#define REDCONF_IMAGE_BUILDER 1 + +/* The image builder needs red_mkdir(). +*/ +#undef REDCONF_API_POSIX_MKDIR +#define REDCONF_API_POSIX_MKDIR 1 + +/* The image copier utility needs red_readdir(). +*/ +#undef REDCONF_API_POSIX_READDIR +#define REDCONF_API_POSIX_READDIR 1 + +/* The image copier utility needs a handle for every level of directory depth. + While Reliance Edge has no maximum directory depth or path depth, Windows + limits paths to 260 bytes, and each level of depth eats up at least two + characters, 130 handles will be sufficient for all images that can be + copied. +*/ +#undef REDCONF_HANDLE_COUNT +#define REDCONF_HANDLE_COUNT 130U + +/* The target redconf.h may have configured the memory and string functions to + use custom implementations that are only available on the target system. So + for the host, we just use the C library versions. +*/ +#include + +#undef RedMemCpy +#define RedMemCpy memcpy +#undef RedMemMove +#define RedMemMove memmove +#undef RedMemSet +#define RedMemSet memset +#undef RedMemCmp +#define RedMemCmp memcmp + +#undef RedStrLen +#define RedStrLen (uint32_t)strlen +#undef RedStrCmp +#define RedStrCmp strcmp +#undef RedStrNCmp +#define RedStrNCmp strncmp +#undef RedStrNCpy +#define RedStrNCpy strncpy + +#endif + diff --git a/projects/win32/host/redtypes.h b/projects/win32/host/redtypes.h new file mode 100644 index 0000000..9ec53cc --- /dev/null +++ b/projects/win32/host/redtypes.h @@ -0,0 +1,110 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +typedef int bool; /**< @brief Boolean type; either true or false. */ + +typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ +typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ + +typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ +typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ + +typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ +typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ + +typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ +typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ + +/** @brief Unsigned integer capable of storing a pointer. +*/ +#ifdef _WIN64 +typedef uint64_t uintptr_t; +#else +typedef uint32_t uintptr_t; +#endif + + +#endif + diff --git a/projects/win32/redconf.c b/projects/win32/redconf.c new file mode 100644 index 0000000..40e09a6 --- /dev/null +++ b/projects/win32/redconf.c @@ -0,0 +1,15 @@ +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + UTILITY. DO NOT MODIFY. +*/ +/** @file +*/ +#include +#include +#include +#include + + +const VOLCONF gaRedVolConf[REDCONF_VOLUME_COUNT] = +{ + { 512U, 65536U, false, 1000U, "VOL0:"} +}; diff --git a/projects/win32/redconf.h b/projects/win32/redconf.h new file mode 100644 index 0000000..18d8db4 --- /dev/null +++ b/projects/win32/redconf.h @@ -0,0 +1,102 @@ +/* THIS FILE WAS GENERATED BY THE DATALIGHT RELIANCE EDGE CONFIGURATION + UTILITY. DO NOT MODIFY. +*/ +/** @file +*/ +#ifndef REDCONF_H +#define REDCONF_H + + +#include + +#define REDCONF_READ_ONLY 0 + +#define REDCONF_API_POSIX 1 + +#define REDCONF_API_FSE 0 + +#define REDCONF_API_POSIX_FORMAT 1 + +#define REDCONF_API_POSIX_LINK 1 + +#define REDCONF_API_POSIX_UNLINK 1 + +#define REDCONF_API_POSIX_MKDIR 1 + +#define REDCONF_API_POSIX_RMDIR 1 + +#define REDCONF_API_POSIX_RENAME 1 + +#define REDCONF_RENAME_ATOMIC 1 + +#define REDCONF_API_POSIX_FTRUNCATE 1 + +#define REDCONF_API_POSIX_READDIR 1 + +#define REDCONF_NAME_MAX 12U + +#define REDCONF_PATH_SEPARATOR '/' + +#define REDCONF_TASK_COUNT 10U + +#define REDCONF_HANDLE_COUNT 10U + +#define REDCONF_API_FSE_TRUNCATE 0 + +#define REDCONF_API_FSE_TRANSMASKGET 0 + +#define REDCONF_API_FSE_TRANSMASKSET 0 + +#define REDCONF_OUTPUT 1 + +#define REDCONF_ASSERTS 1 + +#define REDCONF_BLOCK_SIZE 4096U + +#define REDCONF_VOLUME_COUNT 1U + +#define REDCONF_ENDIAN_BIG 0 + +#define REDCONF_ALIGNMENT_SIZE 4U + +#define REDCONF_CRC_ALGORITHM CRC_SLICEBY8 + +#define REDCONF_INODE_BLOCKS 1 + +#define REDCONF_INODE_TIMESTAMPS 1 + +#define REDCONF_ATIME 0 + +#define REDCONF_DIRECT_POINTERS 4U + +#define REDCONF_INDIRECT_POINTERS 32U + +#define REDCONF_BUFFER_COUNT 12U + +#define RedMemCpy memcpy + +#define RedMemMove memmove + +#define RedMemSet memset + +#define RedMemCmp memcmp + +#define RedStrLen (uint32_t)strlen + +#define RedStrCmp strcmp + +#define RedStrNCmp strncmp + +#define RedStrNCpy strncpy + +#define REDCONF_TRANSACT_DEFAULT (( RED_TRANSACT_CREAT | RED_TRANSACT_MKDIR | RED_TRANSACT_RENAME | RED_TRANSACT_LINK | RED_TRANSACT_UNLINK | RED_TRANSACT_FSYNC | RED_TRANSACT_CLOSE | RED_TRANSACT_VOLFULL | RED_TRANSACT_UMOUNT ) & RED_TRANSACT_MASK) + +#define REDCONF_IMAP_INLINE 1 + +#define REDCONF_IMAP_EXTERNAL 0 + +#define REDCONF_IMAGE_BUILDER 0 + +#define REDCONF_CHECKER 0 + +#endif diff --git a/projects/win32/redtypes.h b/projects/win32/redtypes.h new file mode 100644 index 0000000..9ec53cc --- /dev/null +++ b/projects/win32/redtypes.h @@ -0,0 +1,110 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines basic types used by Reliance Edge. + + The following types *must* be defined by this header, either directly (using + typedef) or indirectly (by including other headers, such as the C99 headers + stdint.h and stdbool.h): + + - bool: Boolean type, capable of storing true (1) or false (0) + - uint8_t: Unsigned 8-bit integer + - int8_t: Signed 8-bit integer + - uint16_t: Unsigned 16-bit integer + - int16_t: Signed 16-bit integer + - uint32_t: Unsigned 32-bit integer + - int32_t: Signed 32-bit integer + - uint64_t: Unsigned 64-bit integer + - int64_t: Signed 64-bit integer + - uintptr_t: Unsigned integer capable of storing a pointer, preferably the + same size as pointers themselves. + + These types deliberately use the same names as the standard C99 types, so + that if the C99 headers stdint.h and stdbool.h are available, they may be + included here. + + If the user application defines similar types, those may be reused. For + example, suppose there is an application header apptypes.h which defines + types with a similar purpose but different names. That header could be + reused to define the types Reliance Edge needs: + + ~~~{.c} + #include + + typedef BOOL bool; + typedef BYTE uint8_t; + typedef INT8 int8_t; + // And so on... + ~~~ + + If there are neither C99 headers nor suitable types in application headers, + this header should be populated with typedefs that define the required types + in terms of the standard C types. This requires knowledge of the size of + the C types on the target hardware (e.g., how big is an "int" or a pointer). + Below is an example which assumes the target has 8-bit chars, 16-bit shorts, + 32-bit ints, 32-bit pointers, and 64-bit long longs: + + ~~~{.c} + typedef int bool; + typedef unsigned char uint8_t; + typedef signed char int8_t; + typedef unsigned short uint16_t; + typedef short int16_t; + typedef unsigned int uint32_t; + typedef int int32_t; + typedef unsigned long long uint64_t; + typedef long long int64_t; + typedef uint32_t uintptr_t; + ~~~ +*/ +#ifndef REDTYPES_H +#define REDTYPES_H + + +typedef int bool; /**< @brief Boolean type; either true or false. */ + +typedef unsigned __int8 uint8_t; /**< @brief Unsigned 8-bit integer. */ +typedef __int8 int8_t; /**< @brief Signed 8-bit integer. */ + +typedef unsigned __int16 uint16_t; /**< @brief Unsigned 16-bit integer. */ +typedef __int16 int16_t; /**< @brief Signed 16-bit integer. */ + +typedef unsigned __int32 uint32_t; /**< @brief Unsigned 32-bit integer. */ +typedef __int32 int32_t; /**< @brief Signed 32-bit integer. */ + +typedef unsigned __int64 uint64_t; /**< @brief Unsigned 64-bit integer. */ +typedef __int64 int64_t; /**< @brief Signed 64-bit integer. */ + +/** @brief Unsigned integer capable of storing a pointer. +*/ +#ifdef _WIN64 +typedef uint64_t uintptr_t; +#else +typedef uint32_t uintptr_t; +#endif + + +#endif + diff --git a/tests/posix/fsstress.c b/tests/posix/fsstress.c new file mode 100644 index 0000000..40a8435 --- /dev/null +++ b/tests/posix/fsstress.c @@ -0,0 +1,2029 @@ +/* + * Copyright (c) 2000 Silicon Graphics, Inc. All Rights Reserved. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of version 2 of the GNU General Public License as + * published by the Free Software Foundation. + * + * This program is distributed in the hope that it would be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Further, this software is distributed without any warranty that it is + * free of the rightful claim of any third person regarding infringement + * or the like. Any license provided herein, whether implied or + * otherwise, applies only to this software file. Patent licenses, if + * any, provided herein do not apply to combinations of this program with + * other software, or any other product whatsoever. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, + * Mountain View, CA 94043, or: + * + * http://www.sgi.com + * + * For further information regarding this notice, see: + * + * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/ + */ +/** @file + @brief File system stress test. + + This version of SGI fsstress has been modified to be single-threaded and to + work with the Reliance Edge POSIX-like API. +*/ +#include +#include +#include +#include +#include +#include + +#include +#include + +#if FSSTRESS_SUPPORTED + +#include "redposixcompat.h" + +#include +#include +#include + +#if REDCONF_CHECKER == 1 +#include +#endif + + +/* Create POSIX types. Use #define to avoid name conflicts in those + environments where the type names already exist. +*/ +#define off_t int64_t +#define off64_t off_t +#define ino_t uint32_t +#define mode_t uint16_t +#define __int64_t int64_t + + +/** @brief Generate a random number. + + @return A nonnegative random number. +*/ +#define random() ((int)(RedRand32(NULL) & 0x7FFFFFFF)) + + +/** @brief Seed the random number generator. +*/ +#define srandom(seed) RedRandSeed(seed) + + +#define _exit(status) exit(status) +#define getpagesize() 4096U +#define getpid() 1 + + +/** @brief Determine the maximum file size. + + This is used for the MAXFSSIZE macro. +*/ +static uint64_t MaxFileSize(void) +{ + REDSTATFS info; + int32_t iStatus; + REDSTATUS errnoSave = errno; + uint64_t ullMaxFileSize; + + iStatus = red_statvfs("", &info); + if(iStatus == 0) + { + ullMaxFileSize = info.f_maxfsize; + } + else + { + /* This function does not change errno. + */ + errno = errnoSave; + + ullMaxFileSize = 0x7FFFFFFFU; + } + + return ullMaxFileSize; +} + + +/*------------------------------------------------------------------- + Simulated current working directory support +-------------------------------------------------------------------*/ + + +/* Forward declaration for red_chdir(). +*/ +static int red_stat(const char *pszPath, REDSTAT *pStat); + +/* The simulated CWD functions. +*/ +#undef chdir +#undef getcwd +#define chdir(path) red_chdir(path) +#define getcwd(buf, size) red_getcwd(buf, size) + + +/* Redefine the path-based APIs to call MakeFullPath() on their arguments + since there is no CWD support in the red_*() APIs. +*/ +#undef open +#undef unlink +#undef mkdir +#undef rmdir +#undef rename +#undef link +#undef opendir +#define open(path, oflag) red_open(MakeFullPath(path), oflag) +#define unlink(path) red_unlink(MakeFullPath(path)) +#define mkdir(path) red_mkdir(MakeFullPath(path)) +#define rmdir(path) red_rmdir(MakeFullPath(path)) +#define rename(old, new) red_rename(MakeFullPath(old), MakeFullPath(new)) +#define link(path, hardlink) red_link(MakeFullPath(path), MakeFullPath(hardlink)) +#define opendir(path) red_opendir(MakeFullPath(path)) + + +/* Stores the simulated current working directory. +*/ +static char szLocalCwd[1024U] = "/"; + + +/** @brief Change the current working directory. + + This function only supports a subset of what is possible with POSIX chdir(). + + @param pszPath The new current working directory. + + @return Upon successful completion, 0 shall be returned. Otherwise, -1 + shall be returned, and errno shall be set to indicate the error. +*/ +static int red_chdir( + const char *pszPath) +{ + uint32_t ulIdx; + int iErrno = 0; + + if(strcmp(pszPath, "..") == 0) + { + uint32_t ulLastSlashIdx = 0U; + + /* Chop off the last path separator and everything after it, so that + "/foo/bar/baz" becomes "/foo/bar", moving the CWD up one directory. + */ + for(ulIdx = 0U; szLocalCwd[ulIdx] != '\0'; ulIdx++) + { + if(szLocalCwd[ulIdx] == '/') + { + ulLastSlashIdx = ulIdx; + } + } + + if(ulLastSlashIdx != 0U) + { + szLocalCwd[ulLastSlashIdx] = '\0'; + } + } + else + { + char szOldCwd[1024U]; + + /* chdir() must have no effect on the CWD if it fails, so save the CWD + so we can revert it if necessary. + */ + strcpy(szOldCwd, szLocalCwd); + + if(pszPath[0U] == '/') + { + if(strlen(pszPath) >= sizeof(szLocalCwd)) + { + iErrno = RED_ENAMETOOLONG; + } + else + { + strcpy(szLocalCwd, pszPath); + } + } + else + { + ulIdx = strlen(szLocalCwd); + + if((ulIdx + 1U + strlen(pszPath)) >= sizeof(szLocalCwd)) + { + iErrno = RED_ENAMETOOLONG; + } + else + { + if(szLocalCwd[1U] != '\0') + { + szLocalCwd[ulIdx] = '/'; + ulIdx++; + } + + strcpy(&szLocalCwd[ulIdx], pszPath); + } + } + + if(iErrno == 0) + { + REDSTAT s; + int iStatus; + + iStatus = red_stat(szLocalCwd, &s); + if(iStatus != 0) + { + iErrno = errno; + } + else if(!S_ISDIR(s.st_mode)) + { + iErrno = RED_ENOTDIR; + } + else + { + /* No error, new CWD checks out. + */ + } + } + + if(iErrno != 0) + { + strcpy(szLocalCwd, szOldCwd); + } + } + + if(iErrno != 0) + { + errno = iErrno; + } + + return iErrno == 0 ? 0 : -1; +} + + +/** @brief Retrieve the current working directory. + + @param pszBuf On successful return, populated with the current working + directory. If NULL, memory will be allocated for the CWD + and returned by this function. + @param nSize The size of @p pszBuf. + + @return On success, if @p pszBuf was non-NULL, returns @p pszBuf; if + @p pszBuf was NULL, returns an allocated buffer populated with the + CWD which must be freed by the caller. On failure, returns NULL + and errno will be set. +*/ +static char *red_getcwd( + char *pszBuf, + size_t nSize) +{ + char *pszRet; + + if(pszBuf == NULL) + { + pszRet = malloc(strlen(szLocalCwd) + 1U); + if(pszRet == NULL) + { + errno = RED_ENOMEM; + } + else + { + strcpy(pszRet, szLocalCwd); + } + } + else if(nSize < strlen(szLocalCwd) + 1U) + { + errno = RED_ERANGE; + pszRet = NULL; + } + else + { + strcpy(pszBuf, szLocalCwd); + pszRet = pszBuf; + } + + return pszRet; +} + + +/** @brief Make a relative path into a fully qualified path. + + @param pszName The relative path. + + @return On success, a pointer to a fully qualified path. On error, NULL. +*/ +static const char *MakeFullPath( + const char *pszName) +{ + #define MAXVOLNAME 64U /* Enough for most configs. */ + static char aszFullPath[2U][MAXVOLNAME + 1U + 1024U]; + static uint32_t ulWhich = 0U; + + char *pszFullPath = aszFullPath[ulWhich]; + const char *pszVolume = gpRedVolConf->pszPathPrefix; + int32_t iLen; + + if(pszName[0U] == '/') + { + iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, pszName); + } + else if(strcmp(pszName, ".") == 0U) + { + iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s", pszVolume, szLocalCwd); + } + else if((szLocalCwd[0U] == '/') && (szLocalCwd[1U] == '\0')) + { + iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s/%s", pszVolume, pszName); + } + else + { + iLen = RedSNPrintf(pszFullPath, sizeof(aszFullPath[0U]), "%s%s/%s", pszVolume, szLocalCwd, pszName); + } + + if(iLen == -1) + { + /* Insufficient path buffer space. + */ + pszFullPath = NULL; + } + else + { + /* Toggle between two full path arrays; a kluge to make rename() and + link() work correctly. + */ + ulWhich ^= 1U; + } + + return pszFullPath; +} + + +/*------------------------------------------------------------------- + POSIX functions not implemented by the RED POSIX-like API +-------------------------------------------------------------------*/ + +#define stat(p, s) red_stat(p, s) +#define stat64(p, s) stat(p, s) +#define lstat(p, s) stat(p, s) +#define lstat64(p, s) stat(p, s) +#define truncate(p, s) red_truncate(p, s) +#define truncate64(p, s) truncate(p, s) + + +/** @brief Get the status of a file or directory. +*/ +static int red_stat( + const char *pszPath, + REDSTAT *pStat) +{ + int iFd; + int iRet; + + iFd = open(pszPath, O_RDONLY); + iRet = iFd; + if(iFd != -1) + { + iRet = fstat(iFd, pStat); + + (void)close(iFd); + } + + return iRet; +} + + +/** @brief Truncate a file to a specified length. +*/ +static int red_truncate( + const char *pszPath, + off_t llSize) +{ + int iFd; + int iRet; + + iFd = open(pszPath, O_WRONLY); + iRet = iFd; + if(iFd != -1) + { + iRet = ftruncate(iFd, llSize); + + (void)close(iFd); + } + + return iRet; +} + + +/*------------------------------------------------------------------- + Begin ported fsstress code +-------------------------------------------------------------------*/ + +/* Stuff from xfscompat.h */ + +#define MAXNAMELEN REDCONF_NAME_MAX + +struct dioattr { + int d_miniosz, d_maxiosz, d_mem; +}; + +#define MIN(a,b) ((a)<(b) ? (a):(b)) +#define MAX(a,b) ((a)>(b) ? (a):(b)) + +/* End xfscompat.h */ + + +typedef enum { + OP_CREAT, + OP_FDATASYNC, + OP_FSYNC, + OP_GETDENTS, + OP_LINK, + OP_MKDIR, + OP_READ, + OP_RENAME, + OP_RMDIR, + OP_STAT, + OP_TRUNCATE, + OP_UNLINK, + OP_WRITE, + #if REDCONF_CHECKER == 1 + OP_CHECK, + #endif + OP_LAST +} opty_t; + +typedef void (*opfnc_t) (int, long); + +typedef struct opdesc { + opty_t op; + const char *name; + opfnc_t func; + int freq; + int iswrite; +} opdesc_t; + +typedef struct fent { + int id; + int parent; +} fent_t; + +typedef struct flist { + int nfiles; + int nslots; + int tag; + fent_t *fents; +} flist_t; + +typedef struct pathname { + int len; + char *path; +} pathname_t; + +#define FT_DIR 0 +#define FT_DIRm (1 << FT_DIR) +#define FT_REG 1 +#define FT_REGm (1 << FT_REG) +#define FT_SYM 2 +#define FT_SYMm (1 << FT_SYM) +#define FT_DEV 3 +#define FT_DEVm (1 << FT_DEV) +#define FT_RTF 4 +#define FT_RTFm (1 << FT_RTF) +#define FT_nft 5 +#define FT_ANYm ((1 << FT_nft) - 1) +#define FT_REGFILE (FT_REGm | FT_RTFm) +#define FT_NOTDIR (FT_ANYm & ~FT_DIRm) + +#define FLIST_SLOT_INCR 16 +#define NDCACHE 64 + +#define MAXFSIZE MaxFileSize() + +static void creat_f(int opno, long r); +static void fdatasync_f(int opno, long r); +static void fsync_f(int opno, long r); +static void getdents_f(int opno, long r); +static void link_f(int opno, long r); +static void mkdir_f(int opno, long r); +static void read_f(int opno, long r); +static void rename_f(int opno, long r); +static void rmdir_f(int opno, long r); +static void stat_f(int opno, long r); +static void truncate_f(int opno, long r); +static void unlink_f(int opno, long r); +static void write_f(int opno, long r); +#if REDCONF_CHECKER == 1 +static void check_f(int opno, long r); +#endif + +static opdesc_t ops[] = { + {OP_CREAT, "creat", creat_f, 4, 1}, + {OP_FDATASYNC, "fdatasync", fdatasync_f, 1, 1}, + {OP_FSYNC, "fsync", fsync_f, 1, 1}, + {OP_GETDENTS, "getdents", getdents_f, 1, 0}, + {OP_LINK, "link", link_f, 1, 1}, + {OP_MKDIR, "mkdir", mkdir_f, 2, 1}, + {OP_READ, "read", read_f, 1, 0}, + {OP_RENAME, "rename", rename_f, 2, 1}, + {OP_RMDIR, "rmdir", rmdir_f, 1, 1}, + {OP_STAT, "stat", stat_f, 1, 0}, + {OP_TRUNCATE, "truncate", truncate_f, 2, 1}, + {OP_UNLINK, "unlink", unlink_f, 1, 1}, + {OP_WRITE, "write", write_f, 4, 1}, + #if REDCONF_CHECKER == 1 + {OP_CHECK, "check", check_f, 1, 1}, + #endif +}, *ops_end; + +static flist_t flist[FT_nft] = { + {0, 0, 'd', NULL}, + {0, 0, 'f', NULL}, + {0, 0, 'l', NULL}, + {0, 0, 'c', NULL}, + {0, 0, 'r', NULL}, +}; + +static int dcache[NDCACHE]; +static opty_t *freq_table; +static int freq_table_size; +static char *homedir; +static int *ilist; +static int ilistlen; +static off64_t maxfsize; +static char *myprog; +static int namerand; +static int nameseq; +static int nops; +static int operations = 1; +static int procid; +static int rtpct; +static unsigned long seed = 0; +static ino_t top_ino; +static int verbose = 0; + +static int delete_tree(const char *path); +static void add_to_flist(int fd, int it, int parent); +static void append_pathname(pathname_t *name, const char *str); +static void check_cwd(void); +static int creat_path(pathname_t *name, mode_t mode); +static void dcache_enter(int dirid, int slot); +static void dcache_init(void); +static fent_t *dcache_lookup(int dirid); +static void dcache_purge(int dirid); +static void del_from_flist(int ft, int slot); +static void doproc(void); +static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep); +static void fix_parent(int oldid, int newid); +static void free_pathname(pathname_t *name); +static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v); +static int get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v); +static void init_pathname(pathname_t *name); +static int link_path(pathname_t *name1, pathname_t *name2); +static int lstat64_path(pathname_t *name, REDSTAT *sbuf); +static void make_freq_table(void); +static int mkdir_path(pathname_t *name, mode_t mode); +static void namerandpad(int id, char *buf, int i); +static int open_path(pathname_t *name, int oflag); +static DIR *opendir_path(pathname_t *name); +static void process_freq(char *arg); +static int rename_path(pathname_t *name1, pathname_t *name2); +static int rmdir_path(pathname_t *name); +static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname); +static void show_ops(int flag, const char *lead_str); +static int stat64_path(pathname_t *name, REDSTAT *sbuf); +static int truncate64_path(pathname_t *name, off64_t length); +static int unlink_path(pathname_t *name); +static void usage(void); +static void write_freq(void); +static void zero_freq(void); + +int fsstress_main(int argc, char **argv) +{ + char buf[10]; + int c; + char *dirname = NULL; + int fd; + int i; + int cleanup = 0; + int loops = 1; + int loopcntr = 1; + char *p; + int nousage = 0; + + nops = sizeof(ops) / sizeof(ops[0]); + ops_end = &ops[nops]; + myprog = argv[0]; + for (i = 1; i < argc; i++) { + const char *const opts = "cd:f:i:l:n:rs:vwzHS"; + char *thisarg = argv[i]; + char *optarg = NULL; + char *found; + + /* Rudimentary simulation of getopt(). + */ + c = '?'; + if (*thisarg == '-') { + c = thisarg[1]; + found = strchr(opts, c); + if (c && found) { + if (found[1] == ':') { + if (thisarg[2]) + optarg = &thisarg[2]; + else { + optarg = (i + 1 < argc) ? argv[i+1] : NULL;; + ++i; + } + } + } + } + + switch (c) { + case 'c': + /*Don't cleanup */ + cleanup = 1; + break; + case 'd': + dirname = optarg; + break; + case 'f': + process_freq(optarg); + break; + case 'i': + ilist = realloc(ilist, ++ilistlen * sizeof(*ilist)); + ilist[ilistlen - 1] = strtol(optarg, &p, 16); + break; + case 'l': + loops = atoi(optarg); + break; + case 'n': + operations = atoi(optarg); + break; + case 'r': + namerand = 1; + break; + case 's': + seed = strtoul(optarg, NULL, 0); + break; + case 'v': + verbose = 1; + break; + case 'w': + write_freq(); + break; + case 'z': + zero_freq(); + break; + case 'S': + show_ops(0, NULL); + RedPrintf("\n"); + nousage = 1; + break; + default: + case '?': + RedPrintf("%s - invalid parameters\n", myprog); + /* fall through */ + case 'H': + usage(); + exit(1); + } + } + + make_freq_table(); + + while ((loopcntr <= loops) || (loops == 0)) { + if (!dirname) { + /* no directory specified */ + if (!nousage) + usage(); + exit(1); + } + + (void)mkdir(dirname); + if (chdir(dirname) < 0) { + perror(dirname); + exit(1); + } + RedSNPrintf(buf, sizeof(buf), "fss%x", getpid()); + fd = creat(buf, 0666); + maxfsize = (off64_t) MAXFSIZE; + dcache_init(); + if (!seed) { + seed = (unsigned long)RedOsClockGetTime(); + RedPrintf("seed = %ld\n", seed); + } + close(fd); + unlink(buf); + procid = 0; + doproc(); + if (cleanup == 0) { + delete_tree(dirname); + for (i = 0; i < FT_nft; i++) { + flist[i].nslots = 0; + flist[i].nfiles = 0; + free(flist[i].fents); + flist[i].fents = NULL; + } + } + loopcntr++; + } + return 0; +} + +static int delete_tree(const char *path) +{ + REDSTAT sb; + DIR *dp; + REDDIRENT *dep; + char *childpath; + size_t len; + int e; + + e = stat(path, &sb); + if (e) + return errno; + + if (!S_ISDIR(sb.st_mode)) + return unlink(path) ? errno : 0; + + dp = opendir(path); + if (dp == NULL) + return errno; + + while((dep = readdir(dp)) != NULL) { + len = strlen(path) + 1 + strlen(dep->d_name) + 1; + childpath = malloc(len); + + strcpy(childpath, path); + if (childpath[strlen(childpath) - 1] != '/') + strcat(childpath, "/"); + strcat(childpath, dep->d_name); + + e = delete_tree(childpath); + + free(childpath); + + if (e) + break; + } + + if (e == 0 && strcmp(path, "/") != 0) { + e = rmdir(path) ? errno : 0; + } + closedir(dp); + return e; +} + +static void add_to_flist(int ft, int id, int parent) +{ + fent_t *fep; + flist_t *ftp; + + ftp = &flist[ft]; + if (ftp->nfiles == ftp->nslots) { + ftp->nslots += FLIST_SLOT_INCR; + ftp->fents = realloc(ftp->fents, ftp->nslots * sizeof(fent_t)); + } + fep = &ftp->fents[ftp->nfiles++]; + fep->id = id; + fep->parent = parent; +} + +static void append_pathname(pathname_t *name, const char *str) +{ + int len; + + len = strlen(str); +#ifdef DEBUG + if (len && *str == '/' && name->len == 0) { + RedPrintf("fsstress: append_pathname failure\n"); + chdir(homedir); + abort(); + + } +#endif + name->path = realloc(name->path, name->len + 1 + len); + strcpy(&name->path[name->len], str); + name->len += len; +} + +static void check_cwd(void) +{ +#ifdef DEBUG + REDSTAT statbuf; + + if (stat64(".", &statbuf) == 0 && statbuf.st_ino == top_ino) + return; + chdir(homedir); + RedPrintf("fsstress: check_cwd failure\n"); + abort(); + +#endif +} + +static int creat_path(pathname_t *name, mode_t mode) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = creat(name->path, mode); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = creat_path(&newname, mode); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void dcache_enter(int dirid, int slot) +{ + dcache[dirid % NDCACHE] = slot; +} + +static void dcache_init(void) +{ + int i; + + for (i = 0; i < NDCACHE; i++) + dcache[i] = -1; +} + +static fent_t *dcache_lookup(int dirid) +{ + fent_t *fep; + int i; + + i = dcache[dirid % NDCACHE]; + if (i >= 0 && (fep = &flist[FT_DIR].fents[i])->id == dirid) + return fep; + return NULL; +} + +static void dcache_purge(int dirid) +{ + int *dcp; + + dcp = &dcache[dirid % NDCACHE]; + if (*dcp >= 0 && flist[FT_DIR].fents[*dcp].id == dirid) + *dcp = -1; +} + +static void del_from_flist(int ft, int slot) +{ + flist_t *ftp; + + ftp = &flist[ft]; + if (ft == FT_DIR) + dcache_purge(ftp->fents[slot].id); + if (slot != ftp->nfiles - 1) { + if (ft == FT_DIR) + dcache_purge(ftp->fents[ftp->nfiles - 1].id); + ftp->fents[slot] = ftp->fents[--ftp->nfiles]; + } else + ftp->nfiles--; +} + +static fent_t *dirid_to_fent(int dirid) +{ + fent_t *efep; + fent_t *fep; + flist_t *flp; + + if ((fep = dcache_lookup(dirid))) + return fep; + flp = &flist[FT_DIR]; + for (fep = flp->fents, efep = &fep[flp->nfiles]; fep < efep; fep++) { + if (fep->id == dirid) { + dcache_enter(dirid, (int)(fep - flp->fents)); + return fep; + } + } + return NULL; +} + +static void doproc(void) +{ + REDSTAT statbuf; + char buf[10]; + int opno; + opdesc_t *p; + + RedSNPrintf(buf, sizeof(buf), "p%x", procid); + (void)mkdir(buf); + if (chdir(buf) < 0 || stat64(".", &statbuf) < 0) { + perror(buf); + _exit(1); + } + top_ino = statbuf.st_ino; + homedir = getcwd(NULL, 0); + seed += procid; + srandom(seed); + if (namerand) + namerand = random(); + for (opno = 0; opno < operations; opno++) { + p = &ops[freq_table[random() % freq_table_size]]; + if ((unsigned long)p->func < 4096) + abort(); + + p->func(opno, random()); + } + free(homedir); +} + +static void fent_to_name(pathname_t *name, flist_t *flp, fent_t *fep) +{ + char buf[MAXNAMELEN]; + int i; + fent_t *pfep; + + if (fep == NULL) + return; + if (fep->parent != -1) { + pfep = dirid_to_fent(fep->parent); + fent_to_name(name, &flist[FT_DIR], pfep); + append_pathname(name, "/"); + } + i = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, fep->id); + namerandpad(fep->id, buf, i); + append_pathname(name, buf); +} + +static void fix_parent(int oldid, int newid) +{ + fent_t *fep; + flist_t *flp; + int i; + int j; + + for (i = 0, flp = flist; i < FT_nft; i++, flp++) { + for (j = 0, fep = flp->fents; j < flp->nfiles; j++, fep++) { + if (fep->parent == oldid) + fep->parent = newid; + } + } +} + +static void free_pathname(pathname_t *name) +{ + if (name->path) { + free(name->path); + name->path = NULL; + name->len = 0; + } +} + +static int generate_fname(fent_t *fep, int ft, pathname_t *name, int *idp, int *v) +{ + char buf[MAXNAMELEN]; + flist_t *flp; + int id; + int j; + int len; + + flp = &flist[ft]; + len = RedSNPrintf(buf, sizeof(buf), "%c%x", flp->tag, id = nameseq++); + namerandpad(id, buf, len); + if (fep) { + fent_to_name(name, &flist[FT_DIR], fep); + append_pathname(name, "/"); + } + append_pathname(name, buf); + *idp = id; + *v = verbose; + for (j = 0; !*v && j < ilistlen; j++) { + if (ilist[j] == id) { + *v = 1; + break; + } + } + return 1; +} + +static int +get_fname(int which, long r, pathname_t *name, flist_t **flpp, fent_t **fepp, int *v) +{ + int c; + fent_t *fep; + flist_t *flp; + int i; + int j; + int x; + + for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) { + if (which & (1 << i)) + c += flp->nfiles; + } + if (c == 0) { + if (flpp) + *flpp = NULL; + if (fepp) + *fepp = NULL; + *v = verbose; + return 0; + } + x = (int)(r % c); + for (i = 0, c = 0, flp = flist; i < FT_nft; i++, flp++) { + if (which & (1 << i)) { + if (x < c + flp->nfiles) { + fep = &flp->fents[x - c]; + if (name) + fent_to_name(name, flp, fep); + if (flpp) + *flpp = flp; + if (fepp) + *fepp = fep; + *v = verbose; + for (j = 0; !*v && j < ilistlen; j++) { + if (ilist[j] == fep->id) { + *v = 1; + break; + } + } + return 1; + } + c += flp->nfiles; + } + } +#ifdef DEBUG + RedPrintf("fsstress: get_fname failure\n"); + abort(); +#endif + return -1; + +} + +static void init_pathname(pathname_t *name) +{ + name->len = 0; + name->path = NULL; +} + +static int link_path(pathname_t *name1, pathname_t *name2) +{ + char buf1[MAXNAMELEN]; + char buf2[MAXNAMELEN]; + int down1; + pathname_t newname1; + pathname_t newname2; + int rval; + + rval = link(name1->path, name2->path); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name1, buf1, &newname1); + separate_pathname(name2, buf2, &newname2); + if (strcmp(buf1, buf2) == 0) { + if (chdir(buf1) == 0) { + rval = link_path(&newname1, &newname2); + chdir(".."); + } + } else { + if (strcmp(buf1, "..") == 0) + down1 = 0; + else if (strcmp(buf2, "..") == 0) + down1 = 1; + else if (strlen(buf1) == 0) + down1 = 0; + else if (strlen(buf2) == 0) + down1 = 1; + else + down1 = MAX(newname1.len, 3 + name2->len) <= + MAX(3 + name1->len, newname2.len); + if (down1) { + free_pathname(&newname2); + append_pathname(&newname2, "../"); + append_pathname(&newname2, name2->path); + if (chdir(buf1) == 0) { + rval = link_path(&newname1, &newname2); + chdir(".."); + } + } else { + free_pathname(&newname1); + append_pathname(&newname1, "../"); + append_pathname(&newname1, name1->path); + if (chdir(buf2) == 0) { + rval = link_path(&newname1, &newname2); + chdir(".."); + } + } + } + free_pathname(&newname1); + free_pathname(&newname2); + return rval; +} + +static int lstat64_path(pathname_t *name, REDSTAT *sbuf) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = lstat64(name->path, sbuf); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = lstat64_path(&newname, sbuf); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void make_freq_table(void) +{ + int f; + int i; + opdesc_t *p; + + for (p = ops, f = 0; p < ops_end; p++) + f += p->freq; + freq_table = malloc(f * sizeof(*freq_table)); + freq_table_size = f; + for (p = ops, i = 0; p < ops_end; p++) { + for (f = 0; f < p->freq; f++, i++) + freq_table[i] = p->op; + } +} + +static int mkdir_path(pathname_t *name, mode_t mode) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = mkdir(name->path); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = mkdir_path(&newname, mode); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void namerandpad(int id, char *buf, int i) +{ + int bucket; + static int buckets[] = { 2, 4, 8, 16, 32, 64, 128, MAXNAMELEN - 1 }; + int padlen; + int padmod; + + if (namerand == 0) + return; + bucket = (id ^ namerand) % (sizeof(buckets) / sizeof(buckets[0])); + padmod = buckets[bucket] + 1 - i; + if (padmod <= 0) + return; + padlen = (id ^ namerand) % padmod; + if (padlen) { + memset(&buf[i], 'X', padlen); + buf[i + padlen] = '\0'; + } +} + +static int open_path(pathname_t *name, int oflag) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = open(name->path, oflag); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = open_path(&newname, oflag); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static DIR *opendir_path(pathname_t *name) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + DIR *rval; + + rval = opendir(name->path); + if (rval || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = opendir_path(&newname); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void process_freq(char *arg) +{ + opdesc_t *p; + char *s; + + s = strchr(arg, '='); + if (s == NULL) { + RedPrintf("bad argument '%s'\n", arg); + exit(1); + } + *s++ = '\0'; + for (p = ops; p < ops_end; p++) { + if (strcmp(arg, p->name) == 0) { + p->freq = atoi(s); + return; + } + } + RedPrintf("can't find op type %s for -f\n", arg); + exit(1); +} + +static int rename_path(pathname_t *name1, pathname_t *name2) +{ + char buf1[MAXNAMELEN]; + char buf2[MAXNAMELEN]; + int down1; + pathname_t newname1; + pathname_t newname2; + int rval; + + rval = rename(name1->path, name2->path); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name1, buf1, &newname1); + separate_pathname(name2, buf2, &newname2); + if (strcmp(buf1, buf2) == 0) { + if (chdir(buf1) == 0) { + rval = rename_path(&newname1, &newname2); + chdir(".."); + } + } else { + if (strcmp(buf1, "..") == 0) + down1 = 0; + else if (strcmp(buf2, "..") == 0) + down1 = 1; + else if (strlen(buf1) == 0) + down1 = 0; + else if (strlen(buf2) == 0) + down1 = 1; + else + down1 = MAX(newname1.len, 3 + name2->len) <= + MAX(3 + name1->len, newname2.len); + if (down1) { + free_pathname(&newname2); + append_pathname(&newname2, "../"); + append_pathname(&newname2, name2->path); + if (chdir(buf1) == 0) { + rval = rename_path(&newname1, &newname2); + chdir(".."); + } + } else { + free_pathname(&newname1); + append_pathname(&newname1, "../"); + append_pathname(&newname1, name1->path); + if (chdir(buf2) == 0) { + rval = rename_path(&newname1, &newname2); + chdir(".."); + } + } + } + free_pathname(&newname1); + free_pathname(&newname2); + return rval; +} + +static int rmdir_path(pathname_t *name) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = rmdir(name->path); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = rmdir_path(&newname); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void separate_pathname(pathname_t *name, char *buf, pathname_t *newname) +{ + char *slash; + + init_pathname(newname); + slash = strchr(name->path, '/'); + if (slash == NULL) { + buf[0] = '\0'; + return; + } + *slash = '\0'; + strcpy(buf, name->path); + *slash = '/'; + append_pathname(newname, slash + 1); +} + +#define WIDTH 80 + +static void show_ops(int flag, const char *lead_str) +{ + opdesc_t *p; + + if (flag < 0) { + /* print in list form */ + int x = WIDTH; + + for (p = ops; p < ops_end; p++) { + if (lead_str != NULL && x + strlen(p->name) >= WIDTH - 5) { + if (p == ops) { + RedPrintf("%s", lead_str); + x = strlen(lead_str); + } else { + RedPrintf("%s%s", "\n", lead_str); + x = strlen(lead_str) + 1; + } + } + RedPrintf("%s ", p->name); + x += strlen(p->name) + 1; + } + RedPrintf("\n"); + } else { + int f; + for (f = 0, p = ops; p < ops_end; p++) + f += p->freq; + + if (f == 0) + flag = 1; + + for (p = ops; p < ops_end; p++) { + if (flag != 0 || p->freq > 0) { + if (lead_str != NULL) + RedPrintf("%s", lead_str); + RedPrintf("%20s %d/%d %s\n", + p->name, p->freq, f, + (p->iswrite == 0) ? " " : "write op"); + } + } + } +} + +static int stat64_path(pathname_t *name, REDSTAT *sbuf) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = stat64(name->path, sbuf); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = stat64_path(&newname, sbuf); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static int truncate64_path(pathname_t *name, off64_t length) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = truncate64(name->path, length); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = truncate64_path(&newname, length); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static int unlink_path(pathname_t *name) +{ + char buf[MAXNAMELEN]; + pathname_t newname; + int rval; + + rval = unlink(name->path); + if (rval >= 0 || errno != RED_ENAMETOOLONG) + return rval; + separate_pathname(name, buf, &newname); + if (chdir(buf) == 0) { + rval = unlink_path(&newname); + chdir(".."); + } + free_pathname(&newname); + return rval; +} + +static void usage(void) +{ + RedPrintf("Usage: %s -H or\n", myprog); + RedPrintf + (" %s [-c][-d dir][-f op_name=freq][-l loops][-n nops]\n", + myprog); + RedPrintf(" [-r len][-s seed][-v][-w][-z][-S]\n"); + RedPrintf("where\n"); + RedPrintf + (" -c specifies not to remove files(cleanup) after execution\n"); + RedPrintf + (" -d dir specifies the base directory for operations\n"); + RedPrintf + (" -f op_name=freq changes the frequency of option name to freq\n"); + RedPrintf(" the valid operation names are:\n"); + show_ops(-1, " "); + RedPrintf + (" -l loops specifies the no. of times the testrun should loop.\n"); + RedPrintf(" *use 0 for infinite (default 1)\n"); + RedPrintf + (" -n nops specifies the no. of operations per process (default 1)\n"); + RedPrintf(" -r specifies random name padding\n"); + RedPrintf + (" -s seed specifies the seed for the random generator (default random)\n"); + RedPrintf(" -v specifies verbose mode\n"); + RedPrintf + (" -w zeros frequencies of non-write operations\n"); + RedPrintf(" -z zeros frequencies of all operations\n"); + RedPrintf + (" -S prints the table of operations (omitting zero frequency)\n"); + RedPrintf(" -H prints usage and exits\n"); +} + +static void write_freq(void) +{ + opdesc_t *p; + + for (p = ops; p < ops_end; p++) { + if (!p->iswrite) + p->freq = 0; + } +} + +static void zero_freq(void) +{ + opdesc_t *p; + + for (p = ops; p < ops_end; p++) + p->freq = 0; +} + +static void creat_f(int opno, long r) +{ + int e; + int e1; + pathname_t f; + int fd; + fent_t *fep; + int id; + int parid; + int type; + int v; + int v1; + int esz = 0; + + if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v1)) + parid = -1; + else + parid = fep->id; + init_pathname(&f); + type = rtpct ? ((int)(random() % 100) > rtpct ? FT_REG : FT_RTF) : FT_REG; + e = generate_fname(fep, type, &f, &id, &v); + v |= v1; + if (!e) { + if (v) { + fent_to_name(&f, &flist[FT_DIR], fep); + RedPrintf("%d/%d: creat - no filename from %s\n", + procid, opno, f.path); + } + free_pathname(&f); + return; + } + fd = creat_path(&f, 0666); + e = fd < 0 ? errno : 0; + e1 = 0; + check_cwd(); + esz = 0; + if (fd >= 0) { + add_to_flist(type, id, parid); + close(fd); + } + if (v) + RedPrintf("%d/%d: creat %s x:%d %d %d\n", procid, opno, f.path, + esz, e, e1); + free_pathname(&f); +} + +static void fdatasync_f(int opno, long r) +{ + int e; + pathname_t f; + int fd; + int v; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: fdatasync - no filename\n", + procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_WRONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + RedPrintf("%d/%d: fdatasync - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + e = fdatasync(fd) < 0 ? errno : 0; + if (v) + RedPrintf("%d/%d: fdatasync %s %d\n", procid, opno, f.path, e); + free_pathname(&f); + close(fd); +} + +static void fsync_f(int opno, long r) +{ + int e; + pathname_t f; + int fd; + int v; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: fsync - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_WRONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + RedPrintf("%d/%d: fsync - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + e = fsync(fd) < 0 ? errno : 0; + if (v) + RedPrintf("%d/%d: fsync %s %d\n", procid, opno, f.path, e); + free_pathname(&f); + close(fd); +} + +static void getdents_f(int opno, long r) +{ + DIR *dir; + pathname_t f; + int v; + + init_pathname(&f); + if (!get_fname(FT_DIRm, r, &f, NULL, NULL, &v)) + append_pathname(&f, "."); + dir = opendir_path(&f); + check_cwd(); + if (dir == NULL) { + if (v) + RedPrintf("%d/%d: getdents - can't open %s\n", + procid, opno, f.path); + free_pathname(&f); + return; + } + while (readdir64(dir) != NULL) + continue; + if (v) + RedPrintf("%d/%d: getdents %s 0\n", procid, opno, f.path); + free_pathname(&f); + closedir(dir); +} + +static void link_f(int opno, long r) +{ + int e; + pathname_t f; + fent_t *fep; + flist_t *flp; + int id; + pathname_t l; + int parid; + int v; + int v1; + + init_pathname(&f); + if (!get_fname(FT_NOTDIR, r, &f, &flp, NULL, &v1)) { + if (v1) + RedPrintf("%d/%d: link - no file\n", procid, opno); + free_pathname(&f); + return; + } + if (!get_fname(FT_DIRm, random(), NULL, NULL, &fep, &v)) + parid = -1; + else + parid = fep->id; + v |= v1; + init_pathname(&l); + e = generate_fname(fep, (int)(flp - flist), &l, &id, &v1); + v |= v1; + if (!e) { + if (v) { + fent_to_name(&l, &flist[FT_DIR], fep); + RedPrintf("%d/%d: link - no filename from %s\n", + procid, opno, l.path); + } + free_pathname(&l); + free_pathname(&f); + return; + } + e = link_path(&f, &l) < 0 ? errno : 0; + check_cwd(); + if (e == 0) + add_to_flist((int)(flp - flist), id, parid); + if (v) + RedPrintf("%d/%d: link %s %s %d\n", procid, opno, f.path, l.path, + e); + free_pathname(&l); + free_pathname(&f); +} + +static void mkdir_f(int opno, long r) +{ + int e; + pathname_t f; + fent_t *fep; + int id; + int parid; + int v; + int v1; + + if (!get_fname(FT_DIRm, r, NULL, NULL, &fep, &v)) + parid = -1; + else + parid = fep->id; + init_pathname(&f); + e = generate_fname(fep, FT_DIR, &f, &id, &v1); + v |= v1; + if (!e) { + if (v) { + fent_to_name(&f, &flist[FT_DIR], fep); + RedPrintf("%d/%d: mkdir - no filename from %s\n", + procid, opno, f.path); + } + free_pathname(&f); + return; + } + e = mkdir_path(&f, 0777) < 0 ? errno : 0; + check_cwd(); + if (e == 0) + add_to_flist(FT_DIR, id, parid); + if (v) + RedPrintf("%d/%d: mkdir %s %d\n", procid, opno, f.path, e); + free_pathname(&f); +} + +static void read_f(int opno, long r) +{ + char *buf; + int e; + pathname_t f; + int fd; + uint32_t len; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: read - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_RDONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + RedPrintf("%d/%d: read - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + if (fstat64(fd, &stb) < 0) { + if (v) + RedPrintf("%d/%d: read - fstat64 %s failed %d\n", + procid, opno, f.path, errno); + free_pathname(&f); + close(fd); + return; + } + if (stb.st_size == 0) { + if (v) + RedPrintf("%d/%d: read - %s zero size\n", procid, opno, + f.path); + free_pathname(&f); + close(fd); + return; + } + lr = ((__int64_t) random() << 32) + random(); + off = (off64_t) (lr % stb.st_size); + lseek64(fd, off, SEEK_SET); + len = (random() % (getpagesize() * 4)) + 1; + buf = malloc(len); + e = read(fd, buf, len) < 0 ? errno : 0; + free(buf); + if (v) + RedPrintf("%d/%d: read %s [%lld,%ld] %d\n", + procid, opno, f.path, (long long)off, (long int)len, e); + free_pathname(&f); + close(fd); +} + +static void rename_f(int opno, long r) +{ + fent_t *dfep; + int e; + pathname_t f; + fent_t *fep; + flist_t *flp; + int id; + pathname_t newf; + int oldid; + int parid; + int v; + int v1; + + init_pathname(&f); + if (!get_fname(FT_ANYm, r, &f, &flp, &fep, &v1)) { + if (v1) + RedPrintf("%d/%d: rename - no filename\n", procid, opno); + free_pathname(&f); + return; + } + if (!get_fname(FT_DIRm, random(), NULL, NULL, &dfep, &v)) + parid = -1; + else + parid = dfep->id; + v |= v1; + init_pathname(&newf); + e = generate_fname(dfep, (int)(flp - flist), &newf, &id, &v1); + v |= v1; + if (!e) { + if (v) { + fent_to_name(&f, &flist[FT_DIR], dfep); + RedPrintf("%d/%d: rename - no filename from %s\n", + procid, opno, f.path); + } + free_pathname(&newf); + free_pathname(&f); + return; + } + e = rename_path(&f, &newf) < 0 ? errno : 0; + check_cwd(); + if (e == 0) { + if (flp - flist == FT_DIR) { + oldid = fep->id; + fix_parent(oldid, id); + } + del_from_flist((int)(flp - flist), (int)(fep - flp->fents)); + add_to_flist((int)(flp - flist), id, parid); + } + if (v) + RedPrintf("%d/%d: rename %s to %s %d\n", procid, opno, f.path, + newf.path, e); + free_pathname(&newf); + free_pathname(&f); +} + +static void rmdir_f(int opno, long r) +{ + int e; + pathname_t f; + fent_t *fep; + int v; + + init_pathname(&f); + if (!get_fname(FT_DIRm, r, &f, NULL, &fep, &v)) { + if (v) + RedPrintf("%d/%d: rmdir - no directory\n", procid, opno); + free_pathname(&f); + return; + } + e = rmdir_path(&f) < 0 ? errno : 0; + check_cwd(); + if (e == 0) + del_from_flist(FT_DIR, (int)(fep - flist[FT_DIR].fents)); + if (v) + RedPrintf("%d/%d: rmdir %s %d\n", procid, opno, f.path, e); + free_pathname(&f); +} + +static void stat_f(int opno, long r) +{ + int e; + pathname_t f; + REDSTAT stb; + int v; + + init_pathname(&f); + if (!get_fname(FT_ANYm, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: stat - no entries\n", procid, opno); + free_pathname(&f); + return; + } + e = lstat64_path(&f, &stb) < 0 ? errno : 0; + check_cwd(); + if (v) + RedPrintf("%d/%d: stat %s %d\n", procid, opno, f.path, e); + free_pathname(&f); +} + +static void truncate_f(int opno, long r) +{ + int e; + pathname_t f; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname(&f); + if (!get_fname(FT_REGFILE, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: truncate - no filename\n", procid, opno); + free_pathname(&f); + return; + } + e = stat64_path(&f, &stb) < 0 ? errno : 0; + check_cwd(); + if (e > 0) { + if (v) + RedPrintf("%d/%d: truncate - stat64 %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + lr = ((__int64_t) random() << 32) + random(); + off = lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE); + off %= maxfsize; + e = truncate64_path(&f, off) < 0 ? errno : 0; + check_cwd(); + if (v) + RedPrintf("%d/%d: truncate %s %lld %d\n", procid, opno, f.path, + (long long)off, e); + free_pathname(&f); +} + +static void unlink_f(int opno, long r) +{ + int e; + pathname_t f; + fent_t *fep; + flist_t *flp; + int v; + + init_pathname(&f); + if (!get_fname(FT_NOTDIR, r, &f, &flp, &fep, &v)) { + if (v) + RedPrintf("%d/%d: unlink - no file\n", procid, opno); + free_pathname(&f); + return; + } + e = unlink_path(&f) < 0 ? errno : 0; + check_cwd(); + if (e == 0) + del_from_flist((int)(flp - flist), (int)(fep - flp->fents)); + if (v) + RedPrintf("%d/%d: unlink %s %d\n", procid, opno, f.path, e); + free_pathname(&f); +} + +static void write_f(int opno, long r) +{ + char *buf; + int e; + pathname_t f; + int fd; + uint32_t len; + __int64_t lr; + off64_t off; + REDSTAT stb; + int v; + + init_pathname(&f); + if (!get_fname(FT_REGm, r, &f, NULL, NULL, &v)) { + if (v) + RedPrintf("%d/%d: write - no filename\n", procid, opno); + free_pathname(&f); + return; + } + fd = open_path(&f, O_WRONLY); + e = fd < 0 ? errno : 0; + check_cwd(); + if (fd < 0) { + if (v) + RedPrintf("%d/%d: write - open %s failed %d\n", + procid, opno, f.path, e); + free_pathname(&f); + return; + } + if (fstat64(fd, &stb) < 0) { + if (v) + RedPrintf("%d/%d: write - fstat64 %s failed %d\n", + procid, opno, f.path, errno); + free_pathname(&f); + close(fd); + return; + } + lr = ((__int64_t) random() << 32) + random(); + off = (off64_t) (lr % MIN(stb.st_size + (1024 * 1024), MAXFSIZE)); + off %= maxfsize; + lseek64(fd, off, SEEK_SET); + len = (random() % (getpagesize() * 4)) + 1; + buf = malloc(len); + memset(buf, nameseq & 0xff, len); + e = write(fd, buf, len) < 0 ? errno : 0; + free(buf); + if (v) + RedPrintf("%d/%d: write %s [%lld,%ld] %d\n", + procid, opno, f.path, (long long)off, (long int)len, e); + free_pathname(&f); + close(fd); +} + + +#if REDCONF_CHECKER == 1 +static void check_f(int opno, long r) +{ + int32_t ret; + const char *pszVolume = gpRedVolConf->pszPathPrefix; + + (void)r; + + errno = 0; + + ret = red_transact(pszVolume); + + if(ret == 0) + { + ret = red_umount(pszVolume); + + if(ret == 0) + { + int32_t ret2; + + errno = -RedCoreVolCheck(); + if(errno != 0) + { + ret = -1; + } + + ret2 = red_mount(pszVolume); + + if(ret == 0) + { + ret = ret2; + } + + if(ret2 != 0) + { + exit(1); + } + } + } + + if (verbose) + { + RedPrintf("%d/%d: check %s %d\n", procid, opno, pszVolume, errno); + } +} +#endif + + +#endif /* FSSTRESS_SUPPORTED */ + diff --git a/tests/posix/redposixcompat.h b/tests/posix/redposixcompat.h new file mode 100644 index 0000000..4ace1e2 --- /dev/null +++ b/tests/posix/redposixcompat.h @@ -0,0 +1,150 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Defines macros which make the Reliance Edge POSIX-like API look more + like the actual POSIX API. + + This file is intended for porting POSIX file system tests; it is not + intended for application use. +*/ +#ifndef REDPOSIXCOMPAT_H +#define REDPOSIXCOMPAT_H + + +#ifndef assert +#define assert(x) REDASSERT(x) +#endif + + +#undef O_RDONLY +#undef O_WRONLY +#undef O_RDWR +#undef O_APPEND +#undef O_CREAT +#undef O_EXCL +#undef O_TRUNC +#define O_RDONLY RED_O_RDONLY +#define O_WRONLY RED_O_WRONLY +#define O_RDWR RED_O_RDWR +#define O_APPEND RED_O_APPEND +#define O_CREAT RED_O_CREAT +#define O_EXCL RED_O_EXCL +#define O_TRUNC RED_O_TRUNC + +#undef SEEK_SET +#undef SEEK_CUR +#undef SEEK_END +#define SEEK_SET RED_SEEK_SET +#define SEEK_CUR RED_SEEK_CUR +#define SEEK_END RED_SEEK_END + +/* Old-fashioned Linux seek names. +*/ +#undef L_SET +#undef L_INCR +#undef L_XTND +#define L_SET SEEK_SET +#define L_INCR SEEK_CUR +#define L_XTND SEEK_END + +#undef S_IFDIR +#undef S_IFREG +#undef S_ISDIR +#undef S_ISREG +#define S_IFDIR RED_S_IFDIR +#define S_IFREG RED_S_IFREG +#define S_ISDIR(m) RED_S_ISDIR(m) +#define S_ISREG(m) RED_S_ISREG(m) + +#undef ST_RDONLY +#undef ST_NOSUID +#define ST_RDONLY RED_ST_RDONLY +#define ST_NOSUID RED_ST_NOSUID + +#undef open +#undef creat +#undef unlink +#undef mkdir +#undef rmdir +#undef rename +#undef link +#undef close +#undef read +#undef write +#undef fsync +#undef fdatasync +#undef lseek +#undef ftruncate +#undef fstat +#undef opendir +#undef readdir +#undef rewinddir +#undef closedir +#define open(path, oflag) red_open(path, oflag) +#define creat(path, mode) open(path, O_WRONLY|O_CREAT|O_TRUNC) +#define unlink(path) red_unlink(path) +#define mkdir(path) red_mkdir(path) +#define rmdir(path) red_rmdir(path) +#define rename(old, new) red_rename(old, new) +#define link(path, hardlink) red_link(path, hardlink) +#define close(fd) red_close(fd) +#define read(fd, buf, len) red_read(fd, buf, len) +#define write(fd, buf, len) red_write(fd, buf, len) +#define fsync(fd) red_fsync(fd) +#define fdatasync(fd) fsync(fd) +#define lseek(fd, offset, whence) red_lseek(fd, offset, whence) +#define lseek64(fd, offset, whence) lseek(fd, offset, whence) +#define ftruncate(fd, size) red_ftruncate(fd, size) +#define fstat(fd, stat) red_fstat(fd, stat) +#define fstat64(fd, stat) fstat(fd, stat) +#define opendir(path) red_opendir(path) +#define readdir(dirp) red_readdir(dirp) +#define readdir64(dirp) readdir(dirp) +#define rewinddir(dirp) red_rewinddir(dirp) +#define closedir(dirp) red_closedir(dirp) + +#undef DIR +#define DIR REDDIR + +#undef errno +#define errno (*(int *)red_errnoptr()) + +#undef memcpy +#undef memmove +#undef memset +#undef strlen +#undef strncmp +#undef strcmp +#undef strncpy +#define memcpy(d, s, l) RedMemCpy(d, s, (uint32_t)(l)) +#define memmove(d, s, l) RedMemMove(d, s, (uint32_t)(l)) +#define memset(d, c, l) RedMemSet(d, (uint8_t)(c), (uint32_t)(l)) +#define strlen(s) RedStrLen(s) +#define strncmp(s1, s2, l) RedStrNCmp(s1, s2, (uint32_t)(l)) +#define strcmp(s1, s2) RedStrCmp(s1, s2) +#define strncpy(d, s, l) RedStrNCpy(d, s, (uint32_t)(l)) + + +#endif diff --git a/tests/util/printf.c b/tests/util/printf.c new file mode 100644 index 0000000..bb2c90a --- /dev/null +++ b/tests/util/printf.c @@ -0,0 +1,1398 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements functions for printing. + + These functions are intended to be used in portable test code, which cannot + assume the standard I/O functions will be available. Similar to their ANSI + C counterparts, these functions allow formatting text strings and (if the + configuration allows it) outputing formatted text. The latter ability + relies on the RedOsOutputString() OS service function. + + Do *not* use these functions in code which can safely assume the standard + I/O functions are available (e.g., in host tools code). + + Do *not* use these functions from within the file system driver. These + functions use variable arguments and thus are not MISRA-C:2012 compliant. +*/ +#include +#include +#include +#include + + +/** @brief Maximum number of bytes of output supported by RedPrintf(). + + Typically only Datalight code uses these functions, and that could should be + written to respect this limit, so it should not normally be necessary to + adjust this value. +*/ +#define OUTPUT_BUFFER_SIZE 256U + + +typedef enum +{ + PRFMT_UNKNOWN = 0, + PRFMT_CHAR, + PRFMT_ANSISTRING, + PRFMT_SIGNED8BIT, + PRFMT_UNSIGNED8BIT, + PRFMT_SIGNED16BIT, + PRFMT_UNSIGNED16BIT, + PRFMT_SIGNED32BIT, + PRFMT_UNSIGNED32BIT, + PRFMT_SIGNED64BIT, + PRFMT_UNSIGNED64BIT, + PRFMT_HEX8BIT, + PRFMT_HEX16BIT, + PRFMT_HEX32BIT, + PRFMT_HEX64BIT, + PRFMT_POINTER, + PRFMT_DOUBLEPERCENT +} PRINTTYPE; + +typedef struct +{ + PRINTTYPE type; /* The PRFMT_* type found */ + uint32_t ulSpecifierIdx; /* Returns a pointer to the % sign */ + uint32_t ulFillLen; + char cFillChar; + bool fLeftJustified; + bool fHasIllegalType; /* TRUE if an illegal sequence was skipped over */ + bool fHasVarWidth; +} PRINTFORMAT; + + +/* Our output handlers are written for standard fixed width data types. Map + the standard ANSI C data types onto our handlers. Currently this code has + the following requirements: + + 1) shorts must be either 16 or 32 bits + 2) ints must be either 16 or 32 bits + 3) longs must be between 32 or 64 bits + 4) long longs must be 64 bits +*/ +#if (USHRT_MAX == 0xFFFFU) + #define MAPSHORT PRFMT_SIGNED16BIT + #define MAPUSHORT PRFMT_UNSIGNED16BIT + #define MAPHEXUSHORT PRFMT_HEX16BIT +#elif (USHRT_MAX == 0xFFFFFFFFU) + #define MAPSHORT PRFMT_SIGNED32BIT + #define MAPUSHORT PRFMT_UNSIGNED32BIT + #define MAPHEXUSHORT PRFMT_HEX32BIT +#else + #error "The 'short' data type does not have a 16 or 32-bit width" +#endif + +#if (UINT_MAX == 0xFFFFU) + #define MAPINT PRFMT_SIGNED16BIT + #define MAPUINT PRFMT_UNSIGNED16BIT + #define MAPHEXUINT PRFMT_HEX16BIT +#elif (UINT_MAX == 0xFFFFFFFFU) + #define MAPINT PRFMT_SIGNED32BIT + #define MAPUINT PRFMT_UNSIGNED32BIT + #define MAPHEXUINT PRFMT_HEX32BIT +#else + #error "The 'int' data type does not have a 16 or 32-bit width" +#endif + +#if (ULONG_MAX == 0xFFFFFFFFU) + #define MAPLONG PRFMT_SIGNED32BIT + #define MAPULONG PRFMT_UNSIGNED32BIT + #define MAPHEXULONG PRFMT_HEX32BIT +#elif (ULONG_MAX <= 0xFFFFFFFFFFFFFFFFULL) + /* We've run into unusual environments where "longs" are 40-bits wide. + In this event, map them to 64-bit types so no data is lost. + */ + #define MAPLONG PRFMT_SIGNED64BIT + #define MAPULONG PRFMT_UNSIGNED64BIT + #define MAPHEXULONG PRFMT_HEX64BIT +#else + #error "The 'long' data type is not between 32 and 64 bits wide" +#endif + +#if defined(ULLONG_MAX) && (ULLONG_MAX != 0xFFFFFFFFFFFFFFFFULL) + #error "The 'long long' data type is not 64 bits wide" +#else + #define MAPLONGLONG PRFMT_SIGNED64BIT + #define MAPULONGLONG PRFMT_UNSIGNED64BIT + #define MAPHEXULONGLONG PRFMT_HEX64BIT +#endif + + +#define ISDIGIT(c) (((c) >= '0') && ((c) <= '9')) + + +static uint32_t ProcessFormatSegment(char *pcBuffer, uint32_t ulBufferLen, const char *pszFormat, PRINTFORMAT *pFormat, uint32_t *pulSpecifierLen); +static uint32_t ParseFormatSpecifier(char const *pszFomat, PRINTFORMAT *pFormatType); +static PRINTTYPE ParseFormatType(const char *pszFormat, uint32_t *pulTypeLen); +static uint32_t LtoA(char *pcBuffer, uint32_t ulBufferLen, int32_t lNum, uint32_t ulFillLen, char cFill); +static uint32_t LLtoA(char *pcBuffer, uint32_t ulBufferLen, int64_t llNum, uint32_t ulFillLen, char cFill); +static uint32_t ULtoA(char *pcBuffer, uint32_t ulBufferLen, uint32_t ulNum, bool fHex, uint32_t ulFillLen, char cFill); +static uint32_t ULLtoA(char *pcBuffer, uint32_t ulBufferLen, uint64_t ullNum, bool fHex, uint32_t ulFillLen, char cFill); +static uint32_t FinishToA(const char *pcDigits, uint32_t ulDigits, char *pcOutBuffer, uint32_t ulBufferLen, uint32_t ulFillLen, char cFill); +static void Uint64DivMod(uint64_t ullDividend, uint32_t ulDivisor, uint64_t *pullQuotient, uint32_t *pulRemainder); +static int32_t AtoL(const char *pach); + + +/* Digits for the *LtoA() routines. +*/ +static const char gacDigits[] = "0123456789ABCDEF"; + + +#if REDCONF_OUTPUT == 1 +/** @brief Print formatted data with a variable length argument list. + + This function provides a subset of the ANSI C printf() functionality with + several extensions to support fixed size data types. + + See RedVSNPrintf() for the list of supported types. + + @param pszFormat A pointer to the null-terminated format string. + @param ... The variable length argument list. +*/ +void RedPrintf( + const char *pszFormat, + ...) +{ + va_list arglist; + + va_start(arglist, pszFormat); + + RedVPrintf(pszFormat, arglist); + + va_end(arglist); +} + + +/** @brief Print formatted data using a pointer to a variable length argument + list. + + This function provides a subset of the ANSI C vprintf() functionality. + + See RedVSNPrintf() for the list of supported types. + + This function accommodates a maximum output length of #OUTPUT_BUFFER_SIZE. + If this function must truncate the output, and the original string was + \n terminated, the truncated output will be \n terminated as well. + + @param pszFormat A pointer to the null-terminated format string. + @param arglist The variable length argument list. +*/ +void RedVPrintf( + const char *pszFormat, + va_list arglist) +{ + char achBuffer[OUTPUT_BUFFER_SIZE]; + + if(RedVSNPrintf(achBuffer, sizeof(achBuffer), pszFormat, arglist) == -1) + { + /* Ensture the buffer is null terminated. + */ + achBuffer[sizeof(achBuffer) - 1U] = '\0'; + + /* If the original string was \n terminated and the new one is not, due to + truncation, stuff a \n into the new one. + */ + if(pszFormat[RedStrLen(pszFormat) - 1U] == '\n') + { + achBuffer[sizeof(achBuffer) - 2U] = '\n'; + } + } + + RedOsOutputString(achBuffer); +} +#endif /* #if REDCONF_OUTPUT == 1 */ + + +/** @brief Format arguments into a string using a subset of the ANSI C + vsprintf() functionality. + + This function is modeled after the Microsoft _snprint() extension to the + ANSI C sprintf() function, and allows a buffer length to be specified so + that overflow is avoided. + + See RedVSNPrintf() for the list of supported types. + + @param pcBuffer A pointer to the output buffer + @param ulBufferLen The output buffer length + @param pszFormat A pointer to the null terminated format string + @param ... Variable argument list + + @return The length output, or -1 if the buffer filled up. If -1 is + returned, the output buffer may not be null-terminated. +*/ +int32_t RedSNPrintf( + char *pcBuffer, + uint32_t ulBufferLen, + const char *pszFormat, + ...) +{ + int32_t iLen; + va_list arglist; + + va_start(arglist, pszFormat); + + iLen = RedVSNPrintf(pcBuffer, ulBufferLen, pszFormat, arglist); + + va_end(arglist); + + return iLen; +} + + +/** @brief Format arguments into a string using a subset of the ANSI C + vsprintf() functionality. + + This function is modeled after the Microsoft _vsnprint() extension to the + ANSI C vsprintf() function, and requires a buffer length to be specified so + that overflow is avoided. + + The following ANSI C standard formatting codes are supported: + + | Code | Meaning | + | ---- | ---------------------------------- | + | %c | Format a character | + | %s | Format a null-terminated C string | + | %hd | Format a signed short | + | %hu | Format an unsigned short | + | %d | Format a signed integer | + | %u | Format an unsigned integer | + | %ld | Format a signed long | + | %lu | Format an unsigned long | + | %lld | Format a signed long long | + | %llu | Format an unsigned long long | + | %hx | Format a short in hex | + | %x | Format an integer in hex | + | %lx | Format a long in hex | + | %llx | Format a long long in hex | + | %p | Format a pointer (hex value) | + + @note All formatting codes are case-sensitive. + + Fill characters and field widths are supported per the ANSI standard, as is + left justification with the '-' character. + + The only supported fill characters are '0', ' ', and '_'. + + '*' is supported to specify variable length field widths. + + Hexidecimal numbers are always displayed in upper case. Formatting codes + which specifically request upper case (e.g., "%lX") are not supported. + + Unsupported behaviors: + - Precision is not supported. + - Floating point is not supported. + + Errata: + - There is a subtle difference in the return value for this function versus + the Microsoft implementation. In the Microsoft version, if the buffer + exactly fills up, but there is no room for a null-terminator, the return + value will be the length of the buffer. In this code, -1 will be returned + when this happens. + - When using left justified strings, the only supported fill character is a + space, regardless of what may be specified. It is not clear if this is + ANSI standard or just the way the Microsoft function works, but we emulate + the Microsoft behavior. + + @param pcBuffer A pointer to the output buffer. + @param ulBufferLen The output buffer length. + @param pszFormat A pointer to the null terminated ANSI format string. + @param arglist Variable argument list. + + @return The length output, or -1 if the buffer filled up. If -1 is + returned, the output buffer may not be null-terminated. +*/ +int32_t RedVSNPrintf( + char *pcBuffer, + uint32_t ulBufferLen, + const char *pszFormat, + va_list arglist) +{ + uint32_t ulBufIdx = 0U; + uint32_t ulFmtIdx = 0U; + int32_t iLen; + + while((pszFormat[ulFmtIdx] != '\0') && (ulBufIdx < ulBufferLen)) + { + PRINTFORMAT fmt; + uint32_t ulSpecifierLen; + uint32_t ulWidth; + + /* Process the next segment of the format string, outputting + any non-format specifiers, as output buffer space allows, + and return information about the next format specifier. + */ + ulWidth = ProcessFormatSegment(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, &pszFormat[ulFmtIdx], &fmt, &ulSpecifierLen); + if(ulWidth) + { + REDASSERT(ulWidth <= (ulBufferLen - ulBufIdx)); + + ulBufIdx += ulWidth; + } + + /* If no specifier was found, or if the output buffer is + full, we're done -- get out. + */ + if((ulSpecifierLen == 0U) || (ulBufIdx == ulBufferLen)) + { + break; + } + + /* Otherwise, the math should add up for these things... + */ + REDASSERT(&pszFormat[fmt.ulSpecifierIdx] == &pszFormat[ulWidth]); + + /* Point past the specifier, to the next piece of the format string. + */ + ulFmtIdx = ulFmtIdx + fmt.ulSpecifierIdx + ulSpecifierLen; + + if(fmt.fHasVarWidth) + { + int iFillLen = va_arg(arglist, int); + + if(iFillLen >= 0) + { + fmt.ulFillLen = (uint32_t)iFillLen; + } + else + { + /* Bogus fill length. Ignore. + */ + fmt.ulFillLen = 0U; + } + } + + switch(fmt.type) + { + case PRFMT_DOUBLEPERCENT: + { + /* Nothing to do. A single percent has already been output, + and we just finished skipping past the second percent. + */ + break; + } + + /*-----------------> Small int handling <------------------ + * + * Values smaller than "int" will be promoted to "int" by + * the compiler, so we must retrieve them using "int" when + * calling va_arg(). Once we've done that, we immediately + * put the value into the desired data type. + *---------------------------------------------------------*/ + + case PRFMT_CHAR: + { + pcBuffer[ulBufIdx] = (char)va_arg(arglist, int); + ulBufIdx++; + break; + } + case PRFMT_SIGNED8BIT: + { + int8_t num = (int8_t)va_arg(arglist, int); + + ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_UNSIGNED8BIT: + { + uint8_t bNum = (uint8_t)va_arg(arglist, unsigned); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, false, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_HEX8BIT: + { + uint8_t bNum = (uint8_t)va_arg(arglist, unsigned); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, bNum, true, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_SIGNED16BIT: + { + int16_t num = (int16_t)va_arg(arglist, int); + + ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, num, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_UNSIGNED16BIT: + { + uint16_t uNum = (uint16_t)va_arg(arglist, unsigned); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, false, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_HEX16BIT: + { + uint16_t uNum = (uint16_t)va_arg(arglist, unsigned); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, uNum, true, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_SIGNED32BIT: + { + int32_t lNum = va_arg(arglist, int32_t); + + ulBufIdx += LtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, lNum, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_UNSIGNED32BIT: + { + uint32_t ulNum = va_arg(arglist, uint32_t); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, false, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_HEX32BIT: + { + uint32_t ulNum = va_arg(arglist, uint32_t); + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulNum, true, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_SIGNED64BIT: + { + int64_t llNum = va_arg(arglist, int64_t); + + ulBufIdx += LLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, llNum, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_UNSIGNED64BIT: + { + uint64_t ullNum = va_arg(arglist, uint64_t); + + ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, false, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_HEX64BIT: + { + uint64_t ullNum = va_arg(arglist, uint64_t); + + ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullNum, true, fmt.ulFillLen, fmt.cFillChar); + break; + } + case PRFMT_POINTER: + { + const void *ptr = va_arg(arglist, const void *); + + /* Assert our assumption. + */ + REDASSERT(sizeof(void *) <= 8U); + + /* Format as either a 64-bit or a 32-bit value. + */ + if(sizeof(void *) > 4U) + { + /* Attempt to quiet warnings. + */ + uintptr_t ptrval = (uintptr_t)ptr; + uint64_t ullPtrVal = (uint64_t)ptrval; + + ulBufIdx += ULLtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ullPtrVal, true, fmt.ulFillLen, fmt.cFillChar); + } + else + { + /* Attempt to quiet warnings. + */ + uintptr_t ptrval = (uintptr_t)ptr; + uint32_t ulPtrVal = (uint32_t)ptrval; + + ulBufIdx += ULtoA(&pcBuffer[ulBufIdx], ulBufferLen - ulBufIdx, ulPtrVal, true, fmt.ulFillLen, fmt.cFillChar); + } + + break; + } + case PRFMT_ANSISTRING: + { + const char *pszArg = va_arg(arglist, const char *); + uint32_t ulArgIdx = 0U; + + if(pszArg == NULL) + { + pszArg = "null"; + } + + if(fmt.ulFillLen > 0U) + { + if(!fmt.fLeftJustified) + { + uint32_t ulLen = RedStrLen(pszArg); + + /* So long as we are not left justifying, fill as many + characters as is necessary to make the string right + justified. + */ + while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > ulLen)) + { + pcBuffer[ulBufIdx] = fmt.cFillChar; + ulBufIdx++; + fmt.ulFillLen--; + } + } + + /* Move as many characters as we have space for into the + output buffer. + */ + while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0')) + { + pcBuffer[ulBufIdx] = pszArg[ulArgIdx]; + ulBufIdx++; + ulArgIdx++; + if(fmt.ulFillLen > 0U) + { + fmt.ulFillLen--; + } + } + + /* If there is any space left to fill, do it (the string + must have been left justified). + */ + while(((ulBufferLen - ulBufIdx) > 0U) && (fmt.ulFillLen > 0U)) + { + /* This is NOT a typo -- when using left justified + strings, spaces are the only allowed fill character. + See the errata. + */ + pcBuffer[ulBufIdx] = ' '; + ulBufIdx++; + fmt.ulFillLen--; + } + } + else + { + /* No fill characters, just move up to as many + characters as we have space for in the output + buffer. + */ + while(((ulBufferLen - ulBufIdx) > 0U) && (pszArg[ulArgIdx] != '\0')) + { + pcBuffer[ulBufIdx] = pszArg[ulArgIdx]; + ulBufIdx++; + ulArgIdx++; + } + } + break; + } + default: + { + REDERROR(); + break; + } + } + } + + /* If there is space, tack on a null and return the output length + processed, not including the null. + */ + if(ulBufIdx < ulBufferLen) + { + pcBuffer[ulBufIdx] = '\0'; + iLen = (int32_t)ulBufIdx; + } + else + { + /* Not enough space, just return -1, with no null termination + */ + iLen = -1; + } + + return iLen; +} + + +/** @brief Process the next segment of the format string, outputting any + non-format specifiers, as output buffer space allows, and return + information about the next format specifier. + + @note If the returned value is the same as the supplied @p ulBufferLen, + the output buffer will not be null-terminated. In all other cases, + the result will be null-terminated. The returned length will never + include the null in the count. + + @param pcBuffer The output buffer. + @param ulBufferLen The output buffer length. + @param pszFormat The format string to process. + @param pFormat The PRINTFORMAT structure to fill. + @param pulSpecifierLen Returns the length of any format specifier string, + or zero if no specifier was found. + + @return The count of characters from pszFormatt which were processed and + copied to pcBuffer. + - If zero is returned and *pulSpecifierLen is non-zero, then + a format specifier string was found at the start of pszFmt. + - If non-zero is returned and *pulSpecifierLen is zero, then + no format specifier string was found, and the entire pszFmt + string was copied to pBuffer (or as much as will fit). +*/ +static uint32_t ProcessFormatSegment( + char *pcBuffer, + uint32_t ulBufferLen, + const char *pszFormat, + PRINTFORMAT *pFormat, + uint32_t *pulSpecifierLen) +{ + uint32_t ulWidth = 0U; + + /* Find the next format specifier string, and information about it. + */ + *pulSpecifierLen = ParseFormatSpecifier(pszFormat, pFormat); + + if(*pulSpecifierLen == 0U) + { + /* If no specifier was found at all, then simply output the full length + of the string, or as much as will fit. + */ + ulWidth = REDMIN(ulBufferLen, RedStrLen(pszFormat)); + + RedMemCpy(pcBuffer, pszFormat, ulWidth); + } + else + { + /* If we encountered a double percent, skip past one of them so it is + copied into the output buffer. + */ + if(pFormat->type == PRFMT_DOUBLEPERCENT) + { + pFormat->ulSpecifierIdx++; + + /* A double percent specifier always has a length of two. Since + we're processing one of those percent signs, reduce the length + to one. Assert it so. + */ + REDASSERT(*pulSpecifierLen == 2U); + + (*pulSpecifierLen)--; + } + + /* So long as the specifier is not the very first thing in the format + string... + */ + if(pFormat->ulSpecifierIdx != 0U) + { + /* A specifier was found, but there is other data preceding it. + Copy as much as allowed to the output buffer. + */ + ulWidth = REDMIN(ulBufferLen, pFormat->ulSpecifierIdx); + + RedMemCpy(pcBuffer, pszFormat, ulWidth); + } + } + + /* If there is room in the output buffer, null-terminate whatever is there. + But note that the returned length never includes the null. + */ + if(ulWidth < ulBufferLen) + { + pcBuffer[ulWidth] = 0U; + } + + return ulWidth; +} + + +/** @brief Parse the specified format string for a valid RedVSNPrintf() format + sequence, and return information about it. + + @param pszFormat The format string to process. + @param pFormatType The PRINTFORMAT structure to fill. The data is only + valid if a non-zero length is returned. + + @return The length of the full format specifier string, starting at + pFormat->ulSpecifierIdx. Returns zero if a valid specifier was + not found. +*/ +static uint32_t ParseFormatSpecifier( + char const *pszFomat, + PRINTFORMAT *pFormatType) +{ + bool fContainsIllegalSequence = false; + uint32_t ulLen = 0U; + uint32_t ulIdx = 0U; + + while(pszFomat[ulIdx] != '\0') + { + uint32_t ulTypeLen; + + /* general output + */ + if(pszFomat[ulIdx] != '%') + { + ulIdx++; + } + else + { + RedMemSet(pFormatType, 0U, sizeof(*pFormatType)); + + /* Record the location of the start of the format sequence + */ + pFormatType->ulSpecifierIdx = ulIdx; + ulIdx++; + + if(pszFomat[ulIdx] == '-') + { + pFormatType->fLeftJustified = true; + ulIdx++; + } + + if((pszFomat[ulIdx] == '0') || (pszFomat[ulIdx] == '_')) + { + pFormatType->cFillChar = pszFomat[ulIdx]; + ulIdx++; + } + else + { + pFormatType->cFillChar = ' '; + } + + if(pszFomat[ulIdx] == '*') + { + pFormatType->fHasVarWidth = true; + ulIdx++; + } + else if(ISDIGIT(pszFomat[ulIdx])) + { + pFormatType->ulFillLen = (uint32_t)AtoL(&pszFomat[ulIdx]); + while(ISDIGIT(pszFomat[ulIdx])) + { + ulIdx++; + } + } + else + { + /* No fill length. + */ + } + + pFormatType->type = ParseFormatType(&pszFomat[ulIdx], &ulTypeLen); + if(pFormatType->type != PRFMT_UNKNOWN) + { + /* Even though we are returning successfully, keep track of + whether an illegal sequence was encountered and skipped. + */ + pFormatType->fHasIllegalType = fContainsIllegalSequence; + + ulLen = (ulIdx - pFormatType->ulSpecifierIdx) + ulTypeLen; + break; + } + + /* In the case of an unrecognized type string, simply ignore + it entirely. Reset the pointer to the position following + the percent sign, so it is not found again. + */ + fContainsIllegalSequence = false; + ulIdx = pFormatType->ulSpecifierIdx + 1U; + } + } + + return ulLen; +} + + +/** @brief Parse a RedPrintf() format type string to determine the proper data + type. + + @param pszFormat The format string to process. This must be a pointer to + the character following any width or justification + characters. + @param pulTypeLen The location in which to store the type length. The + value will be 0 if PRFMT_UNKNOWN is returned. + + @return Rhe PRFMT_* type value, or PRFMT_UNKNOWN if the type is not + recognized. +*/ +static PRINTTYPE ParseFormatType( + const char *pszFormat, + uint32_t *pulTypeLen) +{ + PRINTTYPE fmtType = PRFMT_UNKNOWN; + uint32_t ulIdx = 0U; + + switch(pszFormat[ulIdx]) + { + case '%': + fmtType = PRFMT_DOUBLEPERCENT; + break; + case 'c': + fmtType = PRFMT_CHAR; + break; + case 's': + fmtType = PRFMT_ANSISTRING; + break; + case 'p': + fmtType = PRFMT_POINTER; + break; + case 'd': + fmtType = MAPINT; + break; + case 'u': + fmtType = MAPUINT; + break; + case 'x': + fmtType = MAPHEXUINT; + break; + case 'h': + { + ulIdx++; + switch(pszFormat[ulIdx]) + { + case 'd': + fmtType = MAPSHORT; + break; + case 'u': + fmtType = MAPUSHORT; + break; + case 'x': + fmtType = MAPHEXUSHORT; + break; + default: + break; + } + break; + } + case 'l': + { + ulIdx++; + switch(pszFormat[ulIdx]) + { + case 'd': + fmtType = MAPLONG; + break; + case 'u': + fmtType = MAPULONG; + break; + case 'x': + fmtType = MAPHEXULONG; + break; + case 'l': + { + ulIdx++; + switch(pszFormat[ulIdx]) + { + case 'd': + fmtType = MAPLONGLONG; + break; + case 'u': + fmtType = MAPULONGLONG; + break; + case 'X': + fmtType = MAPHEXULONGLONG; + break; + default: + break; + } + break; + } + default: + break; + } + break; + } + default: + break; + } + + if(fmtType != PRFMT_UNKNOWN) + { + *pulTypeLen = ulIdx + 1U; + } + else + { + *pulTypeLen = 0U; + } + + return fmtType; +} + + +/** @brief Format a signed 32-bit integer as a base 10 ASCII string. + + @note If the output buffer length is exhausted, the result will *not* be + null-terminated. + + @note If the @p ulFillLen value is greater than or equal to the buffer + length, the result will not be null-terminated, even if the + formatted portion of the data is shorter than the buffer length. + + @param pcBuffer The output buffer + @param ulBufferLen A pointer to the output buffer length + @param lNum The 32-bit signed number to convert + @param ulFillLen The fill length, if any + @param cFill The fill character to use + + @return The length of the string. +*/ +static uint32_t LtoA( + char *pcBuffer, + uint32_t ulBufferLen, + int32_t lNum, + uint32_t ulFillLen, + char cFill) +{ + uint32_t ulLen; + + if(pcBuffer == NULL) + { + REDERROR(); + ulLen = 0U; + } + else + { + char ach[12U]; /* big enough for a int32_t in base 10 */ + uint32_t ulDigits = 0U; + uint32_t ulNum; + bool fSign; + + if(lNum < 0) + { + fSign = true; + ulNum = (uint32_t)-lNum; + } + else + { + fSign = false; + ulNum = (uint32_t)lNum; + } + + do + { + ach[ulDigits] = gacDigits[ulNum % 10U]; + ulNum = ulNum / 10U; + ulDigits++; + } + while(ulNum); + + if(fSign) + { + ach[ulDigits] = '-'; + ulDigits++; + } + + ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + } + + return ulLen; +} + + +/** @brief Format a signed 64-bit integer as a base 10 ASCII string. + + @note If the output buffer length is exhausted, the result will *not* be + null-terminated. + + @note If the @p ulFillLen value is greater than or equal to the buffer + length, the result will not be null-terminated, even if the + formatted portion of the data is shorter than the buffer length. + + @param pcBuffer The output buffer + @param ulBufferLen A pointer to the output buffer length + @param llNum The 64-bit signed number to convert + @param ulFillLen The fill length, if any + @param cFill The fill character to use + + @return The length of the string. +*/ +static uint32_t LLtoA( + char *pcBuffer, + uint32_t ulBufferLen, + int64_t llNum, + uint32_t ulFillLen, + char cFill) +{ + uint32_t ulLen; + + if(pcBuffer == NULL) + { + REDERROR(); + ulLen = 0U; + } + else + { + char ach[12U]; /* big enough for a int32_t in base 10 */ + uint32_t ulDigits = 0U; + uint64_t ullNum; + bool fSign; + + if(llNum < 0) + { + fSign = true; + ullNum = (uint64_t)-llNum; + } + else + { + fSign = false; + ullNum = (uint64_t)llNum; + } + + /* Not allowed to assume that 64-bit division is OK, so use a + software division routine. + */ + do + { + uint64_t ullQuotient; + uint32_t ulRemainder; + + /* Note: Uint64DivMod() is smart enough to use normal division + once ullNumericVal <= UINT32_MAX. + */ + Uint64DivMod(ullNum, 10U, &ullQuotient, &ulRemainder); + + ach[ulDigits] = gacDigits[ulRemainder]; + ullNum = ullQuotient; + ulDigits++; + } + while(ullNum > 0U); + + if(fSign) + { + ach[ulDigits] = '-'; + ulDigits++; + } + + ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + } + + return ulLen; +} + + +/** @brief Format an unsigned 32-bit integer as an ASCII string as decimal or + hex. + + @note If the output buffer length is exhausted, the result will *not* be + null-terminated. + + @param pcBuffer The output buffer + @param ulBufferLen The output buffer length + @param ulNum The 32-bit unsigned number to convert + @param fHex If true, format as hex; if false, decimal. + @param ulFillLen The fill length, if any + @param cFill The fill character to use + + @return The length of the string. +*/ +static uint32_t ULtoA( + char *pcBuffer, + uint32_t ulBufferLen, + uint32_t ulNum, + bool fHex, + uint32_t ulFillLen, + char cFill) +{ + uint32_t ulLen; + + if(pcBuffer == NULL) + { + REDERROR(); + ulLen = 0U; + } + else + { + char ach[11U]; /* Big enough for a uint32_t in radix 10 */ + uint32_t ulDigits = 0U; + uint32_t ulNumericVal = ulNum; + uint32_t ulRadix = fHex ? 16U : 10U; + + do + { + ach[ulDigits] = gacDigits[ulNumericVal % ulRadix]; + ulNumericVal = ulNumericVal / ulRadix; + ulDigits++; + } + while(ulNumericVal > 0U); + + ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + } + + return ulLen; +} + + +/** @brief Format an unsigned 64-bit integer as an ASCII string as decimal or + hex. + + @note If the output buffer length is exhausted, the result will *not* be + null-terminated. + + @param pcBuffer The output buffer. + @param ulBufferLen The output buffer length. + @param ullNum The unsigned 64-bit number to convert. + @param fHex If true, format as hex; if false, decimal. + @param ulFillLen The fill length, if any. + @param cFill The fill character to use. + + @return The length of the string. +*/ +static uint32_t ULLtoA( + char *pcBuffer, + uint32_t ulBufferLen, + uint64_t ullNum, + bool fHex, + uint32_t ulFillLen, + char cFill) +{ + uint32_t ulLen; + + if(pcBuffer == NULL) + { + REDERROR(); + ulLen = 0U; + } + else + { + + char ach[21U]; /* Big enough for a uint64_t in radix 10 */ + uint32_t ulDigits = 0U; + uint64_t ullNumericVal = ullNum; + + if(fHex) + { + /* We can figure out the digits using bit operations. + */ + do + { + ach[ulDigits] = gacDigits[ullNumericVal & 15U]; + ullNumericVal >>= 4U; + ulDigits++; + } + while(ullNumericVal > 0U); + } + else + { + /* Not allowed to assume that 64-bit division is OK, so use a + software division routine. + */ + do + { + uint64_t ullQuotient; + uint32_t ulRemainder; + + /* Note: Uint64DivMod() is smart enough to use normal division + once ullNumericVal <= UINT32_MAX. + */ + Uint64DivMod(ullNumericVal, 10U, &ullQuotient, &ulRemainder); + + ach[ulDigits] = gacDigits[ulRemainder]; + ullNumericVal = ullQuotient; + ulDigits++; + } + while(ullNumericVal > 0U); + } + + ulLen = FinishToA(ach, ulDigits, pcBuffer, ulBufferLen, ulFillLen, cFill); + } + + return ulLen; +} + + +/** @brief Finish converting a number into an ASCII string representing that + number. + + This helper function contains common logic that needs to run at the end of + all the "toA" functions. It adds the fill character and reverses the digits + string. + + @param pcDigits The digits (and sign) for the ASCII string, in reverse + order as they were computed. + @param ulDigits The number of digit characters. + @param pcOutBuffer The output buffer. + @param ulBufferLen The length of the output buffer. + @param ulFillLen The fill length. If the number string is shorter than + this, the remaining bytes are filled with @p cFill. + @param cFill The fill character. + + @return The length of @p pcOutBuffer. +*/ +static uint32_t FinishToA( + const char *pcDigits, + uint32_t ulDigits, + char *pcOutBuffer, + uint32_t ulBufferLen, + uint32_t ulFillLen, + char cFill) +{ + uint32_t ulIdx = 0U; + uint32_t ulDigitIdx = ulDigits; + + /* user may have asked for a fill char + */ + if(ulFillLen > ulDigits) + { + uint32_t ulFillRem = ulFillLen - ulDigits; + + while((ulFillRem > 0U) && (ulIdx < ulBufferLen)) + { + pcOutBuffer[ulIdx] = cFill; + ulIdx++; + ulFillRem--; + } + } + + /* reverse the string + */ + while((ulDigitIdx > 0) && (ulIdx < ulBufferLen)) + { + ulDigitIdx--; + pcOutBuffer[ulIdx] = pcDigits[ulDigitIdx]; + ulIdx++; + } + + if(ulIdx < ulBufferLen) + { + pcOutBuffer[ulIdx] = '\0'; + } + + return ulIdx; +} + + +/** @brief Divide a 64-bit value by a 32-bit value, returning the quotient and + the remainder. + + @param ullDividend The value to divide. + @param ulDivisor The value to divide by. + @param pullQuotient Populated with the result of the division. + @param pulRemander Populated with the remainder. +*/ +static void Uint64DivMod( + uint64_t ullDividend, + uint32_t ulDivisor, + uint64_t *pullQuotient, + uint32_t *pulRemainder) +{ + /* Check for divide by zero. + */ + if(ulDivisor == 0) + { + REDERROR(); + + /* Nonsense value if no asserts. + */ + *pullQuotient = 0xFFFFFFFFFFFFFBADULL; + *pulRemainder = 0xFFFFFBADU; + } + else if(ullDividend <= UINT32_MAX) + { + uint32_t ulDividend = (uint32_t)ullDividend; + + *pullQuotient = ulDividend / ulDivisor; + *pulRemainder = ulDividend % ulDivisor; + } + else + { + uint32_t ulResultHi; + uint32_t ulResultLo; + uint32_t ulRemainder; + uint8_t bIndex; + uint32_t ulThisDivision; + uint32_t ulMask; + uint8_t ucNextValue; + uint32_t ulInterimHi, ulInterimLo; + uint32_t ulLowDword = (uint32_t)ullDividend; + uint32_t ulHighDword = (uint32_t)(ullDividend >> 32U); + + /* Compute the high part and get the remainder + */ + ulResultHi = ulHighDword / ulDivisor; + ulResultLo = 0U; + ulRemainder = ulHighDword % ulDivisor; + + /* Compute the low part + */ + ulMask = 0xFF000000U; + for(bIndex = 0U; bIndex < sizeof(uint32_t); bIndex++) + { + ucNextValue = (uint8_t)((ulLowDword & ulMask) >> ((sizeof(uint32_t) - 1U - bIndex) * 8U)); + ulInterimHi = ulRemainder >> 24U; + ulInterimLo = (ulRemainder << 8U) | ucNextValue; + ulThisDivision = 0U; + while(ulInterimHi != 0U) + { + uint64_t ullInterim = ((uint64_t)ulInterimHi << 32U) + ulInterimLo; + + ullInterim -= ulDivisor; + ulThisDivision++; + + ulInterimHi = (uint32_t)(ullInterim >> 32U); + ulInterimLo = (uint32_t)ullInterim; + } + ulThisDivision += ulInterimLo / ulDivisor; + ulRemainder = ulInterimLo % ulDivisor; + ulResultLo <<= 8U; + ulResultLo += ulThisDivision; + ulMask >>= 8U; + } + + *pullQuotient = ((uint64_t)ulResultHi << 32U) + ulResultLo; + *pulRemainder = (uint32_t)(ullDividend - (*pullQuotient * ulDivisor)); + } +} + + +/** @brief Converts an ASCII number into an int32_t. + + Converts all decimal digit numbers up to the end of the string or to the + first non-numerical character. + + @note This function does *not* ignore leading white space. + + @param pach Pointer to a constant array of characters. + + @return The integer represented in the string. +*/ +static int32_t AtoL( + const char *pach) +{ + int32_t lValue = 0; + int32_t lNegative = 1; + uint32_t ulIdx = 0U; + + if(*pach == '+') + { + pach++; + } + else if(*pach == '-') + { + pach++; + lNegative = -1; + } + else + { + /* No sign, implicitly positive. + */ + } + + while(ISDIGIT(pach[ulIdx])) + { + lValue *= 10; + lValue += pach[ulIdx] - '0'; + ulIdx++; + } + + lValue *= lNegative; + + return lValue; +} + diff --git a/tests/util/rand.c b/tests/util/rand.c new file mode 100644 index 0000000..bca66bf --- /dev/null +++ b/tests/util/rand.c @@ -0,0 +1,159 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a random number generator. +*/ +#include +#include + + +/* This is the global seed used by the random number generator when the caller + has not provided a seed to either the RedRand32() or RedRand64() functions. +*/ +static uint64_t ullGlobalRandomNumberSeed; + +/* Whether the above seed has been initialized. +*/ +static bool fGlobalSeedInited; + + +/** @brief Set the global seed used by the random number generator. + + The global seed gets used when RedRand64() or RedRand32() are called with + a NULL seed argument. + + @param ullSeed The value to use as the global RNG seed. +*/ +void RedRandSeed( + uint64_t ullSeed) +{ + ullGlobalRandomNumberSeed = ullSeed; + fGlobalSeedInited = true; +} + + +/** @brief Generate a 64-bit pseudo-random number. + + The period of this random number generator is 2^64 (1.8 x 1019). These + parameters are the same as the default one-stream SPRNG lcg64 generator and + it satisfies the requirements for a maximal period. + + The tempering value is used and an AND mask and is specifically selected to + favor the distribution of lower bits. + + @param pullSeed A pointer to the seed to use. Set this value to NULL to + use the internal global seed value. + + @return A pseudo-random number in the range [0, UINT64_MAX]. +*/ +uint64_t RedRand64( + uint64_t *pullSeed) +{ + const uint64_t ullA = 2862933555777941757ULL; + const uint64_t ullC = 3037000493ULL; + const uint64_t ullT = 4921441182957829599ULL; + uint64_t ullN; + uint64_t *pullSeedPtr; + uint64_t ullLocalSeed; + + if(pullSeed != NULL) + { + ullLocalSeed = *pullSeed; + pullSeedPtr = pullSeed; + } + else + { + if(!fGlobalSeedInited) + { + /* Unfortunately, the Reliance Edge OS services don't give us much + to work with to initialize the global seed. There is no entropy + abstraction, no tick count abstraction, and the timestamp + abstraction uses an opaque type which is not guaranteed to be an + integer. The best we can do is use the RTC. + + Tests using the RNG should be supplying a seed anyway, for + reproducibility. + */ + RedRandSeed((uint64_t)RedOsClockGetTime()); + } + + ullLocalSeed = ullGlobalRandomNumberSeed; + pullSeedPtr = &ullGlobalRandomNumberSeed; + } + + ullN = (ullLocalSeed * ullA) + ullC; + + *pullSeedPtr = ullN; + + /* The linear congruential generator used above produces good psuedo-random + 64-bit number sequences, however, as with any LCG, the period of the + lower order bits is much shorter resulting in alternately odd/even pairs + in bit zero. + + The result of the LGC above is tempered below with a series of XOR and + shift operations to produce a more acceptable equidistribution of bits + throughout the 64-bit range. + */ + ullN ^= (ullN >> 21U) & ullT; + ullN ^= (ullN >> 43U) & ullT; + ullN ^= (ullN << 23U) & ~ullT; + ullN ^= (ullN << 31U) & ~ullT; + + return ullN; +} + + +/** @brief Generate a 32-bit pseudo-random number. + + @note The 32-bit random number generator internally uses the 64-bit random + number generator, returning the low 32-bits of the pseudo-random + 64-bit value. + + @param pulSeed A pointer to the seed to use. Set this value to NULL to use + the internal global seed value. + + @return A pseudo-random number in the range [0, UINT32_MAX]. +*/ +uint32_t RedRand32( + uint32_t *pulSeed) +{ + uint64_t ullN; + + if(pulSeed != NULL) + { + uint64_t ullLocalSeed; + + ullLocalSeed = *pulSeed; + ullN = RedRand64(&ullLocalSeed); + *pulSeed = (uint32_t)ullLocalSeed; + } + else + { + ullN = RedRand64(NULL); + } + + return (uint32_t)ullN; +} + diff --git a/util/bitmap.c b/util/bitmap.c new file mode 100644 index 0000000..ac341fd --- /dev/null +++ b/util/bitmap.c @@ -0,0 +1,101 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements utilities for working with bitmaps. +*/ +#include + + +/** @brief Query the state of a bit in a bitmap. + + Bits are counted from most significant to least significant. Thus, the mask + for bit zero is 0x80 applied to the first byte in the bitmap. + + @param pbBitmap Pointer to the bitmap. + @param ulBit The bit to query. + + @retval Whether the bit is set (true) or clear (false. +*/ +bool RedBitGet( + const uint8_t *pbBitmap, + uint32_t ulBit) +{ + bool fRet; + + if(pbBitmap == NULL) + { + REDERROR(); + fRet = false; + } + else + { + fRet = (pbBitmap[ulBit / 8U] & (0x80U >> (ulBit % 8U))) != 0U; + } + + return fRet; +} + + +/** @brief Set a bit in a bitmap to one. + + Bits are counted from most significant to least significant. Thus, the mask + for bit zero is 0x80 applied to the first byte in the bitmap. + + @param pbBitmap Pointer to the bitmap. + @param ulBit The bit to set. +*/ +void RedBitSet( + uint8_t *pbBitmap, + uint32_t ulBit) +{ + REDASSERT(pbBitmap != NULL); + + if(pbBitmap != NULL) + { + pbBitmap[ulBit / 8U] |= (0x80U >> (ulBit % 8U)); + } +} + + +/** @brief Clear a bit in a bitmap to zero. + + Bits are counted from most significant to least significant. Thus, the mask + for bit zero is 0x80 applied to the first byte in the bitmap. + + @param pbBitmap Pointer to the bitmap. + @param ulBit The bit to clear. +*/ +void RedBitClear( + uint8_t *pbBitmap, + uint32_t ulBit) +{ + REDASSERT(pbBitmap != NULL); + + if(pbBitmap != NULL) + { + pbBitmap[ulBit / 8U] &= ~(0x80U >> (ulBit % 8U)); + } +} + diff --git a/util/crc.c b/util/crc.c new file mode 100644 index 0000000..6048942 --- /dev/null +++ b/util/crc.c @@ -0,0 +1,672 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements utilities for calculating CRC-32 checksums. +*/ +#include + + +/* The CRC functions do not return errors since the only detectable error + condition is a NULL buffer pointer. If such a condition does arise, the + functions assert and return the below CRC, which, although a legal CRC, + is nonetheless suspicious and could provide a clue that something has + gone wrong. +*/ +#define SUSPICIOUS_CRC_VALUE (0xBAADC0DEU) + +#define CRC_BITWISE (0U) +#define CRC_SARWATE (1U) +#define CRC_SLICEBY8 (2U) + + +#if REDCONF_CRC_ALGORITHM == CRC_BITWISE + +/* The following is representative of the polynomial accepted by CCITT 32-bit + and in IEEE 802.3, Ethernet 2 specification. + + x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1 + (reverse order) + 1110 1101 1011 1000 1000 0011 0010 0000 1 + (E) (D) (B) (8) (8) (3) (2) (0) +*/ +#define CCITT_32_POLYNOMIAL (0xEDB88320U) + + +/** @brief Compute a CRC32 for the given data buffer. + + For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + buffers, call this function with the previously returned CRC value. + + @param ulInitCrc32 Starting CRC value. + @param pBuffer Data buffer to calculate the CRC from. + @param ulLength Number of bytes of data in the given buffer. + + @return The updated CRC value. +*/ +uint32_t RedCrc32Update( + uint32_t ulInitCrc32, + const void *pBuffer, + uint32_t ulLength) +{ + uint32_t ulCrc32; + + if(pBuffer == NULL) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + uint32_t ulIdx; + + ulCrc32 = ~ulInitCrc32; + + for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx) + { + uint32_t ulBit; + + ulCrc32 ^= pbBuffer[ulIdx]; + + /* Branchless inner loop (greatly improves performance). + */ + for(ulBit = 0U; ulBit < 8U; ulBit++) + { + ulCrc32 = ((ulCrc32 & 1U) * CCITT_32_POLYNOMIAL) ^ (ulCrc32 >> 1U); + } + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; +} + +#elif REDCONF_CRC_ALGORITHM == CRC_SARWATE + +static const uint32_t gaulCrc32Table[] = +{ + 0x00000000UL, 0x77073096UL, 0xEE0E612CUL, 0x990951BAUL, + 0x076DC419UL, 0x706AF48FUL, 0xE963A535UL, 0x9E6495A3UL, + 0x0EDB8832UL, 0x79DCB8A4UL, 0xE0D5E91EUL, 0x97D2D988UL, + 0x09B64C2BUL, 0x7EB17CBDUL, 0xE7B82D07UL, 0x90BF1D91UL, + 0x1DB71064UL, 0x6AB020F2UL, 0xF3B97148UL, 0x84BE41DEUL, + 0x1ADAD47DUL, 0x6DDDE4EBUL, 0xF4D4B551UL, 0x83D385C7UL, + 0x136C9856UL, 0x646BA8C0UL, 0xFD62F97AUL, 0x8A65C9ECUL, + 0x14015C4FUL, 0x63066CD9UL, 0xFA0F3D63UL, 0x8D080DF5UL, + 0x3B6E20C8UL, 0x4C69105EUL, 0xD56041E4UL, 0xA2677172UL, + 0x3C03E4D1UL, 0x4B04D447UL, 0xD20D85FDUL, 0xA50AB56BUL, + 0x35B5A8FAUL, 0x42B2986CUL, 0xDBBBC9D6UL, 0xACBCF940UL, + 0x32D86CE3UL, 0x45DF5C75UL, 0xDCD60DCFUL, 0xABD13D59UL, + 0x26D930ACUL, 0x51DE003AUL, 0xC8D75180UL, 0xBFD06116UL, + 0x21B4F4B5UL, 0x56B3C423UL, 0xCFBA9599UL, 0xB8BDA50FUL, + 0x2802B89EUL, 0x5F058808UL, 0xC60CD9B2UL, 0xB10BE924UL, + 0x2F6F7C87UL, 0x58684C11UL, 0xC1611DABUL, 0xB6662D3DUL, + 0x76DC4190UL, 0x01DB7106UL, 0x98D220BCUL, 0xEFD5102AUL, + 0x71B18589UL, 0x06B6B51FUL, 0x9FBFE4A5UL, 0xE8B8D433UL, + 0x7807C9A2UL, 0x0F00F934UL, 0x9609A88EUL, 0xE10E9818UL, + 0x7F6A0DBBUL, 0x086D3D2DUL, 0x91646C97UL, 0xE6635C01UL, + 0x6B6B51F4UL, 0x1C6C6162UL, 0x856530D8UL, 0xF262004EUL, + 0x6C0695EDUL, 0x1B01A57BUL, 0x8208F4C1UL, 0xF50FC457UL, + 0x65B0D9C6UL, 0x12B7E950UL, 0x8BBEB8EAUL, 0xFCB9887CUL, + 0x62DD1DDFUL, 0x15DA2D49UL, 0x8CD37CF3UL, 0xFBD44C65UL, + 0x4DB26158UL, 0x3AB551CEUL, 0xA3BC0074UL, 0xD4BB30E2UL, + 0x4ADFA541UL, 0x3DD895D7UL, 0xA4D1C46DUL, 0xD3D6F4FBUL, + 0x4369E96AUL, 0x346ED9FCUL, 0xAD678846UL, 0xDA60B8D0UL, + 0x44042D73UL, 0x33031DE5UL, 0xAA0A4C5FUL, 0xDD0D7CC9UL, + 0x5005713CUL, 0x270241AAUL, 0xBE0B1010UL, 0xC90C2086UL, + 0x5768B525UL, 0x206F85B3UL, 0xB966D409UL, 0xCE61E49FUL, + 0x5EDEF90EUL, 0x29D9C998UL, 0xB0D09822UL, 0xC7D7A8B4UL, + 0x59B33D17UL, 0x2EB40D81UL, 0xB7BD5C3BUL, 0xC0BA6CADUL, + 0xEDB88320UL, 0x9ABFB3B6UL, 0x03B6E20CUL, 0x74B1D29AUL, + 0xEAD54739UL, 0x9DD277AFUL, 0x04DB2615UL, 0x73DC1683UL, + 0xE3630B12UL, 0x94643B84UL, 0x0D6D6A3EUL, 0x7A6A5AA8UL, + 0xE40ECF0BUL, 0x9309FF9DUL, 0x0A00AE27UL, 0x7D079EB1UL, + 0xF00F9344UL, 0x8708A3D2UL, 0x1E01F268UL, 0x6906C2FEUL, + 0xF762575DUL, 0x806567CBUL, 0x196C3671UL, 0x6E6B06E7UL, + 0xFED41B76UL, 0x89D32BE0UL, 0x10DA7A5AUL, 0x67DD4ACCUL, + 0xF9B9DF6FUL, 0x8EBEEFF9UL, 0x17B7BE43UL, 0x60B08ED5UL, + 0xD6D6A3E8UL, 0xA1D1937EUL, 0x38D8C2C4UL, 0x4FDFF252UL, + 0xD1BB67F1UL, 0xA6BC5767UL, 0x3FB506DDUL, 0x48B2364BUL, + 0xD80D2BDAUL, 0xAF0A1B4CUL, 0x36034AF6UL, 0x41047A60UL, + 0xDF60EFC3UL, 0xA867DF55UL, 0x316E8EEFUL, 0x4669BE79UL, + 0xCB61B38CUL, 0xBC66831AUL, 0x256FD2A0UL, 0x5268E236UL, + 0xCC0C7795UL, 0xBB0B4703UL, 0x220216B9UL, 0x5505262FUL, + 0xC5BA3BBEUL, 0xB2BD0B28UL, 0x2BB45A92UL, 0x5CB36A04UL, + 0xC2D7FFA7UL, 0xB5D0CF31UL, 0x2CD99E8BUL, 0x5BDEAE1DUL, + 0x9B64C2B0UL, 0xEC63F226UL, 0x756AA39CUL, 0x026D930AUL, + 0x9C0906A9UL, 0xEB0E363FUL, 0x72076785UL, 0x05005713UL, + 0x95BF4A82UL, 0xE2B87A14UL, 0x7BB12BAEUL, 0x0CB61B38UL, + 0x92D28E9BUL, 0xE5D5BE0DUL, 0x7CDCEFB7UL, 0x0BDBDF21UL, + 0x86D3D2D4UL, 0xF1D4E242UL, 0x68DDB3F8UL, 0x1FDA836EUL, + 0x81BE16CDUL, 0xF6B9265BUL, 0x6FB077E1UL, 0x18B74777UL, + 0x88085AE6UL, 0xFF0F6A70UL, 0x66063BCAUL, 0x11010B5CUL, + 0x8F659EFFUL, 0xF862AE69UL, 0x616BFFD3UL, 0x166CCF45UL, + 0xA00AE278UL, 0xD70DD2EEUL, 0x4E048354UL, 0x3903B3C2UL, + 0xA7672661UL, 0xD06016F7UL, 0x4969474DUL, 0x3E6E77DBUL, + 0xAED16A4AUL, 0xD9D65ADCUL, 0x40DF0B66UL, 0x37D83BF0UL, + 0xA9BCAE53UL, 0xDEBB9EC5UL, 0x47B2CF7FUL, 0x30B5FFE9UL, + 0xBDBDF21CUL, 0xCABAC28AUL, 0x53B39330UL, 0x24B4A3A6UL, + 0xBAD03605UL, 0xCDD70693UL, 0x54DE5729UL, 0x23D967BFUL, + 0xB3667A2EUL, 0xC4614AB8UL, 0x5D681B02UL, 0x2A6F2B94UL, + 0xB40BBE37UL, 0xC30C8EA1UL, 0x5A05DF1BUL, 0x2D02EF8DUL, +}; + + +/** @brief Compute a CRC32 for the given data buffer. + + For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + buffers, call this function with the previously returned CRC value. + + @param ulInitCrc32 Starting CRC value. + @param pBuffer Data buffer to calculate the CRC from. + @param ulLength Number of bytes of data in the given buffer. + + @return The updated CRC value. +*/ +uint32_t RedCrc32Update( + uint32_t ulInitCrc32, + const void *pBuffer, + uint32_t ulLength) +{ + uint32_t ulCrc32; + + if(pBuffer == NULL) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + uint32_t ulIdx; + + ulCrc32 = ~ulInitCrc32; + + for(ulIdx = 0U; ulIdx < ulLength; ++ulIdx) + { + ulCrc32 = (ulCrc32 >> 8U) ^ gaulCrc32Table[(ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU]; + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; +} + +#elif REDCONF_CRC_ALGORITHM == CRC_SLICEBY8 + +/* CRC32 XOR table, with slicing-by-8 extensions. + + This first column of the table contains the same XOR values as used in the + classic byte-at-a-time Sarwate algorithm. The other seven columns are + derived from the first, and are used in Intel's slicing-by-eight CRC + algorithm. + + The layout of this array in memory is novel and deserves explanation. In + other implementations, including Intel's example, each of the below columns + is an array. The first column is a 256-entry array, followed by another + 256-entry array for the second column, etc. Testing on both ARM and x86 + has shown the below mixed arrangement to be about 5-9% faster. One + possible explanation: With the array-per-table approach, each of the eight + table lookups is guaranteed to be in a separate 1 KB chunk of memory. With + the below array, sometimes multiple table lookups will, by coincidence, be + close together, making better use of the cache. +*/ +static const uint32_t gaulCrc32Table[] = +{ + 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, 0x00000000UL, + 0x77073096UL, 0x191B3141UL, 0x01C26A37UL, 0xB8BC6765UL, 0x3D6029B0UL, 0xCB5CD3A5UL, 0xA6770BB4UL, 0xCCAA009EUL, + 0xEE0E612CUL, 0x32366282UL, 0x0384D46EUL, 0xAA09C88BUL, 0x7AC05360UL, 0x4DC8A10BUL, 0x979F1129UL, 0x4225077DUL, + 0x990951BAUL, 0x2B2D53C3UL, 0x0246BE59UL, 0x12B5AFEEUL, 0x47A07AD0UL, 0x869472AEUL, 0x31E81A9DUL, 0x8E8F07E3UL, + 0x076DC419UL, 0x646CC504UL, 0x0709A8DCUL, 0x8F629757UL, 0xF580A6C0UL, 0x9B914216UL, 0xF44F2413UL, 0x844A0EFAUL, + 0x706AF48FUL, 0x7D77F445UL, 0x06CBC2EBUL, 0x37DEF032UL, 0xC8E08F70UL, 0x50CD91B3UL, 0x52382FA7UL, 0x48E00E64UL, + 0xE963A535UL, 0x565AA786UL, 0x048D7CB2UL, 0x256B5FDCUL, 0x8F40F5A0UL, 0xD659E31DUL, 0x63D0353AUL, 0xC66F0987UL, + 0x9E6495A3UL, 0x4F4196C7UL, 0x054F1685UL, 0x9DD738B9UL, 0xB220DC10UL, 0x1D0530B8UL, 0xC5A73E8EUL, 0x0AC50919UL, + 0x0EDB8832UL, 0xC8D98A08UL, 0x0E1351B8UL, 0xC5B428EFUL, 0x30704BC1UL, 0xEC53826DUL, 0x33EF4E67UL, 0xD3E51BB5UL, + 0x79DCB8A4UL, 0xD1C2BB49UL, 0x0FD13B8FUL, 0x7D084F8AUL, 0x0D106271UL, 0x270F51C8UL, 0x959845D3UL, 0x1F4F1B2BUL, + 0xE0D5E91EUL, 0xFAEFE88AUL, 0x0D9785D6UL, 0x6FBDE064UL, 0x4AB018A1UL, 0xA19B2366UL, 0xA4705F4EUL, 0x91C01CC8UL, + 0x97D2D988UL, 0xE3F4D9CBUL, 0x0C55EFE1UL, 0xD7018701UL, 0x77D03111UL, 0x6AC7F0C3UL, 0x020754FAUL, 0x5D6A1C56UL, + 0x09B64C2BUL, 0xACB54F0CUL, 0x091AF964UL, 0x4AD6BFB8UL, 0xC5F0ED01UL, 0x77C2C07BUL, 0xC7A06A74UL, 0x57AF154FUL, + 0x7EB17CBDUL, 0xB5AE7E4DUL, 0x08D89353UL, 0xF26AD8DDUL, 0xF890C4B1UL, 0xBC9E13DEUL, 0x61D761C0UL, 0x9B0515D1UL, + 0xE7B82D07UL, 0x9E832D8EUL, 0x0A9E2D0AUL, 0xE0DF7733UL, 0xBF30BE61UL, 0x3A0A6170UL, 0x503F7B5DUL, 0x158A1232UL, + 0x90BF1D91UL, 0x87981CCFUL, 0x0B5C473DUL, 0x58631056UL, 0x825097D1UL, 0xF156B2D5UL, 0xF64870E9UL, 0xD92012ACUL, + 0x1DB71064UL, 0x4AC21251UL, 0x1C26A370UL, 0x5019579FUL, 0x60E09782UL, 0x03D6029BUL, 0x67DE9CCEUL, 0x7CBB312BUL, + 0x6AB020F2UL, 0x53D92310UL, 0x1DE4C947UL, 0xE8A530FAUL, 0x5D80BE32UL, 0xC88AD13EUL, 0xC1A9977AUL, 0xB01131B5UL, + 0xF3B97148UL, 0x78F470D3UL, 0x1FA2771EUL, 0xFA109F14UL, 0x1A20C4E2UL, 0x4E1EA390UL, 0xF0418DE7UL, 0x3E9E3656UL, + 0x84BE41DEUL, 0x61EF4192UL, 0x1E601D29UL, 0x42ACF871UL, 0x2740ED52UL, 0x85427035UL, 0x56368653UL, 0xF23436C8UL, + 0x1ADAD47DUL, 0x2EAED755UL, 0x1B2F0BACUL, 0xDF7BC0C8UL, 0x95603142UL, 0x9847408DUL, 0x9391B8DDUL, 0xF8F13FD1UL, + 0x6DDDE4EBUL, 0x37B5E614UL, 0x1AED619BUL, 0x67C7A7ADUL, 0xA80018F2UL, 0x531B9328UL, 0x35E6B369UL, 0x345B3F4FUL, + 0xF4D4B551UL, 0x1C98B5D7UL, 0x18ABDFC2UL, 0x75720843UL, 0xEFA06222UL, 0xD58FE186UL, 0x040EA9F4UL, 0xBAD438ACUL, + 0x83D385C7UL, 0x05838496UL, 0x1969B5F5UL, 0xCDCE6F26UL, 0xD2C04B92UL, 0x1ED33223UL, 0xA279A240UL, 0x767E3832UL, + 0x136C9856UL, 0x821B9859UL, 0x1235F2C8UL, 0x95AD7F70UL, 0x5090DC43UL, 0xEF8580F6UL, 0x5431D2A9UL, 0xAF5E2A9EUL, + 0x646BA8C0UL, 0x9B00A918UL, 0x13F798FFUL, 0x2D111815UL, 0x6DF0F5F3UL, 0x24D95353UL, 0xF246D91DUL, 0x63F42A00UL, + 0xFD62F97AUL, 0xB02DFADBUL, 0x11B126A6UL, 0x3FA4B7FBUL, 0x2A508F23UL, 0xA24D21FDUL, 0xC3AEC380UL, 0xED7B2DE3UL, + 0x8A65C9ECUL, 0xA936CB9AUL, 0x10734C91UL, 0x8718D09EUL, 0x1730A693UL, 0x6911F258UL, 0x65D9C834UL, 0x21D12D7DUL, + 0x14015C4FUL, 0xE6775D5DUL, 0x153C5A14UL, 0x1ACFE827UL, 0xA5107A83UL, 0x7414C2E0UL, 0xA07EF6BAUL, 0x2B142464UL, + 0x63066CD9UL, 0xFF6C6C1CUL, 0x14FE3023UL, 0xA2738F42UL, 0x98705333UL, 0xBF481145UL, 0x0609FD0EUL, 0xE7BE24FAUL, + 0xFA0F3D63UL, 0xD4413FDFUL, 0x16B88E7AUL, 0xB0C620ACUL, 0xDFD029E3UL, 0x39DC63EBUL, 0x37E1E793UL, 0x69312319UL, + 0x8D080DF5UL, 0xCD5A0E9EUL, 0x177AE44DUL, 0x087A47C9UL, 0xE2B00053UL, 0xF280B04EUL, 0x9196EC27UL, 0xA59B2387UL, + 0x3B6E20C8UL, 0x958424A2UL, 0x384D46E0UL, 0xA032AF3EUL, 0xC1C12F04UL, 0x07AC0536UL, 0xCFBD399CUL, 0xF9766256UL, + 0x4C69105EUL, 0x8C9F15E3UL, 0x398F2CD7UL, 0x188EC85BUL, 0xFCA106B4UL, 0xCCF0D693UL, 0x69CA3228UL, 0x35DC62C8UL, + 0xD56041E4UL, 0xA7B24620UL, 0x3BC9928EUL, 0x0A3B67B5UL, 0xBB017C64UL, 0x4A64A43DUL, 0x582228B5UL, 0xBB53652BUL, + 0xA2677172UL, 0xBEA97761UL, 0x3A0BF8B9UL, 0xB28700D0UL, 0x866155D4UL, 0x81387798UL, 0xFE552301UL, 0x77F965B5UL, + 0x3C03E4D1UL, 0xF1E8E1A6UL, 0x3F44EE3CUL, 0x2F503869UL, 0x344189C4UL, 0x9C3D4720UL, 0x3BF21D8FUL, 0x7D3C6CACUL, + 0x4B04D447UL, 0xE8F3D0E7UL, 0x3E86840BUL, 0x97EC5F0CUL, 0x0921A074UL, 0x57619485UL, 0x9D85163BUL, 0xB1966C32UL, + 0xD20D85FDUL, 0xC3DE8324UL, 0x3CC03A52UL, 0x8559F0E2UL, 0x4E81DAA4UL, 0xD1F5E62BUL, 0xAC6D0CA6UL, 0x3F196BD1UL, + 0xA50AB56BUL, 0xDAC5B265UL, 0x3D025065UL, 0x3DE59787UL, 0x73E1F314UL, 0x1AA9358EUL, 0x0A1A0712UL, 0xF3B36B4FUL, + 0x35B5A8FAUL, 0x5D5DAEAAUL, 0x365E1758UL, 0x658687D1UL, 0xF1B164C5UL, 0xEBFF875BUL, 0xFC5277FBUL, 0x2A9379E3UL, + 0x42B2986CUL, 0x44469FEBUL, 0x379C7D6FUL, 0xDD3AE0B4UL, 0xCCD14D75UL, 0x20A354FEUL, 0x5A257C4FUL, 0xE639797DUL, + 0xDBBBC9D6UL, 0x6F6BCC28UL, 0x35DAC336UL, 0xCF8F4F5AUL, 0x8B7137A5UL, 0xA6372650UL, 0x6BCD66D2UL, 0x68B67E9EUL, + 0xACBCF940UL, 0x7670FD69UL, 0x3418A901UL, 0x7733283FUL, 0xB6111E15UL, 0x6D6BF5F5UL, 0xCDBA6D66UL, 0xA41C7E00UL, + 0x32D86CE3UL, 0x39316BAEUL, 0x3157BF84UL, 0xEAE41086UL, 0x0431C205UL, 0x706EC54DUL, 0x081D53E8UL, 0xAED97719UL, + 0x45DF5C75UL, 0x202A5AEFUL, 0x3095D5B3UL, 0x525877E3UL, 0x3951EBB5UL, 0xBB3216E8UL, 0xAE6A585CUL, 0x62737787UL, + 0xDCD60DCFUL, 0x0B07092CUL, 0x32D36BEAUL, 0x40EDD80DUL, 0x7EF19165UL, 0x3DA66446UL, 0x9F8242C1UL, 0xECFC7064UL, + 0xABD13D59UL, 0x121C386DUL, 0x331101DDUL, 0xF851BF68UL, 0x4391B8D5UL, 0xF6FAB7E3UL, 0x39F54975UL, 0x205670FAUL, + 0x26D930ACUL, 0xDF4636F3UL, 0x246BE590UL, 0xF02BF8A1UL, 0xA121B886UL, 0x047A07ADUL, 0xA863A552UL, 0x85CD537DUL, + 0x51DE003AUL, 0xC65D07B2UL, 0x25A98FA7UL, 0x48979FC4UL, 0x9C419136UL, 0xCF26D408UL, 0x0E14AEE6UL, 0x496753E3UL, + 0xC8D75180UL, 0xED705471UL, 0x27EF31FEUL, 0x5A22302AUL, 0xDBE1EBE6UL, 0x49B2A6A6UL, 0x3FFCB47BUL, 0xC7E85400UL, + 0xBFD06116UL, 0xF46B6530UL, 0x262D5BC9UL, 0xE29E574FUL, 0xE681C256UL, 0x82EE7503UL, 0x998BBFCFUL, 0x0B42549EUL, + 0x21B4F4B5UL, 0xBB2AF3F7UL, 0x23624D4CUL, 0x7F496FF6UL, 0x54A11E46UL, 0x9FEB45BBUL, 0x5C2C8141UL, 0x01875D87UL, + 0x56B3C423UL, 0xA231C2B6UL, 0x22A0277BUL, 0xC7F50893UL, 0x69C137F6UL, 0x54B7961EUL, 0xFA5B8AF5UL, 0xCD2D5D19UL, + 0xCFBA9599UL, 0x891C9175UL, 0x20E69922UL, 0xD540A77DUL, 0x2E614D26UL, 0xD223E4B0UL, 0xCBB39068UL, 0x43A25AFAUL, + 0xB8BDA50FUL, 0x9007A034UL, 0x2124F315UL, 0x6DFCC018UL, 0x13016496UL, 0x197F3715UL, 0x6DC49BDCUL, 0x8F085A64UL, + 0x2802B89EUL, 0x179FBCFBUL, 0x2A78B428UL, 0x359FD04EUL, 0x9151F347UL, 0xE82985C0UL, 0x9B8CEB35UL, 0x562848C8UL, + 0x5F058808UL, 0x0E848DBAUL, 0x2BBADE1FUL, 0x8D23B72BUL, 0xAC31DAF7UL, 0x23755665UL, 0x3DFBE081UL, 0x9A824856UL, + 0xC60CD9B2UL, 0x25A9DE79UL, 0x29FC6046UL, 0x9F9618C5UL, 0xEB91A027UL, 0xA5E124CBUL, 0x0C13FA1CUL, 0x140D4FB5UL, + 0xB10BE924UL, 0x3CB2EF38UL, 0x283E0A71UL, 0x272A7FA0UL, 0xD6F18997UL, 0x6EBDF76EUL, 0xAA64F1A8UL, 0xD8A74F2BUL, + 0x2F6F7C87UL, 0x73F379FFUL, 0x2D711CF4UL, 0xBAFD4719UL, 0x64D15587UL, 0x73B8C7D6UL, 0x6FC3CF26UL, 0xD2624632UL, + 0x58684C11UL, 0x6AE848BEUL, 0x2CB376C3UL, 0x0241207CUL, 0x59B17C37UL, 0xB8E41473UL, 0xC9B4C492UL, 0x1EC846ACUL, + 0xC1611DABUL, 0x41C51B7DUL, 0x2EF5C89AUL, 0x10F48F92UL, 0x1E1106E7UL, 0x3E7066DDUL, 0xF85CDE0FUL, 0x9047414FUL, + 0xB6662D3DUL, 0x58DE2A3CUL, 0x2F37A2ADUL, 0xA848E8F7UL, 0x23712F57UL, 0xF52CB578UL, 0x5E2BD5BBUL, 0x5CED41D1UL, + 0x76DC4190UL, 0xF0794F05UL, 0x709A8DC0UL, 0x9B14583DUL, 0x58F35849UL, 0x0F580A6CUL, 0x440B7579UL, 0x299DC2EDUL, + 0x01DB7106UL, 0xE9627E44UL, 0x7158E7F7UL, 0x23A83F58UL, 0x659371F9UL, 0xC404D9C9UL, 0xE27C7ECDUL, 0xE537C273UL, + 0x98D220BCUL, 0xC24F2D87UL, 0x731E59AEUL, 0x311D90B6UL, 0x22330B29UL, 0x4290AB67UL, 0xD3946450UL, 0x6BB8C590UL, + 0xEFD5102AUL, 0xDB541CC6UL, 0x72DC3399UL, 0x89A1F7D3UL, 0x1F532299UL, 0x89CC78C2UL, 0x75E36FE4UL, 0xA712C50EUL, + 0x71B18589UL, 0x94158A01UL, 0x7793251CUL, 0x1476CF6AUL, 0xAD73FE89UL, 0x94C9487AUL, 0xB044516AUL, 0xADD7CC17UL, + 0x06B6B51FUL, 0x8D0EBB40UL, 0x76514F2BUL, 0xACCAA80FUL, 0x9013D739UL, 0x5F959BDFUL, 0x16335ADEUL, 0x617DCC89UL, + 0x9FBFE4A5UL, 0xA623E883UL, 0x7417F172UL, 0xBE7F07E1UL, 0xD7B3ADE9UL, 0xD901E971UL, 0x27DB4043UL, 0xEFF2CB6AUL, + 0xE8B8D433UL, 0xBF38D9C2UL, 0x75D59B45UL, 0x06C36084UL, 0xEAD38459UL, 0x125D3AD4UL, 0x81AC4BF7UL, 0x2358CBF4UL, + 0x7807C9A2UL, 0x38A0C50DUL, 0x7E89DC78UL, 0x5EA070D2UL, 0x68831388UL, 0xE30B8801UL, 0x77E43B1EUL, 0xFA78D958UL, + 0x0F00F934UL, 0x21BBF44CUL, 0x7F4BB64FUL, 0xE61C17B7UL, 0x55E33A38UL, 0x28575BA4UL, 0xD19330AAUL, 0x36D2D9C6UL, + 0x9609A88EUL, 0x0A96A78FUL, 0x7D0D0816UL, 0xF4A9B859UL, 0x124340E8UL, 0xAEC3290AUL, 0xE07B2A37UL, 0xB85DDE25UL, + 0xE10E9818UL, 0x138D96CEUL, 0x7CCF6221UL, 0x4C15DF3CUL, 0x2F236958UL, 0x659FFAAFUL, 0x460C2183UL, 0x74F7DEBBUL, + 0x7F6A0DBBUL, 0x5CCC0009UL, 0x798074A4UL, 0xD1C2E785UL, 0x9D03B548UL, 0x789ACA17UL, 0x83AB1F0DUL, 0x7E32D7A2UL, + 0x086D3D2DUL, 0x45D73148UL, 0x78421E93UL, 0x697E80E0UL, 0xA0639CF8UL, 0xB3C619B2UL, 0x25DC14B9UL, 0xB298D73CUL, + 0x91646C97UL, 0x6EFA628BUL, 0x7A04A0CAUL, 0x7BCB2F0EUL, 0xE7C3E628UL, 0x35526B1CUL, 0x14340E24UL, 0x3C17D0DFUL, + 0xE6635C01UL, 0x77E153CAUL, 0x7BC6CAFDUL, 0xC377486BUL, 0xDAA3CF98UL, 0xFE0EB8B9UL, 0xB2430590UL, 0xF0BDD041UL, + 0x6B6B51F4UL, 0xBABB5D54UL, 0x6CBC2EB0UL, 0xCB0D0FA2UL, 0x3813CFCBUL, 0x0C8E08F7UL, 0x23D5E9B7UL, 0x5526F3C6UL, + 0x1C6C6162UL, 0xA3A06C15UL, 0x6D7E4487UL, 0x73B168C7UL, 0x0573E67BUL, 0xC7D2DB52UL, 0x85A2E203UL, 0x998CF358UL, + 0x856530D8UL, 0x888D3FD6UL, 0x6F38FADEUL, 0x6104C729UL, 0x42D39CABUL, 0x4146A9FCUL, 0xB44AF89EUL, 0x1703F4BBUL, + 0xF262004EUL, 0x91960E97UL, 0x6EFA90E9UL, 0xD9B8A04CUL, 0x7FB3B51BUL, 0x8A1A7A59UL, 0x123DF32AUL, 0xDBA9F425UL, + 0x6C0695EDUL, 0xDED79850UL, 0x6BB5866CUL, 0x446F98F5UL, 0xCD93690BUL, 0x971F4AE1UL, 0xD79ACDA4UL, 0xD16CFD3CUL, + 0x1B01A57BUL, 0xC7CCA911UL, 0x6A77EC5BUL, 0xFCD3FF90UL, 0xF0F340BBUL, 0x5C439944UL, 0x71EDC610UL, 0x1DC6FDA2UL, + 0x8208F4C1UL, 0xECE1FAD2UL, 0x68315202UL, 0xEE66507EUL, 0xB7533A6BUL, 0xDAD7EBEAUL, 0x4005DC8DUL, 0x9349FA41UL, + 0xF50FC457UL, 0xF5FACB93UL, 0x69F33835UL, 0x56DA371BUL, 0x8A3313DBUL, 0x118B384FUL, 0xE672D739UL, 0x5FE3FADFUL, + 0x65B0D9C6UL, 0x7262D75CUL, 0x62AF7F08UL, 0x0EB9274DUL, 0x0863840AUL, 0xE0DD8A9AUL, 0x103AA7D0UL, 0x86C3E873UL, + 0x12B7E950UL, 0x6B79E61DUL, 0x636D153FUL, 0xB6054028UL, 0x3503ADBAUL, 0x2B81593FUL, 0xB64DAC64UL, 0x4A69E8EDUL, + 0x8BBEB8EAUL, 0x4054B5DEUL, 0x612BAB66UL, 0xA4B0EFC6UL, 0x72A3D76AUL, 0xAD152B91UL, 0x87A5B6F9UL, 0xC4E6EF0EUL, + 0xFCB9887CUL, 0x594F849FUL, 0x60E9C151UL, 0x1C0C88A3UL, 0x4FC3FEDAUL, 0x6649F834UL, 0x21D2BD4DUL, 0x084CEF90UL, + 0x62DD1DDFUL, 0x160E1258UL, 0x65A6D7D4UL, 0x81DBB01AUL, 0xFDE322CAUL, 0x7B4CC88CUL, 0xE47583C3UL, 0x0289E689UL, + 0x15DA2D49UL, 0x0F152319UL, 0x6464BDE3UL, 0x3967D77FUL, 0xC0830B7AUL, 0xB0101B29UL, 0x42028877UL, 0xCE23E617UL, + 0x8CD37CF3UL, 0x243870DAUL, 0x662203BAUL, 0x2BD27891UL, 0x872371AAUL, 0x36846987UL, 0x73EA92EAUL, 0x40ACE1F4UL, + 0xFBD44C65UL, 0x3D23419BUL, 0x67E0698DUL, 0x936E1FF4UL, 0xBA43581AUL, 0xFDD8BA22UL, 0xD59D995EUL, 0x8C06E16AUL, + 0x4DB26158UL, 0x65FD6BA7UL, 0x48D7CB20UL, 0x3B26F703UL, 0x9932774DUL, 0x08F40F5AUL, 0x8BB64CE5UL, 0xD0EBA0BBUL, + 0x3AB551CEUL, 0x7CE65AE6UL, 0x4915A117UL, 0x839A9066UL, 0xA4525EFDUL, 0xC3A8DCFFUL, 0x2DC14751UL, 0x1C41A025UL, + 0xA3BC0074UL, 0x57CB0925UL, 0x4B531F4EUL, 0x912F3F88UL, 0xE3F2242DUL, 0x453CAE51UL, 0x1C295DCCUL, 0x92CEA7C6UL, + 0xD4BB30E2UL, 0x4ED03864UL, 0x4A917579UL, 0x299358EDUL, 0xDE920D9DUL, 0x8E607DF4UL, 0xBA5E5678UL, 0x5E64A758UL, + 0x4ADFA541UL, 0x0191AEA3UL, 0x4FDE63FCUL, 0xB4446054UL, 0x6CB2D18DUL, 0x93654D4CUL, 0x7FF968F6UL, 0x54A1AE41UL, + 0x3DD895D7UL, 0x188A9FE2UL, 0x4E1C09CBUL, 0x0CF80731UL, 0x51D2F83DUL, 0x58399EE9UL, 0xD98E6342UL, 0x980BAEDFUL, + 0xA4D1C46DUL, 0x33A7CC21UL, 0x4C5AB792UL, 0x1E4DA8DFUL, 0x167282EDUL, 0xDEADEC47UL, 0xE86679DFUL, 0x1684A93CUL, + 0xD3D6F4FBUL, 0x2ABCFD60UL, 0x4D98DDA5UL, 0xA6F1CFBAUL, 0x2B12AB5DUL, 0x15F13FE2UL, 0x4E11726BUL, 0xDA2EA9A2UL, + 0x4369E96AUL, 0xAD24E1AFUL, 0x46C49A98UL, 0xFE92DFECUL, 0xA9423C8CUL, 0xE4A78D37UL, 0xB8590282UL, 0x030EBB0EUL, + 0x346ED9FCUL, 0xB43FD0EEUL, 0x4706F0AFUL, 0x462EB889UL, 0x9422153CUL, 0x2FFB5E92UL, 0x1E2E0936UL, 0xCFA4BB90UL, + 0xAD678846UL, 0x9F12832DUL, 0x45404EF6UL, 0x549B1767UL, 0xD3826FECUL, 0xA96F2C3CUL, 0x2FC613ABUL, 0x412BBC73UL, + 0xDA60B8D0UL, 0x8609B26CUL, 0x448224C1UL, 0xEC277002UL, 0xEEE2465CUL, 0x6233FF99UL, 0x89B1181FUL, 0x8D81BCEDUL, + 0x44042D73UL, 0xC94824ABUL, 0x41CD3244UL, 0x71F048BBUL, 0x5CC29A4CUL, 0x7F36CF21UL, 0x4C162691UL, 0x8744B5F4UL, + 0x33031DE5UL, 0xD05315EAUL, 0x400F5873UL, 0xC94C2FDEUL, 0x61A2B3FCUL, 0xB46A1C84UL, 0xEA612D25UL, 0x4BEEB56AUL, + 0xAA0A4C5FUL, 0xFB7E4629UL, 0x4249E62AUL, 0xDBF98030UL, 0x2602C92CUL, 0x32FE6E2AUL, 0xDB8937B8UL, 0xC561B289UL, + 0xDD0D7CC9UL, 0xE2657768UL, 0x438B8C1DUL, 0x6345E755UL, 0x1B62E09CUL, 0xF9A2BD8FUL, 0x7DFE3C0CUL, 0x09CBB217UL, + 0x5005713CUL, 0x2F3F79F6UL, 0x54F16850UL, 0x6B3FA09CUL, 0xF9D2E0CFUL, 0x0B220DC1UL, 0xEC68D02BUL, 0xAC509190UL, + 0x270241AAUL, 0x362448B7UL, 0x55330267UL, 0xD383C7F9UL, 0xC4B2C97FUL, 0xC07EDE64UL, 0x4A1FDB9FUL, 0x60FA910EUL, + 0xBE0B1010UL, 0x1D091B74UL, 0x5775BC3EUL, 0xC1366817UL, 0x8312B3AFUL, 0x46EAACCAUL, 0x7BF7C102UL, 0xEE7596EDUL, + 0xC90C2086UL, 0x04122A35UL, 0x56B7D609UL, 0x798A0F72UL, 0xBE729A1FUL, 0x8DB67F6FUL, 0xDD80CAB6UL, 0x22DF9673UL, + 0x5768B525UL, 0x4B53BCF2UL, 0x53F8C08CUL, 0xE45D37CBUL, 0x0C52460FUL, 0x90B34FD7UL, 0x1827F438UL, 0x281A9F6AUL, + 0x206F85B3UL, 0x52488DB3UL, 0x523AAABBUL, 0x5CE150AEUL, 0x31326FBFUL, 0x5BEF9C72UL, 0xBE50FF8CUL, 0xE4B09FF4UL, + 0xB966D409UL, 0x7965DE70UL, 0x507C14E2UL, 0x4E54FF40UL, 0x7692156FUL, 0xDD7BEEDCUL, 0x8FB8E511UL, 0x6A3F9817UL, + 0xCE61E49FUL, 0x607EEF31UL, 0x51BE7ED5UL, 0xF6E89825UL, 0x4BF23CDFUL, 0x16273D79UL, 0x29CFEEA5UL, 0xA6959889UL, + 0x5EDEF90EUL, 0xE7E6F3FEUL, 0x5AE239E8UL, 0xAE8B8873UL, 0xC9A2AB0EUL, 0xE7718FACUL, 0xDF879E4CUL, 0x7FB58A25UL, + 0x29D9C998UL, 0xFEFDC2BFUL, 0x5B2053DFUL, 0x1637EF16UL, 0xF4C282BEUL, 0x2C2D5C09UL, 0x79F095F8UL, 0xB31F8ABBUL, + 0xB0D09822UL, 0xD5D0917CUL, 0x5966ED86UL, 0x048240F8UL, 0xB362F86EUL, 0xAAB92EA7UL, 0x48188F65UL, 0x3D908D58UL, + 0xC7D7A8B4UL, 0xCCCBA03DUL, 0x58A487B1UL, 0xBC3E279DUL, 0x8E02D1DEUL, 0x61E5FD02UL, 0xEE6F84D1UL, 0xF13A8DC6UL, + 0x59B33D17UL, 0x838A36FAUL, 0x5DEB9134UL, 0x21E91F24UL, 0x3C220DCEUL, 0x7CE0CDBAUL, 0x2BC8BA5FUL, 0xFBFF84DFUL, + 0x2EB40D81UL, 0x9A9107BBUL, 0x5C29FB03UL, 0x99557841UL, 0x0142247EUL, 0xB7BC1E1FUL, 0x8DBFB1EBUL, 0x37558441UL, + 0xB7BD5C3BUL, 0xB1BC5478UL, 0x5E6F455AUL, 0x8BE0D7AFUL, 0x46E25EAEUL, 0x31286CB1UL, 0xBC57AB76UL, 0xB9DA83A2UL, + 0xC0BA6CADUL, 0xA8A76539UL, 0x5FAD2F6DUL, 0x335CB0CAUL, 0x7B82771EUL, 0xFA74BF14UL, 0x1A20A0C2UL, 0x7570833CUL, + 0xEDB88320UL, 0x3B83984BUL, 0xE1351B80UL, 0xED59B63BUL, 0xB1E6B092UL, 0x1EB014D8UL, 0x8816EAF2UL, 0x533B85DAUL, + 0x9ABFB3B6UL, 0x2298A90AUL, 0xE0F771B7UL, 0x55E5D15EUL, 0x8C869922UL, 0xD5ECC77DUL, 0x2E61E146UL, 0x9F918544UL, + 0x03B6E20CUL, 0x09B5FAC9UL, 0xE2B1CFEEUL, 0x47507EB0UL, 0xCB26E3F2UL, 0x5378B5D3UL, 0x1F89FBDBUL, 0x111E82A7UL, + 0x74B1D29AUL, 0x10AECB88UL, 0xE373A5D9UL, 0xFFEC19D5UL, 0xF646CA42UL, 0x98246676UL, 0xB9FEF06FUL, 0xDDB48239UL, + 0xEAD54739UL, 0x5FEF5D4FUL, 0xE63CB35CUL, 0x623B216CUL, 0x44661652UL, 0x852156CEUL, 0x7C59CEE1UL, 0xD7718B20UL, + 0x9DD277AFUL, 0x46F46C0EUL, 0xE7FED96BUL, 0xDA874609UL, 0x79063FE2UL, 0x4E7D856BUL, 0xDA2EC555UL, 0x1BDB8BBEUL, + 0x04DB2615UL, 0x6DD93FCDUL, 0xE5B86732UL, 0xC832E9E7UL, 0x3EA64532UL, 0xC8E9F7C5UL, 0xEBC6DFC8UL, 0x95548C5DUL, + 0x73DC1683UL, 0x74C20E8CUL, 0xE47A0D05UL, 0x708E8E82UL, 0x03C66C82UL, 0x03B52460UL, 0x4DB1D47CUL, 0x59FE8CC3UL, + 0xE3630B12UL, 0xF35A1243UL, 0xEF264A38UL, 0x28ED9ED4UL, 0x8196FB53UL, 0xF2E396B5UL, 0xBBF9A495UL, 0x80DE9E6FUL, + 0x94643B84UL, 0xEA412302UL, 0xEEE4200FUL, 0x9051F9B1UL, 0xBCF6D2E3UL, 0x39BF4510UL, 0x1D8EAF21UL, 0x4C749EF1UL, + 0x0D6D6A3EUL, 0xC16C70C1UL, 0xECA29E56UL, 0x82E4565FUL, 0xFB56A833UL, 0xBF2B37BEUL, 0x2C66B5BCUL, 0xC2FB9912UL, + 0x7A6A5AA8UL, 0xD8774180UL, 0xED60F461UL, 0x3A58313AUL, 0xC6368183UL, 0x7477E41BUL, 0x8A11BE08UL, 0x0E51998CUL, + 0xE40ECF0BUL, 0x9736D747UL, 0xE82FE2E4UL, 0xA78F0983UL, 0x74165D93UL, 0x6972D4A3UL, 0x4FB68086UL, 0x04949095UL, + 0x9309FF9DUL, 0x8E2DE606UL, 0xE9ED88D3UL, 0x1F336EE6UL, 0x49767423UL, 0xA22E0706UL, 0xE9C18B32UL, 0xC83E900BUL, + 0x0A00AE27UL, 0xA500B5C5UL, 0xEBAB368AUL, 0x0D86C108UL, 0x0ED60EF3UL, 0x24BA75A8UL, 0xD82991AFUL, 0x46B197E8UL, + 0x7D079EB1UL, 0xBC1B8484UL, 0xEA695CBDUL, 0xB53AA66DUL, 0x33B62743UL, 0xEFE6A60DUL, 0x7E5E9A1BUL, 0x8A1B9776UL, + 0xF00F9344UL, 0x71418A1AUL, 0xFD13B8F0UL, 0xBD40E1A4UL, 0xD1062710UL, 0x1D661643UL, 0xEFC8763CUL, 0x2F80B4F1UL, + 0x8708A3D2UL, 0x685ABB5BUL, 0xFCD1D2C7UL, 0x05FC86C1UL, 0xEC660EA0UL, 0xD63AC5E6UL, 0x49BF7D88UL, 0xE32AB46FUL, + 0x1E01F268UL, 0x4377E898UL, 0xFE976C9EUL, 0x1749292FUL, 0xABC67470UL, 0x50AEB748UL, 0x78576715UL, 0x6DA5B38CUL, + 0x6906C2FEUL, 0x5A6CD9D9UL, 0xFF5506A9UL, 0xAFF54E4AUL, 0x96A65DC0UL, 0x9BF264EDUL, 0xDE206CA1UL, 0xA10FB312UL, + 0xF762575DUL, 0x152D4F1EUL, 0xFA1A102CUL, 0x322276F3UL, 0x248681D0UL, 0x86F75455UL, 0x1B87522FUL, 0xABCABA0BUL, + 0x806567CBUL, 0x0C367E5FUL, 0xFBD87A1BUL, 0x8A9E1196UL, 0x19E6A860UL, 0x4DAB87F0UL, 0xBDF0599BUL, 0x6760BA95UL, + 0x196C3671UL, 0x271B2D9CUL, 0xF99EC442UL, 0x982BBE78UL, 0x5E46D2B0UL, 0xCB3FF55EUL, 0x8C184306UL, 0xE9EFBD76UL, + 0x6E6B06E7UL, 0x3E001CDDUL, 0xF85CAE75UL, 0x2097D91DUL, 0x6326FB00UL, 0x006326FBUL, 0x2A6F48B2UL, 0x2545BDE8UL, + 0xFED41B76UL, 0xB9980012UL, 0xF300E948UL, 0x78F4C94BUL, 0xE1766CD1UL, 0xF135942EUL, 0xDC27385BUL, 0xFC65AF44UL, + 0x89D32BE0UL, 0xA0833153UL, 0xF2C2837FUL, 0xC048AE2EUL, 0xDC164561UL, 0x3A69478BUL, 0x7A5033EFUL, 0x30CFAFDAUL, + 0x10DA7A5AUL, 0x8BAE6290UL, 0xF0843D26UL, 0xD2FD01C0UL, 0x9BB63FB1UL, 0xBCFD3525UL, 0x4BB82972UL, 0xBE40A839UL, + 0x67DD4ACCUL, 0x92B553D1UL, 0xF1465711UL, 0x6A4166A5UL, 0xA6D61601UL, 0x77A1E680UL, 0xEDCF22C6UL, 0x72EAA8A7UL, + 0xF9B9DF6FUL, 0xDDF4C516UL, 0xF4094194UL, 0xF7965E1CUL, 0x14F6CA11UL, 0x6AA4D638UL, 0x28681C48UL, 0x782FA1BEUL, + 0x8EBEEFF9UL, 0xC4EFF457UL, 0xF5CB2BA3UL, 0x4F2A3979UL, 0x2996E3A1UL, 0xA1F8059DUL, 0x8E1F17FCUL, 0xB485A120UL, + 0x17B7BE43UL, 0xEFC2A794UL, 0xF78D95FAUL, 0x5D9F9697UL, 0x6E369971UL, 0x276C7733UL, 0xBFF70D61UL, 0x3A0AA6C3UL, + 0x60B08ED5UL, 0xF6D996D5UL, 0xF64FFFCDUL, 0xE523F1F2UL, 0x5356B0C1UL, 0xEC30A496UL, 0x198006D5UL, 0xF6A0A65DUL, + 0xD6D6A3E8UL, 0xAE07BCE9UL, 0xD9785D60UL, 0x4D6B1905UL, 0x70279F96UL, 0x191C11EEUL, 0x47ABD36EUL, 0xAA4DE78CUL, + 0xA1D1937EUL, 0xB71C8DA8UL, 0xD8BA3757UL, 0xF5D77E60UL, 0x4D47B626UL, 0xD240C24BUL, 0xE1DCD8DAUL, 0x66E7E712UL, + 0x38D8C2C4UL, 0x9C31DE6BUL, 0xDAFC890EUL, 0xE762D18EUL, 0x0AE7CCF6UL, 0x54D4B0E5UL, 0xD034C247UL, 0xE868E0F1UL, + 0x4FDFF252UL, 0x852AEF2AUL, 0xDB3EE339UL, 0x5FDEB6EBUL, 0x3787E546UL, 0x9F886340UL, 0x7643C9F3UL, 0x24C2E06FUL, + 0xD1BB67F1UL, 0xCA6B79EDUL, 0xDE71F5BCUL, 0xC2098E52UL, 0x85A73956UL, 0x828D53F8UL, 0xB3E4F77DUL, 0x2E07E976UL, + 0xA6BC5767UL, 0xD37048ACUL, 0xDFB39F8BUL, 0x7AB5E937UL, 0xB8C710E6UL, 0x49D1805DUL, 0x1593FCC9UL, 0xE2ADE9E8UL, + 0x3FB506DDUL, 0xF85D1B6FUL, 0xDDF521D2UL, 0x680046D9UL, 0xFF676A36UL, 0xCF45F2F3UL, 0x247BE654UL, 0x6C22EE0BUL, + 0x48B2364BUL, 0xE1462A2EUL, 0xDC374BE5UL, 0xD0BC21BCUL, 0xC2074386UL, 0x04192156UL, 0x820CEDE0UL, 0xA088EE95UL, + 0xD80D2BDAUL, 0x66DE36E1UL, 0xD76B0CD8UL, 0x88DF31EAUL, 0x4057D457UL, 0xF54F9383UL, 0x74449D09UL, 0x79A8FC39UL, + 0xAF0A1B4CUL, 0x7FC507A0UL, 0xD6A966EFUL, 0x3063568FUL, 0x7D37FDE7UL, 0x3E134026UL, 0xD23396BDUL, 0xB502FCA7UL, + 0x36034AF6UL, 0x54E85463UL, 0xD4EFD8B6UL, 0x22D6F961UL, 0x3A978737UL, 0xB8873288UL, 0xE3DB8C20UL, 0x3B8DFB44UL, + 0x41047A60UL, 0x4DF36522UL, 0xD52DB281UL, 0x9A6A9E04UL, 0x07F7AE87UL, 0x73DBE12DUL, 0x45AC8794UL, 0xF727FBDAUL, + 0xDF60EFC3UL, 0x02B2F3E5UL, 0xD062A404UL, 0x07BDA6BDUL, 0xB5D77297UL, 0x6EDED195UL, 0x800BB91AUL, 0xFDE2F2C3UL, + 0xA867DF55UL, 0x1BA9C2A4UL, 0xD1A0CE33UL, 0xBF01C1D8UL, 0x88B75B27UL, 0xA5820230UL, 0x267CB2AEUL, 0x3148F25DUL, + 0x316E8EEFUL, 0x30849167UL, 0xD3E6706AUL, 0xADB46E36UL, 0xCF1721F7UL, 0x2316709EUL, 0x1794A833UL, 0xBFC7F5BEUL, + 0x4669BE79UL, 0x299FA026UL, 0xD2241A5DUL, 0x15080953UL, 0xF2770847UL, 0xE84AA33BUL, 0xB1E3A387UL, 0x736DF520UL, + 0xCB61B38CUL, 0xE4C5AEB8UL, 0xC55EFE10UL, 0x1D724E9AUL, 0x10C70814UL, 0x1ACA1375UL, 0x20754FA0UL, 0xD6F6D6A7UL, + 0xBC66831AUL, 0xFDDE9FF9UL, 0xC49C9427UL, 0xA5CE29FFUL, 0x2DA721A4UL, 0xD196C0D0UL, 0x86024414UL, 0x1A5CD639UL, + 0x256FD2A0UL, 0xD6F3CC3AUL, 0xC6DA2A7EUL, 0xB77B8611UL, 0x6A075B74UL, 0x5702B27EUL, 0xB7EA5E89UL, 0x94D3D1DAUL, + 0x5268E236UL, 0xCFE8FD7BUL, 0xC7184049UL, 0x0FC7E174UL, 0x576772C4UL, 0x9C5E61DBUL, 0x119D553DUL, 0x5879D144UL, + 0xCC0C7795UL, 0x80A96BBCUL, 0xC25756CCUL, 0x9210D9CDUL, 0xE547AED4UL, 0x815B5163UL, 0xD43A6BB3UL, 0x52BCD85DUL, + 0xBB0B4703UL, 0x99B25AFDUL, 0xC3953CFBUL, 0x2AACBEA8UL, 0xD8278764UL, 0x4A0782C6UL, 0x724D6007UL, 0x9E16D8C3UL, + 0x220216B9UL, 0xB29F093EUL, 0xC1D382A2UL, 0x38191146UL, 0x9F87FDB4UL, 0xCC93F068UL, 0x43A57A9AUL, 0x1099DF20UL, + 0x5505262FUL, 0xAB84387FUL, 0xC011E895UL, 0x80A57623UL, 0xA2E7D404UL, 0x07CF23CDUL, 0xE5D2712EUL, 0xDC33DFBEUL, + 0xC5BA3BBEUL, 0x2C1C24B0UL, 0xCB4DAFA8UL, 0xD8C66675UL, 0x20B743D5UL, 0xF6999118UL, 0x139A01C7UL, 0x0513CD12UL, + 0xB2BD0B28UL, 0x350715F1UL, 0xCA8FC59FUL, 0x607A0110UL, 0x1DD76A65UL, 0x3DC542BDUL, 0xB5ED0A73UL, 0xC9B9CD8CUL, + 0x2BB45A92UL, 0x1E2A4632UL, 0xC8C97BC6UL, 0x72CFAEFEUL, 0x5A7710B5UL, 0xBB513013UL, 0x840510EEUL, 0x4736CA6FUL, + 0x5CB36A04UL, 0x07317773UL, 0xC90B11F1UL, 0xCA73C99BUL, 0x67173905UL, 0x700DE3B6UL, 0x22721B5AUL, 0x8B9CCAF1UL, + 0xC2D7FFA7UL, 0x4870E1B4UL, 0xCC440774UL, 0x57A4F122UL, 0xD537E515UL, 0x6D08D30EUL, 0xE7D525D4UL, 0x8159C3E8UL, + 0xB5D0CF31UL, 0x516BD0F5UL, 0xCD866D43UL, 0xEF189647UL, 0xE857CCA5UL, 0xA65400ABUL, 0x41A22E60UL, 0x4DF3C376UL, + 0x2CD99E8BUL, 0x7A468336UL, 0xCFC0D31AUL, 0xFDAD39A9UL, 0xAFF7B675UL, 0x20C07205UL, 0x704A34FDUL, 0xC37CC495UL, + 0x5BDEAE1DUL, 0x635DB277UL, 0xCE02B92DUL, 0x45115ECCUL, 0x92979FC5UL, 0xEB9CA1A0UL, 0xD63D3F49UL, 0x0FD6C40BUL, + 0x9B64C2B0UL, 0xCBFAD74EUL, 0x91AF9640UL, 0x764DEE06UL, 0xE915E8DBUL, 0x11E81EB4UL, 0xCC1D9F8BUL, 0x7AA64737UL, + 0xEC63F226UL, 0xD2E1E60FUL, 0x906DFC77UL, 0xCEF18963UL, 0xD475C16BUL, 0xDAB4CD11UL, 0x6A6A943FUL, 0xB60C47A9UL, + 0x756AA39CUL, 0xF9CCB5CCUL, 0x922B422EUL, 0xDC44268DUL, 0x93D5BBBBUL, 0x5C20BFBFUL, 0x5B828EA2UL, 0x3883404AUL, + 0x026D930AUL, 0xE0D7848DUL, 0x93E92819UL, 0x64F841E8UL, 0xAEB5920BUL, 0x977C6C1AUL, 0xFDF58516UL, 0xF42940D4UL, + 0x9C0906A9UL, 0xAF96124AUL, 0x96A63E9CUL, 0xF92F7951UL, 0x1C954E1BUL, 0x8A795CA2UL, 0x3852BB98UL, 0xFEEC49CDUL, + 0xEB0E363FUL, 0xB68D230BUL, 0x976454ABUL, 0x41931E34UL, 0x21F567ABUL, 0x41258F07UL, 0x9E25B02CUL, 0x32464953UL, + 0x72076785UL, 0x9DA070C8UL, 0x9522EAF2UL, 0x5326B1DAUL, 0x66551D7BUL, 0xC7B1FDA9UL, 0xAFCDAAB1UL, 0xBCC94EB0UL, + 0x05005713UL, 0x84BB4189UL, 0x94E080C5UL, 0xEB9AD6BFUL, 0x5B3534CBUL, 0x0CED2E0CUL, 0x09BAA105UL, 0x70634E2EUL, + 0x95BF4A82UL, 0x03235D46UL, 0x9FBCC7F8UL, 0xB3F9C6E9UL, 0xD965A31AUL, 0xFDBB9CD9UL, 0xFFF2D1ECUL, 0xA9435C82UL, + 0xE2B87A14UL, 0x1A386C07UL, 0x9E7EADCFUL, 0x0B45A18CUL, 0xE4058AAAUL, 0x36E74F7CUL, 0x5985DA58UL, 0x65E95C1CUL, + 0x7BB12BAEUL, 0x31153FC4UL, 0x9C381396UL, 0x19F00E62UL, 0xA3A5F07AUL, 0xB0733DD2UL, 0x686DC0C5UL, 0xEB665BFFUL, + 0x0CB61B38UL, 0x280E0E85UL, 0x9DFA79A1UL, 0xA14C6907UL, 0x9EC5D9CAUL, 0x7B2FEE77UL, 0xCE1ACB71UL, 0x27CC5B61UL, + 0x92D28E9BUL, 0x674F9842UL, 0x98B56F24UL, 0x3C9B51BEUL, 0x2CE505DAUL, 0x662ADECFUL, 0x0BBDF5FFUL, 0x2D095278UL, + 0xE5D5BE0DUL, 0x7E54A903UL, 0x99770513UL, 0x842736DBUL, 0x11852C6AUL, 0xAD760D6AUL, 0xADCAFE4BUL, 0xE1A352E6UL, + 0x7CDCEFB7UL, 0x5579FAC0UL, 0x9B31BB4AUL, 0x96929935UL, 0x562556BAUL, 0x2BE27FC4UL, 0x9C22E4D6UL, 0x6F2C5505UL, + 0x0BDBDF21UL, 0x4C62CB81UL, 0x9AF3D17DUL, 0x2E2EFE50UL, 0x6B457F0AUL, 0xE0BEAC61UL, 0x3A55EF62UL, 0xA386559BUL, + 0x86D3D2D4UL, 0x8138C51FUL, 0x8D893530UL, 0x2654B999UL, 0x89F57F59UL, 0x123E1C2FUL, 0xABC30345UL, 0x061D761CUL, + 0xF1D4E242UL, 0x9823F45EUL, 0x8C4B5F07UL, 0x9EE8DEFCUL, 0xB49556E9UL, 0xD962CF8AUL, 0x0DB408F1UL, 0xCAB77682UL, + 0x68DDB3F8UL, 0xB30EA79DUL, 0x8E0DE15EUL, 0x8C5D7112UL, 0xF3352C39UL, 0x5FF6BD24UL, 0x3C5C126CUL, 0x44387161UL, + 0x1FDA836EUL, 0xAA1596DCUL, 0x8FCF8B69UL, 0x34E11677UL, 0xCE550589UL, 0x94AA6E81UL, 0x9A2B19D8UL, 0x889271FFUL, + 0x81BE16CDUL, 0xE554001BUL, 0x8A809DECUL, 0xA9362ECEUL, 0x7C75D999UL, 0x89AF5E39UL, 0x5F8C2756UL, 0x825778E6UL, + 0xF6B9265BUL, 0xFC4F315AUL, 0x8B42F7DBUL, 0x118A49ABUL, 0x4115F029UL, 0x42F38D9CUL, 0xF9FB2CE2UL, 0x4EFD7878UL, + 0x6FB077E1UL, 0xD7626299UL, 0x89044982UL, 0x033FE645UL, 0x06B58AF9UL, 0xC467FF32UL, 0xC813367FUL, 0xC0727F9BUL, + 0x18B74777UL, 0xCE7953D8UL, 0x88C623B5UL, 0xBB838120UL, 0x3BD5A349UL, 0x0F3B2C97UL, 0x6E643DCBUL, 0x0CD87F05UL, + 0x88085AE6UL, 0x49E14F17UL, 0x839A6488UL, 0xE3E09176UL, 0xB9853498UL, 0xFE6D9E42UL, 0x982C4D22UL, 0xD5F86DA9UL, + 0xFF0F6A70UL, 0x50FA7E56UL, 0x82580EBFUL, 0x5B5CF613UL, 0x84E51D28UL, 0x35314DE7UL, 0x3E5B4696UL, 0x19526D37UL, + 0x66063BCAUL, 0x7BD72D95UL, 0x801EB0E6UL, 0x49E959FDUL, 0xC34567F8UL, 0xB3A53F49UL, 0x0FB35C0BUL, 0x97DD6AD4UL, + 0x11010B5CUL, 0x62CC1CD4UL, 0x81DCDAD1UL, 0xF1553E98UL, 0xFE254E48UL, 0x78F9ECECUL, 0xA9C457BFUL, 0x5B776A4AUL, + 0x8F659EFFUL, 0x2D8D8A13UL, 0x8493CC54UL, 0x6C820621UL, 0x4C059258UL, 0x65FCDC54UL, 0x6C636931UL, 0x51B26353UL, + 0xF862AE69UL, 0x3496BB52UL, 0x8551A663UL, 0xD43E6144UL, 0x7165BBE8UL, 0xAEA00FF1UL, 0xCA146285UL, 0x9D1863CDUL, + 0x616BFFD3UL, 0x1FBBE891UL, 0x8717183AUL, 0xC68BCEAAUL, 0x36C5C138UL, 0x28347D5FUL, 0xFBFC7818UL, 0x1397642EUL, + 0x166CCF45UL, 0x06A0D9D0UL, 0x86D5720DUL, 0x7E37A9CFUL, 0x0BA5E888UL, 0xE368AEFAUL, 0x5D8B73ACUL, 0xDF3D64B0UL, + 0xA00AE278UL, 0x5E7EF3ECUL, 0xA9E2D0A0UL, 0xD67F4138UL, 0x28D4C7DFUL, 0x16441B82UL, 0x03A0A617UL, 0x83D02561UL, + 0xD70DD2EEUL, 0x4765C2ADUL, 0xA820BA97UL, 0x6EC3265DUL, 0x15B4EE6FUL, 0xDD18C827UL, 0xA5D7ADA3UL, 0x4F7A25FFUL, + 0x4E048354UL, 0x6C48916EUL, 0xAA6604CEUL, 0x7C7689B3UL, 0x521494BFUL, 0x5B8CBA89UL, 0x943FB73EUL, 0xC1F5221CUL, + 0x3903B3C2UL, 0x7553A02FUL, 0xABA46EF9UL, 0xC4CAEED6UL, 0x6F74BD0FUL, 0x90D0692CUL, 0x3248BC8AUL, 0x0D5F2282UL, + 0xA7672661UL, 0x3A1236E8UL, 0xAEEB787CUL, 0x591DD66FUL, 0xDD54611FUL, 0x8DD55994UL, 0xF7EF8204UL, 0x079A2B9BUL, + 0xD06016F7UL, 0x230907A9UL, 0xAF29124BUL, 0xE1A1B10AUL, 0xE03448AFUL, 0x46898A31UL, 0x519889B0UL, 0xCB302B05UL, + 0x4969474DUL, 0x0824546AUL, 0xAD6FAC12UL, 0xF3141EE4UL, 0xA794327FUL, 0xC01DF89FUL, 0x6070932DUL, 0x45BF2CE6UL, + 0x3E6E77DBUL, 0x113F652BUL, 0xACADC625UL, 0x4BA87981UL, 0x9AF41BCFUL, 0x0B412B3AUL, 0xC6079899UL, 0x89152C78UL, + 0xAED16A4AUL, 0x96A779E4UL, 0xA7F18118UL, 0x13CB69D7UL, 0x18A48C1EUL, 0xFA1799EFUL, 0x304FE870UL, 0x50353ED4UL, + 0xD9D65ADCUL, 0x8FBC48A5UL, 0xA633EB2FUL, 0xAB770EB2UL, 0x25C4A5AEUL, 0x314B4A4AUL, 0x9638E3C4UL, 0x9C9F3E4AUL, + 0x40DF0B66UL, 0xA4911B66UL, 0xA4755576UL, 0xB9C2A15CUL, 0x6264DF7EUL, 0xB7DF38E4UL, 0xA7D0F959UL, 0x121039A9UL, + 0x37D83BF0UL, 0xBD8A2A27UL, 0xA5B73F41UL, 0x017EC639UL, 0x5F04F6CEUL, 0x7C83EB41UL, 0x01A7F2EDUL, 0xDEBA3937UL, + 0xA9BCAE53UL, 0xF2CBBCE0UL, 0xA0F829C4UL, 0x9CA9FE80UL, 0xED242ADEUL, 0x6186DBF9UL, 0xC400CC63UL, 0xD47F302EUL, + 0xDEBB9EC5UL, 0xEBD08DA1UL, 0xA13A43F3UL, 0x241599E5UL, 0xD044036EUL, 0xAADA085CUL, 0x6277C7D7UL, 0x18D530B0UL, + 0x47B2CF7FUL, 0xC0FDDE62UL, 0xA37CFDAAUL, 0x36A0360BUL, 0x97E479BEUL, 0x2C4E7AF2UL, 0x539FDD4AUL, 0x965A3753UL, + 0x30B5FFE9UL, 0xD9E6EF23UL, 0xA2BE979DUL, 0x8E1C516EUL, 0xAA84500EUL, 0xE712A957UL, 0xF5E8D6FEUL, 0x5AF037CDUL, + 0xBDBDF21CUL, 0x14BCE1BDUL, 0xB5C473D0UL, 0x866616A7UL, 0x4834505DUL, 0x15921919UL, 0x647E3AD9UL, 0xFF6B144AUL, + 0xCABAC28AUL, 0x0DA7D0FCUL, 0xB40619E7UL, 0x3EDA71C2UL, 0x755479EDUL, 0xDECECABCUL, 0xC209316DUL, 0x33C114D4UL, + 0x53B39330UL, 0x268A833FUL, 0xB640A7BEUL, 0x2C6FDE2CUL, 0x32F4033DUL, 0x585AB812UL, 0xF3E12BF0UL, 0xBD4E1337UL, + 0x24B4A3A6UL, 0x3F91B27EUL, 0xB782CD89UL, 0x94D3B949UL, 0x0F942A8DUL, 0x93066BB7UL, 0x55962044UL, 0x71E413A9UL, + 0xBAD03605UL, 0x70D024B9UL, 0xB2CDDB0CUL, 0x090481F0UL, 0xBDB4F69DUL, 0x8E035B0FUL, 0x90311ECAUL, 0x7B211AB0UL, + 0xCDD70693UL, 0x69CB15F8UL, 0xB30FB13BUL, 0xB1B8E695UL, 0x80D4DF2DUL, 0x455F88AAUL, 0x3646157EUL, 0xB78B1A2EUL, + 0x54DE5729UL, 0x42E6463BUL, 0xB1490F62UL, 0xA30D497BUL, 0xC774A5FDUL, 0xC3CBFA04UL, 0x07AE0FE3UL, 0x39041DCDUL, + 0x23D967BFUL, 0x5BFD777AUL, 0xB08B6555UL, 0x1BB12E1EUL, 0xFA148C4DUL, 0x089729A1UL, 0xA1D90457UL, 0xF5AE1D53UL, + 0xB3667A2EUL, 0xDC656BB5UL, 0xBBD72268UL, 0x43D23E48UL, 0x78441B9CUL, 0xF9C19B74UL, 0x579174BEUL, 0x2C8E0FFFUL, + 0xC4614AB8UL, 0xC57E5AF4UL, 0xBA15485FUL, 0xFB6E592DUL, 0x4524322CUL, 0x329D48D1UL, 0xF1E67F0AUL, 0xE0240F61UL, + 0x5D681B02UL, 0xEE530937UL, 0xB853F606UL, 0xE9DBF6C3UL, 0x028448FCUL, 0xB4093A7FUL, 0xC00E6597UL, 0x6EAB0882UL, + 0x2A6F2B94UL, 0xF7483876UL, 0xB9919C31UL, 0x516791A6UL, 0x3FE4614CUL, 0x7F55E9DAUL, 0x66796E23UL, 0xA201081CUL, + 0xB40BBE37UL, 0xB809AEB1UL, 0xBCDE8AB4UL, 0xCCB0A91FUL, 0x8DC4BD5CUL, 0x6250D962UL, 0xA3DE50ADUL, 0xA8C40105UL, + 0xC30C8EA1UL, 0xA1129FF0UL, 0xBD1CE083UL, 0x740CCE7AUL, 0xB0A494ECUL, 0xA90C0AC7UL, 0x05A95B19UL, 0x646E019BUL, + 0x5A05DF1BUL, 0x8A3FCC33UL, 0xBF5A5EDAUL, 0x66B96194UL, 0xF704EE3CUL, 0x2F987869UL, 0x34414184UL, 0xEAE10678UL, + 0x2D02EF8DUL, 0x9324FD72UL, 0xBE9834EDUL, 0xDE0506F1UL, 0xCA64C78CUL, 0xE4C4ABCCUL, 0x92364A30UL, 0x264B06E6UL, +}; + + +/** @brief Determine whether a pointer is aligned. + + A pointer is aligned if its address is an even multiple of + ::REDCONF_ALIGNMENT_SIZE. + + This is used in the below RedCrc32Update() function, which needs to know + whether a pointer is aligned, since the slice-by-8 algorithm needs to access + the memory in an aligned fashion, and if the pointer is not aligned, this + can result in faults or suboptimal performance (depending on platform). + + There is no way to perform this check without deviating from MISRA C rules + against casting pointers to integer types. Usage of this macro violates + MISRA-C:2012 Rule 11.4 (advisory). The main rationale the rule cites + against converting pointers to integers is that the chosen integer type may + not be able to represent the pointer; this is a non-issue here since we use + uintptr_t. The text says the rule still applies when using uintptr_t due to + concern about unaligned pointers, but that is not an issue here since the + integer value of the pointer is not saved and not converted back into a + pointer and dereferenced. The result of casting a pointer to a sufficiently + large integer is implementation-defined, but macros similar to this one have + been used by Datalight for a long time in a wide variety of environments and + they have always worked as expected. + + As Rule 11.4 is advisory, a deviation record is not required. This notice + and the PC-Lint error inhibition option are the only records of the + deviation. + + @note PC-Lint also thinks this macro as it is used below violates Rule 11.6 + (required). This is a false positive, since Rule 11.6 only applies to + void pointers. Below, we use it on a pointer-to-object (uint8_t *), + which is covered by Rule 11.4. + + @note It should have been possible to use a static function instead of a + function-like macro, but PC-Lint complained that the resulting + function had side effects even when explicitly told it was "pure". +*/ +#define IS_ALIGNED_PTR(ptr) (((uintptr_t)(ptr) & (REDCONF_ALIGNMENT_SIZE - 1U)) == 0U) + + +/** @brief Compute a CRC32 for the given data buffer. + + For CCITT-32 compliance, the initial CRC must be set to 0. To CRC multiple + buffers, call this function with the previously returned CRC value. + + @param ulInitCrc32 Starting CRC value. + @param pBuffer Data buffer to calculate the CRC from. + @param ulLength Number of bytes of data in the given buffer. + + @return The updated CRC value. +*/ +uint32_t RedCrc32Update( + uint32_t ulInitCrc32, + const void *pBuffer, + uint32_t ulLength) +{ + uint32_t ulCrc32; + + if(pBuffer == NULL) + { + REDERROR(); + ulCrc32 = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + uint32_t ulIdx = 0U; + uint32_t ulLen = ulLength; + const uint32_t *pulXorCrc0 = &gaulCrc32Table[7U]; + const uint32_t *pulXorCrc1 = &gaulCrc32Table[6U]; + const uint32_t *pulXorCrc2 = &gaulCrc32Table[5U]; + const uint32_t *pulXorCrc3 = &gaulCrc32Table[4U]; + const uint32_t *pulXorData4 = &gaulCrc32Table[3U]; + const uint32_t *pulXorData5 = &gaulCrc32Table[2U]; + const uint32_t *pulXorData6 = &gaulCrc32Table[1U]; + const uint32_t *pulXorData7 = &gaulCrc32Table[0U]; + uint32_t ulSliceLen; + + ulCrc32 = ~ulInitCrc32; + + /* Aligned memory access is used below. To avoid suboptimal + performance and faults (depending on platform), handle the + unaligned initial bytes (if any) using the Sarwate algorithm. + */ + while((ulLen > 0U) && !IS_ALIGNED_PTR(&pbBuffer[ulIdx])) + { + ulCrc32 = (ulCrc32 >> 8U) ^ gaulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U]; + + ulIdx++; + ulLen--; + } + + /* Round down the length to the nearest multiple of eight. + */ + ulSliceLen = (ulLen >> 3U) << 3U; + + /* Compute the CRC in eight byte "slices". Takes advantage of + modern processors which can load in parallel from multiple + memory locations. + */ + while(ulIdx < ulSliceLen) + { + #if REDCONF_ENDIAN_BIG == 1 + ulCrc32 ^= pbBuffer[ulIdx] | ((uint32_t)pbBuffer[ulIdx+1U] << 8U) | + ((uint32_t)pbBuffer[ulIdx+2U] << 16U) | ((uint32_t)pbBuffer[ulIdx+3U] << 24U); + #else + ulCrc32 ^= *CAST_CONST_UINT32_PTR(&pbBuffer[ulIdx]); + #endif + + ulCrc32 = + pulXorCrc3[((ulCrc32 >> 24U) & 0xFFU) << 3U] ^ + pulXorCrc2[((ulCrc32 >> 16U) & 0xFFU) << 3U] ^ + pulXorCrc1[((ulCrc32 >> 8U) & 0xFFU) << 3U] ^ + pulXorCrc0[ (ulCrc32 & 0xFFU) << 3U] ^ + pulXorData7[pbBuffer[ulIdx+7U] << 3U] ^ + pulXorData6[pbBuffer[ulIdx+6U] << 3U] ^ + pulXorData5[pbBuffer[ulIdx+5U] << 3U] ^ + pulXorData4[pbBuffer[ulIdx+4U] << 3U]; + + ulIdx += 8U; + } + + /* Compute the remaining bytes with the Sarwate algorithm. + */ + while(ulIdx < ulLen) + { + ulCrc32 = (ulCrc32 >> 8U) ^ gaulCrc32Table[((ulCrc32 ^ pbBuffer[ulIdx]) & 0xFFU) << 3U]; + + ulIdx++; + } + + ulCrc32 = ~ulCrc32; + } + + return ulCrc32; +} + +#else + +#error "REDCONF_CRC_ALGORITHM must be set to CRC_BITWISE, CRC_SARWATE, or CRC_SLICEBY8" + +#endif + + +/** @brief Compute a CRC32 for a metadata node buffer. + + @param pBuffer The metadata node buffer for which to compute a CRC. Must + be a block sized buffer. + + @return The CRC of the buffer. +*/ +uint32_t RedCrcNode( + const void *pBuffer) +{ + uint32_t ulCrc; + + if(pBuffer == NULL) + { + REDERROR(); + ulCrc = SUSPICIOUS_CRC_VALUE; + } + else + { + const uint8_t *pbBuffer = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pBuffer); + + /* The first eight bytes of a metadata node contain the signature and + the CRC. There is little value in CRCing the signature, and the + CRC cannot be CRC'd, so skip over that part of the buffer. + */ + ulCrc = RedCrc32Update(0U, &pbBuffer[8U], REDCONF_BLOCK_SIZE - 8U); + } + + return ulCrc; +} + diff --git a/util/endian.c b/util/endian.c new file mode 100644 index 0000000..4cf7307 --- /dev/null +++ b/util/endian.c @@ -0,0 +1,82 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements utilities for performing endian swaps. +*/ +#include + + +#ifdef REDCONF_ENDIAN_SWAP + +/** @brief Reverse the byte order of a 64-bit number. + + @param ullToRev Number whose bytes will be reversed + + @retval @p ullToRev with its bytes reversed. +*/ +uint64_t RedRev64( + uint64_t ullToRev) +{ + uint64_t ullRet = ullToRev; + + ullRet = ((ullRet & 0x00000000FFFFFFFFULL) << 32U) | ((ullRet & 0xFFFFFFFF00000000ULL) >> 32U); + ullRet = ((ullRet & 0x0000FFFF0000FFFFULL) << 16U) | ((ullRet & 0xFFFF0000FFFF0000ULL) >> 16U); + ullRet = ((ullRet & 0x00FF00FF00FF00FFULL) << 8U) | ((ullRet & 0xFF00FF00FF00FF00ULL) >> 8U); + + return ullRet; +} + + +/** @brief Reverse the byte order of a 32-bit number. + + @param ulToRev Number whose bytes will be reversed + + @retval @p ulToRev with its bytes reversed. +*/ +uint32_t RedRev32( + uint32_t ulToRev) +{ + return ((ulToRev & 0x000000FFU) << 24U) + | ((ulToRev & 0x0000FF00U) << 8U) + | ((ulToRev & 0x00FF0000U) >> 8U) + | ((ulToRev & 0xFF000000U) >> 24U); +} + + +/** @brief Reverse the byte order of a 16-bit number. + + @param uToRev Number whose bytes will be reversed + + @retval @p uToRev with its bytes reversed. +*/ +uint16_t RedRev16( + uint16_t uToRev) +{ + return ((uToRev & 0xFF00U) >> 8U) + | ((uToRev & 0x00FFU) << 8U); +} + +#endif + diff --git a/util/memory.c b/util/memory.c new file mode 100644 index 0000000..672b2e8 --- /dev/null +++ b/util/memory.c @@ -0,0 +1,249 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Default implementations of memory manipulation functions. + + These implementations are intended to be small and simple, and thus forego + all optimizations. If the C library is available, or if there are better + third-party implementations available in the system, those can be used + instead by defining the appropriate macros in redconf.h. + + These functions are not intended to be completely 100% ANSI C compatible + implementations, but rather are designed to meet the needs of Reliance Edge. + The compatibility is close enough that ANSI C compatible implementations + can be "dropped in" as replacements without difficulty. +*/ +#include + + +#ifndef RedMemCpy +/** @brief Copy memory from one address to another. + + The source and destination memory buffers should not overlap. If the + buffers overlap, use RedMemMove() instead. + + @param pDest The destination buffer. + @param pSrc The source buffer. + @param ulLen The number of bytes to copy. +*/ +void RedMemCpy( + void *pDest, + const void *pSrc, + uint32_t ulLen) +{ + if((pDest == NULL) || (pSrc == NULL)) + { + REDERROR(); + } + else + { + uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); + const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc); + uint32_t ulIdx; + + for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) + { + pbDest[ulIdx] = pbSrc[ulIdx]; + } + } +} +#endif + + +#ifndef RedMemMove + +/** @brief Determine whether RedMemMove() must copy memory in the forward + direction, instead of in the reverse. + + In order to copy between overlapping memory regions, RedMemMove() must copy + forward if the destination memory is lower, and backward if the destination + memory is higher. Failure to do so would yield incorrect results. + + The only way to make this determination without gross inefficiency is to + use pointer comparison. Pointer comparisons are undefined unless both + pointers point within the same object or array (or one element past the end + of the array); see section 6.3.8 of ANSI C89. While RedMemMove() is + normally only used when memory regions overlap, which would not result in + undefined behavior, it (like memmove()) is supposed to work even for non- + overlapping regions, which would make this function invoke undefined + behavior. Experience has shown the pointer comparisons of this sort behave + intuitively on common platforms, even though the behavior is undefined. For + those platforms where this is not the case, this implementation of memmove() + should be replaced with an alternate one. + + Usages of this function deviate from MISRA-C:2012 Rule 18.3 (required). As + Rule 18.3 is required, a separate deviation record is required. + + @param pbDest The destination buffer. + @param pbSrc The source buffer. + + @return Whether RedMemMove() must copy memory in the forward direction. +*/ +static bool MemMoveMustCopyForward( + const uint8_t *pbDest, + const uint8_t *pbSrc) +{ + return pbDest < pbSrc; +} + + +/** @brief Move memory from one address to another. + + Supports overlapping memory regions. If memory regions do not overlap, it + is generally better to use RedMemCpy() instead. + + @param pDest The destination buffer. + @param pSrc The source buffer. + @param ulLen The number of bytes to copy. +*/ +void RedMemMove( + void *pDest, + const void *pSrc, + uint32_t ulLen) +{ + uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); + const uint8_t *pbSrc = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pSrc); + uint32_t ulIdx; + + if((pDest == NULL) || (pSrc == NULL)) + { + REDERROR(); + } + else if(MemMoveMustCopyForward(pbDest, pbSrc)) + { + /* If the destination is lower than the source with overlapping memory + regions, we must copy from start to end in order to copy the memory + correctly. + + Don't use RedMemCpy() to do this. It is possible that RedMemCpy() + has been replaced (even though this function has not been replaced) + with an implementation that cannot handle any kind of buffer + overlap. + */ + for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) + { + pbDest[ulIdx] = pbSrc[ulIdx]; + } + } + else + { + ulIdx = ulLen; + + while(ulIdx > 0U) + { + ulIdx--; + pbDest[ulIdx] = pbSrc[ulIdx]; + } + } +} + +#endif /* RedMemMove */ + + +#ifndef RedMemSet +/** @brief Initialize a buffer with the specified byte value. + + @param pDest The buffer to initialize. + @param bVal The byte value with which to initialize @p pDest. + @param ulLen The number of bytes to initialize. +*/ +void RedMemSet( + void *pDest, + uint8_t bVal, + uint32_t ulLen) +{ + if(pDest == NULL) + { + REDERROR(); + } + else + { + uint8_t *pbDest = CAST_VOID_PTR_TO_UINT8_PTR(pDest); + uint32_t ulIdx; + + for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) + { + pbDest[ulIdx] = bVal; + } + } +} +#endif + + +#ifndef RedMemCmp +/** @brief Compare the contents of two buffers. + + @param pMem1 The first buffer to compare. + @param pMem2 The second buffer to compare. + @param ulLen The length to compare. + + @return Zero if the two buffers are the same, otherwise nonzero. + + @retval 0 @p pMem1 and @p pMem2 are the same. + @retval 1 @p pMem1 is greater than @p pMem2, as determined by the + values of the first differing bytes. + @retval -1 @p pMem2 is greater than @p pMem1, as determined by the + values of the first differing bytes. +*/ +int32_t RedMemCmp( + const void *pMem1, + const void *pMem2, + uint32_t ulLen) +{ + int32_t lResult; + + if((pMem1 == NULL) || (pMem2 == NULL)) + { + REDERROR(); + lResult = 0; + } + else + { + const uint8_t *pbMem1 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem1); + const uint8_t *pbMem2 = CAST_VOID_PTR_TO_CONST_UINT8_PTR(pMem2); + uint32_t ulIdx = 0U; + + while((ulIdx < ulLen) && (pbMem1[ulIdx] == pbMem2[ulIdx])) + { + ulIdx++; + } + + if(ulIdx == ulLen) + { + lResult = 0; + } + else if(pbMem1[ulIdx] > pbMem2[ulIdx]) + { + lResult = 1; + } + else + { + lResult = -1; + } + } + + return lResult; +} +#endif diff --git a/util/namelen.c b/util/namelen.c new file mode 100644 index 0000000..3c4babc --- /dev/null +++ b/util/namelen.c @@ -0,0 +1,54 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a utility to find the length of a name. +*/ +#include + +#if REDCONF_API_POSIX == 1 + + +/** @brief Determine the length of a name, terminated either by a null or a path + separator character. + + @param pszName The name whose length is to be determined. + + @return The length of the name. +*/ +uint32_t RedNameLen( + const char *pszName) +{ + uint32_t ulIdx = 0U; + + while((pszName[ulIdx] != '\0') && (pszName[ulIdx] != REDCONF_PATH_SEPARATOR)) + { + ulIdx++; + } + + return ulIdx; +} + +#endif + diff --git a/util/sign.c b/util/sign.c new file mode 100644 index 0000000..902a3ee --- /dev/null +++ b/util/sign.c @@ -0,0 +1,59 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Implements a sign on message. +*/ +#include + + +/** @brief Display the Reliance Edge signon message. +*/ +void RedSignOn(void) +{ + #if REDCONF_OUTPUT == 1 + + /* Use RedOsOutputString() instead of RedPrintf() to avoid using variadic + arguments, since this function is called from the driver and cannot use + functions that violate MISRA-C:2012. + */ + RedOsOutputString(RED_PRODUCT_NAME "\n"); + RedOsOutputString(RED_PRODUCT_EDITION "\n"); + RedOsOutputString(RED_PRODUCT_LEGAL "\n"); + RedOsOutputString(RED_PRODUCT_PATENT "\n"); + + #else + + /* Always embed the copyright into the program data. Use "volatile" to try + to avoid the compiler removing the variables. + */ + static volatile const char szVersion[] = RED_PRODUCT_NAME; + static volatile const char szCopyright[] = RED_PRODUCT_LEGAL; + + (void)szVersion; + (void)szCopyright; + + #endif +} + diff --git a/util/string.c b/util/string.c new file mode 100644 index 0000000..eb49b2e --- /dev/null +++ b/util/string.c @@ -0,0 +1,225 @@ +/* ----> DO NOT REMOVE THE FOLLOWING NOTICE <---- + + Copyright (c) 2014-2015 Datalight, Inc. + All Rights Reserved Worldwide. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; use version 2 of the License. + + This program is distributed in the hope that it will be useful, + but "AS-IS," WITHOUT ANY WARRANTY; without even the implied warranty + of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License along + with this program; if not, write to the Free Software Foundation, Inc., + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +*/ +/* Businesses and individuals that for commercial or other reasons cannot + comply with the terms of the GPLv2 license may obtain a commercial license + before incorporating Reliance Edge into proprietary software for + distribution in any form. Visit http://www.datalight.com/reliance-edge for + more information. +*/ +/** @file + @brief Default implementations of string manipulation functions. + + These implementations are intended to be small and simple, and thus forego + all optimizations. If the C library is available, or if there are better + third-party implementations available in the system, those can be used + instead by defining the appropriate macros in redconf.h. + + These functions are not intended to be completely 100% ANSI C compatible + implementations, but rather are designed to meet the needs of Reliance Edge. + The compatibility is close enough that ANSI C compatible implementations + can be "dropped in" as replacements without difficulty. +*/ +#include + + +#ifndef RedStrLen +/** @brief Determine the length (in bytes) of a null terminated string. + + The length does not include the null terminator byte. + + @param pszStr The null terminated string whose length is to be determined. + + @return The length of the @p pszStr string. +*/ +uint32_t RedStrLen( + const char *pszStr) +{ + uint32_t ulLen = 0U; + + if(pszStr == NULL) + { + REDERROR(); + } + else + { + while(pszStr[ulLen] != '\0') + { + ulLen++; + } + } + + return ulLen; +} +#endif + + +#ifndef RedStrCmp +/** @brief Compare two null terminated strings. + + @param pszStr1 The first string to compare. + @param pszStr2 The second string to compare. + + @return Zero if the two strings are the same, otherwise nonzero. + + @retval 0 @p pszStr1 and @p pszStr2 are the same. + @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the + values of the first differing bytes. + @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the + values of the first differing bytes. +*/ +int32_t RedStrCmp( + const char *pszStr1, + const char *pszStr2) +{ + int32_t lResult; + + if((pszStr1 == NULL) || (pszStr2 == NULL)) + { + REDERROR(); + lResult = 0; + } + else + { + uint32_t ulIdx = 0U; + + while((pszStr1[ulIdx] == pszStr2[ulIdx]) && (pszStr1[ulIdx] != '\0')) + { + ulIdx++; + } + + if(pszStr1[ulIdx] > pszStr2[ulIdx]) + { + lResult = 1; + } + else if(pszStr1[ulIdx] < pszStr2[ulIdx]) + { + lResult = -1; + } + else + { + lResult = 0; + } + } + + return lResult; +} +#endif + + +#ifndef RedStrNCmp +/** @brief Compare the first @p ulLen characters of two null terminated strings. + + @param pszStr1 The first string to compare. + @param pszStr2 The second string to compare. + @param ulLen The maximum length to compare. The comparison stops when + either of the strings end or when @p ulLen bytes have been + compared. + + @return Zero if the two strings are the same, otherwise nonzero. + + @retval 0 @p pszStr1 and @p pszStr2 are the same. + @retval 1 @p pszStr1 is greater than @p pszStr2, as determined by the + values of the first differing bytes. + @retval -1 @p pszStr2 is greater than @p pszStr1, as determined by the + values of the first differing bytes. +*/ +int32_t RedStrNCmp( + const char *pszStr1, + const char *pszStr2, + uint32_t ulLen) +{ + int32_t lResult = 0; + + if((pszStr1 == NULL) || (pszStr2 == NULL)) + { + REDERROR(); + } + else + { + uint32_t ulIdx; + + for(ulIdx = 0U; ulIdx < ulLen; ulIdx++) + { + if(pszStr1[ulIdx] != pszStr2[ulIdx]) + { + if(pszStr1[ulIdx] > pszStr2[ulIdx]) + { + lResult = 1; + } + else + { + lResult = -1; + } + } + + if((lResult != 0) || (pszStr1[ulIdx] == '\0')) + { + break; + } + } + } + + return lResult; +} +#endif + + +#ifndef RedStrNCpy +/** @brief Copy a string. + + Copy up to @p ulLen bytes of a null-terminated string (@p pszSrc) to a + destination buffer (@p pszDst). The result will not be null-terminated if + @p pszSrc is longer than @p ulLen - 1 bytes. + + If @p pszSrc is shorter than @p ulLen - 1 bytes, the remainder of @p pszDst + will be filled with null bytes. + + @param pszDst The destination buffer, which is at least @p ulLen bytes + in size. + @param pszSrc The null-terminated string to copy. + @param ulLen The maximum number of characters to copy. +*/ +void RedStrNCpy( + char *pszDst, + const char *pszSrc, + uint32_t ulLen) +{ + if((pszDst == NULL) || (pszSrc == NULL)) + { + REDERROR(); + } + else + { + uint32_t ulIdx = 0U; + + while((ulIdx < ulLen) && (pszSrc[ulIdx] != '\0')) + { + pszDst[ulIdx] = pszSrc[ulIdx]; + ulIdx++; + } + + while(ulIdx < ulLen) + { + pszDst[ulIdx] = '\0'; + ulIdx++; + } + } +} +#endif +

VP5Y7mCGb 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