From 4bbb3305749a9ebd656382a40dd303c49638009d Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 21 Aug 2019 09:47:12 -0400 Subject: [PATCH 01/26] I guess we will need an ARM emulator or something. --- core/arm/armcpu.c | 791 ++++++++++++++++++++++++++++++++++++++++++++++ core/arm/armcpu.h | 37 +++ core/arm/armmem.c | 52 +++ core/arm/armmem.h | 28 ++ gui/qt/CEmu.pro | 4 + 5 files changed, 912 insertions(+) create mode 100644 core/arm/armcpu.c create mode 100644 core/arm/armcpu.h create mode 100644 core/arm/armmem.c create mode 100644 core/arm/armmem.h diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c new file mode 100644 index 000000000..4e3b3fe00 --- /dev/null +++ b/core/arm/armcpu.c @@ -0,0 +1,791 @@ +#include "armcpu.h" +#include "../defines.h" + +#include "armmem.h" + +#include + +arm_cpu_state_t arm_cpu; + +#ifdef __GCC_ASM_FLAG_OUTPUTS__ +# if defined(__i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_IX64) +# define FLAGS_FROM_EXTENDED_X86_ASM 1 +# else +# define FLAGS_FROM_EXTENDED_X86_ASM 0 +# endif +#endif + +#if (__has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow)) || __GNUC__ >= 5 +# define FLAGS_FROM_OVERFLOW_BUILTINS 1 +#else +# define FLAGS_FROM_OVERFLOW_BUILTINS 0 +#endif + +#if __has_builtin(__builtin_constant_p) || __GNUC__ >= 3 // Not sure, so conservative +# define HAVE_BUILTIN_CONSTANT_P 1 +#else +# define HAVE_BUILTIN_CONSTANT_P 0 +#endif + +static uint32_t arm_bitcount_9(uint32_t x) { +#if defined(__POPCNT__) && (__has_builtin(__builtin_popcount) || __GNUC__ >= 4) + return __builtin_popcount(x & 0777); +#else + uint64_t result = x & 0777, mask = UINT64_C(0x1111111111111111); + result *= UINT64_C(0001001001001); +#if defined(__x86_64__) || defined(_M_IX64) + __asm__("andq\t%1, %0\nimulq\t%1, %0" : "+r"(result) : "r"(mask) : "cc"); +#else + result &= mask; + result *= mask; +#endif + return result >> 60; +#endif +} + +static uint32_t arm_movs(uint32_t x) { +#if FLAGS_FROM_EXTENDED_X86_ASM + if (true +# if HAVE_BUILTIN_CONSTANT_P + && !__builtin_constant_p(!x) && !__builtin_constant_p(x >> 31) +# endif + ) { + __asm__("testl\t%2, %2" : "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(x) : "cc"); + } else +#endif + { + arm_cpu.z = !x; + arm_cpu.n = x >> 31; + } + return x; +} + +static uint32_t arm_lsls(uint32_t x, uint8_t y) { + if (unlikely(y >= 32)) { + arm_cpu.c = (y == 32) & x; + x = 0; + } else if (likely(y)) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("shll\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + return x; +#else + arm_cpu.c = x >> (32 - y) & 1; + x <<= y; +#endif + } + return arm_movs(x); +} + +static uint32_t arm_lsrs(uint32_t x, uint8_t y) { + if (unlikely(y >= 32)) { + arm_cpu.c = (y == 32) & x >> 31; + x = 0; + } else if (likely(y)) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("shrl\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + return x; +#else + arm_cpu.c = x >> (y - 1) & 1; + x >>= y; +#endif + } + return arm_movs(x); +} + +static int32_t arm_asrs(int32_t x, uint8_t y) { + if (unlikely(y >= 32)) { + arm_cpu.c = x >>= 31; + } else if (likely(y)) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("sarl\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + return x; +#else + arm_cpu.c = x >> (y - 1) & 1; + x >>= y; +#endif + } + return arm_movs(x); +} + +static uint32_t arm_rors(uint32_t x, uint8_t y) { + if (likely(y)) { + if (likely(y &= 31)) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("rorl\t%2, %0" : "+r"(x), "=@ccc"(arm_cpu.c) : "Ic"(y) : "cc"); +#else + x = x >> y | x << (32 - y); + arm_cpu.c = x >> 31; +#endif + } else { + arm_cpu.c = x >> 31; + } + } + return arm_movs(x); +} + +static uint32_t arm_ands(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("andl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + return x; +#else + return arm_movs(x & y); +#endif +} + +static uint32_t arm_eors(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("xorl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + return x; +#else + return arm_movs(x ^ y); +#endif +} + +static uint32_t arm_orrs(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("orl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + return x; +#else + return arm_movs(x | y); +#endif +} + +static uint32_t arm_mvns(uint32_t x) { + return arm_eors(x, ~UINT32_C(0)); +} + +static uint32_t arm_negs(uint32_t x) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("negl\t%0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) :: "cc"); + return x; +#elif FLAGS_FROM_OVERFLOW_BUILTINS + int32_t result; + arm_cpu.v = __builtin_sub_overflow(0, (int32_t)x, &result); + arm_cpu.c = x; + return arm_movs(-x); +#else + int64_t result = UINT64_C(0) - (int32_t)x; + arm_cpu.v = result != (int32_t)result; + arm_cpu.c = (uint32_t)result <= 0; + //arm_cpu.c = 0 >= x; + return arm_movs(result); +#endif +} + +static uint32_t arm_adds(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("addl\t%5, %0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y) : "cc"); + return x; +#elif FLAGS_FROM_OVERFLOW_BUILTINS + int32_t result; + arm_cpu.v = __builtin_add_overflow((int32_t)x, (int32_t)y, &result); + arm_cpu.c = __builtin_add_overflow(x, y, &x); + return arm_movs(x); +#else + int64_t result = (int64_t)(int32_t)x + (int32_t)y; + arm_cpu.v = result != (int32_t)result; + arm_cpu.c = (uint32_t)result < x; + //arm_cpu.c = x > ~y; + return arm_movs(result); +#endif +} + +static uint32_t arm_subs(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("subl\t%5, %0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y) : "cc"); + return x; +#elif FLAGS_FROM_OVERFLOW_BUILTINS + int32_t result; + arm_cpu.v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &result); + arm_cpu.c = !__builtin_sub_overflow(x, y, &x); + return arm_movs(x); +#else + int64_t result = (int64_t)(int32_t)x - (int32_t)y; + arm_cpu.v = result != (int32_t)result; + arm_cpu.c = (uint32_t)result <= x; + //arm_cpu.c = x >= y; + return arm_movs(result); +#endif +} + +static uint32_t arm_adcs(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("\tbtl\t$0, %k6\n\tadcl\t%5, %0\n" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y), "m"(arm_cpu.c) : "cc"); + return x; +#elif FLAGS_FROM_OVERFLOW_BUILTINS + bool carry = arm_cpu.c; + int32_t result; + arm_cpu.v = __builtin_add_overflow(x, y, &result); + arm_cpu.v |= __builtin_add_overflow(result, carry, &result); + arm_cpu.c = __builtin_add_overflow(x, y, &x); + arm_cpu.c |= __builtin_add_overflow(x, carry, &x); + return arm_movs(x); +#else + int64_t result = (uint64_t)(int32_t)x + (int32_t)y + arm_cpu.c; + arm_cpu.v = result != (int32_t)result; + arm_cpu.c = ((uint64_t)x + y + arm_cpu.c) >> 32; + return arm_movs(result); +#endif +} + +static uint32_t arm_sbcs(uint32_t x, uint32_t y) { +#if FLAGS_FROM_EXTENDED_X86_ASM + __asm__("\tcmpb\t$1, %6\n\tsbbl\t%5, %0\n" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y), "m"(arm_cpu.c) : "cc"); + return x; +#elif FLAGS_FROM_OVERFLOW_BUILTINS + bool borrow = !arm_cpu.c; + int32_t result; + arm_cpu.v = __builtin_sub_overflow(x, y, &result); + arm_cpu.v |= __builtin_sub_overflow(result, borrow, &result); + arm_cpu.c = __builtin_sub_overflow(x, y, &x); + arm_cpu.c |= __builtin_sub_overflow(x, borrow, &x); + return arm_movs(x); +#else + int64_t result = (uint64_t)(int32_t)x - (int32_t)y - !arm_cpu.c; + arm_cpu.v = result != (int32_t)result; + arm_cpu.c = ((uint64_t)x - y - !arm_cpu.c) >> 32; + return arm_movs(result); +#endif +} + +static uint32_t arm_rev(uint32_t x) { + return (x >> 24 & UINT32_C(0x000000FF)) | + (x >> 8 & UINT32_C(0x0000FF00)) | + (x << 8 & UINT32_C(0x00FF0000)) | + (x << 24 & UINT32_C(0xFF000000)); +} + +static uint32_t arm_rev16(uint32_t x) { + return (x >> 8 & UINT32_C(0x000000FF)) | + (x << 8 & UINT32_C(0x0000FF00)) | + (x >> 8 & UINT32_C(0x00FF0000)) | + (x << 8 & UINT32_C(0xFF000000)); +} + +static int16_t arm_revsh(uint32_t x) { + return (x >> 8 & UINT32_C(0x000000FF)) | + (x << 8 & UINT32_C(0x0000FF00)); +} + +static void arm_exception(arm_exception_number_t type) { + abort(); +} + +void arm_execute(void) { + uint32_t opcode; + if (unlikely(arm_cpu.pc & 1)) { + arm_exception(ARM_Exception_HardFault); + } + opcode = arm_mem_load_half(arm_cpu.pc - 4); + arm_cpu.pc += 2; + switch (opcode >> 12 & 0xF) { + case 0: + case 1: + switch (opcode >> 11 & 3) { + case 0: // Logical Shift Left + arm_cpu.r[opcode >> 0 & 7] = arm_lsls(arm_cpu.r[opcode >> 3 & 7], opcode >> 5 & 0x1F); + break; + case 1: // Logical Shift Right + arm_cpu.r[opcode >> 0 & 7] = arm_lsrs(arm_cpu.r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + break; + case 2: // Arithmetic Shift Right + arm_cpu.r[opcode >> 0 & 7] = arm_asrs(arm_cpu.r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + break; + case 3: + switch (opcode >> 8 & 3) { + case 0: // Add register + arm_cpu.r[opcode >> 0 & 7] = arm_adds(arm_cpu.r[opcode >> 3 & 7], arm_cpu.r[opcode >> 6 & 7]); + break; + case 1: // Subtract register + arm_cpu.r[opcode >> 0 & 7] = arm_subs(arm_cpu.r[opcode >> 3 & 7], arm_cpu.r[opcode >> 6 & 7]); + break; + case 2: // Add 3-bit immediate + arm_cpu.r[opcode >> 0 & 7] = arm_adds(arm_cpu.r[opcode >> 3 & 7], opcode >> 6 & 7); + break; + case 3: // Subtract 3-bit immediate + arm_cpu.r[opcode >> 0 & 7] = arm_subs(arm_cpu.r[opcode >> 3 & 7], opcode >> 6 & 7); + break; + } + break; + } + case 2: + case 3: + switch (opcode >> 11 & 3) { + case 0: // Move + arm_cpu.r[opcode >> 8 & 7] = arm_movs(opcode >> 0 & 0xFF); + break; + case 1: // Compare + arm_subs(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + break; + case 2: // Add 8-bit immediate + arm_cpu.r[opcode >> 8 & 7] = arm_adds(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + break; + case 3: // Subtract 8-bit immediate + arm_cpu.r[opcode >> 8 & 7] = arm_subs(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + break; + } + break; + case 4: + switch (opcode >> 10 & 3) { + case 0: // Data processing + switch (opcode >> 6 & 0xF) { + case 0: // Bitwise AND + arm_cpu.r[opcode >> 0 & 7] = arm_ands(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 1: // Exclusive OR + arm_cpu.r[opcode >> 0 & 7] = arm_eors(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 2: // Logical Shift Left + arm_cpu.r[opcode >> 0 & 7] = arm_lsls(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 3: // Logical Shift Right + arm_cpu.r[opcode >> 0 & 7] = arm_lsrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 4: // Arithmetic Shift Right + arm_cpu.r[opcode >> 0 & 7] = arm_asrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 5: // Add with Carry + arm_cpu.r[opcode >> 0 & 7] = arm_adcs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 6: // Subtract with Carry + arm_cpu.r[opcode >> 0 & 7] = arm_sbcs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 7: // Rotate Right + arm_cpu.r[opcode >> 0 & 7] = arm_rors(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 8: // Set flags on bitwise AND + arm_ands(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 9: // Reverse Subtract from 0 + arm_cpu.r[opcode >> 0 & 7] = arm_negs(arm_cpu.r[opcode >> 3 & 7]); + break; + case 10: // Compare Registers + arm_subs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 11: // Compare Negative + arm_adds(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 12: // Logical OR + arm_cpu.r[opcode >> 0 & 7] = arm_orrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + break; + case 13: // Multiply Two Registers + arm_cpu.r[opcode >> 0 & 7] = arm_movs(arm_cpu.r[opcode >> 0 & 7] * arm_cpu.r[opcode >> 3 & 7]); + break; + case 14: // Bit Clear + arm_cpu.r[opcode >> 0 & 7] = arm_ands(arm_cpu.r[opcode >> 0 & 7], ~arm_cpu.r[opcode >> 3 & 7]); + break; + case 15: // Bitwise NOT + arm_cpu.r[opcode >> 0 & 7] = arm_mvns(arm_cpu.r[opcode >> 3 & 7]); + break; + } + break; + case 1: // Special data instructions and branch and exchange + switch (opcode >> 8 & 3) { + case 0: // Add Registers + arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] += arm_cpu.r[opcode >> 1 & 7]; + break; + case 1: // Compare Registers + arm_subs(arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)], arm_cpu.r[opcode >> 1 & 7]); + break; + case 2: // Move Registers + arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] = arm_cpu.r[opcode >> 1 & 7]; + break; + case 3: { // Branch (with Link) and Exchange + uint32_t address = arm_cpu.r[opcode >> 3 & 0xF]; + if (unlikely(opcode >> 7 & 1)) { // Branch with Link and Exchange + arm_cpu.lr = arm_cpu.pc - 1; + } else if (unlikely(arm_cpu.mode && address >> 28 == 0xF)) { + // Exception Return + abort(); + } + arm_cpu.pc = address; + break; + } + } + break; + default: // Load from Literal Pool + arm_cpu.r[opcode >> 8 & 7] = arm_mem_load_word(((arm_cpu.pc >> 2) + (opcode & 0xFF)) << 2); + break; + } + break; + case 5: + switch (opcode >> 9 & 7) { + case 0: // Store Register + arm_mem_store_word(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 1: // Store Register Halfword + arm_mem_store_half(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 2: // Store Register Byte + arm_mem_store_byte(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 3: // Load Register Signed Byte + arm_cpu.r[opcode >> 0 & 7] = (int8_t)arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 4: // Load Register + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_word(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 5: // Load Register Halfword + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 6: // Load Register Byte + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + case 7: // Load Register Signed Halfword + arm_cpu.r[opcode >> 0 & 7] = (int16_t)arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + break; + } + break; + case 6: + if (opcode >> 11 & 1) { // Load Register + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_word(arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + } else { // Store Register + arm_mem_store_word(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + } + break; + case 7: + if (opcode >> 11 & 1) { // Load Register Byte + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + } else { // Store Register Byte + arm_mem_store_byte(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + } + break; + case 8: + if (opcode >> 11 & 1) { // Load Register Halfword + arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + } else { // Store Register Halfword + arm_mem_store_half(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + } + break; + case 9: + if (opcode >> 11 & 1) { // Load Register SP relative + arm_cpu.r[opcode >> 8 & 7] = arm_mem_load_word(arm_cpu.sp + ((opcode >> 0 & 0xFF) << 2)); + } else { // Store Register SP relative + arm_mem_store_word(arm_cpu.r[opcode >> 8 & 7], arm_cpu.sp + ((opcode >> 0 & 0xFF) << 2)); + } + break; + case 10: // Generate SP/PC + arm_cpu.r[opcode >> 8 & 7] = arm_cpu.r[opcode >> 11 & 1 ? 13 : 15] + ((opcode >> 0 & 0xFF) << 2); + break; + case 11: // Miscellaneous 16-bit instructions + switch (opcode >> 9 & 7) { + case 0: + switch (opcode >> 7 & 3) { + case 0: // Add Immediate to SP + arm_cpu.sp += (opcode & 0x7F) << 2; + break; + case 1: // Subtract Immediate from SP + arm_cpu.sp -= (opcode & 0x7F) << 2; + break; + } + break; + case 1: + switch (opcode >> 6 & 7) { + case 0: // Signed Extend Halfword + arm_cpu.r[opcode >> 0 & 7] = (int16_t)arm_cpu.r[opcode >> 3 & 7]; + break; + case 1: // Signed Extend Byte + arm_cpu.r[opcode >> 0 & 7] = (int8_t)arm_cpu.r[opcode >> 3 & 7]; + break; + case 2: // Unsigned Extend Halfword + arm_cpu.r[opcode >> 0 & 7] = (uint16_t)arm_cpu.r[opcode >> 3 & 7]; + break; + case 3: // Unsigned Extend Byte + arm_cpu.r[opcode >> 0 & 7] = (uint8_t)arm_cpu.r[opcode >> 3 & 7]; + break; + } + break; + case 2: { // Push Multiple Registers + uint32_t address = arm_cpu.sp -= (arm_bitcount_9(opcode) << 2); + int i; + for (i = 0; i < 8; i++) { + if (opcode >> i & 1) { + arm_mem_store_word(arm_cpu.r[i], address); + address += 4; + } + } + if (opcode >> i & 1) { + arm_mem_store_word(arm_cpu.lr, address); + } + break; + } + case 3: + switch (opcode >> 5 & 0xF) { + case 3: // Change Processor State + arm_cpu.pm = opcode >> 4 & 1; + break; + } + break; + case 5: + switch (opcode >> 6 & 7) { + case 0: // Byte-Reverse Word + arm_cpu.r[opcode >> 0 & 7] = arm_rev(arm_cpu.r[opcode >> 3 & 7]); + break; + case 1: // Byte-Reverse Packed Halfword + arm_cpu.r[opcode >> 0 & 7] = arm_rev16(arm_cpu.r[opcode >> 3 & 7]); + break; + case 3: // Byte-Reverse Signed Halfword + arm_cpu.r[opcode >> 0 & 7] = arm_revsh(arm_cpu.r[opcode >> 3 & 7]); + break; + } + break; + case 6: { // Pop Multiple Registers + int i; + for (i = 0; i < 8; i++) { + if (opcode >> i & 1) { + arm_cpu.r[i] = arm_mem_load_word(arm_cpu.sp); + arm_cpu.sp += 4; + } + } + if (opcode >> i & 1) { + arm_cpu.pc = arm_mem_load_word(arm_cpu.sp) - 1; + arm_cpu.sp += 4; + } + break; + } + case 7: + switch (opcode >> 8 & 1) { + case 0: // Breakpoint + break; + case 1: // Hints + switch (opcode >> 0 & 0xF) { + case 0: + switch (opcode >> 4 & 0xF) { + case 0: // No Operation hint + break; + case 1: // Yield hint + break; + case 2: // Wait for Event hint + break; + case 3: // Wait for Interrupt hint + break; + case 4: // Send Event hint + break; + } + break; + } + break; + } + break; + } + break; + case 12: + switch (opcode >> 11 & 1) { + case 0: { // Store multiple registers + uint32_t address = arm_cpu.r[opcode >> 8 & 7]; + int i; + for (i = 0; i < 8; i++) { + if (opcode >> i & 1) { + arm_mem_store_word(arm_cpu.r[i], address); + address += 4; + } + } + arm_cpu.r[opcode >> 8 & 7] = address; + break; + } + case 1: { // Load multiple registers + uint32_t address = arm_cpu.r[opcode >> 8 & 7]; + int i; + for (i = 0; i < 8; i++) { + if (opcode >> i & 1) { + arm_cpu.r[i] = arm_mem_load_word(address); + address += 4; + } + } + if (!(opcode >> (opcode >> 8 & 7) & 1)) { + arm_cpu.r[opcode >> 8 & 7] = address; + } + break; + } + } + break; + case 13: + switch (opcode >> 8 & 0xF) { // Conditional branch, and Supervisor Call + case 0: // Branch Equal + if (arm_cpu.z) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 1: // Branch Not equal + if (!arm_cpu.z) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 2: // Branch Carry set + if (arm_cpu.c) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 3: // Branch Carry clear + if (!arm_cpu.c) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 4: // Branch Minus, negative + if (arm_cpu.n) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 5: // Branch Plus, positive or zero + if (!arm_cpu.n) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 6: // Branch Overflow + if (arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 7: // Branch No overflow + if (!arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 8: // Branch Unsigned higher + if (arm_cpu.c && !arm_cpu.z) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 9: // Branch Unsigned lower or same + if (!arm_cpu.c || arm_cpu.z) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 10: // Branch Signed greater than or equal + if (arm_cpu.n == arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 11: // Branch Signed less than + if (arm_cpu.n != arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 12: // Branch Signed greater than + if (!arm_cpu.z && arm_cpu.n == arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + case 13: // Branch Signed less than or equal + if (arm_cpu.z || arm_cpu.n != arm_cpu.v) { + arm_cpu.pc += (int32_t)opcode << 24 >> 23; + } + break; + default: // Permanently UNDEFINED + arm_exception(ARM_Exception_HardFault); + break; + case 15: // Supervisor Call + arm_exception(ARM_Exception_SVCall); + break; + } + break; + case 14: + switch (opcode >> 11 & 1) { + case 0: // Unconditional Branch + arm_cpu.pc += (int32_t)opcode << 21 >> 20; + break; + default: // UNDEFINED 32-bit Thumb instruction + opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 4); + arm_cpu.pc += 2; + arm_exception(ARM_Exception_HardFault); + break; + } + break; + case 15: // 32-bit Thumb instruction. + opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 4); + arm_cpu.pc += 2; + if (!(opcode >> 27 & 1) && (opcode >> 15 & 1)) { + switch (opcode >> 20 & 0x7F) { + case 0x38: + case 0x39: { // Move to Special Register + uint32_t value = arm_cpu.r[opcode >> 16 & 0xF]; + switch (opcode >> 0 & 0xFF) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + arm_cpu.v = value >> 28 & 1; + arm_cpu.c = value >> 29 & 1; + arm_cpu.z = value >> 30 & 1; + arm_cpu.n = value >> 31 & 1; + break; + case 0x80: + case 0x81: + *((opcode >> 0 & 1) == arm_cpu.spsel ? &arm_cpu.sp : &arm_cpu.altsp) = value >> 0 & ~3; + break; + case 0x10: + arm_cpu.pm = value >> 0 & 1; + break; + case 0x14: + if (arm_cpu.mode && arm_cpu.spsel != (value >> 1 & 1)) { + uint32_t sp = arm_cpu.sp; + arm_cpu.sp = arm_cpu.altsp; + arm_cpu.altsp = sp; + arm_cpu.spsel = value >> 1 & 1; + } + break; + } + break; + } + case 0x3B: // Miscellaneous control instructions + switch (opcode >> 4 & 0xF) { + case 4: // Data Synchronization Barrier + break; + case 5: // Data Memory Barrier + break; + case 6: // Instruction Synchronization Barrier + break; + } + break; + case 0x3E: + case 0x3F: { // Move from Special Register + uint32_t value = 0; + switch (opcode >> 0 & 0xFF) { + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + if (opcode >> 0 & 1) { + value |= arm_cpu.excNum << 0; + } + if (!(opcode >> 2 & 1)) { + value |= arm_cpu.v << 28; + value |= arm_cpu.c << 29; + value |= arm_cpu.z << 30; + value |= arm_cpu.n << 31; + } + break; + case 0x08: + case 0x09: + value = (opcode >> 0 & 1) == arm_cpu.spsel ? arm_cpu.sp : arm_cpu.altsp; + break; + case 0x10: + value |= arm_cpu.pm; + break; + case 0x14: + value |= arm_cpu.spsel << 1; + break; + } + arm_cpu.r[opcode >> 16 & 0xF] = value; + break; + } + default: + arm_exception(ARM_Exception_HardFault); + break; + } + } else if ((opcode >> 1 & 5) == 5) { // Branch with Link + arm_cpu.lr = arm_cpu.pc - 1; + arm_cpu.pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | + (~(opcode >> 3 ^ opcode << 10) & UINT32_C(0x00800000)) | + (~(opcode >> 4 ^ opcode << 11) & UINT32_C(0x00400000)) | + (opcode >> 4 & UINT32_C(0x003FF000)) | + (opcode << 1 & UINT32_C(0x00000FFE)); + } else { // UNDEFINED 32-bit Thumb instruction + arm_exception(ARM_Exception_HardFault); + } + break; + } +} diff --git a/core/arm/armcpu.h b/core/arm/armcpu.h new file mode 100644 index 000000000..88fd1d196 --- /dev/null +++ b/core/arm/armcpu.h @@ -0,0 +1,37 @@ +#ifndef ARMCPU_H +#define ARMCPU_H + +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum arm_exception_number { + ARM_Exception_Reset = 1, + ARM_Exception_NMI = 2, + ARM_Exception_HardFault = 3, + ARM_Exception_SVCall = 11, + ARM_Exception_PendSV = 14, + ARM_Exception_SysTick = 15, +} arm_exception_number_t; + +typedef union arm_cpu_state { + uint32_t r[32]; + struct { + uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc, altsp; + uint8_t excNum : 6; + bool v, c, z, n, pm, spsel, mode; + }; +} arm_cpu_state_t; + +extern arm_cpu_state_t arm_cpu; + +void arm_execute(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/arm/armmem.c b/core/arm/armmem.c new file mode 100644 index 000000000..8c8151922 --- /dev/null +++ b/core/arm/armmem.c @@ -0,0 +1,52 @@ +#include "armmem.h" + +#include +#include + +arm_mem_state_t arm_mem; + +void arm_mem_init(void) { + arm_mem.flash = calloc(0x10000, sizeof(uint32_t)); + arm_mem.ram = calloc(0x2000, sizeof(uint32_t)); +} + +uint8_t arm_mem_load_byte(uint32_t addr) { + return arm_mem_load_word(addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); +} + +uint16_t arm_mem_load_half(uint32_t addr) { + return arm_mem_load_word(addr & ~UINT32_C(1)) >> ((addr & UINT32_C(1)) << UINT32_C(4)); +} + +uint32_t arm_mem_load_word(uint32_t addr) { + assert(!(addr & UINT32_C(3))); + if (addr - UINT32_C(0) < UINT32_C(0x40000)) { + return arm_mem.flash[(addr - UINT32_C(0)) >> 2]; + } + if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { + return arm_mem.ram[(addr - UINT32_C(0x20000000)) >> 2]; + } + return 0; +} + +static void arm_mem_store(uint32_t val, uint32_t mask, uint32_t addr) { + assert(!(addr & UINT32_C(3)) && !(val & ~mask)); + if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { + uint32_t *ptr = &arm_mem.ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; + *ptr = (*ptr & ~mask) | val; + } +} + +void arm_mem_store_byte(uint8_t val, uint32_t addr) { + uint32_t shift = (addr & UINT32_C(3)) << UINT32_C(3); + arm_mem_store(val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); +} + +void arm_mem_store_half(uint16_t val, uint32_t addr) { + uint32_t shift = (addr & UINT32_C(1)) << UINT32_C(4); + arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(1)); +} + +void arm_mem_store_word(uint32_t val, uint32_t addr) { + arm_mem_store(val, UINT32_C(0xFFFFFFFF), addr); +} diff --git a/core/arm/armmem.h b/core/arm/armmem.h new file mode 100644 index 000000000..7869b49cb --- /dev/null +++ b/core/arm/armmem.h @@ -0,0 +1,28 @@ +#ifndef ARMMEM_H +#define ARMMEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct arm_mem_state { + uint32_t *flash, *ram; +} arm_mem_state_t; + +extern arm_mem_state_t arm_mem; + +void arm_mem_init(void); +uint8_t arm_mem_load_byte(uint32_t addr); +uint16_t arm_mem_load_half(uint32_t addr); +uint32_t arm_mem_load_word(uint32_t addr); +void arm_mem_store_byte(uint8_t val, uint32_t addr); +void arm_mem_store_half(uint16_t val, uint32_t addr); +void arm_mem_store_word(uint32_t val, uint32_t addr); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gui/qt/CEmu.pro b/gui/qt/CEmu.pro index f20238df2..f37d60410 100644 --- a/gui/qt/CEmu.pro +++ b/gui/qt/CEmu.pro @@ -205,6 +205,8 @@ if(macx) { SOURCES += \ ../../tests/autotester/autotester.cpp \ + ../../core/arm/armcpu.c \ + ../../core/arm/armmem.c \ ../../core/asic.c \ ../../core/bootver.c \ ../../core/cpu.c \ @@ -290,6 +292,8 @@ SOURCES += ../../tests/autotester/autotester_cli.cpp \ HEADERS += \ ../../tests/autotester/autotester.h \ + ../../core/arm/armcpu.h \ + ../../core/arm/armmem.h \ ../../core/asic.h \ ../../core/bootver.h \ ../../core/cpu.h \ From 6ad22742c8253dbb1e138084c707268fe795ad84 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Fri, 23 Aug 2019 05:03:27 -0400 Subject: [PATCH 02/26] Fix all the bugs. --- core/arm/armcpu.c | 209 ++++++++++++++++++++++++---------------------- core/arm/armcpu.h | 1 + core/arm/armmem.c | 10 ++- core/arm/armmem.h | 2 +- core/asic.c | 4 + 5 files changed, 123 insertions(+), 103 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 4e3b3fe00..5fe60226e 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -4,6 +4,7 @@ #include "armmem.h" #include +#include arm_cpu_state_t arm_cpu; @@ -271,12 +272,18 @@ static void arm_exception(arm_exception_number_t type) { abort(); } +void arm_cpu_reset(void) { + memset(&arm_cpu, 0, sizeof(arm_cpu)); + arm_cpu.sp = arm_mem_load_word(0x2000); + arm_cpu.pc = arm_mem_load_word(0x2004) + 1; +} + void arm_execute(void) { uint32_t opcode; if (unlikely(arm_cpu.pc & 1)) { arm_exception(ARM_Exception_HardFault); } - opcode = arm_mem_load_half(arm_cpu.pc - 4); + opcode = arm_mem_load_half(arm_cpu.pc - 2); arm_cpu.pc += 2; switch (opcode >> 12 & 0xF) { case 0: @@ -308,6 +315,7 @@ void arm_execute(void) { } break; } + break; case 2: case 3: switch (opcode >> 11 & 3) { @@ -398,7 +406,7 @@ void arm_execute(void) { // Exception Return abort(); } - arm_cpu.pc = address; + arm_cpu.pc = address + 1; break; } } @@ -538,7 +546,7 @@ void arm_execute(void) { } } if (opcode >> i & 1) { - arm_cpu.pc = arm_mem_load_word(arm_cpu.sp) - 1; + arm_cpu.pc = arm_mem_load_word(arm_cpu.sp) + 1; arm_cpu.sp += 4; } break; @@ -603,72 +611,72 @@ void arm_execute(void) { switch (opcode >> 8 & 0xF) { // Conditional branch, and Supervisor Call case 0: // Branch Equal if (arm_cpu.z) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 1: // Branch Not equal if (!arm_cpu.z) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 2: // Branch Carry set if (arm_cpu.c) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 3: // Branch Carry clear if (!arm_cpu.c) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 4: // Branch Minus, negative if (arm_cpu.n) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 5: // Branch Plus, positive or zero if (!arm_cpu.n) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 6: // Branch Overflow if (arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 7: // Branch No overflow if (!arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 8: // Branch Unsigned higher if (arm_cpu.c && !arm_cpu.z) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 9: // Branch Unsigned lower or same if (!arm_cpu.c || arm_cpu.z) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 10: // Branch Signed greater than or equal if (arm_cpu.n == arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 11: // Branch Signed less than if (arm_cpu.n != arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 12: // Branch Signed greater than if (!arm_cpu.z && arm_cpu.n == arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 13: // Branch Signed less than or equal if (arm_cpu.z || arm_cpu.n != arm_cpu.v) { - arm_cpu.pc += (int32_t)opcode << 24 >> 23; + arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; } break; default: // Permanently UNDEFINED @@ -682,107 +690,112 @@ void arm_execute(void) { case 14: switch (opcode >> 11 & 1) { case 0: // Unconditional Branch - arm_cpu.pc += (int32_t)opcode << 21 >> 20; + arm_cpu.pc += ((int32_t)opcode << 21 >> 20) + 2; break; default: // UNDEFINED 32-bit Thumb instruction - opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 4); + opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 2); arm_cpu.pc += 2; arm_exception(ARM_Exception_HardFault); break; } break; case 15: // 32-bit Thumb instruction. - opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 4); + opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 2); arm_cpu.pc += 2; if (!(opcode >> 27 & 1) && (opcode >> 15 & 1)) { - switch (opcode >> 20 & 0x7F) { - case 0x38: - case 0x39: { // Move to Special Register - uint32_t value = arm_cpu.r[opcode >> 16 & 0xF]; - switch (opcode >> 0 & 0xFF) { - case 0x00: - case 0x01: - case 0x02: - case 0x03: - arm_cpu.v = value >> 28 & 1; - arm_cpu.c = value >> 29 & 1; - arm_cpu.z = value >> 30 & 1; - arm_cpu.n = value >> 31 & 1; - break; - case 0x80: - case 0x81: - *((opcode >> 0 & 1) == arm_cpu.spsel ? &arm_cpu.sp : &arm_cpu.altsp) = value >> 0 & ~3; - break; - case 0x10: - arm_cpu.pm = value >> 0 & 1; - break; - case 0x14: - if (arm_cpu.mode && arm_cpu.spsel != (value >> 1 & 1)) { - uint32_t sp = arm_cpu.sp; - arm_cpu.sp = arm_cpu.altsp; - arm_cpu.altsp = sp; - arm_cpu.spsel = value >> 1 & 1; + switch (opcode >> 12 & 5) { + case 0: + switch (opcode >> 20 & 0x7F) { + case 0x38: + case 0x39: { // Move to Special Register + uint32_t value = arm_cpu.r[opcode >> 16 & 0xF]; + switch (opcode >> 0 & 0xFF) { + case 0x00: + case 0x01: + case 0x02: + case 0x03: + arm_cpu.v = value >> 28 & 1; + arm_cpu.c = value >> 29 & 1; + arm_cpu.z = value >> 30 & 1; + arm_cpu.n = value >> 31 & 1; + break; + case 0x80: + case 0x81: + *((opcode >> 0 & 1) == arm_cpu.spsel ? &arm_cpu.sp : &arm_cpu.altsp) = value >> 0 & ~3; + break; + case 0x10: + arm_cpu.pm = value >> 0 & 1; + break; + case 0x14: + if (arm_cpu.mode && arm_cpu.spsel != (value >> 1 & 1)) { + uint32_t sp = arm_cpu.sp; + arm_cpu.sp = arm_cpu.altsp; + arm_cpu.altsp = sp; + arm_cpu.spsel = value >> 1 & 1; + } + break; } break; - } - break; - } - case 0x3B: // Miscellaneous control instructions - switch (opcode >> 4 & 0xF) { - case 4: // Data Synchronization Barrier - break; - case 5: // Data Memory Barrier - break; - case 6: // Instruction Synchronization Barrier - break; - } - break; - case 0x3E: - case 0x3F: { // Move from Special Register - uint32_t value = 0; - switch (opcode >> 0 & 0xFF) { - case 0x00: - case 0x01: - case 0x03: - case 0x04: - case 0x05: - case 0x06: - case 0x07: - if (opcode >> 0 & 1) { - value |= arm_cpu.excNum << 0; - } - if (!(opcode >> 2 & 1)) { - value |= arm_cpu.v << 28; - value |= arm_cpu.c << 29; - value |= arm_cpu.z << 30; - value |= arm_cpu.n << 31; + } + case 0x3B: // Miscellaneous control instructions + switch (opcode >> 4 & 0xF) { + case 4: // Data Synchronization Barrier + break; + case 5: // Data Memory Barrier + break; + case 6: // Instruction Synchronization Barrier + break; } break; - case 0x08: - case 0x09: - value = (opcode >> 0 & 1) == arm_cpu.spsel ? arm_cpu.sp : arm_cpu.altsp; - break; - case 0x10: - value |= arm_cpu.pm; + case 0x3E: + case 0x3F: { // Move from Special Register + uint32_t value = 0; + switch (opcode >> 0 & 0xFF) { + case 0x00: + case 0x01: + case 0x03: + case 0x04: + case 0x05: + case 0x06: + case 0x07: + if (opcode >> 0 & 1) { + value |= arm_cpu.excNum << 0; + } + if (!(opcode >> 2 & 1)) { + value |= arm_cpu.v << 28; + value |= arm_cpu.c << 29; + value |= arm_cpu.z << 30; + value |= arm_cpu.n << 31; + } + break; + case 0x08: + case 0x09: + value = (opcode >> 0 & 1) == arm_cpu.spsel ? arm_cpu.sp : arm_cpu.altsp; + break; + case 0x10: + value |= arm_cpu.pm; + break; + case 0x14: + value |= arm_cpu.spsel << 1; + break; + } + arm_cpu.r[opcode >> 16 & 0xF] = value; break; - case 0x14: - value |= arm_cpu.spsel << 1; + } + default: + arm_exception(ARM_Exception_HardFault); break; } - arm_cpu.r[opcode >> 16 & 0xF] = value; break; - } - default: - arm_exception(ARM_Exception_HardFault); + case 5: // Branch with Link + arm_cpu.lr = arm_cpu.pc - 1; + arm_cpu.pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | + (~(opcode >> 3 ^ opcode << 10) & UINT32_C(0x00800000)) | + (~(opcode >> 4 ^ opcode << 11) & UINT32_C(0x00400000)) | + (opcode >> 4 & UINT32_C(0x003FF000)) | + (opcode << 1 & UINT32_C(0x00000FFE)); break; } - } else if ((opcode >> 1 & 5) == 5) { // Branch with Link - arm_cpu.lr = arm_cpu.pc - 1; - arm_cpu.pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | - (~(opcode >> 3 ^ opcode << 10) & UINT32_C(0x00800000)) | - (~(opcode >> 4 ^ opcode << 11) & UINT32_C(0x00400000)) | - (opcode >> 4 & UINT32_C(0x003FF000)) | - (opcode << 1 & UINT32_C(0x00000FFE)); } else { // UNDEFINED 32-bit Thumb instruction arm_exception(ARM_Exception_HardFault); } diff --git a/core/arm/armcpu.h b/core/arm/armcpu.h index 88fd1d196..f189bced9 100644 --- a/core/arm/armcpu.h +++ b/core/arm/armcpu.h @@ -28,6 +28,7 @@ typedef union arm_cpu_state { extern arm_cpu_state_t arm_cpu; +void arm_cpu_reset(void); void arm_execute(void); #ifdef __cplusplus diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 8c8151922..4ddaff55a 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -5,7 +5,9 @@ arm_mem_state_t arm_mem; -void arm_mem_init(void) { +void arm_mem_reset(void) { + free(arm_mem.flash); + free(arm_mem.ram); arm_mem.flash = calloc(0x10000, sizeof(uint32_t)); arm_mem.ram = calloc(0x2000, sizeof(uint32_t)); } @@ -15,7 +17,7 @@ uint8_t arm_mem_load_byte(uint32_t addr) { } uint16_t arm_mem_load_half(uint32_t addr) { - return arm_mem_load_word(addr & ~UINT32_C(1)) >> ((addr & UINT32_C(1)) << UINT32_C(4)); + return arm_mem_load_word(addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); } uint32_t arm_mem_load_word(uint32_t addr) { @@ -43,8 +45,8 @@ void arm_mem_store_byte(uint8_t val, uint32_t addr) { } void arm_mem_store_half(uint16_t val, uint32_t addr) { - uint32_t shift = (addr & UINT32_C(1)) << UINT32_C(4); - arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(1)); + uint32_t shift = (addr & UINT32_C(2)) << UINT32_C(3); + arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); } void arm_mem_store_word(uint32_t val, uint32_t addr) { diff --git a/core/arm/armmem.h b/core/arm/armmem.h index 7869b49cb..9acf70c0f 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -13,7 +13,7 @@ typedef struct arm_mem_state { extern arm_mem_state_t arm_mem; -void arm_mem_init(void); +void arm_mem_reset(void); uint8_t arm_mem_load_byte(uint32_t addr); uint16_t arm_mem_load_half(uint32_t addr); uint32_t arm_mem_load_word(uint32_t addr); diff --git a/core/asic.c b/core/asic.c index 7a8f3a738..9e232229b 100644 --- a/core/asic.c +++ b/core/asic.c @@ -1,4 +1,6 @@ #include "asic.h" +#include "arm/armcpu.h" +#include "arm/armmem.h" #include "cpu.h" #include "misc.h" #include "mem.h" @@ -84,6 +86,8 @@ static void plug_devices(void) { add_reset_proc(panel_reset); add_reset_proc(spi_reset); add_reset_proc(uart_reset); + add_reset_proc(arm_mem_reset); + add_reset_proc(arm_cpu_reset); gui_console_printf("[CEmu] Initialized Advanced Peripheral Bus...\n"); } From a1f82951e2ac908ade83092c2ed89937fde93bd2 Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Tue, 2 Jun 2020 21:21:12 -0400 Subject: [PATCH 03/26] Ok, pendant. --- core/arm/armcpu.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 5fe60226e..12ae8cfeb 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -14,6 +14,8 @@ arm_cpu_state_t arm_cpu; # else # define FLAGS_FROM_EXTENDED_X86_ASM 0 # endif +#else +# define FLAGS_FROM_EXTENDED_X86_ASM 0 #endif #if (__has_builtin(__builtin_add_overflow) && __has_builtin(__builtin_sub_overflow)) || __GNUC__ >= 5 From e7b0311a20f3171655e828afaebfdd55e0cfb64b Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Mon, 8 Jun 2020 01:54:06 -0400 Subject: [PATCH 04/26] Moar threads! \o/ --- core/arm/armcpu.c | 461 +++++++++++++++++++++--------------------- core/arm/armcpu.h | 20 +- core/arm/armmem.c | 70 +++++-- core/arm/armmem.h | 27 +-- core/arm/armstate.c | 21 ++ core/arm/armstate.h | 28 +++ core/arm/sync.c | 74 +++++++ core/arm/sync.h | 33 +++ core/asic.c | 4 +- core/coproc.c | 15 ++ core/coproc.h | 24 +++ gui/qt/CEmu.pro | 8 + gui/qt/CMakeLists.txt | 6 + 13 files changed, 515 insertions(+), 276 deletions(-) create mode 100644 core/arm/armstate.c create mode 100644 core/arm/armstate.h create mode 100644 core/arm/sync.c create mode 100644 core/arm/sync.h create mode 100644 core/coproc.c create mode 100644 core/coproc.h diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 12ae8cfeb..c93b4ef58 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -1,13 +1,12 @@ #include "armcpu.h" -#include "../defines.h" #include "armmem.h" +#include "armstate.h" +#include "../defines.h" #include #include -arm_cpu_state_t arm_cpu; - #ifdef __GCC_ASM_FLAG_OUTPUTS__ # if defined(__i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_IX64) # define FLAGS_FROM_EXTENDED_X86_ASM 1 @@ -30,6 +29,12 @@ arm_cpu_state_t arm_cpu; # define HAVE_BUILTIN_CONSTANT_P 0 #endif +void arm_cpu_reset(arm_state_t *state) { + memset(&state->cpu, 0, sizeof(state->cpu)); + state->cpu.sp = arm_mem_load_word(state, 0x2000); + state->cpu.pc = arm_mem_load_word(state, 0x2004) + 1; +} + static uint32_t arm_bitcount_9(uint32_t x) { #if defined(__POPCNT__) && (__has_builtin(__builtin_popcount) || __GNUC__ >= 4) return __builtin_popcount(x & 0777); @@ -46,208 +51,208 @@ static uint32_t arm_bitcount_9(uint32_t x) { #endif } -static uint32_t arm_movs(uint32_t x) { +static uint32_t arm_movs(arm_cpu_t *cpu, uint32_t x) { #if FLAGS_FROM_EXTENDED_X86_ASM if (true # if HAVE_BUILTIN_CONSTANT_P && !__builtin_constant_p(!x) && !__builtin_constant_p(x >> 31) # endif ) { - __asm__("testl\t%2, %2" : "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(x) : "cc"); + __asm__("testl\t%2, %2" : "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "r"(x) : "cc"); } else #endif { - arm_cpu.z = !x; - arm_cpu.n = x >> 31; + cpu->z = !x; + cpu->n = x >> 31; } return x; } -static uint32_t arm_lsls(uint32_t x, uint8_t y) { +static uint32_t arm_lsls(arm_cpu_t *cpu, uint32_t x, uint8_t y) { if (unlikely(y >= 32)) { - arm_cpu.c = (y == 32) & x; + cpu->c = (y == 32) & x; x = 0; } else if (likely(y)) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("shll\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + __asm__("shll\t%4, %0" : "+r"(x), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "Ic"(y) : "cc"); return x; #else - arm_cpu.c = x >> (32 - y) & 1; + cpu->c = x >> (32 - y) & 1; x <<= y; #endif } - return arm_movs(x); + return arm_movs(cpu, x); } -static uint32_t arm_lsrs(uint32_t x, uint8_t y) { +static uint32_t arm_lsrs(arm_cpu_t *cpu, uint32_t x, uint8_t y) { if (unlikely(y >= 32)) { - arm_cpu.c = (y == 32) & x >> 31; + cpu->c = (y == 32) & x >> 31; x = 0; } else if (likely(y)) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("shrl\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + __asm__("shrl\t%4, %0" : "+r"(x), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "Ic"(y) : "cc"); return x; #else - arm_cpu.c = x >> (y - 1) & 1; + cpu->c = x >> (y - 1) & 1; x >>= y; #endif } - return arm_movs(x); + return arm_movs(cpu, x); } -static int32_t arm_asrs(int32_t x, uint8_t y) { +static int32_t arm_asrs(arm_cpu_t *cpu, int32_t x, uint8_t y) { if (unlikely(y >= 32)) { - arm_cpu.c = x >>= 31; + cpu->c = x >>= 31; } else if (likely(y)) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("sarl\t%4, %0" : "+r"(x), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "Ic"(y) : "cc"); + __asm__("sarl\t%4, %0" : "+r"(x), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "Ic"(y) : "cc"); return x; #else - arm_cpu.c = x >> (y - 1) & 1; + cpu->c = x >> (y - 1) & 1; x >>= y; #endif } - return arm_movs(x); + return arm_movs(cpu, x); } -static uint32_t arm_rors(uint32_t x, uint8_t y) { +static uint32_t arm_rors(arm_cpu_t *cpu, uint32_t x, uint8_t y) { if (likely(y)) { if (likely(y &= 31)) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("rorl\t%2, %0" : "+r"(x), "=@ccc"(arm_cpu.c) : "Ic"(y) : "cc"); + __asm__("rorl\t%2, %0" : "+r"(x), "=@ccc"(cpu->c) : "Ic"(y) : "cc"); #else x = x >> y | x << (32 - y); - arm_cpu.c = x >> 31; + cpu->c = x >> 31; #endif } else { - arm_cpu.c = x >> 31; + cpu->c = x >> 31; } } - return arm_movs(x); + return arm_movs(cpu, x); } -static uint32_t arm_ands(uint32_t x, uint32_t y) { +static uint32_t arm_ands(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("andl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + __asm__("andl\t%3, %0" : "+r"(x), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "r"(y) : "cc"); return x; #else - return arm_movs(x & y); + return arm_movs(cpu, x & y); #endif } -static uint32_t arm_eors(uint32_t x, uint32_t y) { +static uint32_t arm_eors(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("xorl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + __asm__("xorl\t%3, %0" : "+r"(x), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "r"(y) : "cc"); return x; #else - return arm_movs(x ^ y); + return arm_movs(cpu, x ^ y); #endif } -static uint32_t arm_orrs(uint32_t x, uint32_t y) { +static uint32_t arm_orrs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("orl\t%3, %0" : "+r"(x), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "r"(y) : "cc"); + __asm__("orl\t%3, %0" : "+r"(x), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "r"(y) : "cc"); return x; #else - return arm_movs(x | y); + return arm_movs(cpu, x | y); #endif } -static uint32_t arm_mvns(uint32_t x) { - return arm_eors(x, ~UINT32_C(0)); +static uint32_t arm_mvns(arm_cpu_t *cpu, uint32_t x) { + return arm_eors(cpu, x, ~UINT32_C(0)); } -static uint32_t arm_negs(uint32_t x) { +static uint32_t arm_negs(arm_cpu_t *cpu, uint32_t x) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("negl\t%0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) :: "cc"); + __asm__("negl\t%0" : "+r"(x), "=@cco"(cpu->v), "=@ccnc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) :: "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS int32_t result; - arm_cpu.v = __builtin_sub_overflow(0, (int32_t)x, &result); - arm_cpu.c = x; - return arm_movs(-x); + cpu->v = __builtin_sub_overflow(0, (int32_t)x, &result); + cpu->c = x; + return arm_movs(cpu, -x); #else int64_t result = UINT64_C(0) - (int32_t)x; - arm_cpu.v = result != (int32_t)result; - arm_cpu.c = (uint32_t)result <= 0; - //arm_cpu.c = 0 >= x; - return arm_movs(result); + cpu->v = result != (int32_t)result; + cpu->c = (uint32_t)result <= 0; + //cpu->c = 0 >= x; + return arm_movs(cpu, result); #endif } -static uint32_t arm_adds(uint32_t x, uint32_t y) { +static uint32_t arm_adds(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("addl\t%5, %0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y) : "cc"); + __asm__("addl\t%5, %0" : "+r"(x), "=@cco"(cpu->v), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS int32_t result; - arm_cpu.v = __builtin_add_overflow((int32_t)x, (int32_t)y, &result); - arm_cpu.c = __builtin_add_overflow(x, y, &x); - return arm_movs(x); + cpu->v = __builtin_add_overflow((int32_t)x, (int32_t)y, &result); + cpu->c = __builtin_add_overflow(x, y, &x); + return arm_movs(cpu, x); #else int64_t result = (int64_t)(int32_t)x + (int32_t)y; - arm_cpu.v = result != (int32_t)result; - arm_cpu.c = (uint32_t)result < x; - //arm_cpu.c = x > ~y; - return arm_movs(result); + cpu->v = result != (int32_t)result; + cpu->c = (uint32_t)result < x; + //cpu->c = x > ~y; + return arm_movs(cpu, result); #endif } -static uint32_t arm_subs(uint32_t x, uint32_t y) { +static uint32_t arm_subs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("subl\t%5, %0" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y) : "cc"); + __asm__("subl\t%5, %0" : "+r"(x), "=@cco"(cpu->v), "=@ccnc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS int32_t result; - arm_cpu.v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &result); - arm_cpu.c = !__builtin_sub_overflow(x, y, &x); - return arm_movs(x); + cpu->v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &result); + cpu->c = !__builtin_sub_overflow(x, y, &x); + return arm_movs(cpu, x); #else int64_t result = (int64_t)(int32_t)x - (int32_t)y; - arm_cpu.v = result != (int32_t)result; - arm_cpu.c = (uint32_t)result <= x; - //arm_cpu.c = x >= y; - return arm_movs(result); + cpu->v = result != (int32_t)result; + cpu->c = (uint32_t)result <= x; + //cpu->c = x >= y; + return arm_movs(cpu, result); #endif } -static uint32_t arm_adcs(uint32_t x, uint32_t y) { +static uint32_t arm_adcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("\tbtl\t$0, %k6\n\tadcl\t%5, %0\n" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y), "m"(arm_cpu.c) : "cc"); + __asm__("\tbtl\t$0, %k6\n\tadcl\t%5, %0\n" : "+r"(x), "=@cco"(cpu->v), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y), "m"(cpu->c) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS - bool carry = arm_cpu.c; + bool carry = cpu->c; int32_t result; - arm_cpu.v = __builtin_add_overflow(x, y, &result); - arm_cpu.v |= __builtin_add_overflow(result, carry, &result); - arm_cpu.c = __builtin_add_overflow(x, y, &x); - arm_cpu.c |= __builtin_add_overflow(x, carry, &x); - return arm_movs(x); + cpu->v = __builtin_add_overflow(x, y, &result); + cpu->v |= __builtin_add_overflow(result, carry, &result); + cpu->c = __builtin_add_overflow(x, y, &x); + cpu->c |= __builtin_add_overflow(x, carry, &x); + return arm_movs(cpu, x); #else - int64_t result = (uint64_t)(int32_t)x + (int32_t)y + arm_cpu.c; - arm_cpu.v = result != (int32_t)result; - arm_cpu.c = ((uint64_t)x + y + arm_cpu.c) >> 32; - return arm_movs(result); + int64_t result = (uint64_t)(int32_t)x + (int32_t)y + cpu->c; + cpu->v = result != (int32_t)result; + cpu->c = ((uint64_t)x + y + cpu->c) >> 32; + return arm_movs(cpu, result); #endif } -static uint32_t arm_sbcs(uint32_t x, uint32_t y) { +static uint32_t arm_sbcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { #if FLAGS_FROM_EXTENDED_X86_ASM - __asm__("\tcmpb\t$1, %6\n\tsbbl\t%5, %0\n" : "+r"(x), "=@cco"(arm_cpu.v), "=@ccnc"(arm_cpu.c), "=@ccz"(arm_cpu.z), "=@ccs"(arm_cpu.n) : "ir"(y), "m"(arm_cpu.c) : "cc"); + __asm__("\tcmpb\t$1, %6\n\tsbbl\t%5, %0\n" : "+r"(x), "=@cco"(cpu->v), "=@ccnc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y), "m"(cpu->c) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS - bool borrow = !arm_cpu.c; + bool borrow = !cpu->c; int32_t result; - arm_cpu.v = __builtin_sub_overflow(x, y, &result); - arm_cpu.v |= __builtin_sub_overflow(result, borrow, &result); - arm_cpu.c = __builtin_sub_overflow(x, y, &x); - arm_cpu.c |= __builtin_sub_overflow(x, borrow, &x); - return arm_movs(x); + cpu->v = __builtin_sub_overflow(x, y, &result); + cpu->v |= __builtin_sub_overflow(result, borrow, &result); + cpu->c = __builtin_sub_overflow(x, y, &x); + cpu->c |= __builtin_sub_overflow(x, borrow, &x); + return arm_movs(cpu, x); #else - int64_t result = (uint64_t)(int32_t)x - (int32_t)y - !arm_cpu.c; - arm_cpu.v = result != (int32_t)result; - arm_cpu.c = ((uint64_t)x - y - !arm_cpu.c) >> 32; - return arm_movs(result); + int64_t result = (uint64_t)(int32_t)x - (int32_t)y - !cpu->c; + cpu->v = result != (int32_t)result; + cpu->c = ((uint64_t)x - y - !cpu->c) >> 32; + return arm_movs(cpu, result); #endif } @@ -271,48 +276,44 @@ static int16_t arm_revsh(uint32_t x) { } static void arm_exception(arm_exception_number_t type) { + (void)type; abort(); } -void arm_cpu_reset(void) { - memset(&arm_cpu, 0, sizeof(arm_cpu)); - arm_cpu.sp = arm_mem_load_word(0x2000); - arm_cpu.pc = arm_mem_load_word(0x2004) + 1; -} - -void arm_execute(void) { +void arm_execute(arm_state_t *state) { + arm_cpu_t *cpu = &state->cpu; uint32_t opcode; - if (unlikely(arm_cpu.pc & 1)) { + if (unlikely(cpu->pc & 1)) { arm_exception(ARM_Exception_HardFault); } - opcode = arm_mem_load_half(arm_cpu.pc - 2); - arm_cpu.pc += 2; + opcode = arm_mem_load_half(state, cpu->pc - 2); + cpu->pc += 2; switch (opcode >> 12 & 0xF) { case 0: case 1: switch (opcode >> 11 & 3) { case 0: // Logical Shift Left - arm_cpu.r[opcode >> 0 & 7] = arm_lsls(arm_cpu.r[opcode >> 3 & 7], opcode >> 5 & 0x1F); + cpu->r[opcode >> 0 & 7] = arm_lsls(cpu, cpu->r[opcode >> 3 & 7], opcode >> 5 & 0x1F); break; case 1: // Logical Shift Right - arm_cpu.r[opcode >> 0 & 7] = arm_lsrs(arm_cpu.r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + cpu->r[opcode >> 0 & 7] = arm_lsrs(cpu, cpu->r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); break; case 2: // Arithmetic Shift Right - arm_cpu.r[opcode >> 0 & 7] = arm_asrs(arm_cpu.r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + cpu->r[opcode >> 0 & 7] = arm_asrs(cpu, cpu->r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); break; case 3: switch (opcode >> 8 & 3) { case 0: // Add register - arm_cpu.r[opcode >> 0 & 7] = arm_adds(arm_cpu.r[opcode >> 3 & 7], arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = arm_adds(cpu, cpu->r[opcode >> 3 & 7], cpu->r[opcode >> 6 & 7]); break; case 1: // Subtract register - arm_cpu.r[opcode >> 0 & 7] = arm_subs(arm_cpu.r[opcode >> 3 & 7], arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = arm_subs(cpu, cpu->r[opcode >> 3 & 7], cpu->r[opcode >> 6 & 7]); break; case 2: // Add 3-bit immediate - arm_cpu.r[opcode >> 0 & 7] = arm_adds(arm_cpu.r[opcode >> 3 & 7], opcode >> 6 & 7); + cpu->r[opcode >> 0 & 7] = arm_adds(cpu, cpu->r[opcode >> 3 & 7], opcode >> 6 & 7); break; case 3: // Subtract 3-bit immediate - arm_cpu.r[opcode >> 0 & 7] = arm_subs(arm_cpu.r[opcode >> 3 & 7], opcode >> 6 & 7); + cpu->r[opcode >> 0 & 7] = arm_subs(cpu, cpu->r[opcode >> 3 & 7], opcode >> 6 & 7); break; } break; @@ -322,16 +323,16 @@ void arm_execute(void) { case 3: switch (opcode >> 11 & 3) { case 0: // Move - arm_cpu.r[opcode >> 8 & 7] = arm_movs(opcode >> 0 & 0xFF); + cpu->r[opcode >> 8 & 7] = arm_movs(cpu, opcode >> 0 & 0xFF); break; case 1: // Compare - arm_subs(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + arm_subs(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); break; case 2: // Add 8-bit immediate - arm_cpu.r[opcode >> 8 & 7] = arm_adds(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + cpu->r[opcode >> 8 & 7] = arm_adds(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); break; case 3: // Subtract 8-bit immediate - arm_cpu.r[opcode >> 8 & 7] = arm_subs(arm_cpu.r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + cpu->r[opcode >> 8 & 7] = arm_subs(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); break; } break; @@ -340,202 +341,202 @@ void arm_execute(void) { case 0: // Data processing switch (opcode >> 6 & 0xF) { case 0: // Bitwise AND - arm_cpu.r[opcode >> 0 & 7] = arm_ands(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_ands(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 1: // Exclusive OR - arm_cpu.r[opcode >> 0 & 7] = arm_eors(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_eors(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 2: // Logical Shift Left - arm_cpu.r[opcode >> 0 & 7] = arm_lsls(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_lsls(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 3: // Logical Shift Right - arm_cpu.r[opcode >> 0 & 7] = arm_lsrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_lsrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 4: // Arithmetic Shift Right - arm_cpu.r[opcode >> 0 & 7] = arm_asrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_asrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 5: // Add with Carry - arm_cpu.r[opcode >> 0 & 7] = arm_adcs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_adcs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 6: // Subtract with Carry - arm_cpu.r[opcode >> 0 & 7] = arm_sbcs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_sbcs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 7: // Rotate Right - arm_cpu.r[opcode >> 0 & 7] = arm_rors(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_rors(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 8: // Set flags on bitwise AND - arm_ands(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + arm_ands(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 9: // Reverse Subtract from 0 - arm_cpu.r[opcode >> 0 & 7] = arm_negs(arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_negs(cpu, cpu->r[opcode >> 3 & 7]); break; case 10: // Compare Registers - arm_subs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + arm_subs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 11: // Compare Negative - arm_adds(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + arm_adds(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 12: // Logical OR - arm_cpu.r[opcode >> 0 & 7] = arm_orrs(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_orrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); break; case 13: // Multiply Two Registers - arm_cpu.r[opcode >> 0 & 7] = arm_movs(arm_cpu.r[opcode >> 0 & 7] * arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_movs(cpu, cpu->r[opcode >> 0 & 7] * cpu->r[opcode >> 3 & 7]); break; case 14: // Bit Clear - arm_cpu.r[opcode >> 0 & 7] = arm_ands(arm_cpu.r[opcode >> 0 & 7], ~arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_ands(cpu, cpu->r[opcode >> 0 & 7], ~cpu->r[opcode >> 3 & 7]); break; case 15: // Bitwise NOT - arm_cpu.r[opcode >> 0 & 7] = arm_mvns(arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_mvns(cpu, cpu->r[opcode >> 3 & 7]); break; } break; case 1: // Special data instructions and branch and exchange switch (opcode >> 8 & 3) { case 0: // Add Registers - arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] += arm_cpu.r[opcode >> 1 & 7]; + cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] += cpu->r[opcode >> 1 & 7]; break; case 1: // Compare Registers - arm_subs(arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)], arm_cpu.r[opcode >> 1 & 7]); + arm_subs(cpu, cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)], cpu->r[opcode >> 1 & 7]); break; case 2: // Move Registers - arm_cpu.r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] = arm_cpu.r[opcode >> 1 & 7]; + cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] = cpu->r[opcode >> 1 & 7]; break; case 3: { // Branch (with Link) and Exchange - uint32_t address = arm_cpu.r[opcode >> 3 & 0xF]; + uint32_t address = cpu->r[opcode >> 3 & 0xF]; if (unlikely(opcode >> 7 & 1)) { // Branch with Link and Exchange - arm_cpu.lr = arm_cpu.pc - 1; - } else if (unlikely(arm_cpu.mode && address >> 28 == 0xF)) { + cpu->lr = cpu->pc - 1; + } else if (unlikely(cpu->mode && address >> 28 == 0xF)) { // Exception Return abort(); } - arm_cpu.pc = address + 1; + cpu->pc = address + 1; break; } } break; default: // Load from Literal Pool - arm_cpu.r[opcode >> 8 & 7] = arm_mem_load_word(((arm_cpu.pc >> 2) + (opcode & 0xFF)) << 2); + cpu->r[opcode >> 8 & 7] = arm_mem_load_word(state, ((cpu->pc >> 2) + (opcode & 0xFF)) << 2); break; } break; case 5: switch (opcode >> 9 & 7) { case 0: // Store Register - arm_mem_store_word(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + arm_mem_store_word(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 1: // Store Register Halfword - arm_mem_store_half(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + arm_mem_store_half(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 2: // Store Register Byte - arm_mem_store_byte(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + arm_mem_store_byte(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 3: // Load Register Signed Byte - arm_cpu.r[opcode >> 0 & 7] = (int8_t)arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = (int8_t)arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 4: // Load Register - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_word(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = arm_mem_load_word(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 5: // Load Register Halfword - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 6: // Load Register Byte - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; case 7: // Load Register Signed Halfword - arm_cpu.r[opcode >> 0 & 7] = (int16_t)arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + arm_cpu.r[opcode >> 6 & 7]); + cpu->r[opcode >> 0 & 7] = (int16_t)arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); break; } break; case 6: if (opcode >> 11 & 1) { // Load Register - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_word(arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + cpu->r[opcode >> 0 & 7] = arm_mem_load_word(state, cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); } else { // Store Register - arm_mem_store_word(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + arm_mem_store_word(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); } break; case 7: if (opcode >> 11 & 1) { // Load Register Byte - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_byte(arm_cpu.r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + cpu->r[opcode >> 0 & 7] = arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); } else { // Store Register Byte - arm_mem_store_byte(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + arm_mem_store_byte(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); } break; case 8: if (opcode >> 11 & 1) { // Load Register Halfword - arm_cpu.r[opcode >> 0 & 7] = arm_mem_load_half(arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + cpu->r[opcode >> 0 & 7] = arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); } else { // Store Register Halfword - arm_mem_store_half(arm_cpu.r[opcode >> 0 & 7], arm_cpu.r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + arm_mem_store_half(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); } break; case 9: if (opcode >> 11 & 1) { // Load Register SP relative - arm_cpu.r[opcode >> 8 & 7] = arm_mem_load_word(arm_cpu.sp + ((opcode >> 0 & 0xFF) << 2)); + cpu->r[opcode >> 8 & 7] = arm_mem_load_word(state, cpu->sp + ((opcode >> 0 & 0xFF) << 2)); } else { // Store Register SP relative - arm_mem_store_word(arm_cpu.r[opcode >> 8 & 7], arm_cpu.sp + ((opcode >> 0 & 0xFF) << 2)); + arm_mem_store_word(state, cpu->r[opcode >> 8 & 7], cpu->sp + ((opcode >> 0 & 0xFF) << 2)); } break; case 10: // Generate SP/PC - arm_cpu.r[opcode >> 8 & 7] = arm_cpu.r[opcode >> 11 & 1 ? 13 : 15] + ((opcode >> 0 & 0xFF) << 2); + cpu->r[opcode >> 8 & 7] = cpu->r[opcode >> 11 & 1 ? 13 : 15] + ((opcode >> 0 & 0xFF) << 2); break; case 11: // Miscellaneous 16-bit instructions switch (opcode >> 9 & 7) { case 0: switch (opcode >> 7 & 3) { case 0: // Add Immediate to SP - arm_cpu.sp += (opcode & 0x7F) << 2; + cpu->sp += (opcode & 0x7F) << 2; break; case 1: // Subtract Immediate from SP - arm_cpu.sp -= (opcode & 0x7F) << 2; + cpu->sp -= (opcode & 0x7F) << 2; break; } break; case 1: switch (opcode >> 6 & 7) { case 0: // Signed Extend Halfword - arm_cpu.r[opcode >> 0 & 7] = (int16_t)arm_cpu.r[opcode >> 3 & 7]; + cpu->r[opcode >> 0 & 7] = (int16_t)cpu->r[opcode >> 3 & 7]; break; case 1: // Signed Extend Byte - arm_cpu.r[opcode >> 0 & 7] = (int8_t)arm_cpu.r[opcode >> 3 & 7]; + cpu->r[opcode >> 0 & 7] = (int8_t)cpu->r[opcode >> 3 & 7]; break; case 2: // Unsigned Extend Halfword - arm_cpu.r[opcode >> 0 & 7] = (uint16_t)arm_cpu.r[opcode >> 3 & 7]; + cpu->r[opcode >> 0 & 7] = (uint16_t)cpu->r[opcode >> 3 & 7]; break; case 3: // Unsigned Extend Byte - arm_cpu.r[opcode >> 0 & 7] = (uint8_t)arm_cpu.r[opcode >> 3 & 7]; + cpu->r[opcode >> 0 & 7] = (uint8_t)cpu->r[opcode >> 3 & 7]; break; } break; case 2: { // Push Multiple Registers - uint32_t address = arm_cpu.sp -= (arm_bitcount_9(opcode) << 2); + uint32_t address = cpu->sp -= (arm_bitcount_9(opcode) << 2); int i; for (i = 0; i < 8; i++) { if (opcode >> i & 1) { - arm_mem_store_word(arm_cpu.r[i], address); + arm_mem_store_word(state, cpu->r[i], address); address += 4; } } if (opcode >> i & 1) { - arm_mem_store_word(arm_cpu.lr, address); + arm_mem_store_word(state, cpu->lr, address); } break; } case 3: switch (opcode >> 5 & 0xF) { case 3: // Change Processor State - arm_cpu.pm = opcode >> 4 & 1; + cpu->pm = opcode >> 4 & 1; break; } break; case 5: switch (opcode >> 6 & 7) { case 0: // Byte-Reverse Word - arm_cpu.r[opcode >> 0 & 7] = arm_rev(arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_rev(cpu->r[opcode >> 3 & 7]); break; case 1: // Byte-Reverse Packed Halfword - arm_cpu.r[opcode >> 0 & 7] = arm_rev16(arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_rev16(cpu->r[opcode >> 3 & 7]); break; case 3: // Byte-Reverse Signed Halfword - arm_cpu.r[opcode >> 0 & 7] = arm_revsh(arm_cpu.r[opcode >> 3 & 7]); + cpu->r[opcode >> 0 & 7] = arm_revsh(cpu->r[opcode >> 3 & 7]); break; } break; @@ -543,13 +544,13 @@ void arm_execute(void) { int i; for (i = 0; i < 8; i++) { if (opcode >> i & 1) { - arm_cpu.r[i] = arm_mem_load_word(arm_cpu.sp); - arm_cpu.sp += 4; + cpu->r[i] = arm_mem_load_word(state, cpu->sp); + cpu->sp += 4; } } if (opcode >> i & 1) { - arm_cpu.pc = arm_mem_load_word(arm_cpu.sp) + 1; - arm_cpu.sp += 4; + cpu->pc = arm_mem_load_word(state, cpu->sp) + 1; + cpu->sp += 4; } break; } @@ -582,28 +583,28 @@ void arm_execute(void) { case 12: switch (opcode >> 11 & 1) { case 0: { // Store multiple registers - uint32_t address = arm_cpu.r[opcode >> 8 & 7]; + uint32_t address = cpu->r[opcode >> 8 & 7]; int i; for (i = 0; i < 8; i++) { if (opcode >> i & 1) { - arm_mem_store_word(arm_cpu.r[i], address); + arm_mem_store_word(state, cpu->r[i], address); address += 4; } } - arm_cpu.r[opcode >> 8 & 7] = address; + cpu->r[opcode >> 8 & 7] = address; break; } case 1: { // Load multiple registers - uint32_t address = arm_cpu.r[opcode >> 8 & 7]; + uint32_t address = cpu->r[opcode >> 8 & 7]; int i; for (i = 0; i < 8; i++) { if (opcode >> i & 1) { - arm_cpu.r[i] = arm_mem_load_word(address); + cpu->r[i] = arm_mem_load_word(state, address); address += 4; } } if (!(opcode >> (opcode >> 8 & 7) & 1)) { - arm_cpu.r[opcode >> 8 & 7] = address; + cpu->r[opcode >> 8 & 7] = address; } break; } @@ -612,73 +613,73 @@ void arm_execute(void) { case 13: switch (opcode >> 8 & 0xF) { // Conditional branch, and Supervisor Call case 0: // Branch Equal - if (arm_cpu.z) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->z) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 1: // Branch Not equal - if (!arm_cpu.z) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->z) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 2: // Branch Carry set - if (arm_cpu.c) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->c) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 3: // Branch Carry clear - if (!arm_cpu.c) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->c) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 4: // Branch Minus, negative - if (arm_cpu.n) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->n) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 5: // Branch Plus, positive or zero - if (!arm_cpu.n) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->n) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 6: // Branch Overflow - if (arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 7: // Branch No overflow - if (!arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 8: // Branch Unsigned higher - if (arm_cpu.c && !arm_cpu.z) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->c && !cpu->z) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 9: // Branch Unsigned lower or same - if (!arm_cpu.c || arm_cpu.z) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->c || cpu->z) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 10: // Branch Signed greater than or equal - if (arm_cpu.n == arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->n == cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 11: // Branch Signed less than - if (arm_cpu.n != arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->n != cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 12: // Branch Signed greater than - if (!arm_cpu.z && arm_cpu.n == arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (!cpu->z && cpu->n == cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; case 13: // Branch Signed less than or equal - if (arm_cpu.z || arm_cpu.n != arm_cpu.v) { - arm_cpu.pc += ((int32_t)opcode << 24 >> 23) + 2; + if (cpu->z || cpu->n != cpu->v) { + cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; } break; default: // Permanently UNDEFINED @@ -692,48 +693,48 @@ void arm_execute(void) { case 14: switch (opcode >> 11 & 1) { case 0: // Unconditional Branch - arm_cpu.pc += ((int32_t)opcode << 21 >> 20) + 2; + cpu->pc += ((int32_t)opcode << 21 >> 20) + 2; break; default: // UNDEFINED 32-bit Thumb instruction - opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 2); - arm_cpu.pc += 2; + opcode = opcode << 16 | arm_mem_load_half(state, cpu->pc - 2); + cpu->pc += 2; arm_exception(ARM_Exception_HardFault); break; } break; case 15: // 32-bit Thumb instruction. - opcode = opcode << 16 | arm_mem_load_half(arm_cpu.pc - 2); - arm_cpu.pc += 2; + opcode = opcode << 16 | arm_mem_load_half(state, cpu->pc - 2); + cpu->pc += 2; if (!(opcode >> 27 & 1) && (opcode >> 15 & 1)) { switch (opcode >> 12 & 5) { case 0: switch (opcode >> 20 & 0x7F) { case 0x38: case 0x39: { // Move to Special Register - uint32_t value = arm_cpu.r[opcode >> 16 & 0xF]; + uint32_t value = cpu->r[opcode >> 16 & 0xF]; switch (opcode >> 0 & 0xFF) { case 0x00: case 0x01: case 0x02: case 0x03: - arm_cpu.v = value >> 28 & 1; - arm_cpu.c = value >> 29 & 1; - arm_cpu.z = value >> 30 & 1; - arm_cpu.n = value >> 31 & 1; + cpu->v = value >> 28 & 1; + cpu->c = value >> 29 & 1; + cpu->z = value >> 30 & 1; + cpu->n = value >> 31 & 1; break; case 0x80: case 0x81: - *((opcode >> 0 & 1) == arm_cpu.spsel ? &arm_cpu.sp : &arm_cpu.altsp) = value >> 0 & ~3; + *((opcode >> 0 & 1) == cpu->spsel ? &cpu->sp : &cpu->altsp) = value >> 0 & ~3; break; case 0x10: - arm_cpu.pm = value >> 0 & 1; + cpu->pm = value >> 0 & 1; break; case 0x14: - if (arm_cpu.mode && arm_cpu.spsel != (value >> 1 & 1)) { - uint32_t sp = arm_cpu.sp; - arm_cpu.sp = arm_cpu.altsp; - arm_cpu.altsp = sp; - arm_cpu.spsel = value >> 1 & 1; + if (cpu->mode && cpu->spsel != (value >> 1 & 1)) { + uint32_t sp = cpu->sp; + cpu->sp = cpu->altsp; + cpu->altsp = sp; + cpu->spsel = value >> 1 & 1; } break; } @@ -761,27 +762,27 @@ void arm_execute(void) { case 0x06: case 0x07: if (opcode >> 0 & 1) { - value |= arm_cpu.excNum << 0; + value |= cpu->excNum << 0; } if (!(opcode >> 2 & 1)) { - value |= arm_cpu.v << 28; - value |= arm_cpu.c << 29; - value |= arm_cpu.z << 30; - value |= arm_cpu.n << 31; + value |= cpu->v << 28; + value |= cpu->c << 29; + value |= cpu->z << 30; + value |= cpu->n << 31; } break; case 0x08: case 0x09: - value = (opcode >> 0 & 1) == arm_cpu.spsel ? arm_cpu.sp : arm_cpu.altsp; + value = (opcode >> 0 & 1) == cpu->spsel ? cpu->sp : cpu->altsp; break; case 0x10: - value |= arm_cpu.pm; + value |= cpu->pm; break; case 0x14: - value |= arm_cpu.spsel << 1; + value |= cpu->spsel << 1; break; } - arm_cpu.r[opcode >> 16 & 0xF] = value; + cpu->r[opcode >> 16 & 0xF] = value; break; } default: @@ -790,8 +791,8 @@ void arm_execute(void) { } break; case 5: // Branch with Link - arm_cpu.lr = arm_cpu.pc - 1; - arm_cpu.pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | + cpu->lr = cpu->pc - 1; + cpu->pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | (~(opcode >> 3 ^ opcode << 10) & UINT32_C(0x00800000)) | (~(opcode >> 4 ^ opcode << 11) & UINT32_C(0x00400000)) | (opcode >> 4 & UINT32_C(0x003FF000)) | diff --git a/core/arm/armcpu.h b/core/arm/armcpu.h index f189bced9..7d578960a 100644 --- a/core/arm/armcpu.h +++ b/core/arm/armcpu.h @@ -4,10 +4,6 @@ #include #include -#ifdef __cplusplus -extern "C" { -#endif - typedef enum arm_exception_number { ARM_Exception_Reset = 1, ARM_Exception_NMI = 2, @@ -17,19 +13,23 @@ typedef enum arm_exception_number { ARM_Exception_SysTick = 15, } arm_exception_number_t; -typedef union arm_cpu_state { +typedef union arm_cpu { uint32_t r[32]; struct { uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc, altsp; - uint8_t excNum : 6; + arm_exception_number_t excNum : 6; bool v, c, z, n, pm, spsel, mode; }; -} arm_cpu_state_t; +} arm_cpu_t; -extern arm_cpu_state_t arm_cpu; +typedef struct arm_state arm_state_t; + +#ifdef __cplusplus +extern "C" { +#endif -void arm_cpu_reset(void); -void arm_execute(void); +void arm_cpu_reset(arm_state_t *state); +void arm_execute(arm_state_t *state); #ifdef __cplusplus } diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 4ddaff55a..3555bc3f8 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -1,54 +1,82 @@ #include "armmem.h" +#include "armstate.h" + #include #include +#include -arm_mem_state_t arm_mem; +#define ARM_FLASH_WORDS 0x10000 +#define ARM_RAM_WORDS 0x2000 -void arm_mem_reset(void) { - free(arm_mem.flash); - free(arm_mem.ram); - arm_mem.flash = calloc(0x10000, sizeof(uint32_t)); - arm_mem.ram = calloc(0x2000, sizeof(uint32_t)); +bool arm_mem_init(arm_state_t *state) { + state->flash = calloc(ARM_FLASH_WORDS, sizeof(uint32_t)); + if (state->flash) { + state->ram = calloc(ARM_RAM_WORDS, sizeof(uint32_t)); + if (state->ram) { + return true; + free(state->ram); + } + free(state->flash); + } + return false; +} + +void arm_mem_destroy(arm_state_t *state) { + free(state->flash); + free(state->ram); +} + +void arm_mem_reset(arm_state_t *state) { + memset(state->ram, 0, ARM_RAM_WORDS * sizeof(uint32_t)); +} + +bool arm_mem_load_rom(arm_state_t *state, FILE *file) { + size_t read = fread(state->flash, 1, ARM_FLASH_WORDS * sizeof(uint32_t), file); + if (!read) { + return false; + } + memset(state->flash + read, ~0, ARM_FLASH_WORDS * sizeof(uint32_t) - read); + return true; } -uint8_t arm_mem_load_byte(uint32_t addr) { - return arm_mem_load_word(addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); +uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr) { + return arm_mem_load_word(state, addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); } -uint16_t arm_mem_load_half(uint32_t addr) { - return arm_mem_load_word(addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); +uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr) { + return arm_mem_load_word(state, addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); } -uint32_t arm_mem_load_word(uint32_t addr) { +uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr) { assert(!(addr & UINT32_C(3))); if (addr - UINT32_C(0) < UINT32_C(0x40000)) { - return arm_mem.flash[(addr - UINT32_C(0)) >> 2]; + return state->flash[(addr - UINT32_C(0)) >> 2]; } if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { - return arm_mem.ram[(addr - UINT32_C(0x20000000)) >> 2]; + return state->ram[(addr - UINT32_C(0x20000000)) >> 2]; } return 0; } -static void arm_mem_store(uint32_t val, uint32_t mask, uint32_t addr) { +static void arm_mem_store(arm_state_t *state, uint32_t val, uint32_t mask, uint32_t addr) { assert(!(addr & UINT32_C(3)) && !(val & ~mask)); if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { - uint32_t *ptr = &arm_mem.ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; + uint32_t *ptr = &state->ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; *ptr = (*ptr & ~mask) | val; } } -void arm_mem_store_byte(uint8_t val, uint32_t addr) { +void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr) { uint32_t shift = (addr & UINT32_C(3)) << UINT32_C(3); - arm_mem_store(val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); + arm_mem_store(state, val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); } -void arm_mem_store_half(uint16_t val, uint32_t addr) { +void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr) { uint32_t shift = (addr & UINT32_C(2)) << UINT32_C(3); - arm_mem_store(val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); + arm_mem_store(state, val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); } -void arm_mem_store_word(uint32_t val, uint32_t addr) { - arm_mem_store(val, UINT32_C(0xFFFFFFFF), addr); +void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr) { + arm_mem_store(state, val, UINT32_C(0xFFFFFFFF), addr); } diff --git a/core/arm/armmem.h b/core/arm/armmem.h index 9acf70c0f..28c1a747f 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -1,25 +1,26 @@ #ifndef ARMMEM_H #define ARMMEM_H +#include #include +#include + +typedef struct arm_state arm_state_t; #ifdef __cplusplus extern "C" { #endif -typedef struct arm_mem_state { - uint32_t *flash, *ram; -} arm_mem_state_t; - -extern arm_mem_state_t arm_mem; - -void arm_mem_reset(void); -uint8_t arm_mem_load_byte(uint32_t addr); -uint16_t arm_mem_load_half(uint32_t addr); -uint32_t arm_mem_load_word(uint32_t addr); -void arm_mem_store_byte(uint8_t val, uint32_t addr); -void arm_mem_store_half(uint16_t val, uint32_t addr); -void arm_mem_store_word(uint32_t val, uint32_t addr); +bool arm_mem_init(arm_state_t *state); +void arm_mem_destroy(arm_state_t *state); +void arm_mem_reset(arm_state_t *state); +bool arm_mem_load_rom(arm_state_t *state, FILE *file); +uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr); +uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr); +uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr); +void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr); +void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr); +void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr); #ifdef __cplusplus } diff --git a/core/arm/armstate.c b/core/arm/armstate.c new file mode 100644 index 000000000..b9f84b869 --- /dev/null +++ b/core/arm/armstate.c @@ -0,0 +1,21 @@ +#include "armstate.h" + +#include "armcpu.h" +#include "armmem.h" + +bool arm_state_init(arm_state_t *state) { + return arm_mem_init(state); +} + +void arm_state_destroy(arm_state_t *state) { + arm_mem_destroy(state); +} + +void arm_state_reset(arm_state_t *state) { + arm_mem_reset(state); + arm_cpu_reset(state); +} + +void arm_state_load(arm_state_t *state, FILE *file) { + arm_mem_load_rom(state, file); +} diff --git a/core/arm/armstate.h b/core/arm/armstate.h new file mode 100644 index 000000000..5e79db314 --- /dev/null +++ b/core/arm/armstate.h @@ -0,0 +1,28 @@ +#ifndef ARMSTATE_H +#define ARMSTATE_H + +#include "armcpu.h" + +#include +#include +#include + +typedef struct arm_state { + arm_cpu_t cpu; + uint32_t *flash, *ram; +} arm_state_t; + +#ifdef __cplusplus +extern "C" { +#endif + +bool arm_state_init(arm_state_t *state); +void arm_state_destroy(arm_state_t *state); +void arm_state_reset(arm_state_t *state); +void arm_state_load(arm_state_t *state, FILE *file); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/arm/sync.c b/core/arm/sync.c new file mode 100644 index 000000000..282a1a7be --- /dev/null +++ b/core/arm/sync.c @@ -0,0 +1,74 @@ +#include "sync.h" + +#include "../defines.h" + +#include + +bool sync_init(sync_t *sync) { + if (likely(mtx_init(&sync->mtx, mtx_plain) == thrd_success)) { + if (likely(cnd_init(&sync->cnd[0]) == thrd_success)) { + if (likely(cnd_init(&sync->cnd[1]) == thrd_success)) { + atomic_init(&sync->cnt, 0u); + sync->run = true; + sync->rdy = false; + return true; + cnd_destroy(&sync->cnd[1]); + } + cnd_destroy(&sync->cnd[0]); + } + mtx_destroy(&sync->mtx); + } + return false; +} + +void sync_destroy(sync_t *sync) { + cnd_destroy(&sync->cnd[1]); + cnd_destroy(&sync->cnd[0]); + mtx_destroy(&sync->mtx); +} + +bool sync_check(sync_t *sync) { + if (likely(!atomic_load_explicit(&sync->cnt, memory_order_relaxed))) { + return true; + } + if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) { + abort(); + } + sync->rdy = true; + do { + if (cnd_signal(&sync->cnd[0]) != thrd_success || + cnd_wait(&sync->cnd[1], &sync->mtx) != thrd_success) { + abort(); + } + } while (unlikely(atomic_load_explicit(&sync->cnt, memory_order_relaxed))); + bool run = sync->run; + sync->rdy = false; + if (unlikely(mtx_unlock(&sync->mtx) != thrd_success)) { + abort(); + } + if (likely(run)) { + return true; + } + sync_destroy(sync); + return false; +} + +void sync_enter(sync_t *sync) { + if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) { + abort(); + } + (void)atomic_fetch_add_explicit(&sync->cnt, 1, memory_order_relaxed); + while (unlikely(!sync->rdy)) { + if (unlikely(cnd_wait(&sync->cnd[0], &sync->mtx) != thrd_success)) { + abort(); + } + } +} + +void sync_leave(sync_t *sync) { + bool done = atomic_fetch_sub_explicit(&sync->cnt, 1, memory_order_relaxed) == 1; + if (unlikely(mtx_unlock(&sync->mtx) != thrd_success || + cnd_signal(&sync->cnd[done]) != thrd_success)) { + abort(); + } +} diff --git a/core/arm/sync.h b/core/arm/sync.h new file mode 100644 index 000000000..a9fa01fae --- /dev/null +++ b/core/arm/sync.h @@ -0,0 +1,33 @@ +#ifndef SYNC_H +#define SYNC_H + +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct sync { + mtx_t mtx; + cnd_t cnd[2]; + bool run, rdy; + atomic_uint cnt; +} sync_t; + +bool sync_init(sync_t *sync); +void sync_destroy(sync_t *sync); + +/* Target thread only */ +bool sync_check(sync_t *sync); + +/* Thread-safe, not target thread */ +void sync_enter(sync_t *sync); +void sync_leave(sync_t *sync); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/asic.c b/core/asic.c index 9e232229b..eeec771f6 100644 --- a/core/asic.c +++ b/core/asic.c @@ -1,7 +1,6 @@ #include "asic.h" -#include "arm/armcpu.h" -#include "arm/armmem.h" #include "cpu.h" +#include "coproc.h" #include "misc.h" #include "mem.h" #include "lcd.h" @@ -88,6 +87,7 @@ static void plug_devices(void) { add_reset_proc(uart_reset); add_reset_proc(arm_mem_reset); add_reset_proc(arm_cpu_reset); + add_reset_proc(coproc_reset); gui_console_printf("[CEmu] Initialized Advanced Peripheral Bus...\n"); } diff --git a/core/coproc.c b/core/coproc.c new file mode 100644 index 000000000..24b9f523f --- /dev/null +++ b/core/coproc.c @@ -0,0 +1,15 @@ +#include "coproc.h" + +coproc_state_t coproc; + +void coproc_init(void) { +} + +void coproc_reset(void) { + arm_destroy(coproc.arm); + coproc.arm = arm_create(); +} + +bool coproc_load(const char *path) { + return arm_load(coproc.arm, path); +} diff --git a/core/coproc.h b/core/coproc.h new file mode 100644 index 000000000..45a772ba5 --- /dev/null +++ b/core/coproc.h @@ -0,0 +1,24 @@ +#ifndef COPROC_H +#define COPROC_H + +#include "arm/arm.h" + +typedef struct coproc_state { + arm_t *arm; +} coproc_state_t; + +#ifdef __cplusplus +extern "C" { +#endif + +extern coproc_state_t state; + +void coproc_init(void); +void coproc_reset(void); +bool coproc_load(const char *path); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/gui/qt/CEmu.pro b/gui/qt/CEmu.pro index f37d60410..bcfbd720e 100644 --- a/gui/qt/CEmu.pro +++ b/gui/qt/CEmu.pro @@ -205,10 +205,14 @@ if(macx) { SOURCES += \ ../../tests/autotester/autotester.cpp \ + ../../core/arm/arm.c \ ../../core/arm/armcpu.c \ ../../core/arm/armmem.c \ + ../../core/arm/armstate.c \ + ../../core/arm/sync.c \ ../../core/asic.c \ ../../core/bootver.c \ + ../../core/coproc.c \ ../../core/cpu.c \ ../../core/keypad.c \ ../../core/lcd.c \ @@ -292,10 +296,14 @@ SOURCES += ../../tests/autotester/autotester_cli.cpp \ HEADERS += \ ../../tests/autotester/autotester.h \ + ../../core/arm/arm.h \ ../../core/arm/armcpu.h \ ../../core/arm/armmem.h \ + ../../core/arm/armstate.h \ + ../../core/arm/sync.h \ ../../core/asic.h \ ../../core/bootver.h \ + ../../core/coproc.h \ ../../core/cpu.h \ ../../core/atomics.h \ ../../core/defines.h \ diff --git a/gui/qt/CMakeLists.txt b/gui/qt/CMakeLists.txt index 571f78ea0..33bbd8b67 100644 --- a/gui/qt/CMakeLists.txt +++ b/gui/qt/CMakeLists.txt @@ -87,6 +87,11 @@ endif() qt_add_resources(CEmu_Resources resources.qrc) set(CEmu_Sources + ../../core/arm/arm.c ../../core/arm/arm.h + ../../core/arm/armcpu.c ../../core/arm/armcpu.h + ../../core/arm/armmem.c ../../core/arm/armmem.h + ../../core/arm/armstate.c ../../core/arm/armstate.h + ../../core/arm/sync.c ../../core/arm/sync.h ../../core/asic.c ../../core/asic.h ../../core/atomics.h ../../core/backlight.c ../../core/backlight.h @@ -94,6 +99,7 @@ set(CEmu_Sources ../../core/bus.c ../../core/bus.h ../../core/cert.c ../../core/cert.h ../../core/control.c ../../core/control.h + ../../core/coproc.c ../../core/coproc.h ../../core/cpu.c ../../core/cpu.h ../../core/debug/debug.c ../../core/debug/debug.h ../../core/debug/zdis/zdis.c ../../core/debug/zdis/zdis.h From aeb70473ef2b3294080346525ba35d485936cc3f Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Sat, 13 Jun 2020 09:33:56 -0400 Subject: [PATCH 05/26] Add files from packs.download.atmel.com. --- core/arm/CMSIS/Core/Include/cmsis_armcc.h | 865 + core/arm/CMSIS/Core/Include/cmsis_armclang.h | 1869 ++ core/arm/CMSIS/Core/Include/cmsis_compiler.h | 266 + core/arm/CMSIS/Core/Include/cmsis_gcc.h | 2085 ++ core/arm/CMSIS/Core/Include/cmsis_iccarm.h | 935 + core/arm/CMSIS/Core/Include/cmsis_version.h | 39 + core/arm/CMSIS/Core/Include/core_cm0plus.h | 1083 + core/arm/CMSIS/Core/Include/mpu_armv7.h | 270 + core/arm/CMSIS/Core_A/Include/cmsis_armcc.h | 544 + .../arm/CMSIS/Core_A/Include/cmsis_armclang.h | 503 + .../arm/CMSIS/Core_A/Include/cmsis_compiler.h | 201 + core/arm/CMSIS/Core_A/Include/cmsis_cp15.h | 514 + core/arm/CMSIS/Core_A/Include/cmsis_gcc.h | 679 + core/arm/CMSIS/Core_A/Include/cmsis_iccarm.h | 559 + core/arm/CMSIS/Core_A/Include/core_ca.h | 2614 +++ core/arm/CMSIS/Core_A/Include/irq_ctrl.h | 186 + core/arm/README.md | 1 + .../Device/SAMD21A/Source/system_samd21.c | 78 + core/arm/samd21a/atdf/ATSAMD21E18A.atdf | 5239 +++++ core/arm/samd21a/edc/ATSAMD21E18A.PIC | 13425 +++++++++++ core/arm/samd21a/gcc/gcc/samd21e18a_flash.ld | 143 + core/arm/samd21a/gcc/gcc/samd21e18a_sram.ld | 142 + core/arm/samd21a/gcc/gcc/startup_samd21.c | 255 + core/arm/samd21a/gcc/system_samd21.c | 64 + .../config/debugger/Atmel/ATSAMD21E18A.ddf | 26 + .../config/debugger/Atmel/Trace_SAMD21.dmac | 78 + .../Atmel/SAMD/ATSAMD21/ATSAMD21E18A.i79 | 41 + .../Atmel/SAMD/ATSAMD21/ATSAMD21E18A.menu | 7 + .../Atmel/samd21e18a/samd21e18a-flash.board | 9 + .../Atmel/samd21e18a/samd21e18a-flash.flash | 13 + core/arm/samd21a/iar/iar/samd21e18a_flash.icf | 62 + core/arm/samd21a/iar/iar/samd21e18a_sram.icf | 59 + core/arm/samd21a/iar/iar/startup_samd21.c | 232 + core/arm/samd21a/iar/system_samd21.c | 64 + core/arm/samd21a/include/component-version.h | 64 + core/arm/samd21a/include/component/ac.h | 545 + core/arm/samd21a/include/component/adc.h | 685 + core/arm/samd21a/include/component/dac.h | 272 + core/arm/samd21a/include/component/dmac.h | 1073 + core/arm/samd21a/include/component/dsu.h | 549 + core/arm/samd21a/include/component/eic.h | 667 + core/arm/samd21a/include/component/evsys.h | 590 + core/arm/samd21a/include/component/gclk.h | 298 + core/arm/samd21a/include/component/hmatrixb.h | 104 + core/arm/samd21a/include/component/i2s.h | 625 + core/arm/samd21a/include/component/mtb.h | 382 + core/arm/samd21a/include/component/nvmctrl.h | 507 + core/arm/samd21a/include/component/pac.h | 90 + core/arm/samd21a/include/component/pm.h | 519 + core/arm/samd21a/include/component/port.h | 380 + core/arm/samd21a/include/component/rtc.h | 1054 + core/arm/samd21a/include/component/sercom.h | 1494 ++ core/arm/samd21a/include/component/sysctrl.h | 934 + core/arm/samd21a/include/component/tc.h | 670 + core/arm/samd21a/include/component/tcc.h | 1803 ++ core/arm/samd21a/include/component/usb.h | 1791 ++ core/arm/samd21a/include/component/wdt.h | 289 + core/arm/samd21a/include/instance/ac.h | 73 + core/arm/samd21a/include/instance/adc.h | 85 + core/arm/samd21a/include/instance/dac.h | 60 + core/arm/samd21a/include/instance/dmac.h | 95 + core/arm/samd21a/include/instance/dsu.h | 85 + core/arm/samd21a/include/instance/eic.h | 64 + core/arm/samd21a/include/instance/evsys.h | 180 + core/arm/samd21a/include/instance/gclk.h | 65 + core/arm/samd21a/include/instance/i2s.h | 80 + core/arm/samd21a/include/instance/mtb.h | 89 + core/arm/samd21a/include/instance/nvmctrl.h | 77 + core/arm/samd21a/include/instance/pac0.h | 45 + core/arm/samd21a/include/instance/pac1.h | 45 + core/arm/samd21a/include/instance/pac2.h | 45 + core/arm/samd21a/include/instance/pm.h | 73 + core/arm/samd21a/include/instance/port.h | 122 + core/arm/samd21a/include/instance/ptc.h | 36 + core/arm/samd21a/include/instance/rtc.h | 103 + core/arm/samd21a/include/instance/sbmatrix.h | 151 + core/arm/samd21a/include/instance/sercom0.h | 129 + core/arm/samd21a/include/instance/sercom1.h | 129 + core/arm/samd21a/include/instance/sercom2.h | 129 + core/arm/samd21a/include/instance/sercom3.h | 129 + core/arm/samd21a/include/instance/sercom4.h | 129 + core/arm/samd21a/include/instance/sercom5.h | 129 + core/arm/samd21a/include/instance/sysctrl.h | 107 + core/arm/samd21a/include/instance/tc3.h | 97 + core/arm/samd21a/include/instance/tc4.h | 97 + core/arm/samd21a/include/instance/tc5.h | 97 + core/arm/samd21a/include/instance/tc6.h | 97 + core/arm/samd21a/include/instance/tc7.h | 97 + core/arm/samd21a/include/instance/tcc0.h | 117 + core/arm/samd21a/include/instance/tcc1.h | 105 + core/arm/samd21a/include/instance/tcc2.h | 101 + core/arm/samd21a/include/instance/usb.h | 330 + core/arm/samd21a/include/instance/wdt.h | 57 + core/arm/samd21a/include/pio/samd21e18a.h | 652 + core/arm/samd21a/include/sam.h | 66 + core/arm/samd21a/include/samd21.h | 70 + core/arm/samd21a/include/samd21e18a.h | 559 + core/arm/samd21a/include/system_samd21.h | 48 + .../samd21a/include_mcc/component-version.h | 64 + core/arm/samd21a/include_mcc/component/ac.h | 377 + core/arm/samd21a/include_mcc/component/adc.h | 496 + core/arm/samd21a/include_mcc/component/dac.h | 190 + core/arm/samd21a/include_mcc/component/dmac.h | 779 + core/arm/samd21a/include_mcc/component/dsu.h | 348 + core/arm/samd21a/include_mcc/component/eic.h | 550 + .../arm/samd21a/include_mcc/component/evsys.h | 430 + core/arm/samd21a/include_mcc/component/gclk.h | 241 + .../samd21a/include_mcc/component/hmatrixb.h | 78 + core/arm/samd21a/include_mcc/component/i2s.h | 480 + core/arm/samd21a/include_mcc/component/mtb.h | 235 + .../samd21a/include_mcc/component/nvmctrl.h | 247 + core/arm/samd21a/include_mcc/component/pac.h | 63 + core/arm/samd21a/include_mcc/component/pm.h | 419 + core/arm/samd21a/include_mcc/component/port.h | 262 + core/arm/samd21a/include_mcc/component/ptc.h | 39 + core/arm/samd21a/include_mcc/component/rtc.h | 747 + .../samd21a/include_mcc/component/sercom.h | 1841 ++ .../samd21a/include_mcc/component/sysctrl.h | 778 + core/arm/samd21a/include_mcc/component/tc.h | 469 + core/arm/samd21a/include_mcc/component/tcc.h | 1409 ++ core/arm/samd21a/include_mcc/component/usb.h | 1295 ++ core/arm/samd21a/include_mcc/component/wdt.h | 213 + core/arm/samd21a/include_mcc/pio/samd21e18a.h | 864 + core/arm/samd21a/include_mcc/sam.h | 66 + core/arm/samd21a/include_mcc/samd21e18a.h | 577 + core/arm/samd21a/include_mcc/system_samd21.h | 48 + core/arm/samd21a/keil/Flash/ATSAMD21_128.FLM | Bin 0 -> 13592 bytes core/arm/samd21a/keil/Flash/ATSAMD21_256.FLM | Bin 0 -> 13592 bytes core/arm/samd21a/keil/Flash/ATSAMD21_32.FLM | Bin 0 -> 13588 bytes core/arm/samd21a/keil/Flash/ATSAMD21_64.FLM | Bin 0 -> 13588 bytes core/arm/samd21a/svd/ATSAMD21E18A.svd | 19410 ++++++++++++++++ 131 files changed, 86594 insertions(+) create mode 100644 core/arm/CMSIS/Core/Include/cmsis_armcc.h create mode 100644 core/arm/CMSIS/Core/Include/cmsis_armclang.h create mode 100644 core/arm/CMSIS/Core/Include/cmsis_compiler.h create mode 100644 core/arm/CMSIS/Core/Include/cmsis_gcc.h create mode 100644 core/arm/CMSIS/Core/Include/cmsis_iccarm.h create mode 100644 core/arm/CMSIS/Core/Include/cmsis_version.h create mode 100644 core/arm/CMSIS/Core/Include/core_cm0plus.h create mode 100644 core/arm/CMSIS/Core/Include/mpu_armv7.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_armcc.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_armclang.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_compiler.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_cp15.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_gcc.h create mode 100644 core/arm/CMSIS/Core_A/Include/cmsis_iccarm.h create mode 100644 core/arm/CMSIS/Core_A/Include/core_ca.h create mode 100644 core/arm/CMSIS/Core_A/Include/irq_ctrl.h create mode 100644 core/arm/README.md create mode 100644 core/arm/samd21a/armcc/Device/SAMD21A/Source/system_samd21.c create mode 100644 core/arm/samd21a/atdf/ATSAMD21E18A.atdf create mode 100644 core/arm/samd21a/edc/ATSAMD21E18A.PIC create mode 100644 core/arm/samd21a/gcc/gcc/samd21e18a_flash.ld create mode 100644 core/arm/samd21a/gcc/gcc/samd21e18a_sram.ld create mode 100644 core/arm/samd21a/gcc/gcc/startup_samd21.c create mode 100644 core/arm/samd21a/gcc/system_samd21.c create mode 100644 core/arm/samd21a/iar/config/debugger/Atmel/ATSAMD21E18A.ddf create mode 100644 core/arm/samd21a/iar/config/debugger/Atmel/Trace_SAMD21.dmac create mode 100644 core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.i79 create mode 100644 core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.menu create mode 100644 core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.board create mode 100644 core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.flash create mode 100644 core/arm/samd21a/iar/iar/samd21e18a_flash.icf create mode 100644 core/arm/samd21a/iar/iar/samd21e18a_sram.icf create mode 100644 core/arm/samd21a/iar/iar/startup_samd21.c create mode 100644 core/arm/samd21a/iar/system_samd21.c create mode 100644 core/arm/samd21a/include/component-version.h create mode 100644 core/arm/samd21a/include/component/ac.h create mode 100644 core/arm/samd21a/include/component/adc.h create mode 100644 core/arm/samd21a/include/component/dac.h create mode 100644 core/arm/samd21a/include/component/dmac.h create mode 100644 core/arm/samd21a/include/component/dsu.h create mode 100644 core/arm/samd21a/include/component/eic.h create mode 100644 core/arm/samd21a/include/component/evsys.h create mode 100644 core/arm/samd21a/include/component/gclk.h create mode 100644 core/arm/samd21a/include/component/hmatrixb.h create mode 100644 core/arm/samd21a/include/component/i2s.h create mode 100644 core/arm/samd21a/include/component/mtb.h create mode 100644 core/arm/samd21a/include/component/nvmctrl.h create mode 100644 core/arm/samd21a/include/component/pac.h create mode 100644 core/arm/samd21a/include/component/pm.h create mode 100644 core/arm/samd21a/include/component/port.h create mode 100644 core/arm/samd21a/include/component/rtc.h create mode 100644 core/arm/samd21a/include/component/sercom.h create mode 100644 core/arm/samd21a/include/component/sysctrl.h create mode 100644 core/arm/samd21a/include/component/tc.h create mode 100644 core/arm/samd21a/include/component/tcc.h create mode 100644 core/arm/samd21a/include/component/usb.h create mode 100644 core/arm/samd21a/include/component/wdt.h create mode 100644 core/arm/samd21a/include/instance/ac.h create mode 100644 core/arm/samd21a/include/instance/adc.h create mode 100644 core/arm/samd21a/include/instance/dac.h create mode 100644 core/arm/samd21a/include/instance/dmac.h create mode 100644 core/arm/samd21a/include/instance/dsu.h create mode 100644 core/arm/samd21a/include/instance/eic.h create mode 100644 core/arm/samd21a/include/instance/evsys.h create mode 100644 core/arm/samd21a/include/instance/gclk.h create mode 100644 core/arm/samd21a/include/instance/i2s.h create mode 100644 core/arm/samd21a/include/instance/mtb.h create mode 100644 core/arm/samd21a/include/instance/nvmctrl.h create mode 100644 core/arm/samd21a/include/instance/pac0.h create mode 100644 core/arm/samd21a/include/instance/pac1.h create mode 100644 core/arm/samd21a/include/instance/pac2.h create mode 100644 core/arm/samd21a/include/instance/pm.h create mode 100644 core/arm/samd21a/include/instance/port.h create mode 100644 core/arm/samd21a/include/instance/ptc.h create mode 100644 core/arm/samd21a/include/instance/rtc.h create mode 100644 core/arm/samd21a/include/instance/sbmatrix.h create mode 100644 core/arm/samd21a/include/instance/sercom0.h create mode 100644 core/arm/samd21a/include/instance/sercom1.h create mode 100644 core/arm/samd21a/include/instance/sercom2.h create mode 100644 core/arm/samd21a/include/instance/sercom3.h create mode 100644 core/arm/samd21a/include/instance/sercom4.h create mode 100644 core/arm/samd21a/include/instance/sercom5.h create mode 100644 core/arm/samd21a/include/instance/sysctrl.h create mode 100644 core/arm/samd21a/include/instance/tc3.h create mode 100644 core/arm/samd21a/include/instance/tc4.h create mode 100644 core/arm/samd21a/include/instance/tc5.h create mode 100644 core/arm/samd21a/include/instance/tc6.h create mode 100644 core/arm/samd21a/include/instance/tc7.h create mode 100644 core/arm/samd21a/include/instance/tcc0.h create mode 100644 core/arm/samd21a/include/instance/tcc1.h create mode 100644 core/arm/samd21a/include/instance/tcc2.h create mode 100644 core/arm/samd21a/include/instance/usb.h create mode 100644 core/arm/samd21a/include/instance/wdt.h create mode 100644 core/arm/samd21a/include/pio/samd21e18a.h create mode 100644 core/arm/samd21a/include/sam.h create mode 100644 core/arm/samd21a/include/samd21.h create mode 100644 core/arm/samd21a/include/samd21e18a.h create mode 100644 core/arm/samd21a/include/system_samd21.h create mode 100644 core/arm/samd21a/include_mcc/component-version.h create mode 100644 core/arm/samd21a/include_mcc/component/ac.h create mode 100644 core/arm/samd21a/include_mcc/component/adc.h create mode 100644 core/arm/samd21a/include_mcc/component/dac.h create mode 100644 core/arm/samd21a/include_mcc/component/dmac.h create mode 100644 core/arm/samd21a/include_mcc/component/dsu.h create mode 100644 core/arm/samd21a/include_mcc/component/eic.h create mode 100644 core/arm/samd21a/include_mcc/component/evsys.h create mode 100644 core/arm/samd21a/include_mcc/component/gclk.h create mode 100644 core/arm/samd21a/include_mcc/component/hmatrixb.h create mode 100644 core/arm/samd21a/include_mcc/component/i2s.h create mode 100644 core/arm/samd21a/include_mcc/component/mtb.h create mode 100644 core/arm/samd21a/include_mcc/component/nvmctrl.h create mode 100644 core/arm/samd21a/include_mcc/component/pac.h create mode 100644 core/arm/samd21a/include_mcc/component/pm.h create mode 100644 core/arm/samd21a/include_mcc/component/port.h create mode 100644 core/arm/samd21a/include_mcc/component/ptc.h create mode 100644 core/arm/samd21a/include_mcc/component/rtc.h create mode 100644 core/arm/samd21a/include_mcc/component/sercom.h create mode 100644 core/arm/samd21a/include_mcc/component/sysctrl.h create mode 100644 core/arm/samd21a/include_mcc/component/tc.h create mode 100644 core/arm/samd21a/include_mcc/component/tcc.h create mode 100644 core/arm/samd21a/include_mcc/component/usb.h create mode 100644 core/arm/samd21a/include_mcc/component/wdt.h create mode 100644 core/arm/samd21a/include_mcc/pio/samd21e18a.h create mode 100644 core/arm/samd21a/include_mcc/sam.h create mode 100644 core/arm/samd21a/include_mcc/samd21e18a.h create mode 100644 core/arm/samd21a/include_mcc/system_samd21.h create mode 100644 core/arm/samd21a/keil/Flash/ATSAMD21_128.FLM create mode 100644 core/arm/samd21a/keil/Flash/ATSAMD21_256.FLM create mode 100644 core/arm/samd21a/keil/Flash/ATSAMD21_32.FLM create mode 100644 core/arm/samd21a/keil/Flash/ATSAMD21_64.FLM create mode 100644 core/arm/samd21a/svd/ATSAMD21E18A.svd diff --git a/core/arm/CMSIS/Core/Include/cmsis_armcc.h b/core/arm/CMSIS/Core/Include/cmsis_armcc.h new file mode 100644 index 000000000..7d751fb3a --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_armcc.h @@ -0,0 +1,865 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler ARMCC (Arm Compiler 5) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if ((defined (__TARGET_ARCH_6_M ) && (__TARGET_ARCH_6_M == 1)) || \ + (defined (__TARGET_ARCH_6S_M ) && (__TARGET_ARCH_6S_M == 1)) ) + #define __ARM_ARCH_6M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7_M ) && (__TARGET_ARCH_7_M == 1)) + #define __ARM_ARCH_7M__ 1 +#endif + +#if (defined (__TARGET_ARCH_7E_M) && (__TARGET_ARCH_7E_M == 1)) + #define __ARM_ARCH_7EM__ 1 +#endif + + /* __ARM_ARCH_8M_BASE__ not applicable */ + /* __ARM_ARCH_8M_MAIN__ not applicable */ + + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION __packed union +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #define __UNALIGNED_UINT32(x) (*((__packed uint32_t *)(x))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); */ + +/** + \brief Get Control Register + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 + \details 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 ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief Enable FIQ + \details 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 + \details 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 + \details 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 + \details 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 & 0xFFU); +} + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_INLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + register uint32_t __regBasePriMax __ASM("basepri_max"); + __regBasePriMax = (basePri & 0xFFU); +} + + +/** + \brief Get Fault Mask + \details 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 + \details 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)1U); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details 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 ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details 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 ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __nop + + +/** + \brief Wait For Interrupt + \details 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 + \details 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 + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __sev + + +/** + \brief Instruction Synchronization Barrier + \details 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() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + #define __RBIT __rbit +#else +__attribute__((always_inline)) __STATIC_INLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ + return result; +} +#endif + + +/** + \brief Count leading zeros + \details 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 + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details 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 + \details 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 Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rrx_text"))) __STATIC_INLINE __ASM uint32_t __RRX(uint32_t value) +{ + rrx r0, r0 + bx lr +} +#endif + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDRBT(ptr) ((uint8_t ) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDRHT(ptr) ((uint16_t) __ldrt(ptr)) + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDRT(ptr) ((uint32_t ) __ldrt(ptr)) + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRBT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRHT(value, ptr) __strt(value, ptr) + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +#define __STRT(value, ptr) __strt(value, ptr) + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__attribute__((always_inline)) __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) + +#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) ) + +#define __SMMLA(ARG1,ARG2,ARG3) ( (int32_t)((((int64_t)(ARG1) * (ARG2)) + \ + ((int64_t)(ARG3) << 32U) ) >> 32U)) + +#endif /* ((defined (__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ == 1)) ) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCC_H */ diff --git a/core/arm/CMSIS/Core/Include/cmsis_armclang.h b/core/arm/CMSIS/Core/Include/cmsis_armclang.h new file mode 100644 index 000000000..d8031b030 --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_armclang.h @@ -0,0 +1,1869 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler armclang (Arm Compiler 6) header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/*lint -esym(9058, IRQn)*/ /* disable MISRA 2012 Rule 2.4 for IRQn */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32 */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_READ */ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __enable_irq(); see arm_compat.h */ + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +/* intrinsic void __disable_irq(); see arm_compat.h */ + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __enable_fault_irq __enable_fiq /* see arm_compat.h */ + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +#define __disable_fault_irq __disable_fiq /* see arm_compat.h */ + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __get_FPSCR (uint32_t)__builtin_arm_get_fpscr +#else +#define __get_FPSCR() ((uint32_t)0U) +#endif + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#define __set_FPSCR __builtin_arm_set_fpscr +#else +#define __set_FPSCR(x) ((void)(x)) +#endif + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI __builtin_arm_wfi + + +/** + \brief Wait For Event + \details 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 __builtin_arm_wfe + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV __builtin_arm_sev + + +/** + \brief Instruction Synchronization Barrier + \details 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() __builtin_arm_isb(0xF); + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +#define __DSB() __builtin_arm_dsb(0xF); + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +#define __DMB() __builtin_arm_dmb(0xF); + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \details 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 (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + +/** + \brief Signed Saturate + \details 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 __builtin_arm_ssat + + +/** + \brief Unsigned Saturate + \details 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 __builtin_arm_usat + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDAEXB (uint8_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDAEXH (uint16_t)__builtin_arm_ldaex + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDAEX (uint32_t)__builtin_arm_ldaex + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction 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 __STLEXB (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction 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 __STLEXH (uint32_t)__builtin_arm_stlex + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction 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 __STLEX (uint32_t)__builtin_arm_stlex + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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) \ +({ \ + int32_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; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#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; \ + }) +#endif + +#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) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/core/arm/CMSIS/Core/Include/cmsis_compiler.h b/core/arm/CMSIS/Core/Include/cmsis_compiler.h new file mode 100644 index 000000000..79a2cac36 --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_compiler.h @@ -0,0 +1,266 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler generic header file + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed)) + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed)) + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void*)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * 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. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __packed__ + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION union __packed__ + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + #ifndef __PACKED_STRUCT + #define __PACKED_STRUCT @packed struct + #endif + #ifndef __PACKED_UNION + #define __PACKED_UNION @packed union + #endif + #ifndef __UNALIGNED_UINT32 /* deprecated */ + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __UNALIGNED_UINT16_WRITE + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT16_READ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) + #endif + #ifndef __UNALIGNED_UINT32_WRITE + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) + #endif + #ifndef __UNALIGNED_UINT32_READ + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __RESTRICT + #warning No compiler specific solution for __RESTRICT. __RESTRICT is ignored. + #define __RESTRICT + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/core/arm/CMSIS/Core/Include/cmsis_gcc.h b/core/arm/CMSIS/Core/Include/cmsis_gcc.h new file mode 100644 index 000000000..1bd41a495 --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_gcc.h @@ -0,0 +1,2085 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler GCC header file + * @version V5.0.4 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_UNION + #define __PACKED_UNION union __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + #pragma GCC diagnostic ignored "-Wattributes" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + + +/* ########################### Core Function Access ########################### */ +/** \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_RegAccFunctions CMSIS Core Register Access Functions + @{ + */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + + +/** + \brief Get Control Register + \details Returns the content of the Control Register. + \return Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CONTROL(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Control Register (non-secure) + \details Returns the content of the non-secure Control Register when in secure mode. + \return non-secure Control Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_CONTROL_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, control_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Control Register + \details Writes the given value to the Control Register. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __set_CONTROL(uint32_t control) +{ + __ASM volatile ("MSR control, %0" : : "r" (control) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Control Register (non-secure) + \details Writes the given value to the non-secure Control Register when in secure state. + \param [in] control Control Register value to set + */ +__STATIC_FORCEINLINE void __TZ_set_CONTROL_NS(uint32_t control) +{ + __ASM volatile ("MSR control_ns, %0" : : "r" (control) : "memory"); +} +#endif + + +/** + \brief Get IPSR Register + \details Returns the content of the IPSR Register. + \return IPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, ipsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get APSR Register + \details Returns the content of the APSR Register. + \return APSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_APSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, apsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get xPSR Register + \details Returns the content of the xPSR Register. + \return xPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_xPSR(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, xpsr" : "=r" (result) ); + return(result); +} + + +/** + \brief Get Process Stack Pointer + \details Returns the current value of the Process Stack Pointer (PSP). + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer (non-secure) + \details Returns the current value of the non-secure Process Stack Pointer (PSP) when in secure state. + \return PSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, psp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Process Stack Pointer + \details Assigns the given value to the Process Stack Pointer (PSP). + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_PSP(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp, %0" : : "r" (topOfProcStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Process Stack Pointer (PSP) when in secure state. + \param [in] topOfProcStack Process Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSP_NS(uint32_t topOfProcStack) +{ + __ASM volatile ("MSR psp_ns, %0" : : "r" (topOfProcStack) : ); +} +#endif + + +/** + \brief Get Main Stack Pointer + \details Returns the current value of the Main Stack Pointer (MSP). + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSP(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer (non-secure) + \details Returns the current value of the non-secure Main Stack Pointer (MSP) when in secure state. + \return MSP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, msp_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Main Stack Pointer + \details Assigns the given value to the Main Stack Pointer (MSP). + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_MSP(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp, %0" : : "r" (topOfMainStack) : ); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Main Stack Pointer (MSP) when in secure state. + \param [in] topOfMainStack Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSP_NS(uint32_t topOfMainStack) +{ + __ASM volatile ("MSR msp_ns, %0" : : "r" (topOfMainStack) : ); +} +#endif + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Stack Pointer (non-secure) + \details Returns the current value of the non-secure Stack Pointer (SP) when in secure state. + \return SP Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_SP_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, sp_ns" : "=r" (result) ); + return(result); +} + + +/** + \brief Set Stack Pointer (non-secure) + \details Assigns the given value to the non-secure Stack Pointer (SP) when in secure state. + \param [in] topOfStack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_SP_NS(uint32_t topOfStack) +{ + __ASM volatile ("MSR sp_ns, %0" : : "r" (topOfStack) : ); +} +#endif + + +/** + \brief Get Priority Mask + \details Returns the current state of the priority mask bit from the Priority Mask Register. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __get_PRIMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask" : "=r" (result) :: "memory"); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Priority Mask (non-secure) + \details Returns the current state of the non-secure priority mask bit from the Priority Mask Register when in secure state. + \return Priority Mask value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PRIMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, primask_ns" : "=r" (result) :: "memory"); + return(result); +} +#endif + + +/** + \brief Set Priority Mask + \details Assigns the given value to the Priority Mask Register. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __set_PRIMASK(uint32_t priMask) +{ + __ASM volatile ("MSR primask, %0" : : "r" (priMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Priority Mask (non-secure) + \details Assigns the given value to the non-secure Priority Mask Register when in secure state. + \param [in] priMask Priority Mask + */ +__STATIC_FORCEINLINE void __TZ_set_PRIMASK_NS(uint32_t priMask) +{ + __ASM volatile ("MSR primask_ns, %0" : : "r" (priMask) : "memory"); +} +#endif + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Enable FIQ + \details Enables FIQ interrupts by clearing the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_fault_irq(void) +{ + __ASM volatile ("cpsie f" : : : "memory"); +} + + +/** + \brief Disable FIQ + \details Disables FIQ interrupts by setting the F-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_fault_irq(void) +{ + __ASM volatile ("cpsid f" : : : "memory"); +} + + +/** + \brief Get Base Priority + \details Returns the current value of the Base Priority register. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __get_BASEPRI(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Base Priority (non-secure) + \details Returns the current value of the non-secure Base Priority register when in secure state. + \return Base Priority register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_BASEPRI_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, basepri_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Base Priority + \details Assigns the given value to the Base Priority register. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI(uint32_t basePri) +{ + __ASM volatile ("MSR basepri, %0" : : "r" (basePri) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Base Priority (non-secure) + \details Assigns the given value to the non-secure Base Priority register when in secure state. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __TZ_set_BASEPRI_NS(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_ns, %0" : : "r" (basePri) : "memory"); +} +#endif + + +/** + \brief Set Base Priority with condition + \details Assigns the given value to the Base Priority register only if BASEPRI masking is disabled, + or the new value increases the BASEPRI priority level. + \param [in] basePri Base Priority value to set + */ +__STATIC_FORCEINLINE void __set_BASEPRI_MAX(uint32_t basePri) +{ + __ASM volatile ("MSR basepri_max, %0" : : "r" (basePri) : "memory"); +} + + +/** + \brief Get Fault Mask + \details Returns the current value of the Fault Mask register. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __get_FAULTMASK(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask" : "=r" (result) ); + return(result); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Fault Mask (non-secure) + \details Returns the current value of the non-secure Fault Mask register when in secure state. + \return Fault Mask register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_FAULTMASK_NS(void) +{ + uint32_t result; + + __ASM volatile ("MRS %0, faultmask_ns" : "=r" (result) ); + return(result); +} +#endif + + +/** + \brief Set Fault Mask + \details Assigns the given value to the Fault Mask register. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __set_FAULTMASK(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask, %0" : : "r" (faultMask) : "memory"); +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Fault Mask (non-secure) + \details Assigns the given value to the non-secure Fault Mask register when in secure state. + \param [in] faultMask Fault Mask value to set + */ +__STATIC_FORCEINLINE void __TZ_set_FAULTMASK_NS(uint32_t faultMask) +{ + __ASM volatile ("MSR faultmask_ns, %0" : : "r" (faultMask) : "memory"); +} +#endif + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + +/** + \brief Get Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Process Stack Pointer Limit (PSPLIM). + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_PSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim" : "=r" (result) ); + return result; +#endif +} + +#if (defined (__ARM_FEATURE_CMSE) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Process Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \return PSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_PSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, psplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Process Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Process Stack Pointer Limit (PSPLIM). + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_PSPLIM(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim, %0" : : "r" (ProcStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Process Stack Pointer (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Process Stack Pointer Limit (PSPLIM) when in secure state. + \param [in] ProcStackPtrLimit Process Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __TZ_set_PSPLIM_NS(uint32_t ProcStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)ProcStackPtrLimit; +#else + __ASM volatile ("MSR psplim_ns, %0\n" : : "r" (ProcStackPtrLimit)); +#endif +} +#endif + + +/** + \brief Get Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always in non-secure + mode. + + \details Returns the current value of the Main Stack Pointer Limit (MSPLIM). + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MSPLIM(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim" : "=r" (result) ); + return result; +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Get Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence zero is returned always. + + \details Returns the current value of the non-secure Main Stack Pointer Limit(MSPLIM) when in secure state. + \return MSPLIM Register value + */ +__STATIC_FORCEINLINE uint32_t __TZ_get_MSPLIM_NS(void) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + return 0U; +#else + uint32_t result; + __ASM volatile ("MRS %0, msplim_ns" : "=r" (result) ); + return result; +#endif +} +#endif + + +/** + \brief Set Main Stack Pointer Limit + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored in non-secure + mode. + + \details Assigns the given value to the Main Stack Pointer Limit (MSPLIM). + \param [in] MainStackPtrLimit Main Stack Pointer Limit value to set + */ +__STATIC_FORCEINLINE void __set_MSPLIM(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim, %0" : : "r" (MainStackPtrLimit)); +#endif +} + + +#if (defined (__ARM_FEATURE_CMSE ) && (__ARM_FEATURE_CMSE == 3)) +/** + \brief Set Main Stack Pointer Limit (non-secure) + Devices without ARMv8-M Main Extensions (i.e. Cortex-M23) lack the non-secure + Stack Pointer Limit register hence the write is silently ignored. + + \details Assigns the given value to the non-secure Main Stack Pointer Limit (MSPLIM) when in secure state. + \param [in] MainStackPtrLimit Main Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __TZ_set_MSPLIM_NS(uint32_t MainStackPtrLimit) +{ +#if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)MainStackPtrLimit; +#else + __ASM volatile ("MSR msplim_ns, %0" : : "r" (MainStackPtrLimit)); +#endif +} +#endif + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_get_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); +#else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); +#endif +#else + return(0U); +#endif +} + + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) +#if __has_builtin(__builtin_arm_set_fpscr) +// Re-enable using built-in when GCC has been fixed +// || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); +#else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); +#endif +#else + (void)fpscr; +#endif +} + + +/*@} end of CMSIS_Core_RegAccFunctions */ + + +/* ########################## Core Instruction Access ######################### */ +/** \defgroup CMSIS_Core_InstructionInterface CMSIS Core Instruction Interface + Access to dedicated instructions + @{ +*/ + +/* Define macros for porting to both thumb1 and thumb2. + * For thumb1, use low register (r0-r7), specified by constraint "l" + * Otherwise, use general registers, specified by constraint "r" */ +#if defined (__thumb__) && !defined (__thumb2__) +#define __CMSIS_GCC_OUT_REG(r) "=l" (r) +#define __CMSIS_GCC_RW_REG(r) "+l" (r) +#define __CMSIS_GCC_USE_REG(r) "l" (r) +#else +#define __CMSIS_GCC_OUT_REG(r) "=r" (r) +#define __CMSIS_GCC_RW_REG(r) "+r" (r) +#define __CMSIS_GCC_USE_REG(r) "r" (r) +#endif + +/** + \brief No Operation + \details No Operation does nothing. This instruction can be used for code alignment purposes. + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + \details Wait For Interrupt is a hint instruction that suspends execution until one of a number of events occurs. + */ +#define __WFI() __ASM volatile ("wfi") + + +/** + \brief Wait For Event + \details 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() __ASM volatile ("wfe") + + +/** + \brief Send Event + \details Send Event is a hint instruction. It causes an event to be signaled to the CPU. + */ +#define __SEV() __ASM volatile ("sev") + + +/** + \brief Instruction Synchronization Barrier + \details 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. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rev16 %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +} + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \details Causes the processor to enter Debug state. + Debug tools can use this to investigate system state when the instruction at a particular address is reached. + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + uint32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value != 0U; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + + +/** + \brief Count leading zeros + \details 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 (uint8_t)__builtin_clz + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (1..32) + \return Saturated value + */ +#define __SSAT(ARG1,ARG2) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] ARG1 Value to be saturated + \param [in] ARG2 Bit position to saturate to (0..31) + \return Saturated value + */ +#define __USAT(ARG1,ARG2) \ + __extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Rotate Right with Extend (32 bit) + \details Moves each bit of a bitstring right by one bit. + The carry input is shifted in at the left end of the bitstring. + \param [in] value Value to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __RRX(uint32_t value) +{ + uint32_t result; + + __ASM volatile ("rrx %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return(result); +} + + +/** + \brief LDRT Unprivileged (8 bit) + \details Executes a Unprivileged LDRT instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDRBT(volatile uint8_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrbt %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrbt %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (16 bit) + \details Executes a Unprivileged LDRT instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDRHT(volatile uint16_t *ptr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrht %0, %1" : "=r" (result) : "Q" (*ptr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrht %0, [%1]" : "=r" (result) : "r" (ptr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDRT Unprivileged (32 bit) + \details Executes a Unprivileged LDRT instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDRT(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldrt %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief STRT Unprivileged (8 bit) + \details Executes a Unprivileged STRT instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRBT(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("strbt %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (16 bit) + \details Executes a Unprivileged STRT instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRHT(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("strht %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief STRT Unprivileged (32 bit) + \details Executes a Unprivileged STRT instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STRT(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("strt %1, %0" : "=Q" (*ptr) : "r" (value) ); +} + +#else /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + +/** + \brief Signed Saturate + \details Saturates a signed value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (1..32) + \return Saturated value + */ +__STATIC_FORCEINLINE int32_t __SSAT(int32_t val, uint32_t sat) +{ + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; +} + +/** + \brief Unsigned Saturate + \details Saturates an unsigned value. + \param [in] value Value to be saturated + \param [in] sat Bit position to saturate to (0..31) + \return Saturated value + */ +__STATIC_FORCEINLINE uint32_t __USAT(int32_t val, uint32_t sat) +{ + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; +} + +#endif /* ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) */ + + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) +/** + \brief Load-Acquire (8 bit) + \details Executes a LDAB instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldab %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire (16 bit) + \details Executes a LDAH instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldah %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire (32 bit) + \details Executes a LDA instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDA(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("lda %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release (8 bit) + \details Executes a STLB instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLB(uint8_t value, volatile uint8_t *ptr) +{ + __ASM volatile ("stlb %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (16 bit) + \details Executes a STLH instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STLH(uint16_t value, volatile uint16_t *ptr) +{ + __ASM volatile ("stlh %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Store-Release (32 bit) + \details Executes a STL instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + */ +__STATIC_FORCEINLINE void __STL(uint32_t value, volatile uint32_t *ptr) +{ + __ASM volatile ("stl %1, %0" : "=Q" (*ptr) : "r" ((uint32_t)value) ); +} + + +/** + \brief Load-Acquire Exclusive (8 bit) + \details Executes a LDAB exclusive instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDAEXB(volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexb %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint8_t) result); +} + + +/** + \brief Load-Acquire Exclusive (16 bit) + \details Executes a LDAH exclusive instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDAEXH(volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaexh %0, %1" : "=r" (result) : "Q" (*ptr) ); + return ((uint16_t) result); +} + + +/** + \brief Load-Acquire Exclusive (32 bit) + \details Executes a LDA exclusive instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDAEX(volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("ldaex %0, %1" : "=r" (result) : "Q" (*ptr) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (8 bit) + \details Executes a STLB exclusive instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexb %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (16 bit) + \details Executes a STLH exclusive instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlexh %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief Store-Release Exclusive (32 bit) + \details Executes a STL exclusive instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) +{ + uint32_t result; + + __ASM volatile ("stlex %0, %2, %1" : "=&r" (result), "=Q" (*ptr) : "r" ((uint32_t)value) ); + return(result); +} + +#endif /* ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) */ + +/*@}*/ /* end of group CMSIS_Core_InstructionInterface */ + + +/* ################### Compiler specific Intrinsics ########################### */ +/** \defgroup CMSIS_SIMD_intrinsics CMSIS SIMD Intrinsics + Access to dedicated SIMD instructions + @{ +*/ + +#if (defined (__ARM_FEATURE_DSP) && (__ARM_FEATURE_DSP == 1)) + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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) \ +({ \ + int32_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; \ + }) + +__STATIC_FORCEINLINE uint32_t __UXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("uxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint32_t __SXTB16(uint32_t op1) +{ + uint32_t result; + + __ASM volatile ("sxtb16 %0, %1" : "=r" (result) : "r" (op1)); + return(result); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint64_t __SMLALD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlald %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLALDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlaldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLD (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsld %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE uint64_t __SMLSLDX (uint32_t op1, uint32_t op2, uint64_t acc) +{ + union llreg_u{ + uint32_t w32[2]; + uint64_t w64; + } llr; + llr.w64 = acc; + +#ifndef __ARMEB__ /* Little endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[0]), "=r" (llr.w32[1]): "r" (op1), "r" (op2) , "0" (llr.w32[0]), "1" (llr.w32[1]) ); +#else /* Big endian */ + __ASM volatile ("smlsldx %0, %1, %2, %3" : "=r" (llr.w32[1]), "=r" (llr.w32[0]): "r" (op1), "r" (op2) , "0" (llr.w32[1]), "1" (llr.w32[0]) ); +#endif + + return(llr.w64); +} + +__STATIC_FORCEINLINE 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); +} + +__STATIC_FORCEINLINE int32_t __QADD( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qadd %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +__STATIC_FORCEINLINE int32_t __QSUB( int32_t op1, int32_t op2) +{ + int32_t result; + + __ASM volatile ("qsub %0, %1, %2" : "=r" (result) : "r" (op1), "r" (op2) ); + return(result); +} + +#if 0 +#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; \ + }) +#endif + +#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) ) + +__STATIC_FORCEINLINE int32_t __SMMLA (int32_t op1, int32_t op2, int32_t op3) +{ + int32_t result; + + __ASM volatile ("smmla %0, %1, %2, %3" : "=r" (result): "r" (op1), "r" (op2), "r" (op3) ); + return(result); +} + +#endif /* (__ARM_FEATURE_DSP == 1) */ +/*@} end of group CMSIS_SIMD_intrinsics */ + + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/core/arm/CMSIS/Core/Include/cmsis_iccarm.h b/core/arm/CMSIS/Core/Include/cmsis_iccarm.h new file mode 100644 index 000000000..3c90a2cdc --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_iccarm.h @@ -0,0 +1,935 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.7 + * @date 19. June 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_6M__ || __ARM_ARCH_7M__ || __ARM_ARCH_7EM__ || __ARM_ARCH_8M_BASE__ || __ARM_ARCH_8M_MAIN__ +/* Macros already defined */ +#else + #if defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM_ARCH_PROFILE) && __ARM_ARCH_PROFILE == 'M' + #if __ARM_ARCH == 6 + #define __ARM_ARCH_6M__ 1 + #elif __ARM_ARCH == 7 + #if __ARM_FEATURE_DSP + #define __ARM_ARCH_7EM__ 1 + #else + #define __ARM_ARCH_7M__ 1 + #endif + #endif /* __ARM_ARCH */ + #endif /* __ARM_ARCH_PROFILE == 'M' */ +#endif + +/* Alternativ core deduction for older ICCARM's */ +#if !defined(__ARM_ARCH_6M__) && !defined(__ARM_ARCH_7M__) && !defined(__ARM_ARCH_7EM__) && \ + !defined(__ARM_ARCH_8M_BASE__) && !defined(__ARM_ARCH_8M_MAIN__) + #if defined(__ARM6M__) && (__CORE__ == __ARM6M__) + #define __ARM_ARCH_6M__ 1 + #elif defined(__ARM7M__) && (__CORE__ == __ARM7M__) + #define __ARM_ARCH_7M__ 1 + #elif defined(__ARM7EM__) && (__CORE__ == __ARM7EM__) + #define __ARM_ARCH_7EM__ 1 + #elif defined(__ARM8M_BASELINE__) && (__CORE == __ARM8M_BASELINE__) + #define __ARM_ARCH_8M_BASE__ 1 + #elif defined(__ARM8M_MAINLINE__) && (__CORE == __ARM8M_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #elif defined(__ARM8EM_MAINLINE__) && (__CORE == __ARM8EM_MAINLINE__) + #define __ARM_ARCH_8M_MAIN__ 1 + #else + #error "Unknown target." + #endif +#endif + + + +#if defined(__ARM_ARCH_6M__) && __ARM_ARCH_6M__==1 + #define __IAR_M0_FAMILY 1 +#elif defined(__ARM_ARCH_8M_BASE__) && __ARM_ARCH_8M_BASE__==1 + #define __IAR_M0_FAMILY 1 +#else + #define __IAR_M0_FAMILY 0 +#endif + + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + /* Needs IAR language extensions */ + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef __UNALIGNED_UINT16_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint16_t __iar_uint16_read(void const *ptr) +{ + return *(__packed uint16_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) +{ + *(__packed uint16_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ +#pragma language=save +#pragma language=extended +__IAR_FT uint32_t __iar_uint32_read(void const *ptr) +{ + return *(__packed uint32_t*)(ptr); +} +#pragma language=restore +#define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE +#pragma language=save +#pragma language=extended +__IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) +{ + *(__packed uint32_t*)(ptr) = val;; +} +#pragma language=restore +#define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32 /* deprecated */ +#pragma language=save +#pragma language=extended +__packed struct __iar_u32 { uint32_t v; }; +#pragma language=restore +#define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __enable_irq __iar_builtin_enable_interrupt + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + + #define __get_APSR() (__arm_rsr("APSR")) + #define __get_BASEPRI() (__arm_rsr("BASEPRI")) + #define __get_CONTROL() (__arm_rsr("CONTROL")) + #define __get_FAULTMASK() (__arm_rsr("FAULTMASK")) + + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", (VALUE))) + #else + #define __get_FPSCR() ( 0 ) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #define __get_IPSR() (__arm_rsr("IPSR")) + #define __get_MSP() (__arm_rsr("MSP")) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __get_MSPLIM() (0U) + #else + #define __get_MSPLIM() (__arm_rsr("MSPLIM")) + #endif + #define __get_PRIMASK() (__arm_rsr("PRIMASK")) + #define __get_PSP() (__arm_rsr("PSP")) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __get_PSPLIM() (0U) + #else + #define __get_PSPLIM() (__arm_rsr("PSPLIM")) + #endif + + #define __get_xPSR() (__arm_rsr("xPSR")) + + #define __set_BASEPRI(VALUE) (__arm_wsr("BASEPRI", (VALUE))) + #define __set_BASEPRI_MAX(VALUE) (__arm_wsr("BASEPRI_MAX", (VALUE))) + #define __set_CONTROL(VALUE) (__arm_wsr("CONTROL", (VALUE))) + #define __set_FAULTMASK(VALUE) (__arm_wsr("FAULTMASK", (VALUE))) + #define __set_MSP(VALUE) (__arm_wsr("MSP", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + #define __set_MSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_MSPLIM(VALUE) (__arm_wsr("MSPLIM", (VALUE))) + #endif + #define __set_PRIMASK(VALUE) (__arm_wsr("PRIMASK", (VALUE))) + #define __set_PSP(VALUE) (__arm_wsr("PSP", (VALUE))) + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __set_PSPLIM(VALUE) ((void)(VALUE)) + #else + #define __set_PSPLIM(VALUE) (__arm_wsr("PSPLIM", (VALUE))) + #endif + + #define __TZ_get_CONTROL_NS() (__arm_rsr("CONTROL_NS")) + #define __TZ_set_CONTROL_NS(VALUE) (__arm_wsr("CONTROL_NS", (VALUE))) + #define __TZ_get_PSP_NS() (__arm_rsr("PSP_NS")) + #define __TZ_set_PSP_NS(VALUE) (__arm_wsr("PSP_NS", (VALUE))) + #define __TZ_get_MSP_NS() (__arm_rsr("MSP_NS")) + #define __TZ_set_MSP_NS(VALUE) (__arm_wsr("MSP_NS", (VALUE))) + #define __TZ_get_SP_NS() (__arm_rsr("SP_NS")) + #define __TZ_set_SP_NS(VALUE) (__arm_wsr("SP_NS", (VALUE))) + #define __TZ_get_PRIMASK_NS() (__arm_rsr("PRIMASK_NS")) + #define __TZ_set_PRIMASK_NS(VALUE) (__arm_wsr("PRIMASK_NS", (VALUE))) + #define __TZ_get_BASEPRI_NS() (__arm_rsr("BASEPRI_NS")) + #define __TZ_set_BASEPRI_NS(VALUE) (__arm_wsr("BASEPRI_NS", (VALUE))) + #define __TZ_get_FAULTMASK_NS() (__arm_rsr("FAULTMASK_NS")) + #define __TZ_set_FAULTMASK_NS(VALUE)(__arm_wsr("FAULTMASK_NS", (VALUE))) + + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + #define __TZ_get_PSPLIM_NS() (0U) + #define __TZ_set_PSPLIM_NS(VALUE) ((void)(VALUE)) + #else + #define __TZ_get_PSPLIM_NS() (__arm_rsr("PSPLIM_NS")) + #define __TZ_set_PSPLIM_NS(VALUE) (__arm_wsr("PSPLIM_NS", (VALUE))) + #endif + + #define __TZ_get_MSPLIM_NS() (__arm_rsr("MSPLIM_NS")) + #define __TZ_set_MSPLIM_NS(VALUE) (__arm_wsr("MSPLIM_NS", (VALUE))) + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #if !__IAR_M0_FAMILY + #define __SSAT __iar_builtin_SSAT + #endif + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #if !__IAR_M0_FAMILY + #define __USAT __iar_builtin_USAT + #endif + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #if __ARM_MEDIA__ + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + #endif + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #define __CLZ __cmsis_iar_clz_not_active + #define __SSAT __cmsis_iar_ssat_not_active + #define __USAT __cmsis_iar_usat_not_active + #define __RBIT __cmsis_iar_rbit_not_active + #define __get_APSR __cmsis_iar_get_APSR_not_active + #endif + + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #define __set_FPSCR __cmsis_iar_set_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if __IAR_M0_FAMILY + /* Avoid clash between intrinsics.h and arm_math.h when compiling for Cortex-M0. */ + #undef __CLZ + #undef __SSAT + #undef __USAT + #undef __RBIT + #undef __get_APSR + + __STATIC_INLINE uint8_t __CLZ(uint32_t data) + { + if (data == 0U) { return 32U; } + + uint32_t count = 0U; + uint32_t mask = 0x80000000U; + + while ((data & mask) == 0U) + { + count += 1U; + mask = mask >> 1U; + } + return count; + } + + __STATIC_INLINE uint32_t __RBIT(uint32_t v) + { + uint8_t sc = 31U; + uint32_t r = v; + for (v >>= 1U; v; v >>= 1U) + { + r <<= 1U; + r |= v & 1U; + sc--; + } + return (r << sc); + } + + __STATIC_INLINE uint32_t __get_APSR(void) + { + uint32_t res; + __asm("MRS %0,APSR" : "=r" (res)); + return res; + } + + #endif + + #if (!((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) )) + #undef __get_FPSCR + #undef __set_FPSCR + #define __get_FPSCR() (0) + #define __set_FPSCR(VALUE) ((void)VALUE) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + #if (!defined(__ARM_ARCH_6M__) || __ARM_ARCH_6M__==0) + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + #endif + + + /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + #if (__CORTEX_M >= 0x03) + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + __IAR_FT void __set_BASEPRI_MAX(uint32_t value) + { + __asm volatile("MSR BASEPRI_MAX,%0"::"r" (value)); + } + + + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + + + #endif /* (__CORTEX_M >= 0x03) */ + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + #if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + __IAR_FT uint32_t __get_MSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,MSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_MSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure MSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR MSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __get_PSPLIM(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __set_PSPLIM(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_CONTROL_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,CONTROL_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_CONTROL_NS(uint32_t value) + { + __asm volatile("MSR CONTROL_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PSP_NS(uint32_t value) + { + __asm volatile("MSR PSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_MSP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSP_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSP_NS(uint32_t value) + { + __asm volatile("MSR MSP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_SP_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,SP_NS" : "=r" (res)); + return res; + } + __IAR_FT void __TZ_set_SP_NS(uint32_t value) + { + __asm volatile("MSR SP_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PRIMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,PRIMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_PRIMASK_NS(uint32_t value) + { + __asm volatile("MSR PRIMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_BASEPRI_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,BASEPRI_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_BASEPRI_NS(uint32_t value) + { + __asm volatile("MSR BASEPRI_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_FAULTMASK_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,FAULTMASK_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_FAULTMASK_NS(uint32_t value) + { + __asm volatile("MSR FAULTMASK_NS,%0" :: "r" (value)); + } + + __IAR_FT uint32_t __TZ_get_PSPLIM_NS(void) + { + uint32_t res; + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + res = 0U; + #else + __asm volatile("MRS %0,PSPLIM_NS" : "=r" (res)); + #endif + return res; + } + + __IAR_FT void __TZ_set_PSPLIM_NS(uint32_t value) + { + #if (!(defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) && \ + (!defined (__ARM_FEATURE_CMSE ) || (__ARM_FEATURE_CMSE < 3))) + // without main extensions, the non-secure PSPLIM is RAZ/WI + (void)value; + #else + __asm volatile("MSR PSPLIM_NS,%0" :: "r" (value)); + #endif + } + + __IAR_FT uint32_t __TZ_get_MSPLIM_NS(void) + { + uint32_t res; + __asm volatile("MRS %0,MSPLIM_NS" : "=r" (res)); + return res; + } + + __IAR_FT void __TZ_set_MSPLIM_NS(uint32_t value) + { + __asm volatile("MSR MSPLIM_NS,%0" :: "r" (value)); + } + + #endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + +#if __IAR_M0_FAMILY + __STATIC_INLINE int32_t __SSAT(int32_t val, uint32_t sat) + { + if ((sat >= 1U) && (sat <= 32U)) + { + const int32_t max = (int32_t)((1U << (sat - 1U)) - 1U); + const int32_t min = -1 - max ; + if (val > max) + { + return max; + } + else if (val < min) + { + return min; + } + } + return val; + } + + __STATIC_INLINE uint32_t __USAT(int32_t val, uint32_t sat) + { + if (sat <= 31U) + { + const uint32_t max = ((1U << sat) - 1U); + if (val > (int32_t)max) + { + return max; + } + else if (val < 0) + { + return 0U; + } + } + return (uint32_t)val; + } +#endif + +#if (__CORTEX_M >= 0x03) /* __CORTEX_M is defined in core_cm0.h, core_cm3.h and core_cm4.h. */ + + __IAR_FT uint8_t __LDRBT(volatile uint8_t *addr) + { + uint32_t res; + __ASM("LDRBT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDRHT(volatile uint16_t *addr) + { + uint32_t res; + __ASM("LDRHT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDRT(volatile uint32_t *addr) + { + uint32_t res; + __ASM("LDRT %0, [%1]" : "=r" (res) : "r" (addr) : "memory"); + return res; + } + + __IAR_FT void __STRBT(uint8_t value, volatile uint8_t *addr) + { + __ASM("STRBT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRHT(uint16_t value, volatile uint16_t *addr) + { + __ASM("STRHT %1, [%0]" : : "r" (addr), "r" ((uint32_t)value) : "memory"); + } + + __IAR_FT void __STRT(uint32_t value, volatile uint32_t *addr) + { + __ASM("STRT %1, [%0]" : : "r" (addr), "r" (value) : "memory"); + } + +#endif /* (__CORTEX_M >= 0x03) */ + +#if ((defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) || \ + (defined (__ARM_ARCH_8M_BASE__ ) && (__ARM_ARCH_8M_BASE__ == 1)) ) + + + __IAR_FT uint8_t __LDAB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDA(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDA %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT void __STLB(uint8_t value, volatile uint8_t *ptr) + { + __ASM volatile ("STLB %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STLH(uint16_t value, volatile uint16_t *ptr) + { + __ASM volatile ("STLH %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT void __STL(uint32_t value, volatile uint32_t *ptr) + { + __ASM volatile ("STL %1, [%0]" :: "r" (ptr), "r" (value) : "memory"); + } + + __IAR_FT uint8_t __LDAEXB(volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXB %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint8_t)res); + } + + __IAR_FT uint16_t __LDAEXH(volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEXH %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return ((uint16_t)res); + } + + __IAR_FT uint32_t __LDAEX(volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("LDAEX %0, [%1]" : "=r" (res) : "r" (ptr) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXB(uint8_t value, volatile uint8_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXB %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEXH(uint16_t value, volatile uint16_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEXH %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + + __IAR_FT uint32_t __STLEX(uint32_t value, volatile uint32_t *ptr) + { + uint32_t res; + __ASM volatile ("STLEX %0, %2, [%1]" : "=r" (res) : "r" (ptr), "r" (value) : "memory"); + return res; + } + +#endif /* __ARM_ARCH_8M_MAIN__ or __ARM_ARCH_8M_BASE__ */ + +#undef __IAR_FT +#undef __IAR_M0_FAMILY +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/core/arm/CMSIS/Core/Include/cmsis_version.h b/core/arm/CMSIS/Core/Include/cmsis_version.h new file mode 100644 index 000000000..ae3f2e33d --- /dev/null +++ b/core/arm/CMSIS/Core/Include/cmsis_version.h @@ -0,0 +1,39 @@ +/**************************************************************************//** + * @file cmsis_version.h + * @brief CMSIS Core(M) Version definitions + * @version V5.0.2 + * @date 19. April 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_VERSION_H +#define __CMSIS_VERSION_H + +/* CMSIS Version definitions */ +#define __CM_CMSIS_VERSION_MAIN ( 5U) /*!< [31:16] CMSIS Core(M) main version */ +#define __CM_CMSIS_VERSION_SUB ( 1U) /*!< [15:0] CMSIS Core(M) sub version */ +#define __CM_CMSIS_VERSION ((__CM_CMSIS_VERSION_MAIN << 16U) | \ + __CM_CMSIS_VERSION_SUB ) /*!< CMSIS Core(M) version number */ +#endif diff --git a/core/arm/CMSIS/Core/Include/core_cm0plus.h b/core/arm/CMSIS/Core/Include/core_cm0plus.h new file mode 100644 index 000000000..b9377e8c7 --- /dev/null +++ b/core/arm/CMSIS/Core/Include/core_cm0plus.h @@ -0,0 +1,1083 @@ +/**************************************************************************//** + * @file core_cm0plus.h + * @brief CMSIS Cortex-M0+ Core Peripheral Access Layer Header File + * @version V5.0.6 + * @date 28. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CORE_CM0PLUS_H_GENERIC +#define __CORE_CM0PLUS_H_GENERIC + +#include + +#ifdef __cplusplus + extern "C" { +#endif + +/** + \page CMSIS_MISRA_Exceptions MISRA-C:2004 Compliance Exceptions + CMSIS violates the following MISRA-C:2004 rules: + + \li Required Rule 8.5, object/function definition in header file.
+ Function definitions in header files are used to allow 'inlining'. + + \li Required Rule 18.4, declaration of union type or object of union type: '{...}'.
+ Unions are used for effective representation of core registers. + + \li Advisory Rule 19.7, Function-like macro defined.
+ Function-like macros are used to allow more efficient code. + */ + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ +/** + \ingroup Cortex-M0+ + @{ + */ + +#include "cmsis_version.h" + +/* CMSIS CM0+ definitions */ +#define __CM0PLUS_CMSIS_VERSION_MAIN (__CM_CMSIS_VERSION_MAIN) /*!< \deprecated [31:16] CMSIS HAL main version */ +#define __CM0PLUS_CMSIS_VERSION_SUB (__CM_CMSIS_VERSION_SUB) /*!< \deprecated [15:0] CMSIS HAL sub version */ +#define __CM0PLUS_CMSIS_VERSION ((__CM0PLUS_CMSIS_VERSION_MAIN << 16U) | \ + __CM0PLUS_CMSIS_VERSION_SUB ) /*!< \deprecated CMSIS HAL version number */ + +#define __CORTEX_M (0U) /*!< Cortex-M Core */ + +/** __FPU_USED indicates whether an FPU is used or not. + This core does not support an FPU at all +*/ +#define __FPU_USED 0U + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TI_ARM__ ) + #if defined __TI_VFP_SUPPORT__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#elif defined ( __CSMC__ ) + #if ( __CSMC__ & 0x400U) + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #endif + +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CM0PLUS_H_DEPENDANT +#define __CORE_CM0PLUS_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + +/* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CM0PLUS_REV + #define __CM0PLUS_REV 0x0000U + #warning "__CM0PLUS_REV not defined in device header file; using default!" + #endif + + #ifndef __MPU_PRESENT + #define __MPU_PRESENT 0U + #warning "__MPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __VTOR_PRESENT + #define __VTOR_PRESENT 0U + #warning "__VTOR_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __NVIC_PRIO_BITS + #define __NVIC_PRIO_BITS 2U + #warning "__NVIC_PRIO_BITS not defined in device header file; using default!" + #endif + + #ifndef __Vendor_SysTickConfig + #define __Vendor_SysTickConfig 0U + #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 */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*! Defines 'read only' structure member permissions */ +#define __OM volatile /*! Defines 'write only' structure member permissions */ +#define __IOM volatile /*! Defines 'read / write' structure member permissions */ + +/*@} end of group Cortex-M0+ */ + + + +/******************************************************************************* + * Register Abstraction + Core Register contain: + - Core Register + - Core NVIC Register + - Core SCB Register + - Core SysTick Register + - Core MPU Register + ******************************************************************************/ +/** + \defgroup CMSIS_core_register Defines and Type Definitions + \brief Type definitions and defines for Cortex-M processor based devices. +*/ + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CORE Status and Control Registers + \brief Core Register type definitions. + @{ + */ + +/** + \brief Union type to access the Application Program Status Register (APSR). + */ +typedef union +{ + struct + { + uint32_t _reserved0:28; /*!< bit: 0..27 Reserved */ + 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; + +/* APSR Register Definitions */ +#define APSR_N_Pos 31U /*!< APSR: N Position */ +#define APSR_N_Msk (1UL << APSR_N_Pos) /*!< APSR: N Mask */ + +#define APSR_Z_Pos 30U /*!< APSR: Z Position */ +#define APSR_Z_Msk (1UL << APSR_Z_Pos) /*!< APSR: Z Mask */ + +#define APSR_C_Pos 29U /*!< APSR: C Position */ +#define APSR_C_Msk (1UL << APSR_C_Pos) /*!< APSR: C Mask */ + +#define APSR_V_Pos 28U /*!< APSR: V Position */ +#define APSR_V_Msk (1UL << APSR_V_Pos) /*!< APSR: V Mask */ + + +/** + \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; + +/* IPSR Register Definitions */ +#define IPSR_ISR_Pos 0U /*!< IPSR: ISR Position */ +#define IPSR_ISR_Msk (0x1FFUL /*<< IPSR_ISR_Pos*/) /*!< IPSR: ISR Mask */ + + +/** + \brief Union type to access the Special-Purpose Program Status Registers (xPSR). + */ +typedef union +{ + struct + { + uint32_t ISR:9; /*!< bit: 0.. 8 Exception number */ + uint32_t _reserved0:15; /*!< bit: 9..23 Reserved */ + uint32_t T:1; /*!< bit: 24 Thumb bit (read 0) */ + uint32_t _reserved1:3; /*!< bit: 25..27 Reserved */ + 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; + +/* xPSR Register Definitions */ +#define xPSR_N_Pos 31U /*!< xPSR: N Position */ +#define xPSR_N_Msk (1UL << xPSR_N_Pos) /*!< xPSR: N Mask */ + +#define xPSR_Z_Pos 30U /*!< xPSR: Z Position */ +#define xPSR_Z_Msk (1UL << xPSR_Z_Pos) /*!< xPSR: Z Mask */ + +#define xPSR_C_Pos 29U /*!< xPSR: C Position */ +#define xPSR_C_Msk (1UL << xPSR_C_Pos) /*!< xPSR: C Mask */ + +#define xPSR_V_Pos 28U /*!< xPSR: V Position */ +#define xPSR_V_Msk (1UL << xPSR_V_Pos) /*!< xPSR: V Mask */ + +#define xPSR_T_Pos 24U /*!< xPSR: T Position */ +#define xPSR_T_Msk (1UL << xPSR_T_Pos) /*!< xPSR: T Mask */ + +#define xPSR_ISR_Pos 0U /*!< xPSR: ISR Position */ +#define xPSR_ISR_Msk (0x1FFUL /*<< xPSR_ISR_Pos*/) /*!< xPSR: ISR Mask */ + + +/** + \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 _reserved1:30; /*!< bit: 2..31 Reserved */ + } b; /*!< Structure used for bit access */ + uint32_t w; /*!< Type used for word access */ +} CONTROL_Type; + +/* CONTROL Register Definitions */ +#define CONTROL_SPSEL_Pos 1U /*!< CONTROL: SPSEL Position */ +#define CONTROL_SPSEL_Msk (1UL << CONTROL_SPSEL_Pos) /*!< CONTROL: SPSEL Mask */ + +#define CONTROL_nPRIV_Pos 0U /*!< CONTROL: nPRIV Position */ +#define CONTROL_nPRIV_Msk (1UL /*<< CONTROL_nPRIV_Pos*/) /*!< CONTROL: nPRIV Mask */ + +/*@} 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 +{ + __IOM uint32_t ISER[1U]; /*!< Offset: 0x000 (R/W) Interrupt Set Enable Register */ + uint32_t RESERVED0[31U]; + __IOM uint32_t ICER[1U]; /*!< Offset: 0x080 (R/W) Interrupt Clear Enable Register */ + uint32_t RSERVED1[31U]; + __IOM uint32_t ISPR[1U]; /*!< Offset: 0x100 (R/W) Interrupt Set Pending Register */ + uint32_t RESERVED2[31U]; + __IOM uint32_t ICPR[1U]; /*!< Offset: 0x180 (R/W) Interrupt Clear Pending Register */ + uint32_t RESERVED3[31U]; + uint32_t RESERVED4[64U]; + __IOM uint32_t IP[8U]; /*!< Offset: 0x300 (R/W) Interrupt Priority Register */ +} NVIC_Type; + +/*@} end of group CMSIS_NVIC */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SCB System Control Block (SCB) + \brief Type definitions for the System Control Block Registers + @{ + */ + +/** + \brief Structure type to access the System Control Block (SCB). + */ +typedef struct +{ + __IM uint32_t CPUID; /*!< Offset: 0x000 (R/ ) CPUID Base Register */ + __IOM uint32_t ICSR; /*!< Offset: 0x004 (R/W) Interrupt Control and State Register */ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + __IOM uint32_t VTOR; /*!< Offset: 0x008 (R/W) Vector Table Offset Register */ +#else + uint32_t RESERVED0; +#endif + __IOM uint32_t AIRCR; /*!< Offset: 0x00C (R/W) Application Interrupt and Reset Control Register */ + __IOM uint32_t SCR; /*!< Offset: 0x010 (R/W) System Control Register */ + __IOM uint32_t CCR; /*!< Offset: 0x014 (R/W) Configuration Control Register */ + uint32_t RESERVED1; + __IOM uint32_t SHP[2U]; /*!< Offset: 0x01C (R/W) System Handlers Priority Registers. [0] is RESERVED */ + __IOM uint32_t SHCSR; /*!< Offset: 0x024 (R/W) System Handler Control and State Register */ +} SCB_Type; + +/* SCB CPUID Register Definitions */ +#define SCB_CPUID_IMPLEMENTER_Pos 24U /*!< SCB CPUID: IMPLEMENTER Position */ +#define SCB_CPUID_IMPLEMENTER_Msk (0xFFUL << SCB_CPUID_IMPLEMENTER_Pos) /*!< SCB CPUID: IMPLEMENTER Mask */ + +#define SCB_CPUID_VARIANT_Pos 20U /*!< SCB CPUID: VARIANT Position */ +#define SCB_CPUID_VARIANT_Msk (0xFUL << SCB_CPUID_VARIANT_Pos) /*!< SCB CPUID: VARIANT Mask */ + +#define SCB_CPUID_ARCHITECTURE_Pos 16U /*!< SCB CPUID: ARCHITECTURE Position */ +#define SCB_CPUID_ARCHITECTURE_Msk (0xFUL << SCB_CPUID_ARCHITECTURE_Pos) /*!< SCB CPUID: ARCHITECTURE Mask */ + +#define SCB_CPUID_PARTNO_Pos 4U /*!< SCB CPUID: PARTNO Position */ +#define SCB_CPUID_PARTNO_Msk (0xFFFUL << SCB_CPUID_PARTNO_Pos) /*!< SCB CPUID: PARTNO Mask */ + +#define SCB_CPUID_REVISION_Pos 0U /*!< 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 31U /*!< SCB ICSR: NMIPENDSET Position */ +#define SCB_ICSR_NMIPENDSET_Msk (1UL << SCB_ICSR_NMIPENDSET_Pos) /*!< SCB ICSR: NMIPENDSET Mask */ + +#define SCB_ICSR_PENDSVSET_Pos 28U /*!< SCB ICSR: PENDSVSET Position */ +#define SCB_ICSR_PENDSVSET_Msk (1UL << SCB_ICSR_PENDSVSET_Pos) /*!< SCB ICSR: PENDSVSET Mask */ + +#define SCB_ICSR_PENDSVCLR_Pos 27U /*!< SCB ICSR: PENDSVCLR Position */ +#define SCB_ICSR_PENDSVCLR_Msk (1UL << SCB_ICSR_PENDSVCLR_Pos) /*!< SCB ICSR: PENDSVCLR Mask */ + +#define SCB_ICSR_PENDSTSET_Pos 26U /*!< SCB ICSR: PENDSTSET Position */ +#define SCB_ICSR_PENDSTSET_Msk (1UL << SCB_ICSR_PENDSTSET_Pos) /*!< SCB ICSR: PENDSTSET Mask */ + +#define SCB_ICSR_PENDSTCLR_Pos 25U /*!< SCB ICSR: PENDSTCLR Position */ +#define SCB_ICSR_PENDSTCLR_Msk (1UL << SCB_ICSR_PENDSTCLR_Pos) /*!< SCB ICSR: PENDSTCLR Mask */ + +#define SCB_ICSR_ISRPREEMPT_Pos 23U /*!< SCB ICSR: ISRPREEMPT Position */ +#define SCB_ICSR_ISRPREEMPT_Msk (1UL << SCB_ICSR_ISRPREEMPT_Pos) /*!< SCB ICSR: ISRPREEMPT Mask */ + +#define SCB_ICSR_ISRPENDING_Pos 22U /*!< SCB ICSR: ISRPENDING Position */ +#define SCB_ICSR_ISRPENDING_Msk (1UL << SCB_ICSR_ISRPENDING_Pos) /*!< SCB ICSR: ISRPENDING Mask */ + +#define SCB_ICSR_VECTPENDING_Pos 12U /*!< SCB ICSR: VECTPENDING Position */ +#define SCB_ICSR_VECTPENDING_Msk (0x1FFUL << SCB_ICSR_VECTPENDING_Pos) /*!< SCB ICSR: VECTPENDING Mask */ + +#define SCB_ICSR_VECTACTIVE_Pos 0U /*!< SCB ICSR: VECTACTIVE Position */ +#define SCB_ICSR_VECTACTIVE_Msk (0x1FFUL /*<< SCB_ICSR_VECTACTIVE_Pos*/) /*!< SCB ICSR: VECTACTIVE Mask */ + +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) +/* SCB Interrupt Control State Register Definitions */ +#define SCB_VTOR_TBLOFF_Pos 8U /*!< SCB VTOR: TBLOFF Position */ +#define SCB_VTOR_TBLOFF_Msk (0xFFFFFFUL << SCB_VTOR_TBLOFF_Pos) /*!< SCB VTOR: TBLOFF Mask */ +#endif + +/* SCB Application Interrupt and Reset Control Register Definitions */ +#define SCB_AIRCR_VECTKEY_Pos 16U /*!< SCB AIRCR: VECTKEY Position */ +#define SCB_AIRCR_VECTKEY_Msk (0xFFFFUL << SCB_AIRCR_VECTKEY_Pos) /*!< SCB AIRCR: VECTKEY Mask */ + +#define SCB_AIRCR_VECTKEYSTAT_Pos 16U /*!< SCB AIRCR: VECTKEYSTAT Position */ +#define SCB_AIRCR_VECTKEYSTAT_Msk (0xFFFFUL << SCB_AIRCR_VECTKEYSTAT_Pos) /*!< SCB AIRCR: VECTKEYSTAT Mask */ + +#define SCB_AIRCR_ENDIANESS_Pos 15U /*!< SCB AIRCR: ENDIANESS Position */ +#define SCB_AIRCR_ENDIANESS_Msk (1UL << SCB_AIRCR_ENDIANESS_Pos) /*!< SCB AIRCR: ENDIANESS Mask */ + +#define SCB_AIRCR_SYSRESETREQ_Pos 2U /*!< SCB AIRCR: SYSRESETREQ Position */ +#define SCB_AIRCR_SYSRESETREQ_Msk (1UL << SCB_AIRCR_SYSRESETREQ_Pos) /*!< SCB AIRCR: SYSRESETREQ Mask */ + +#define SCB_AIRCR_VECTCLRACTIVE_Pos 1U /*!< SCB AIRCR: VECTCLRACTIVE Position */ +#define SCB_AIRCR_VECTCLRACTIVE_Msk (1UL << SCB_AIRCR_VECTCLRACTIVE_Pos) /*!< SCB AIRCR: VECTCLRACTIVE Mask */ + +/* SCB System Control Register Definitions */ +#define SCB_SCR_SEVONPEND_Pos 4U /*!< SCB SCR: SEVONPEND Position */ +#define SCB_SCR_SEVONPEND_Msk (1UL << SCB_SCR_SEVONPEND_Pos) /*!< SCB SCR: SEVONPEND Mask */ + +#define SCB_SCR_SLEEPDEEP_Pos 2U /*!< SCB SCR: SLEEPDEEP Position */ +#define SCB_SCR_SLEEPDEEP_Msk (1UL << SCB_SCR_SLEEPDEEP_Pos) /*!< SCB SCR: SLEEPDEEP Mask */ + +#define SCB_SCR_SLEEPONEXIT_Pos 1U /*!< 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 9U /*!< SCB CCR: STKALIGN Position */ +#define SCB_CCR_STKALIGN_Msk (1UL << SCB_CCR_STKALIGN_Pos) /*!< SCB CCR: STKALIGN Mask */ + +#define SCB_CCR_UNALIGN_TRP_Pos 3U /*!< SCB CCR: UNALIGN_TRP Position */ +#define SCB_CCR_UNALIGN_TRP_Msk (1UL << SCB_CCR_UNALIGN_TRP_Pos) /*!< SCB CCR: UNALIGN_TRP Mask */ + +/* SCB System Handler Control and State Register Definitions */ +#define SCB_SHCSR_SVCALLPENDED_Pos 15U /*!< SCB SHCSR: SVCALLPENDED Position */ +#define SCB_SHCSR_SVCALLPENDED_Msk (1UL << SCB_SHCSR_SVCALLPENDED_Pos) /*!< SCB SHCSR: SVCALLPENDED Mask */ + +/*@} end of group CMSIS_SCB */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_SysTick System Tick Timer (SysTick) + \brief Type definitions for the System Timer Registers. + @{ + */ + +/** + \brief Structure type to access the System Timer (SysTick). + */ +typedef struct +{ + __IOM uint32_t CTRL; /*!< Offset: 0x000 (R/W) SysTick Control and Status Register */ + __IOM uint32_t LOAD; /*!< Offset: 0x004 (R/W) SysTick Reload Value Register */ + __IOM uint32_t VAL; /*!< Offset: 0x008 (R/W) SysTick Current Value Register */ + __IM uint32_t CALIB; /*!< Offset: 0x00C (R/ ) SysTick Calibration Register */ +} SysTick_Type; + +/* SysTick Control / Status Register Definitions */ +#define SysTick_CTRL_COUNTFLAG_Pos 16U /*!< SysTick CTRL: COUNTFLAG Position */ +#define SysTick_CTRL_COUNTFLAG_Msk (1UL << SysTick_CTRL_COUNTFLAG_Pos) /*!< SysTick CTRL: COUNTFLAG Mask */ + +#define SysTick_CTRL_CLKSOURCE_Pos 2U /*!< SysTick CTRL: CLKSOURCE Position */ +#define SysTick_CTRL_CLKSOURCE_Msk (1UL << SysTick_CTRL_CLKSOURCE_Pos) /*!< SysTick CTRL: CLKSOURCE Mask */ + +#define SysTick_CTRL_TICKINT_Pos 1U /*!< SysTick CTRL: TICKINT Position */ +#define SysTick_CTRL_TICKINT_Msk (1UL << SysTick_CTRL_TICKINT_Pos) /*!< SysTick CTRL: TICKINT Mask */ + +#define SysTick_CTRL_ENABLE_Pos 0U /*!< 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 0U /*!< 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 0U /*!< 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 31U /*!< SysTick CALIB: NOREF Position */ +#define SysTick_CALIB_NOREF_Msk (1UL << SysTick_CALIB_NOREF_Pos) /*!< SysTick CALIB: NOREF Mask */ + +#define SysTick_CALIB_SKEW_Pos 30U /*!< SysTick CALIB: SKEW Position */ +#define SysTick_CALIB_SKEW_Msk (1UL << SysTick_CALIB_SKEW_Pos) /*!< SysTick CALIB: SKEW Mask */ + +#define SysTick_CALIB_TENMS_Pos 0U /*!< SysTick CALIB: TENMS Position */ +#define SysTick_CALIB_TENMS_Msk (0xFFFFFFUL /*<< SysTick_CALIB_TENMS_Pos*/) /*!< SysTick CALIB: TENMS Mask */ + +/*@} end of group CMSIS_SysTick */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) +/** + \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 +{ + __IM uint32_t TYPE; /*!< Offset: 0x000 (R/ ) MPU Type Register */ + __IOM uint32_t CTRL; /*!< Offset: 0x004 (R/W) MPU Control Register */ + __IOM uint32_t RNR; /*!< Offset: 0x008 (R/W) MPU Region RNRber Register */ + __IOM uint32_t RBAR; /*!< Offset: 0x00C (R/W) MPU Region Base Address Register */ + __IOM uint32_t RASR; /*!< Offset: 0x010 (R/W) MPU Region Attribute and Size Register */ +} MPU_Type; + +#define MPU_TYPE_RALIASES 1U + +/* MPU Type Register Definitions */ +#define MPU_TYPE_IREGION_Pos 16U /*!< MPU TYPE: IREGION Position */ +#define MPU_TYPE_IREGION_Msk (0xFFUL << MPU_TYPE_IREGION_Pos) /*!< MPU TYPE: IREGION Mask */ + +#define MPU_TYPE_DREGION_Pos 8U /*!< MPU TYPE: DREGION Position */ +#define MPU_TYPE_DREGION_Msk (0xFFUL << MPU_TYPE_DREGION_Pos) /*!< MPU TYPE: DREGION Mask */ + +#define MPU_TYPE_SEPARATE_Pos 0U /*!< MPU TYPE: SEPARATE Position */ +#define MPU_TYPE_SEPARATE_Msk (1UL /*<< MPU_TYPE_SEPARATE_Pos*/) /*!< MPU TYPE: SEPARATE Mask */ + +/* MPU Control Register Definitions */ +#define MPU_CTRL_PRIVDEFENA_Pos 2U /*!< MPU CTRL: PRIVDEFENA Position */ +#define MPU_CTRL_PRIVDEFENA_Msk (1UL << MPU_CTRL_PRIVDEFENA_Pos) /*!< MPU CTRL: PRIVDEFENA Mask */ + +#define MPU_CTRL_HFNMIENA_Pos 1U /*!< MPU CTRL: HFNMIENA Position */ +#define MPU_CTRL_HFNMIENA_Msk (1UL << MPU_CTRL_HFNMIENA_Pos) /*!< MPU CTRL: HFNMIENA Mask */ + +#define MPU_CTRL_ENABLE_Pos 0U /*!< MPU CTRL: ENABLE Position */ +#define MPU_CTRL_ENABLE_Msk (1UL /*<< MPU_CTRL_ENABLE_Pos*/) /*!< MPU CTRL: ENABLE Mask */ + +/* MPU Region Number Register Definitions */ +#define MPU_RNR_REGION_Pos 0U /*!< MPU RNR: REGION Position */ +#define MPU_RNR_REGION_Msk (0xFFUL /*<< MPU_RNR_REGION_Pos*/) /*!< MPU RNR: REGION Mask */ + +/* MPU Region Base Address Register Definitions */ +#define MPU_RBAR_ADDR_Pos 8U /*!< MPU RBAR: ADDR Position */ +#define MPU_RBAR_ADDR_Msk (0xFFFFFFUL << MPU_RBAR_ADDR_Pos) /*!< MPU RBAR: ADDR Mask */ + +#define MPU_RBAR_VALID_Pos 4U /*!< MPU RBAR: VALID Position */ +#define MPU_RBAR_VALID_Msk (1UL << MPU_RBAR_VALID_Pos) /*!< MPU RBAR: VALID Mask */ + +#define MPU_RBAR_REGION_Pos 0U /*!< MPU RBAR: REGION Position */ +#define MPU_RBAR_REGION_Msk (0xFUL /*<< MPU_RBAR_REGION_Pos*/) /*!< MPU RBAR: REGION Mask */ + +/* MPU Region Attribute and Size Register Definitions */ +#define MPU_RASR_ATTRS_Pos 16U /*!< MPU RASR: MPU Region Attribute field Position */ +#define MPU_RASR_ATTRS_Msk (0xFFFFUL << MPU_RASR_ATTRS_Pos) /*!< MPU RASR: MPU Region Attribute field Mask */ + +#define MPU_RASR_XN_Pos 28U /*!< MPU RASR: ATTRS.XN Position */ +#define MPU_RASR_XN_Msk (1UL << MPU_RASR_XN_Pos) /*!< MPU RASR: ATTRS.XN Mask */ + +#define MPU_RASR_AP_Pos 24U /*!< MPU RASR: ATTRS.AP Position */ +#define MPU_RASR_AP_Msk (0x7UL << MPU_RASR_AP_Pos) /*!< MPU RASR: ATTRS.AP Mask */ + +#define MPU_RASR_TEX_Pos 19U /*!< MPU RASR: ATTRS.TEX Position */ +#define MPU_RASR_TEX_Msk (0x7UL << MPU_RASR_TEX_Pos) /*!< MPU RASR: ATTRS.TEX Mask */ + +#define MPU_RASR_S_Pos 18U /*!< MPU RASR: ATTRS.S Position */ +#define MPU_RASR_S_Msk (1UL << MPU_RASR_S_Pos) /*!< MPU RASR: ATTRS.S Mask */ + +#define MPU_RASR_C_Pos 17U /*!< MPU RASR: ATTRS.C Position */ +#define MPU_RASR_C_Msk (1UL << MPU_RASR_C_Pos) /*!< MPU RASR: ATTRS.C Mask */ + +#define MPU_RASR_B_Pos 16U /*!< MPU RASR: ATTRS.B Position */ +#define MPU_RASR_B_Msk (1UL << MPU_RASR_B_Pos) /*!< MPU RASR: ATTRS.B Mask */ + +#define MPU_RASR_SRD_Pos 8U /*!< 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 1U /*!< 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 0U /*!< MPU RASR: Region enable bit Position */ +#define MPU_RASR_ENABLE_Msk (1UL /*<< MPU_RASR_ENABLE_Pos*/) /*!< MPU RASR: Region enable bit Disable Mask */ + +/*@} end of group CMSIS_MPU */ +#endif + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_CoreDebug Core Debug Registers (CoreDebug) + \brief Cortex-M0+ Core Debug Registers (DCB registers, SHCSR, and DFSR) are only accessible over DAP and not via processor. + Therefore they are not covered by the Cortex-M0+ header file. + @{ + */ +/*@} end of group CMSIS_CoreDebug */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_bitfield Core register bit field macros + \brief Macros for use with bit field definitions (xxx_Pos, xxx_Msk). + @{ + */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param[in] field Name of the register bit field. + \param[in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param[in] field Name of the register bit field. + \param[in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + +/*@} end of group CMSIS_core_bitfield */ + + +/** + \ingroup CMSIS_core_register + \defgroup CMSIS_core_base Core Definitions + \brief Definitions for base addresses, unions, and structures. + @{ + */ + +/* Memory mapping of Core Hardware */ +#define SCS_BASE (0xE000E000UL) /*!< System Control Space Base Address */ +#define SysTick_BASE (SCS_BASE + 0x0010UL) /*!< SysTick Base Address */ +#define NVIC_BASE (SCS_BASE + 0x0100UL) /*!< NVIC Base Address */ +#define SCB_BASE (SCS_BASE + 0x0D00UL) /*!< System Control Block Base Address */ + +#define SCB ((SCB_Type *) SCB_BASE ) /*!< SCB configuration struct */ +#define SysTick ((SysTick_Type *) SysTick_BASE ) /*!< SysTick configuration struct */ +#define NVIC ((NVIC_Type *) NVIC_BASE ) /*!< NVIC configuration struct */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + #define MPU_BASE (SCS_BASE + 0x0D90UL) /*!< Memory Protection Unit */ + #define MPU ((MPU_Type *) MPU_BASE ) /*!< Memory Protection Unit */ +#endif + +/*@} */ + + + +/******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - Core NVIC Functions + - Core SysTick Functions + - Core Register Access Functions + ******************************************************************************/ +/** + \defgroup CMSIS_Core_FunctionInterface Functions and Instructions Reference +*/ + + + +/* ########################## NVIC functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_NVICFunctions NVIC Functions + \brief Functions that manage interrupts and exceptions via the NVIC. + @{ + */ + +#ifdef CMSIS_NVIC_VIRTUAL + #ifndef CMSIS_NVIC_VIRTUAL_HEADER_FILE + #define CMSIS_NVIC_VIRTUAL_HEADER_FILE "cmsis_nvic_virtual.h" + #endif + #include CMSIS_NVIC_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetPriorityGrouping __NVIC_SetPriorityGrouping + #define NVIC_GetPriorityGrouping __NVIC_GetPriorityGrouping + #define NVIC_EnableIRQ __NVIC_EnableIRQ + #define NVIC_GetEnableIRQ __NVIC_GetEnableIRQ + #define NVIC_DisableIRQ __NVIC_DisableIRQ + #define NVIC_GetPendingIRQ __NVIC_GetPendingIRQ + #define NVIC_SetPendingIRQ __NVIC_SetPendingIRQ + #define NVIC_ClearPendingIRQ __NVIC_ClearPendingIRQ +/*#define NVIC_GetActive __NVIC_GetActive not available for Cortex-M0+ */ + #define NVIC_SetPriority __NVIC_SetPriority + #define NVIC_GetPriority __NVIC_GetPriority + #define NVIC_SystemReset __NVIC_SystemReset +#endif /* CMSIS_NVIC_VIRTUAL */ + +#ifdef CMSIS_VECTAB_VIRTUAL + #ifndef CMSIS_VECTAB_VIRTUAL_HEADER_FILE + #define CMSIS_VECTAB_VIRTUAL_HEADER_FILE "cmsis_vectab_virtual.h" + #endif + #include CMSIS_VECTAB_VIRTUAL_HEADER_FILE +#else + #define NVIC_SetVector __NVIC_SetVector + #define NVIC_GetVector __NVIC_GetVector +#endif /* (CMSIS_VECTAB_VIRTUAL) */ + +#define NVIC_USER_IRQ_OFFSET 16 + + +/* The following EXC_RETURN values are saved the LR on exception entry */ +#define EXC_RETURN_HANDLER (0xFFFFFFF1UL) /* return to Handler mode, uses MSP after return */ +#define EXC_RETURN_THREAD_MSP (0xFFFFFFF9UL) /* return to Thread mode, uses MSP after return */ +#define EXC_RETURN_THREAD_PSP (0xFFFFFFFDUL) /* return to Thread mode, uses PSP after return */ + + +/* Interrupt Priorities are WORD accessible only under Armv6-M */ +/* The following MACROS handle generation of the register offset and byte masks */ +#define _BIT_SHIFT(IRQn) ( ((((uint32_t)(int32_t)(IRQn)) ) & 0x03UL) * 8UL) +#define _SHP_IDX(IRQn) ( (((((uint32_t)(int32_t)(IRQn)) & 0x0FUL)-8UL) >> 2UL) ) +#define _IP_IDX(IRQn) ( (((uint32_t)(int32_t)(IRQn)) >> 2UL) ) + +#define __NVIC_SetPriorityGrouping(X) (void)(X) +#define __NVIC_GetPriorityGrouping() (0U) + +/** + \brief Enable Interrupt + \details Enables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_EnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Get Interrupt Enable status + \details Returns a device specific interrupt enable status from the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt is not enabled. + \return 1 Interrupt is enabled. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetEnableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISER[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Disable Interrupt + \details Disables a device specific interrupt in the NVIC interrupt controller. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_DisableIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICER[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + __DSB(); + __ISB(); + } +} + + +/** + \brief Get Pending Interrupt + \details Reads the NVIC pending register and returns the pending bit for the specified device specific interrupt. + \param [in] IRQn Device specific interrupt number. + \return 0 Interrupt status is not pending. + \return 1 Interrupt status is pending. + \note IRQn must not be negative. + */ +__STATIC_INLINE uint32_t __NVIC_GetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->ISPR[0U] & (1UL << (((uint32_t)IRQn) & 0x1FUL))) != 0UL) ? 1UL : 0UL)); + } + else + { + return(0U); + } +} + + +/** + \brief Set Pending Interrupt + \details Sets the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ISPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Clear Pending Interrupt + \details Clears the pending bit of a device specific interrupt in the NVIC pending register. + \param [in] IRQn Device specific interrupt number. + \note IRQn must not be negative. + */ +__STATIC_INLINE void __NVIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->ICPR[0U] = (uint32_t)(1UL << (((uint32_t)IRQn) & 0x1FUL)); + } +} + + +/** + \brief Set Interrupt Priority + \details Sets the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \param [in] priority Priority to set. + \note The priority cannot be set for every processor exception. + */ +__STATIC_INLINE void __NVIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + if ((int32_t)(IRQn) >= 0) + { + NVIC->IP[_IP_IDX(IRQn)] = ((uint32_t)(NVIC->IP[_IP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } + else + { + SCB->SHP[_SHP_IDX(IRQn)] = ((uint32_t)(SCB->SHP[_SHP_IDX(IRQn)] & ~(0xFFUL << _BIT_SHIFT(IRQn))) | + (((priority << (8U - __NVIC_PRIO_BITS)) & (uint32_t)0xFFUL) << _BIT_SHIFT(IRQn))); + } +} + + +/** + \brief Get Interrupt Priority + \details Reads the priority of a device specific interrupt or a processor exception. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \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 ((int32_t)(IRQn) >= 0) + { + return((uint32_t)(((NVIC->IP[ _IP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } + else + { + return((uint32_t)(((SCB->SHP[_SHP_IDX(IRQn)] >> _BIT_SHIFT(IRQn) ) & (uint32_t)0xFFUL) >> (8U - __NVIC_PRIO_BITS))); + } +} + + +/** + \brief Encode Priority + \details 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 smallest 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 & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + return ( + ((PreemptPriority & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL)) << SubPriorityBits) | + ((SubPriority & (uint32_t)((1UL << (SubPriorityBits )) - 1UL))) + ); +} + + +/** + \brief Decode Priority + \details 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 smallest 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* const pPreemptPriority, uint32_t* const pSubPriority) +{ + uint32_t PriorityGroupTmp = (PriorityGroup & (uint32_t)0x07UL); /* only values 0..7 are used */ + uint32_t PreemptPriorityBits; + uint32_t SubPriorityBits; + + PreemptPriorityBits = ((7UL - PriorityGroupTmp) > (uint32_t)(__NVIC_PRIO_BITS)) ? (uint32_t)(__NVIC_PRIO_BITS) : (uint32_t)(7UL - PriorityGroupTmp); + SubPriorityBits = ((PriorityGroupTmp + (uint32_t)(__NVIC_PRIO_BITS)) < (uint32_t)7UL) ? (uint32_t)0UL : (uint32_t)((PriorityGroupTmp - 7UL) + (uint32_t)(__NVIC_PRIO_BITS)); + + *pPreemptPriority = (Priority >> SubPriorityBits) & (uint32_t)((1UL << (PreemptPriorityBits)) - 1UL); + *pSubPriority = (Priority ) & (uint32_t)((1UL << (SubPriorityBits )) - 1UL); +} + + +/** + \brief Set Interrupt Vector + \details Sets an interrupt vector in SRAM based interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + VTOR must been relocated to SRAM before. + If VTOR is not present address 0 must be mapped to SRAM. + \param [in] IRQn Interrupt number + \param [in] vector Address of interrupt handler function + */ +__STATIC_INLINE void __NVIC_SetVector(IRQn_Type IRQn, uint32_t vector) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET] = vector; +} + + +/** + \brief Get Interrupt Vector + \details Reads an interrupt vector from interrupt vector table. + The interrupt number can be positive to specify a device specific interrupt, + or negative to specify a processor exception. + \param [in] IRQn Interrupt number. + \return Address of interrupt handler function + */ +__STATIC_INLINE uint32_t __NVIC_GetVector(IRQn_Type IRQn) +{ +#if defined (__VTOR_PRESENT) && (__VTOR_PRESENT == 1U) + uint32_t *vectors = (uint32_t *)SCB->VTOR; +#else + uint32_t *vectors = (uint32_t *)0x0U; +#endif + return vectors[(int32_t)IRQn + NVIC_USER_IRQ_OFFSET]; + +} + + +/** + \brief System Reset + \details Initiates a system reset request to reset the MCU. + */ +__NO_RETURN __STATIC_INLINE void __NVIC_SystemReset(void) +{ + __DSB(); /* Ensure all outstanding memory accesses included + buffered write are completed before reset */ + SCB->AIRCR = ((0x5FAUL << SCB_AIRCR_VECTKEY_Pos) | + SCB_AIRCR_SYSRESETREQ_Msk); + __DSB(); /* Ensure completion of memory access */ + + for(;;) /* wait until reset */ + { + __NOP(); + } +} + +/*@} end of CMSIS_Core_NVICFunctions */ + +/* ########################## MPU functions #################################### */ + +#if defined (__MPU_PRESENT) && (__MPU_PRESENT == 1U) + +#include "mpu_armv7.h" + +#endif + +/* ########################## FPU functions #################################### */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_FpuFunctions FPU Functions + \brief Function that provides FPU type. + @{ + */ + +/** + \brief get FPU type + \details returns the FPU type + \returns + - \b 0: No FPU + - \b 1: Single precision FPU + - \b 2: Double + Single precision FPU + */ +__STATIC_INLINE uint32_t SCB_GetFPUType(void) +{ + return 0U; /* No FPU */ +} + + +/*@} end of CMSIS_Core_FpuFunctions */ + + + +/* ################################## SysTick function ############################################ */ +/** + \ingroup CMSIS_Core_FunctionInterface + \defgroup CMSIS_Core_SysTickFunctions SysTick Functions + \brief Functions that configure the System. + @{ + */ + +#if defined (__Vendor_SysTickConfig) && (__Vendor_SysTickConfig == 0U) + +/** + \brief System Tick Configuration + \details 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 - 1UL) > SysTick_LOAD_RELOAD_Msk) + { + return (1UL); /* Reload value impossible */ + } + + SysTick->LOAD = (uint32_t)(ticks - 1UL); /* set reload register */ + NVIC_SetPriority (SysTick_IRQn, (1UL << __NVIC_PRIO_BITS) - 1UL); /* set Priority for Systick Interrupt */ + SysTick->VAL = 0UL; /* 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 (0UL); /* Function successful */ +} + +#endif + +/*@} end of CMSIS_Core_SysTickFunctions */ + + + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CM0PLUS_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/core/arm/CMSIS/Core/Include/mpu_armv7.h b/core/arm/CMSIS/Core/Include/mpu_armv7.h new file mode 100644 index 000000000..7d4b600cc --- /dev/null +++ b/core/arm/CMSIS/Core/Include/mpu_armv7.h @@ -0,0 +1,270 @@ +/****************************************************************************** + * @file mpu_armv7.h + * @brief CMSIS MPU API for Armv7-M MPU + * @version V5.0.4 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2017-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef ARM_MPU_ARMV7_H +#define ARM_MPU_ARMV7_H + +#define ARM_MPU_REGION_SIZE_32B ((uint8_t)0x04U) ///!< MPU Region Size 32 Bytes +#define ARM_MPU_REGION_SIZE_64B ((uint8_t)0x05U) ///!< MPU Region Size 64 Bytes +#define ARM_MPU_REGION_SIZE_128B ((uint8_t)0x06U) ///!< MPU Region Size 128 Bytes +#define ARM_MPU_REGION_SIZE_256B ((uint8_t)0x07U) ///!< MPU Region Size 256 Bytes +#define ARM_MPU_REGION_SIZE_512B ((uint8_t)0x08U) ///!< MPU Region Size 512 Bytes +#define ARM_MPU_REGION_SIZE_1KB ((uint8_t)0x09U) ///!< MPU Region Size 1 KByte +#define ARM_MPU_REGION_SIZE_2KB ((uint8_t)0x0AU) ///!< MPU Region Size 2 KBytes +#define ARM_MPU_REGION_SIZE_4KB ((uint8_t)0x0BU) ///!< MPU Region Size 4 KBytes +#define ARM_MPU_REGION_SIZE_8KB ((uint8_t)0x0CU) ///!< MPU Region Size 8 KBytes +#define ARM_MPU_REGION_SIZE_16KB ((uint8_t)0x0DU) ///!< MPU Region Size 16 KBytes +#define ARM_MPU_REGION_SIZE_32KB ((uint8_t)0x0EU) ///!< MPU Region Size 32 KBytes +#define ARM_MPU_REGION_SIZE_64KB ((uint8_t)0x0FU) ///!< MPU Region Size 64 KBytes +#define ARM_MPU_REGION_SIZE_128KB ((uint8_t)0x10U) ///!< MPU Region Size 128 KBytes +#define ARM_MPU_REGION_SIZE_256KB ((uint8_t)0x11U) ///!< MPU Region Size 256 KBytes +#define ARM_MPU_REGION_SIZE_512KB ((uint8_t)0x12U) ///!< MPU Region Size 512 KBytes +#define ARM_MPU_REGION_SIZE_1MB ((uint8_t)0x13U) ///!< MPU Region Size 1 MByte +#define ARM_MPU_REGION_SIZE_2MB ((uint8_t)0x14U) ///!< MPU Region Size 2 MBytes +#define ARM_MPU_REGION_SIZE_4MB ((uint8_t)0x15U) ///!< MPU Region Size 4 MBytes +#define ARM_MPU_REGION_SIZE_8MB ((uint8_t)0x16U) ///!< MPU Region Size 8 MBytes +#define ARM_MPU_REGION_SIZE_16MB ((uint8_t)0x17U) ///!< MPU Region Size 16 MBytes +#define ARM_MPU_REGION_SIZE_32MB ((uint8_t)0x18U) ///!< MPU Region Size 32 MBytes +#define ARM_MPU_REGION_SIZE_64MB ((uint8_t)0x19U) ///!< MPU Region Size 64 MBytes +#define ARM_MPU_REGION_SIZE_128MB ((uint8_t)0x1AU) ///!< MPU Region Size 128 MBytes +#define ARM_MPU_REGION_SIZE_256MB ((uint8_t)0x1BU) ///!< MPU Region Size 256 MBytes +#define ARM_MPU_REGION_SIZE_512MB ((uint8_t)0x1CU) ///!< MPU Region Size 512 MBytes +#define ARM_MPU_REGION_SIZE_1GB ((uint8_t)0x1DU) ///!< MPU Region Size 1 GByte +#define ARM_MPU_REGION_SIZE_2GB ((uint8_t)0x1EU) ///!< MPU Region Size 2 GBytes +#define ARM_MPU_REGION_SIZE_4GB ((uint8_t)0x1FU) ///!< MPU Region Size 4 GBytes + +#define ARM_MPU_AP_NONE 0U ///!< MPU Access Permission no access +#define ARM_MPU_AP_PRIV 1U ///!< MPU Access Permission privileged access only +#define ARM_MPU_AP_URO 2U ///!< MPU Access Permission unprivileged access read-only +#define ARM_MPU_AP_FULL 3U ///!< MPU Access Permission full access +#define ARM_MPU_AP_PRO 5U ///!< MPU Access Permission privileged access read-only +#define ARM_MPU_AP_RO 6U ///!< MPU Access Permission read-only access + +/** MPU Region Base Address Register Value +* +* \param Region The region to be configured, number 0 to 15. +* \param BaseAddress The base address for the region. +*/ +#define ARM_MPU_RBAR(Region, BaseAddress) \ + (((BaseAddress) & MPU_RBAR_ADDR_Msk) | \ + ((Region) & MPU_RBAR_REGION_Msk) | \ + (MPU_RBAR_VALID_Msk)) + +/** +* MPU Memory Access Attributes +* +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +*/ +#define ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable) \ + ((((TypeExtField ) << MPU_RASR_TEX_Pos) & MPU_RASR_TEX_Msk) | \ + (((IsShareable ) << MPU_RASR_S_Pos) & MPU_RASR_S_Msk) | \ + (((IsCacheable ) << MPU_RASR_C_Pos) & MPU_RASR_C_Msk) | \ + (((IsBufferable ) << MPU_RASR_B_Pos) & MPU_RASR_B_Msk)) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param AccessAttributes Memory access attribution, see \ref ARM_MPU_ACCESS_. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR_EX(DisableExec, AccessPermission, AccessAttributes, SubRegionDisable, Size) \ + ((((DisableExec ) << MPU_RASR_XN_Pos) & MPU_RASR_XN_Msk) | \ + (((AccessPermission) << MPU_RASR_AP_Pos) & MPU_RASR_AP_Msk) | \ + (((AccessAttributes) ) & (MPU_RASR_TEX_Msk | MPU_RASR_S_Msk | MPU_RASR_C_Msk | MPU_RASR_B_Msk))) + +/** +* MPU Region Attribute and Size Register Value +* +* \param DisableExec Instruction access disable bit, 1= disable instruction fetches. +* \param AccessPermission Data access permissions, allows you to configure read/write access for User and Privileged mode. +* \param TypeExtField Type extension field, allows you to configure memory access type, for example strongly ordered, peripheral. +* \param IsShareable Region is shareable between multiple bus masters. +* \param IsCacheable Region is cacheable, i.e. its value may be kept in cache. +* \param IsBufferable Region is bufferable, i.e. using write-back caching. Cacheable but non-bufferable regions use write-through policy. +* \param SubRegionDisable Sub-region disable field. +* \param Size Region size of the region to be configured, for example 4K, 8K. +*/ +#define ARM_MPU_RASR(DisableExec, AccessPermission, TypeExtField, IsShareable, IsCacheable, IsBufferable, SubRegionDisable, Size) \ + ARM_MPU_RASR_EX(DisableExec, AccessPermission, ARM_MPU_ACCESS_(TypeExtField, IsShareable, IsCacheable, IsBufferable), SubRegionDisable, Size) + +/** +* MPU Memory Access Attribute for strongly ordered memory. +* - TEX: 000b +* - Shareable +* - Non-cacheable +* - Non-bufferable +*/ +#define ARM_MPU_ACCESS_ORDERED ARM_MPU_ACCESS_(0U, 1U, 0U, 0U) + +/** +* MPU Memory Access Attribute for device memory. +* - TEX: 000b (if non-shareable) or 010b (if shareable) +* - Shareable or non-shareable +* - Non-cacheable +* - Bufferable (if shareable) or non-bufferable (if non-shareable) +* +* \param IsShareable Configures the device memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_DEVICE(IsShareable) ((IsShareable) ? ARM_MPU_ACCESS_(0U, 1U, 0U, 1U) : ARM_MPU_ACCESS_(2U, 0U, 0U, 0U)) + +/** +* MPU Memory Access Attribute for normal memory. +* - TEX: 1BBb (reflecting outer cacheability rules) +* - Shareable or non-shareable +* - Cacheable or non-cacheable (reflecting inner cacheability rules) +* - Bufferable or non-bufferable (reflecting inner cacheability rules) +* +* \param OuterCp Configures the outer cache policy. +* \param InnerCp Configures the inner cache policy. +* \param IsShareable Configures the memory as shareable or non-shareable. +*/ +#define ARM_MPU_ACCESS_NORMAL(OuterCp, InnerCp, IsShareable) ARM_MPU_ACCESS_((4U | (OuterCp)), IsShareable, ((InnerCp) & 2U), ((InnerCp) & 1U)) + +/** +* MPU Memory Access Attribute non-cacheable policy. +*/ +#define ARM_MPU_CACHEP_NOCACHE 0U + +/** +* MPU Memory Access Attribute write-back, write and read allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_WRA 1U + +/** +* MPU Memory Access Attribute write-through, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WT_NWA 2U + +/** +* MPU Memory Access Attribute write-back, no write allocate policy. +*/ +#define ARM_MPU_CACHEP_WB_NWA 3U + + +/** +* Struct for a single MPU Region +*/ +typedef struct { + uint32_t RBAR; //!< The region base address register value (RBAR) + uint32_t RASR; //!< The region attribute and size register value (RASR) \ref MPU_RASR +} ARM_MPU_Region_t; + +/** Enable the MPU. +* \param MPU_Control Default access permissions for unconfigured regions. +*/ +__STATIC_INLINE void ARM_MPU_Enable(uint32_t MPU_Control) +{ + __DSB(); + __ISB(); + MPU->CTRL = MPU_Control | MPU_CTRL_ENABLE_Msk; +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR |= SCB_SHCSR_MEMFAULTENA_Msk; +#endif +} + +/** Disable the MPU. +*/ +__STATIC_INLINE void ARM_MPU_Disable(void) +{ + __DSB(); + __ISB(); +#ifdef SCB_SHCSR_MEMFAULTENA_Msk + SCB->SHCSR &= ~SCB_SHCSR_MEMFAULTENA_Msk; +#endif + MPU->CTRL &= ~MPU_CTRL_ENABLE_Msk; +} + +/** Clear and disable the given MPU region. +* \param rnr Region number to be cleared. +*/ +__STATIC_INLINE void ARM_MPU_ClrRegion(uint32_t rnr) +{ + MPU->RNR = rnr; + MPU->RASR = 0U; +} + +/** Configure an MPU region. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegion(uint32_t rbar, uint32_t rasr) +{ + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Configure the given MPU region. +* \param rnr Region number to be configured. +* \param rbar Value for RBAR register. +* \param rsar Value for RSAR register. +*/ +__STATIC_INLINE void ARM_MPU_SetRegionEx(uint32_t rnr, uint32_t rbar, uint32_t rasr) +{ + MPU->RNR = rnr; + MPU->RBAR = rbar; + MPU->RASR = rasr; +} + +/** Memcopy with strictly ordered memory access, e.g. for register targets. +* \param dst Destination data is copied to. +* \param src Source data is copied from. +* \param len Amount of data words to be copied. +*/ +__STATIC_INLINE void orderedCpy(volatile uint32_t* dst, const uint32_t* __RESTRICT src, uint32_t len) +{ + uint32_t i; + for (i = 0U; i < len; ++i) + { + dst[i] = src[i]; + } +} + +/** Load the given number of MPU regions from a table. +* \param table Pointer to the MPU configuration table. +* \param cnt Amount of regions to be configured. +*/ +__STATIC_INLINE void ARM_MPU_Load(ARM_MPU_Region_t const* table, uint32_t cnt) +{ + const uint32_t rowWordSize = sizeof(ARM_MPU_Region_t)/4U; + while (cnt > MPU_TYPE_RALIASES) { + orderedCpy(&(MPU->RBAR), &(table->RBAR), MPU_TYPE_RALIASES*rowWordSize); + table += MPU_TYPE_RALIASES; + cnt -= MPU_TYPE_RALIASES; + } + orderedCpy(&(MPU->RBAR), &(table->RBAR), cnt*rowWordSize); +} + +#endif diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_armcc.h b/core/arm/CMSIS/Core_A/Include/cmsis_armcc.h new file mode 100644 index 000000000..b2ccb1f2c --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_armcc.h @@ -0,0 +1,544 @@ +/**************************************************************************//** + * @file cmsis_armcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCC_H +#define __CMSIS_ARMCC_H + +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 400677) + #error "Please use Arm Compiler Toolchain V4.0.677 or later!" +#endif + +/* CMSIS compiler control architecture macros */ +#if (defined (__TARGET_ARCH_7_A ) && (__TARGET_ARCH_7_A == 1)) + #define __ARM_ARCH_7A__ 1 +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __forceinline +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE static __forceinline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __declspec(noreturn) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT __packed struct +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #define __UNALIGNED_UINT16_WRITE(addr, val) ((*((__packed uint16_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #define __UNALIGNED_UINT16_READ(addr) (*((const __packed uint16_t *)(addr))) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #define __UNALIGNED_UINT32_WRITE(addr, val) ((*((__packed uint32_t *)(addr))) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #define __UNALIGNED_UINT32_READ(addr) (*((const __packed uint32_t *)(addr))) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __wfi + +/** + \brief Wait For Event + */ +#define __WFE __wfe + +/** + \brief Send Event + */ +#define __SEV __sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV __rev + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE __ASM uint32_t __REV16(uint32_t value) +{ + rev16 r0, r0 + bx lr +} +#endif + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".revsh_text"))) __STATIC_INLINE __ASM int16_t __REVSH(int16_t value) +{ + revsh r0, r0 + bx lr +} +#endif + +/** + \brief Rotate Right in unsigned value (32 bit) + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +#define __ROR __ror + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __breakpoint(value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ __clz + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXB(ptr) ((uint8_t ) __ldrex(ptr)) +#else + #define __LDREXB(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint8_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXH(ptr) ((uint16_t) __ldrex(ptr)) +#else + #define __LDREXH(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint16_t) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __LDREXW(ptr) ((uint32_t ) __ldrex(ptr)) +#else + #define __LDREXW(ptr) _Pragma("push") _Pragma("diag_suppress 3731") ((uint32_t ) __ldrex(ptr)) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXB(value, ptr) __strex(value, ptr) +#else + #define __STREXB(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXH(value, ptr) __strex(value, ptr) +#else + #define __STREXH(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +#if defined(__ARMCC_VERSION) && (__ARMCC_VERSION < 5060020) + #define __STREXW(value, ptr) __strex(value, ptr) +#else + #define __STREXW(value, ptr) _Pragma("push") _Pragma("diag_suppress 3731") __strex(value, ptr) _Pragma("pop") +#endif + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __clrex + + +/** + \brief Signed Saturate + \details 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 + \details 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 + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR (Floating Point Status/Control) + \return Floating Point Status/Control register value + */ +__STATIC_INLINE uint32_t __get_FPSCR(void) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + return(__regfpscr); +#else + return(0U); +#endif +} + +/** + \brief Set FPSCR (Floating Point Status/Control) + \param [in] fpscr Floating Point Status/Control value to set + */ +__STATIC_INLINE void __set_FPSCR(uint32_t fpscr) +{ +#if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + register uint32_t __regfpscr __ASM("fpscr"); + __regfpscr = (fpscr); +#else + (void)fpscr; +#endif +} + +/** \brief Get CPSR (Current Program Status Register) + \return CPSR Register value + */ +__STATIC_INLINE uint32_t __get_CPSR(void) +{ + register uint32_t __regCPSR __ASM("cpsr"); + return(__regCPSR); +} + + +/** \brief Set CPSR (Current Program Status Register) + \param [in] cpsr CPSR value to set + */ +__STATIC_INLINE void __set_CPSR(uint32_t cpsr) +{ + register uint32_t __regCPSR __ASM("cpsr"); + __regCPSR = cpsr; +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_INLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_INLINE __ASM void __set_mode(uint32_t mode) +{ + MOV r1, lr + MSR CPSR_C, r0 + BX r1 +} + +/** \brief Get Stack Pointer + \return Stack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP(void) +{ + MOV r0, sp + BX lr +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP(uint32_t stack) +{ + MOV sp, r0 + BX lr +} + + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYSStack Pointer + */ +__STATIC_INLINE __ASM uint32_t __get_SP_usr(void) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV R0, SP + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_INLINE __ASM void __set_SP_usr(uint32_t topOfProcStack) +{ + ARM + PRESERVE8 + + MRS R1, CPSR + CPS #0x1F ;no effect in USR mode + MOV SP, R0 + MSR CPSR_c, R1 ;no effect in USR mode + ISB + BX LR +} + +/** \brief Get FPEXC (Floating Point Exception Control Register) + \return Floating Point Exception Control Register value + */ +__STATIC_INLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + return(__regfpexc); +#else + return(0); +#endif +} + +/** \brief Set FPEXC (Floating Point Exception Control Register) + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_INLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + register uint32_t __regfpexc __ASM("fpexc"); + __regfpexc = (fpexc); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); (Rt) = tmp; } while(0) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) do { register volatile uint32_t tmp __ASM("cp" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2); tmp = (Rt); } while(0) +#define __get_CP64(cp, op1, Rt, CRm) \ + do { \ + uint32_t ltmp, htmp; \ + __ASM volatile("MRRC p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + (Rt) = ((((uint64_t)htmp) << 32U) | ((uint64_t)ltmp)); \ + } while(0) + +#define __set_CP64(cp, op1, Rt, CRm) \ + do { \ + const uint64_t tmp = (Rt); \ + const uint32_t ltmp = (uint32_t)(tmp); \ + const uint32_t htmp = (uint32_t)(tmp >> 32U); \ + __ASM volatile("MCRR p" # cp ", " # op1 ", ltmp, htmp, c" # CRm); \ + } while(0) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE __ASM void __FPU_Enable(void) +{ + ARM + + //Permit access to VFP/NEON, registers by modifying CPACR + MRC p15,0,R1,c1,c0,2 + ORR R1,R1,#0x00F00000 + MCR p15,0,R1,c1,c0,2 + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + ISB + + //Enable VFP/NEON + VMRS R1,FPEXC + ORR R1,R1,#0x40000000 + VMSR FPEXC,R1 + + //Initialise VFP/NEON registers to 0 + MOV R2,#0 + + //Initialise D16 registers to 0 + VMOV D0, R2,R2 + VMOV D1, R2,R2 + VMOV D2, R2,R2 + VMOV D3, R2,R2 + VMOV D4, R2,R2 + VMOV D5, R2,R2 + VMOV D6, R2,R2 + VMOV D7, R2,R2 + VMOV D8, R2,R2 + VMOV D9, R2,R2 + VMOV D10,R2,R2 + VMOV D11,R2,R2 + VMOV D12,R2,R2 + VMOV D13,R2,R2 + VMOV D14,R2,R2 + VMOV D15,R2,R2 + + IF {TARGET_FEATURE_EXTENSION_REGISTER_COUNT} == 32 + //Initialise D32 registers to 0 + VMOV D16,R2,R2 + VMOV D17,R2,R2 + VMOV D18,R2,R2 + VMOV D19,R2,R2 + VMOV D20,R2,R2 + VMOV D21,R2,R2 + VMOV D22,R2,R2 + VMOV D23,R2,R2 + VMOV D24,R2,R2 + VMOV D25,R2,R2 + VMOV D26,R2,R2 + VMOV D27,R2,R2 + VMOV D28,R2,R2 + VMOV D29,R2,R2 + VMOV D30,R2,R2 + VMOV D31,R2,R2 + ENDIF + + //Initialise FPSCR to a known state + VMRS R2,FPSCR + LDR R3,=0x00086060 //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + AND R2,R2,R3 + VMSR FPSCR,R2 + + BX LR +} + +#endif /* __CMSIS_ARMCC_H */ diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_armclang.h b/core/arm/CMSIS/Core_A/Include/cmsis_armclang.h new file mode 100644 index 000000000..e0de5a458 --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_armclang.h @@ -0,0 +1,503 @@ +/**************************************************************************//** + * @file cmsis_armclang.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_ARMCLANG_H +#define __CMSIS_ARMCLANG_H + +#pragma clang system_header /* treat file as system include file */ + +#ifndef __ARM_COMPAT_H +#include /* Compatibility header for Arm Compiler 5 intrinsics */ +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM __asm +#endif +#ifndef __INLINE + #define __INLINE __inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static __inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static __inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma clang diagnostic push + #pragma clang diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma clang diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed)) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP __builtin_arm_nop + +/** + \brief Wait For Interrupt + */ +#define __WFI __builtin_arm_wfi + +/** + \brief Wait For Event + */ +#define __WFE __builtin_arm_wfe + +/** + \brief Send Event + */ +#define __SEV __builtin_arm_sev + +/** + \brief Instruction Synchronization Barrier + */ +#define __ISB() do {\ + __schedule_barrier();\ + __builtin_arm_isb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Synchronization Barrier + */ +#define __DSB() do {\ + __schedule_barrier();\ + __builtin_arm_dsb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Data Memory Barrier + */ +#define __DMB() do {\ + __schedule_barrier();\ + __builtin_arm_dmb(0xF);\ + __schedule_barrier();\ + } while (0U) + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV(value) __builtin_bswap32(value) + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REV16(value) __ROR(__REV(value), 16) + + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +#define __REVSH(value) (int16_t)__builtin_bswap16(value) + + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) + { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \param [in] value Value to reverse + \return Reversed value + */ +#define __RBIT __builtin_arm_rbit + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +#define __LDREXB (uint8_t)__builtin_arm_ldrex + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +#define __LDREXH (uint16_t)__builtin_arm_ldrex + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +#define __LDREXW (uint32_t)__builtin_arm_ldrex + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction 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 (uint32_t)__builtin_arm_strex + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +#define __CLREX __builtin_arm_clrex + +/** + \brief Signed Saturate + \details 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 __builtin_arm_ssat + +/** + \brief Unsigned Saturate + \details 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 __builtin_arm_usat + + +/* ########################### Core Function Access ########################### */ + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value + */ +#define __get_FPSCR __builtin_arm_get_fpscr + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set + */ +#define __set_FPSCR __builtin_arm_set_fpscr + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP() +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr() +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if __ARM_NEON == 1 + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 " + ); +} + +#endif /* __CMSIS_ARMCLANG_H */ diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_compiler.h b/core/arm/CMSIS/Core_A/Include/cmsis_compiler.h new file mode 100644 index 000000000..cd14cbc04 --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_compiler.h @@ -0,0 +1,201 @@ +/**************************************************************************//** + * @file cmsis_compiler.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 10. January 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_COMPILER_H +#define __CMSIS_COMPILER_H + +#include + +/* + * Arm Compiler 4/5 + */ +#if defined ( __CC_ARM ) + #include "cmsis_armcc.h" + + +/* + * Arm Compiler 6 (armclang) + */ +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #include "cmsis_armclang.h" + + +/* + * GNU Compiler + */ +#elif defined ( __GNUC__ ) + #include "cmsis_gcc.h" + + +/* + * IAR Compiler + */ +#elif defined ( __ICCARM__ ) + #include "cmsis_iccarm.h" + + +/* + * TI Arm Compiler + */ +#elif defined ( __TI_ARM__ ) + #include + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __attribute__((packed)) T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) + #endif + #ifndef __PACKED + #define __PACKED __attribute__((packed)) + #endif + + +/* + * TASKING Compiler + */ +#elif defined ( __TASKING__ ) + /* + * 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. + */ + + #ifndef __ASM + #define __ASM __asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + #define __NO_RETURN __attribute__((noreturn)) + #endif + #ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) + #endif + #ifndef __USED + #define __USED __attribute__((used)) + #endif + #ifndef __WEAK + #define __WEAK __attribute__((weak)) + #endif + #ifndef __UNALIGNED_UINT32 + struct __packed__ T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #define __ALIGNED(x) __align(x) + #endif + #ifndef __PACKED + #define __PACKED __packed__ + #endif + + +/* + * COSMIC Compiler + */ +#elif defined ( __CSMC__ ) + #include + + #ifndef __ASM + #define __ASM _asm + #endif + #ifndef __INLINE + #define __INLINE inline + #endif + #ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline + #endif + #ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __STATIC_INLINE + #endif + #ifndef __NO_RETURN + // NO RETURN is automatically detected hence no warning here + #define __NO_RETURN + #endif + #ifndef __USED + #warning No compiler specific solution for __USED. __USED is ignored. + #define __USED + #endif + #ifndef CMSIS_DEPRECATED + #warning No compiler specific solution for CMSIS_DEPRECATED. CMSIS_DEPRECATED is ignored. + #define CMSIS_DEPRECATED + #endif + #ifndef __WEAK + #define __WEAK __weak + #endif + #ifndef __UNALIGNED_UINT32 + @packed struct T_UINT32 { uint32_t v; }; + #define __UNALIGNED_UINT32(x) (((struct T_UINT32 *)(x))->v) + #endif + #ifndef __ALIGNED + #warning No compiler specific solution for __ALIGNED. __ALIGNED is ignored. + #define __ALIGNED(x) + #endif + #ifndef __PACKED + #define __PACKED @packed + #endif + + +#else + #error Unknown compiler. +#endif + + +#endif /* __CMSIS_COMPILER_H */ + diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_cp15.h b/core/arm/CMSIS/Core_A/Include/cmsis_cp15.h new file mode 100644 index 000000000..75e57b86f --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_cp15.h @@ -0,0 +1,514 @@ +/**************************************************************************//** + * @file cmsis_cp15.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.1 + * @date 07. Sep 2017 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef __CMSIS_CP15_H +#define __CMSIS_CP15_H + +/** \brief Get ACTLR + \return Auxiliary Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return(result); +} + +/** \brief Set ACTLR + \param [in] actlr Auxiliary Control value to set + */ +__STATIC_FORCEINLINE void __set_ACTLR(uint32_t actlr) +{ + __set_CP(15, 0, actlr, 1, 0, 1); +} + +/** \brief Get CPACR + \return Coprocessor Access Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 2); + return result; +} + +/** \brief Set CPACR + \param [in] cpacr Coprocessor Access Control value to set + */ +__STATIC_FORCEINLINE void __set_CPACR(uint32_t cpacr) +{ + __set_CP(15, 0, cpacr, 1, 0, 2); +} + +/** \brief Get DFSR + \return Data Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 0); + return result; +} + +/** \brief Set DFSR + \param [in] dfsr Data Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_DFSR(uint32_t dfsr) +{ + __set_CP(15, 0, dfsr, 5, 0, 0); +} + +/** \brief Get IFSR + \return Instruction Fault Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_IFSR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 5, 0, 1); + return result; +} + +/** \brief Set IFSR + \param [in] ifsr Instruction Fault Status value to set + */ +__STATIC_FORCEINLINE void __set_IFSR(uint32_t ifsr) +{ + __set_CP(15, 0, ifsr, 5, 0, 1); +} + +/** \brief Get ISR + \return Interrupt Status Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ISR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 1, 0); + return result; +} + +/** \brief Get CBAR + \return Configuration Base Address register value + */ +__STATIC_FORCEINLINE uint32_t __get_CBAR(void) +{ + uint32_t result; + __get_CP(15, 4, result, 15, 0, 0); + return result; +} + +/** \brief Get TTBR0 + + This function returns the value of the Translation Table Base Register 0. + + \return Translation Table Base Register 0 value + */ +__STATIC_FORCEINLINE uint32_t __get_TTBR0(void) +{ + uint32_t result; + __get_CP(15, 0, result, 2, 0, 0); + return result; +} + +/** \brief Set TTBR0 + + This function assigns the given value to the Translation Table Base Register 0. + + \param [in] ttbr0 Translation Table Base Register 0 value to set + */ +__STATIC_FORCEINLINE void __set_TTBR0(uint32_t ttbr0) +{ + __set_CP(15, 0, ttbr0, 2, 0, 0); +} + +/** \brief Get DACR + + This function returns the value of the Domain Access Control Register. + + \return Domain Access Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_DACR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 3, 0, 0); + return result; +} + +/** \brief Set DACR + + This function assigns the given value to the Domain Access Control Register. + + \param [in] dacr Domain Access Control Register value to set + */ +__STATIC_FORCEINLINE void __set_DACR(uint32_t dacr) +{ + __set_CP(15, 0, dacr, 3, 0, 0); +} + +/** \brief Set SCTLR + + This function assigns the given value to the System Control Register. + + \param [in] sctlr System Control Register value to set + */ +__STATIC_FORCEINLINE void __set_SCTLR(uint32_t sctlr) +{ + __set_CP(15, 0, sctlr, 1, 0, 0); +} + +/** \brief Get SCTLR + \return System Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_SCTLR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 0); + return result; +} + +/** \brief Set ACTRL + \param [in] actrl Auxiliary Control Register value to set + */ +__STATIC_FORCEINLINE void __set_ACTRL(uint32_t actrl) +{ + __set_CP(15, 0, actrl, 1, 0, 1); +} + +/** \brief Get ACTRL + \return Auxiliary Control Register value + */ +__STATIC_FORCEINLINE uint32_t __get_ACTRL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 1, 0, 1); + return result; +} + +/** \brief Get MPIDR + + This function returns the value of the Multiprocessor Affinity Register. + + \return Multiprocessor Affinity Register value + */ +__STATIC_FORCEINLINE uint32_t __get_MPIDR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 0, 0, 5); + return result; +} + +/** \brief Get VBAR + + This function returns the value of the Vector Base Address Register. + + \return Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_VBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 0); + return result; +} + +/** \brief Set VBAR + + This function assigns the given value to the Vector Base Address Register. + + \param [in] vbar Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_VBAR(uint32_t vbar) +{ + __set_CP(15, 0, vbar, 12, 0, 0); +} + +/** \brief Get MVBAR + + This function returns the value of the Monitor Vector Base Address Register. + + \return Monitor Vector Base Address Register + */ +__STATIC_FORCEINLINE uint32_t __get_MVBAR(void) +{ + uint32_t result; + __get_CP(15, 0, result, 12, 0, 1); + return result; +} + +/** \brief Set MVBAR + + This function assigns the given value to the Monitor Vector Base Address Register. + + \param [in] mvbar Monitor Vector Base Address Register value to set + */ +__STATIC_FORCEINLINE void __set_MVBAR(uint32_t mvbar) +{ + __set_CP(15, 0, mvbar, 12, 0, 1); +} + +#if (defined(__CORTEX_A) && (__CORTEX_A == 7U) && \ + defined(__TIM_PRESENT) && (__TIM_PRESENT == 1U)) || \ + defined(DOXYGEN) + +/** \brief Set CNTFRQ + + This function assigns the given value to PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \param [in] value CNTFRQ Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTFRQ(uint32_t value) +{ + __set_CP(15, 0, value, 14, 0, 0); +} + +/** \brief Get CNTFRQ + + This function returns the value of the PL1 Physical Timer Counter Frequency Register (CNTFRQ). + + \return CNTFRQ Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTFRQ(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 0 , 0); + return result; +} + +/** \brief Set CNTP_TVAL + + This function assigns the given value to PL1 Physical Timer Value Register (CNTP_TVAL). + + \param [in] value CNTP_TVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_TVAL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 0); +} + +/** \brief Get CNTP_TVAL + + This function returns the value of the PL1 Physical Timer Value Register (CNTP_TVAL). + + \return CNTP_TVAL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_TVAL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 0); + return result; +} + +/** \brief Get CNTPCT + + This function returns the value of the 64 bits PL1 Physical Count Register (CNTPCT). + + \return CNTPCT Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTPCT(void) +{ + uint64_t result; + __get_CP64(15, 0, result, 14); + return result; +} + +/** \brief Set CNTP_CVAL + + This function assigns the given value to 64bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \param [in] value CNTP_CVAL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CVAL(uint64_t value) +{ + __set_CP64(15, 2, value, 14); +} + +/** \brief Get CNTP_CVAL + + This function returns the value of the 64 bits PL1 Physical Timer CompareValue Register (CNTP_CVAL). + + \return CNTP_CVAL Register value + */ +__STATIC_FORCEINLINE uint64_t __get_CNTP_CVAL(void) +{ + uint64_t result; + __get_CP64(15, 2, result, 14); + return result; +} + +/** \brief Set CNTP_CTL + + This function assigns the given value to PL1 Physical Timer Control Register (CNTP_CTL). + + \param [in] value CNTP_CTL Register value to set +*/ +__STATIC_FORCEINLINE void __set_CNTP_CTL(uint32_t value) +{ + __set_CP(15, 0, value, 14, 2, 1); +} + +/** \brief Get CNTP_CTL register + \return CNTP_CTL Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CNTP_CTL(void) +{ + uint32_t result; + __get_CP(15, 0, result, 14, 2, 1); + return result; +} + +#endif + +/** \brief Set TLBIALL + + TLB Invalidate All + */ +__STATIC_FORCEINLINE void __set_TLBIALL(uint32_t value) +{ + __set_CP(15, 0, value, 8, 7, 0); +} + +/** \brief Set BPIALL. + + Branch Predictor Invalidate All + */ +__STATIC_FORCEINLINE void __set_BPIALL(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 6); +} + +/** \brief Set ICIALLU + + Instruction Cache Invalidate All + */ +__STATIC_FORCEINLINE void __set_ICIALLU(uint32_t value) +{ + __set_CP(15, 0, value, 7, 5, 0); +} + +/** \brief Set DCCMVAC + + Data cache clean + */ +__STATIC_FORCEINLINE void __set_DCCMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 10, 1); +} + +/** \brief Set DCIMVAC + + Data cache invalidate + */ +__STATIC_FORCEINLINE void __set_DCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 6, 1); +} + +/** \brief Set DCCIMVAC + + Data cache clean and invalidate + */ +__STATIC_FORCEINLINE void __set_DCCIMVAC(uint32_t value) +{ + __set_CP(15, 0, value, 7, 14, 1); +} + +/** \brief Set CSSELR + */ +__STATIC_FORCEINLINE void __set_CSSELR(uint32_t value) +{ +// __ASM volatile("MCR p15, 2, %0, c0, c0, 0" : : "r"(value) : "memory"); + __set_CP(15, 2, value, 0, 0, 0); +} + +/** \brief Get CSSELR + \return CSSELR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CSSELR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 2, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 2, result, 0, 0, 0); + return result; +} + +/** \brief Set CCSIDR + \deprecated CCSIDR itself is read-only. Use __set_CSSELR to select cache level instead. + */ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __set_CCSIDR(uint32_t value) +{ + __set_CSSELR(value); +} + +/** \brief Get CCSIDR + \return CCSIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CCSIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 0" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 0); + return result; +} + +/** \brief Get CLIDR + \return CLIDR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CLIDR(void) +{ + uint32_t result; +// __ASM volatile("MRC p15, 1, %0, c0, c0, 1" : "=r"(result) : : "memory"); + __get_CP(15, 1, result, 0, 0, 1); + return result; +} + +/** \brief Set DCISW + */ +__STATIC_FORCEINLINE void __set_DCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c6, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 6, 2); +} + +/** \brief Set DCCSW + */ +__STATIC_FORCEINLINE void __set_DCCSW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c10, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 10, 2); +} + +/** \brief Set DCCISW + */ +__STATIC_FORCEINLINE void __set_DCCISW(uint32_t value) +{ +// __ASM volatile("MCR p15, 0, %0, c7, c14, 2" : : "r"(value) : "memory") + __set_CP(15, 0, value, 7, 14, 2); +} + +#endif diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_gcc.h b/core/arm/CMSIS/Core_A/Include/cmsis_gcc.h new file mode 100644 index 000000000..fb1442c64 --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_gcc.h @@ -0,0 +1,679 @@ +/**************************************************************************//** + * @file cmsis_gcc.h + * @brief CMSIS compiler specific macros, functions, instructions + * @version V1.0.2 + * @date 09. April 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2018 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef __CMSIS_GCC_H +#define __CMSIS_GCC_H + +/* ignore some GCC warnings */ +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wsign-conversion" +#pragma GCC diagnostic ignored "-Wconversion" +#pragma GCC diagnostic ignored "-Wunused-parameter" + +/* Fallback for __has_builtin */ +#ifndef __has_builtin + #define __has_builtin(x) (0) +#endif + +/* CMSIS compiler specific defines */ +#ifndef __ASM + #define __ASM asm +#endif +#ifndef __INLINE + #define __INLINE inline +#endif +#ifndef __FORCEINLINE + #define __FORCEINLINE __attribute__((always_inline)) +#endif +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __attribute__((always_inline)) static inline +#endif +#ifndef __NO_RETURN + #define __NO_RETURN __attribute__((__noreturn__)) +#endif +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif +#ifndef __USED + #define __USED __attribute__((used)) +#endif +#ifndef __WEAK + #define __WEAK __attribute__((weak)) +#endif +#ifndef __PACKED + #define __PACKED __attribute__((packed, aligned(1))) +#endif +#ifndef __PACKED_STRUCT + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) +#endif +#ifndef __UNALIGNED_UINT16_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_WRITE */ + __PACKED_STRUCT T_UINT16_WRITE { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_WRITE(addr, val) (void)((((struct T_UINT16_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT16_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT16_READ)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT16_READ */ + __PACKED_STRUCT T_UINT16_READ { uint16_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT16_READ(addr) (((const struct T_UINT16_READ *)(const void *)(addr))->v) +#endif +#ifndef __UNALIGNED_UINT32_WRITE + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" +/*lint -esym(9058, T_UINT32_WRITE)*/ /* disable MISRA 2012 Rule 2.4 for T_UINT32_WRITE */ + __PACKED_STRUCT T_UINT32_WRITE { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_WRITE(addr, val) (void)((((struct T_UINT32_WRITE *)(void *)(addr))->v) = (val)) +#endif +#ifndef __UNALIGNED_UINT32_READ + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wpacked" + __PACKED_STRUCT T_UINT32_READ { uint32_t v; }; + #pragma GCC diagnostic pop + #define __UNALIGNED_UINT32_READ(addr) (((const struct T_UINT32_READ *)(const void *)(addr))->v) +#endif +#ifndef __ALIGNED + #define __ALIGNED(x) __attribute__((aligned(x))) +#endif + +/* ########################## Core Instruction Access ######################### */ +/** + \brief No Operation + */ +#define __NOP() __ASM volatile ("nop") + +/** + \brief Wait For Interrupt + */ +#define __WFI() __ASM volatile ("wfi") + +/** + \brief Wait For Event + */ +#define __WFE() __ASM volatile ("wfe") + +/** + \brief Send Event + */ +#define __SEV() __ASM volatile ("sev") + +/** + \brief Instruction Synchronization Barrier + \details 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. + */ +__STATIC_FORCEINLINE void __ISB(void) +{ + __ASM volatile ("isb 0xF":::"memory"); +} + + +/** + \brief Data Synchronization Barrier + \details Acts as a special kind of Data Memory Barrier. + It completes when all explicit memory accesses before this instruction complete. + */ +__STATIC_FORCEINLINE void __DSB(void) +{ + __ASM volatile ("dsb 0xF":::"memory"); +} + +/** + \brief Data Memory Barrier + \details Ensures the apparent order of the explicit memory operations before + and after the instruction, without ensuring their completion. + */ +__STATIC_FORCEINLINE void __DMB(void) +{ + __ASM volatile ("dmb 0xF":::"memory"); +} + +/** + \brief Reverse byte order (32 bit) + \details Reverses the byte order in unsigned integer value. For example, 0x12345678 becomes 0x78563412. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __REV(uint32_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5) + return __builtin_bswap32(value); +#else + uint32_t result; + + __ASM volatile ("rev %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order within each halfword of a word. For example, 0x12345678 becomes 0x34127856. + \param [in] value Value to reverse + \return Reversed value + */ +#ifndef __NO_EMBEDDED_ASM +__attribute__((section(".rev16_text"))) __STATIC_INLINE uint32_t __REV16(uint32_t value) +{ + uint32_t result; + __ASM volatile("rev16 %0, %1" : "=r" (result) : "r" (value)); + return result; +} +#endif + +/** + \brief Reverse byte order (16 bit) + \details Reverses the byte order in a 16-bit value and returns the signed 16-bit result. For example, 0x0080 becomes 0x8000. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE int16_t __REVSH(int16_t value) +{ +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + return (int16_t)__builtin_bswap16(value); +#else + int16_t result; + + __ASM volatile ("revsh %0, %1" : __CMSIS_GCC_OUT_REG (result) : __CMSIS_GCC_USE_REG (value) ); + return result; +#endif +} + +/** + \brief Rotate Right in unsigned value (32 bit) + \details Rotate Right (immediate) provides the value of the contents of a register rotated by a variable number of bits. + \param [in] op1 Value to rotate + \param [in] op2 Number of Bits to rotate + \return Rotated value + */ +__STATIC_FORCEINLINE uint32_t __ROR(uint32_t op1, uint32_t op2) +{ + op2 %= 32U; + if (op2 == 0U) { + return op1; + } + return (op1 >> op2) | (op1 << (32U - op2)); +} + + +/** + \brief Breakpoint + \param [in] value is ignored by the processor. + If required, a debugger can use it to store additional information about the breakpoint. + */ +#define __BKPT(value) __ASM volatile ("bkpt "#value) + +/** + \brief Reverse bit order of value + \details Reverses the bit order of the given value. + \param [in] value Value to reverse + \return Reversed value + */ +__STATIC_FORCEINLINE uint32_t __RBIT(uint32_t value) +{ + uint32_t result; + +#if ((defined (__ARM_ARCH_7M__ ) && (__ARM_ARCH_7M__ == 1)) || \ + (defined (__ARM_ARCH_7EM__ ) && (__ARM_ARCH_7EM__ == 1)) || \ + (defined (__ARM_ARCH_8M_MAIN__ ) && (__ARM_ARCH_8M_MAIN__ == 1)) ) + __ASM volatile ("rbit %0, %1" : "=r" (result) : "r" (value) ); +#else + int32_t s = (4U /*sizeof(v)*/ * 8U) - 1U; /* extra shift needed at end */ + + result = value; /* r will be reversed bits of v; first get LSB of v */ + for (value >>= 1U; value; value >>= 1U) + { + result <<= 1U; + result |= value & 1U; + s--; + } + result <<= s; /* shift when v's highest bits are zero */ +#endif + return result; +} + +/** + \brief Count leading zeros + \param [in] value Value to count the leading zeros + \return number of leading zeros in value + */ +#define __CLZ (uint8_t)__builtin_clz + +/** + \brief LDR Exclusive (8 bit) + \details Executes a exclusive LDR instruction for 8 bit value. + \param [in] ptr Pointer to data + \return value of type uint8_t at (*ptr) + */ +__STATIC_FORCEINLINE uint8_t __LDREXB(volatile uint8_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexb %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexb %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint8_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (16 bit) + \details Executes a exclusive LDR instruction for 16 bit values. + \param [in] ptr Pointer to data + \return value of type uint16_t at (*ptr) + */ +__STATIC_FORCEINLINE uint16_t __LDREXH(volatile uint16_t *addr) +{ + uint32_t result; + +#if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 8) + __ASM volatile ("ldrexh %0, %1" : "=r" (result) : "Q" (*addr) ); +#else + /* Prior to GCC 4.8, "Q" will be expanded to [rx, #0] which is not + accepted by assembler. So has to use following less efficient pattern. + */ + __ASM volatile ("ldrexh %0, [%1]" : "=r" (result) : "r" (addr) : "memory" ); +#endif + return ((uint16_t) result); /* Add explicit type cast here */ +} + + +/** + \brief LDR Exclusive (32 bit) + \details Executes a exclusive LDR instruction for 32 bit values. + \param [in] ptr Pointer to data + \return value of type uint32_t at (*ptr) + */ +__STATIC_FORCEINLINE uint32_t __LDREXW(volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("ldrex %0, %1" : "=r" (result) : "Q" (*addr) ); + return(result); +} + + +/** + \brief STR Exclusive (8 bit) + \details Executes a exclusive STR instruction for 8 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXB(uint8_t value, volatile uint8_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexb %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (16 bit) + \details Executes a exclusive STR instruction for 16 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXH(uint16_t value, volatile uint16_t *addr) +{ + uint32_t result; + + __ASM volatile ("strexh %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" ((uint32_t)value) ); + return(result); +} + + +/** + \brief STR Exclusive (32 bit) + \details Executes a exclusive STR instruction for 32 bit values. + \param [in] value Value to store + \param [in] ptr Pointer to location + \return 0 Function succeeded + \return 1 Function failed + */ +__STATIC_FORCEINLINE uint32_t __STREXW(uint32_t value, volatile uint32_t *addr) +{ + uint32_t result; + + __ASM volatile ("strex %0, %2, %1" : "=&r" (result), "=Q" (*addr) : "r" (value) ); + return(result); +} + + +/** + \brief Remove the exclusive lock + \details Removes the exclusive lock which is created by LDREX. + */ +__STATIC_FORCEINLINE void __CLREX(void) +{ + __ASM volatile ("clrex" ::: "memory"); +} + +/** + \brief Signed Saturate + \details 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) \ +__extension__ \ +({ \ + int32_t __RES, __ARG1 = (ARG1); \ + __ASM ("ssat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + + +/** + \brief Unsigned Saturate + \details 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) \ +__extension__ \ +({ \ + uint32_t __RES, __ARG1 = (ARG1); \ + __ASM ("usat %0, %1, %2" : "=r" (__RES) : "I" (ARG2), "r" (__ARG1) ); \ + __RES; \ + }) + +/* ########################### Core Function Access ########################### */ + +/** + \brief Enable IRQ Interrupts + \details Enables IRQ interrupts by clearing the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __enable_irq(void) +{ + __ASM volatile ("cpsie i" : : : "memory"); +} + +/** + \brief Disable IRQ Interrupts + \details Disables IRQ interrupts by setting the I-bit in the CPSR. + Can only be executed in Privileged modes. + */ +__STATIC_FORCEINLINE void __disable_irq(void) +{ + __ASM volatile ("cpsid i" : : : "memory"); +} + +/** + \brief Get FPSCR + \details Returns the current value of the Floating Point Status/Control register. + \return Floating Point Status/Control register value +*/ +__STATIC_FORCEINLINE uint32_t __get_FPSCR(void) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_get_fpscr) + // Re-enable using built-in when GCC has been fixed + // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + return __builtin_arm_get_fpscr(); + #else + uint32_t result; + + __ASM volatile ("VMRS %0, fpscr" : "=r" (result) ); + return(result); + #endif + #else + return(0U); + #endif +} + +/** + \brief Set FPSCR + \details Assigns the given value to the Floating Point Status/Control register. + \param [in] fpscr Floating Point Status/Control value to set +*/ +__STATIC_FORCEINLINE void __set_FPSCR(uint32_t fpscr) +{ + #if ((defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U)) && \ + (defined (__FPU_USED ) && (__FPU_USED == 1U)) ) + #if __has_builtin(__builtin_arm_set_fpscr) + // Re-enable using built-in when GCC has been fixed + // || (__GNUC__ > 7) || (__GNUC__ == 7 && __GNUC_MINOR__ >= 2) + /* see https://gcc.gnu.org/ml/gcc-patches/2017-04/msg00443.html */ + __builtin_arm_set_fpscr(fpscr); + #else + __ASM volatile ("VMSR fpscr, %0" : : "r" (fpscr) : "vfpcc", "memory"); + #endif + #else + (void)fpscr; + #endif +} + +/** \brief Get CPSR Register + \return CPSR Register value + */ +__STATIC_FORCEINLINE uint32_t __get_CPSR(void) +{ + uint32_t result; + __ASM volatile("MRS %0, cpsr" : "=r" (result) ); + return(result); +} + +/** \brief Set CPSR Register + \param [in] cpsr CPSR value to set + */ +__STATIC_FORCEINLINE void __set_CPSR(uint32_t cpsr) +{ +__ASM volatile ("MSR cpsr, %0" : : "r" (cpsr) : "memory"); +} + +/** \brief Get Mode + \return Processor Mode + */ +__STATIC_FORCEINLINE uint32_t __get_mode(void) +{ + return (__get_CPSR() & 0x1FU); +} + +/** \brief Set Mode + \param [in] mode Mode value to set + */ +__STATIC_FORCEINLINE void __set_mode(uint32_t mode) +{ + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); +} + +/** \brief Get Stack Pointer + \return Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP(void) +{ + uint32_t result; + __ASM volatile("MOV %0, sp" : "=r" (result) : : "memory"); + return result; +} + +/** \brief Set Stack Pointer + \param [in] stack Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP(uint32_t stack) +{ + __ASM volatile("MOV sp, %0" : : "r" (stack) : "memory"); +} + +/** \brief Get USR/SYS Stack Pointer + \return USR/SYS Stack Pointer value + */ +__STATIC_FORCEINLINE uint32_t __get_SP_usr(void) +{ + uint32_t cpsr = __get_CPSR(); + uint32_t result; + __ASM volatile( + "CPS #0x1F \n" + "MOV %0, sp " : "=r"(result) : : "memory" + ); + __set_CPSR(cpsr); + __ISB(); + return result; +} + +/** \brief Set USR/SYS Stack Pointer + \param [in] topOfProcStack USR/SYS Stack Pointer value to set + */ +__STATIC_FORCEINLINE void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr = __get_CPSR(); + __ASM volatile( + "CPS #0x1F \n" + "MOV sp, %0 " : : "r" (topOfProcStack) : "memory" + ); + __set_CPSR(cpsr); + __ISB(); +} + +/** \brief Get FPEXC + \return Floating Point Exception Control register value + */ +__STATIC_FORCEINLINE uint32_t __get_FPEXC(void) +{ +#if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) ); + return(result); +#else + return(0); +#endif +} + +/** \brief Set FPEXC + \param [in] fpexc Floating Point Exception Control value to set + */ +__STATIC_FORCEINLINE void __set_FPEXC(uint32_t fpexc) +{ +#if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); +#endif +} + +/* + * Include common core functions to access Coprocessor 15 registers + */ + +#define __get_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) +#define __set_CP(cp, op1, Rt, CRn, CRm, op2) __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) +#define __get_CP64(cp, op1, Rt, CRm) __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) +#define __set_CP64(cp, op1, Rt, CRm) __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + +#include "cmsis_cp15.h" + +/** \brief Enable Floating Point Unit + + Critical section, called from undef handler, so systick is disabled + */ +__STATIC_INLINE void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#if (defined(__ARM_NEON) && (__ARM_NEON == 1)) + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " LDR R3,=0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 " + ); +} + +#pragma GCC diagnostic pop + +#endif /* __CMSIS_GCC_H */ diff --git a/core/arm/CMSIS/Core_A/Include/cmsis_iccarm.h b/core/arm/CMSIS/Core_A/Include/cmsis_iccarm.h new file mode 100644 index 000000000..c46c39713 --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/cmsis_iccarm.h @@ -0,0 +1,559 @@ +/**************************************************************************//** + * @file cmsis_iccarm.h + * @brief CMSIS compiler ICCARM (IAR Compiler for Arm) header file + * @version V5.0.6 + * @date 02. March 2018 + ******************************************************************************/ + +//------------------------------------------------------------------------------ +// +// Copyright (c) 2017-2018 IAR Systems +// +// Licensed under the Apache License, Version 2.0 (the "License") +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +//------------------------------------------------------------------------------ + + +#ifndef __CMSIS_ICCARM_H__ +#define __CMSIS_ICCARM_H__ + +#ifndef __ICCARM__ + #error This file should only be compiled by ICCARM +#endif + +#pragma system_include + +#define __IAR_FT _Pragma("inline=forced") __intrinsic + +#if (__VER__ >= 8000000) + #define __ICCARM_V8 1 +#else + #define __ICCARM_V8 0 +#endif + +#pragma language=extended + +#ifndef __ALIGNED + #if __ICCARM_V8 + #define __ALIGNED(x) __attribute__((aligned(x))) + #elif (__VER__ >= 7080000) + /* Needs IAR language extensions */ + #define __ALIGNED(x) __attribute__((aligned(x))) + #else + #warning No compiler specific solution for __ALIGNED.__ALIGNED is ignored. + #define __ALIGNED(x) + #endif +#endif + + +/* Define compiler macros for CPU architecture, used in CMSIS 5. + */ +#if __ARM_ARCH_7A__ +/* Macro already defined */ +#else + #if defined(__ARM7A__) + #define __ARM_ARCH_7A__ 1 + #endif +#endif + +#ifndef __ASM + #define __ASM __asm +#endif + +#ifndef __INLINE + #define __INLINE inline +#endif + +#ifndef __NO_RETURN + #if __ICCARM_V8 + #define __NO_RETURN __attribute__((__noreturn__)) + #else + #define __NO_RETURN _Pragma("object_attribute=__noreturn") + #endif +#endif + +#ifndef __PACKED + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED __attribute__((packed, aligned(1))) + #else + #define __PACKED __packed + #endif +#endif + +#ifndef __PACKED_STRUCT + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_STRUCT struct __attribute__((packed, aligned(1))) + #else + #define __PACKED_STRUCT __packed struct + #endif +#endif + +#ifndef __PACKED_UNION + /* Needs IAR language extensions */ + #if __ICCARM_V8 + #define __PACKED_UNION union __attribute__((packed, aligned(1))) + #else + #define __PACKED_UNION __packed union + #endif +#endif + +#ifndef __RESTRICT + #define __RESTRICT __restrict +#endif + +#ifndef __STATIC_INLINE + #define __STATIC_INLINE static inline +#endif + +#ifndef __FORCEINLINE + #define __FORCEINLINE _Pragma("inline=forced") +#endif + +#ifndef __STATIC_FORCEINLINE + #define __STATIC_FORCEINLINE __FORCEINLINE __STATIC_INLINE +#endif + +#ifndef CMSIS_DEPRECATED + #define CMSIS_DEPRECATED __attribute__((deprecated)) +#endif + +#ifndef __UNALIGNED_UINT16_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint16_t __iar_uint16_read(void const *ptr) + { + return *(__packed uint16_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT16_READ(PTR) __iar_uint16_read(PTR) +#endif + + +#ifndef __UNALIGNED_UINT16_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint16_write(void const *ptr, uint16_t val) + { + *(__packed uint16_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT16_WRITE(PTR,VAL) __iar_uint16_write(PTR,VAL) +#endif + +#ifndef __UNALIGNED_UINT32_READ + #pragma language=save + #pragma language=extended + __IAR_FT uint32_t __iar_uint32_read(void const *ptr) + { + return *(__packed uint32_t*)(ptr); + } + #pragma language=restore + #define __UNALIGNED_UINT32_READ(PTR) __iar_uint32_read(PTR) +#endif + +#ifndef __UNALIGNED_UINT32_WRITE + #pragma language=save + #pragma language=extended + __IAR_FT void __iar_uint32_write(void const *ptr, uint32_t val) + { + *(__packed uint32_t*)(ptr) = val;; + } + #pragma language=restore + #define __UNALIGNED_UINT32_WRITE(PTR,VAL) __iar_uint32_write(PTR,VAL) +#endif + +#if 0 +#ifndef __UNALIGNED_UINT32 /* deprecated */ + #pragma language=save + #pragma language=extended + __packed struct __iar_u32 { uint32_t v; }; + #pragma language=restore + #define __UNALIGNED_UINT32(PTR) (((struct __iar_u32 *)(PTR))->v) +#endif +#endif + +#ifndef __USED + #if __ICCARM_V8 + #define __USED __attribute__((used)) + #else + #define __USED _Pragma("__root") + #endif +#endif + +#ifndef __WEAK + #if __ICCARM_V8 + #define __WEAK __attribute__((weak)) + #else + #define __WEAK _Pragma("__weak") + #endif +#endif + + +#ifndef __ICCARM_INTRINSICS_VERSION__ + #define __ICCARM_INTRINSICS_VERSION__ 0 +#endif + +#if __ICCARM_INTRINSICS_VERSION__ == 2 + + #if defined(__CLZ) + #undef __CLZ + #endif + #if defined(__REVSH) + #undef __REVSH + #endif + #if defined(__RBIT) + #undef __RBIT + #endif + #if defined(__SSAT) + #undef __SSAT + #endif + #if defined(__USAT) + #undef __USAT + #endif + + #include "iccarm_builtin.h" + + #define __enable_irq __iar_builtin_enable_interrupt + #define __disable_irq __iar_builtin_disable_interrupt + #define __enable_fault_irq __iar_builtin_enable_fiq + #define __disable_fault_irq __iar_builtin_disable_fiq + #define __arm_rsr __iar_builtin_rsr + #define __arm_wsr __iar_builtin_wsr + + #if __FPU_PRESENT + #define __get_FPSCR() (__arm_rsr("FPSCR")) + #else + #define __get_FPSCR() ( 0 ) + #endif + + #define __set_FPSCR(VALUE) (__arm_wsr("FPSCR", VALUE)) + + #define __get_CPSR() (__arm_rsr("CPSR")) + #define __get_mode() (__get_CPSR() & 0x1FU) + + #define __set_CPSR(VALUE) (__arm_wsr("CPSR", (VALUE))) + #define __set_mode(VALUE) (__arm_wsr("CPSR_c", (VALUE))) + + + #define __get_FPEXC() (__arm_rsr("FPEXC")) + #define __set_FPEXC(VALUE) (__arm_wsr("FPEXC", VALUE)) + + #define __get_CP(cp, op1, RT, CRn, CRm, op2) \ + ((RT) = __arm_rsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2)) + + #define __set_CP(cp, op1, RT, CRn, CRm, op2) \ + (__arm_wsr("p" # cp ":" # op1 ":c" # CRn ":c" # CRm ":" # op2, (RT))) + + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "cmsis_cp15.h" + + #define __NOP __iar_builtin_no_operation + + #define __CLZ __iar_builtin_CLZ + #define __CLREX __iar_builtin_CLREX + + #define __DMB __iar_builtin_DMB + #define __DSB __iar_builtin_DSB + #define __ISB __iar_builtin_ISB + + #define __LDREXB __iar_builtin_LDREXB + #define __LDREXH __iar_builtin_LDREXH + #define __LDREXW __iar_builtin_LDREX + + #define __RBIT __iar_builtin_RBIT + #define __REV __iar_builtin_REV + #define __REV16 __iar_builtin_REV16 + + __IAR_FT int16_t __REVSH(int16_t val) + { + return (int16_t) __iar_builtin_REVSH(val); + } + + #define __ROR __iar_builtin_ROR + #define __RRX __iar_builtin_RRX + + #define __SEV __iar_builtin_SEV + + #define __SSAT __iar_builtin_SSAT + + #define __STREXB __iar_builtin_STREXB + #define __STREXH __iar_builtin_STREXH + #define __STREXW __iar_builtin_STREX + + #define __USAT __iar_builtin_USAT + + #define __WFE __iar_builtin_WFE + #define __WFI __iar_builtin_WFI + + #define __SADD8 __iar_builtin_SADD8 + #define __QADD8 __iar_builtin_QADD8 + #define __SHADD8 __iar_builtin_SHADD8 + #define __UADD8 __iar_builtin_UADD8 + #define __UQADD8 __iar_builtin_UQADD8 + #define __UHADD8 __iar_builtin_UHADD8 + #define __SSUB8 __iar_builtin_SSUB8 + #define __QSUB8 __iar_builtin_QSUB8 + #define __SHSUB8 __iar_builtin_SHSUB8 + #define __USUB8 __iar_builtin_USUB8 + #define __UQSUB8 __iar_builtin_UQSUB8 + #define __UHSUB8 __iar_builtin_UHSUB8 + #define __SADD16 __iar_builtin_SADD16 + #define __QADD16 __iar_builtin_QADD16 + #define __SHADD16 __iar_builtin_SHADD16 + #define __UADD16 __iar_builtin_UADD16 + #define __UQADD16 __iar_builtin_UQADD16 + #define __UHADD16 __iar_builtin_UHADD16 + #define __SSUB16 __iar_builtin_SSUB16 + #define __QSUB16 __iar_builtin_QSUB16 + #define __SHSUB16 __iar_builtin_SHSUB16 + #define __USUB16 __iar_builtin_USUB16 + #define __UQSUB16 __iar_builtin_UQSUB16 + #define __UHSUB16 __iar_builtin_UHSUB16 + #define __SASX __iar_builtin_SASX + #define __QASX __iar_builtin_QASX + #define __SHASX __iar_builtin_SHASX + #define __UASX __iar_builtin_UASX + #define __UQASX __iar_builtin_UQASX + #define __UHASX __iar_builtin_UHASX + #define __SSAX __iar_builtin_SSAX + #define __QSAX __iar_builtin_QSAX + #define __SHSAX __iar_builtin_SHSAX + #define __USAX __iar_builtin_USAX + #define __UQSAX __iar_builtin_UQSAX + #define __UHSAX __iar_builtin_UHSAX + #define __USAD8 __iar_builtin_USAD8 + #define __USADA8 __iar_builtin_USADA8 + #define __SSAT16 __iar_builtin_SSAT16 + #define __USAT16 __iar_builtin_USAT16 + #define __UXTB16 __iar_builtin_UXTB16 + #define __UXTAB16 __iar_builtin_UXTAB16 + #define __SXTB16 __iar_builtin_SXTB16 + #define __SXTAB16 __iar_builtin_SXTAB16 + #define __SMUAD __iar_builtin_SMUAD + #define __SMUADX __iar_builtin_SMUADX + #define __SMMLA __iar_builtin_SMMLA + #define __SMLAD __iar_builtin_SMLAD + #define __SMLADX __iar_builtin_SMLADX + #define __SMLALD __iar_builtin_SMLALD + #define __SMLALDX __iar_builtin_SMLALDX + #define __SMUSD __iar_builtin_SMUSD + #define __SMUSDX __iar_builtin_SMUSDX + #define __SMLSD __iar_builtin_SMLSD + #define __SMLSDX __iar_builtin_SMLSDX + #define __SMLSLD __iar_builtin_SMLSLD + #define __SMLSLDX __iar_builtin_SMLSLDX + #define __SEL __iar_builtin_SEL + #define __QADD __iar_builtin_QADD + #define __QSUB __iar_builtin_QSUB + #define __PKHBT __iar_builtin_PKHBT + #define __PKHTB __iar_builtin_PKHTB + +#else /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + + #if !__FPU_PRESENT + #define __get_FPSCR __cmsis_iar_get_FPSR_not_active + #endif + + #ifdef __INTRINSICS_INCLUDED + #error intrinsics.h is already included previously! + #endif + + #include + + #if !__FPU_PRESENT + #define __get_FPSCR() (0) + #endif + + #pragma diag_suppress=Pe940 + #pragma diag_suppress=Pe177 + + #define __enable_irq __enable_interrupt + #define __disable_irq __disable_interrupt + #define __enable_fault_irq __enable_fiq + #define __disable_fault_irq __disable_fiq + #define __NOP __no_operation + + #define __get_xPSR __get_PSR + + __IAR_FT void __set_mode(uint32_t mode) + { + __ASM volatile("MSR cpsr_c, %0" : : "r" (mode) : "memory"); + } + + __IAR_FT uint32_t __LDREXW(uint32_t volatile *ptr) + { + return __LDREX((unsigned long *)ptr); + } + + __IAR_FT uint32_t __STREXW(uint32_t value, uint32_t volatile *ptr) + { + return __STREX(value, (unsigned long *)ptr); + } + + + __IAR_FT uint32_t __RRX(uint32_t value) + { + uint32_t result; + __ASM("RRX %0, %1" : "=r"(result) : "r" (value) : "cc"); + return(result); + } + + + __IAR_FT uint32_t __ROR(uint32_t op1, uint32_t op2) + { + return (op1 >> op2) | (op1 << ((sizeof(op1)*8)-op2)); + } + + __IAR_FT uint32_t __get_FPEXC(void) + { + #if (__FPU_PRESENT == 1) + uint32_t result; + __ASM volatile("VMRS %0, fpexc" : "=r" (result) : : "memory"); + return(result); + #else + return(0); + #endif + } + + __IAR_FT void __set_FPEXC(uint32_t fpexc) + { + #if (__FPU_PRESENT == 1) + __ASM volatile ("VMSR fpexc, %0" : : "r" (fpexc) : "memory"); + #endif + } + + + #define __get_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MRC p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : "=r" (Rt) : : "memory" ) + #define __set_CP(cp, op1, Rt, CRn, CRm, op2) \ + __ASM volatile("MCR p" # cp ", " # op1 ", %0, c" # CRn ", c" # CRm ", " # op2 : : "r" (Rt) : "memory" ) + #define __get_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MRRC p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : "=r" (Rt) : : "memory" ) + #define __set_CP64(cp, op1, Rt, CRm) \ + __ASM volatile("MCRR p" # cp ", " # op1 ", %Q0, %R0, c" # CRm : : "r" (Rt) : "memory" ) + + #include "cmsis_cp15.h" + +#endif /* __ICCARM_INTRINSICS_VERSION__ == 2 */ + +#define __BKPT(value) __asm volatile ("BKPT %0" : : "i"(value)) + + +__IAR_FT uint32_t __get_SP_usr(void) +{ + uint32_t cpsr; + uint32_t result; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV %1, sp \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr), "=r"(result) : "r"(cpsr) : "memory" + ); + return result; +} + +__IAR_FT void __set_SP_usr(uint32_t topOfProcStack) +{ + uint32_t cpsr; + __ASM volatile( + "MRS %0, cpsr \n" + "CPS #0x1F \n" // no effect in USR mode + "MOV sp, %1 \n" + "MSR cpsr_c, %2 \n" // no effect in USR mode + "ISB" : "=r"(cpsr) : "r" (topOfProcStack), "r"(cpsr) : "memory" + ); +} + +#define __get_mode() (__get_CPSR() & 0x1FU) + +__STATIC_INLINE +void __FPU_Enable(void) +{ + __ASM volatile( + //Permit access to VFP/NEON, registers by modifying CPACR + " MRC p15,0,R1,c1,c0,2 \n" + " ORR R1,R1,#0x00F00000 \n" + " MCR p15,0,R1,c1,c0,2 \n" + + //Ensure that subsequent instructions occur in the context of VFP/NEON access permitted + " ISB \n" + + //Enable VFP/NEON + " VMRS R1,FPEXC \n" + " ORR R1,R1,#0x40000000 \n" + " VMSR FPEXC,R1 \n" + + //Initialise VFP/NEON registers to 0 + " MOV R2,#0 \n" + + //Initialise D16 registers to 0 + " VMOV D0, R2,R2 \n" + " VMOV D1, R2,R2 \n" + " VMOV D2, R2,R2 \n" + " VMOV D3, R2,R2 \n" + " VMOV D4, R2,R2 \n" + " VMOV D5, R2,R2 \n" + " VMOV D6, R2,R2 \n" + " VMOV D7, R2,R2 \n" + " VMOV D8, R2,R2 \n" + " VMOV D9, R2,R2 \n" + " VMOV D10,R2,R2 \n" + " VMOV D11,R2,R2 \n" + " VMOV D12,R2,R2 \n" + " VMOV D13,R2,R2 \n" + " VMOV D14,R2,R2 \n" + " VMOV D15,R2,R2 \n" + +#ifdef __ARM_ADVANCED_SIMD__ + //Initialise D32 registers to 0 + " VMOV D16,R2,R2 \n" + " VMOV D17,R2,R2 \n" + " VMOV D18,R2,R2 \n" + " VMOV D19,R2,R2 \n" + " VMOV D20,R2,R2 \n" + " VMOV D21,R2,R2 \n" + " VMOV D22,R2,R2 \n" + " VMOV D23,R2,R2 \n" + " VMOV D24,R2,R2 \n" + " VMOV D25,R2,R2 \n" + " VMOV D26,R2,R2 \n" + " VMOV D27,R2,R2 \n" + " VMOV D28,R2,R2 \n" + " VMOV D29,R2,R2 \n" + " VMOV D30,R2,R2 \n" + " VMOV D31,R2,R2 \n" +#endif + + //Initialise FPSCR to a known state + " VMRS R2,FPSCR \n" + " MOV32 R3,#0x00086060 \n" //Mask off all bits that do not have to be preserved. Non-preserved bits can/should be zero. + " AND R2,R2,R3 \n" + " VMSR FPSCR,R2 \n"); +} + + + +#undef __IAR_FT +#undef __ICCARM_V8 + +#pragma diag_default=Pe940 +#pragma diag_default=Pe177 + +#endif /* __CMSIS_ICCARM_H__ */ diff --git a/core/arm/CMSIS/Core_A/Include/core_ca.h b/core/arm/CMSIS/Core_A/Include/core_ca.h new file mode 100644 index 000000000..c7b451ffe --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/core_ca.h @@ -0,0 +1,2614 @@ +/**************************************************************************//** + * @file core_ca.h + * @brief CMSIS Cortex-A Core Peripheral Access Layer Header File + * @version V1.0.1 + * @date 07. May 2018 + ******************************************************************************/ +/* + * Copyright (c) 2009-2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifdef __cplusplus + extern "C" { +#endif + +#ifndef __CORE_CA_H_GENERIC +#define __CORE_CA_H_GENERIC + + +/******************************************************************************* + * CMSIS definitions + ******************************************************************************/ + +/* CMSIS CA definitions */ +#define __CA_CMSIS_VERSION_MAIN (1U) /*!< \brief [31:16] CMSIS-Core(A) main version */ +#define __CA_CMSIS_VERSION_SUB (1U) /*!< \brief [15:0] CMSIS-Core(A) sub version */ +#define __CA_CMSIS_VERSION ((__CA_CMSIS_VERSION_MAIN << 16U) | \ + __CA_CMSIS_VERSION_SUB ) /*!< \brief CMSIS-Core(A) version number */ + +#if defined ( __CC_ARM ) + #if defined __TARGET_FPU_VFP + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050) + #if defined __ARM_PCS_VFP + #if defined (__FPU_PRESENT) && (__FPU_PRESENT == 1U) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __ICCARM__ ) + #if defined __ARMVFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TMS470__ ) + #if defined __TI_VFP_SUPPORT__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __GNUC__ ) + #if defined (__VFP_FP__) && !defined(__SOFTFP__) + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #warning "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif + +#elif defined ( __TASKING__ ) + #if defined __FPU_VFP__ + #if (__FPU_PRESENT == 1) + #define __FPU_USED 1U + #else + #error "Compiler generates FPU instructions for a device without an FPU (check __FPU_PRESENT)" + #define __FPU_USED 0U + #endif + #else + #define __FPU_USED 0U + #endif +#endif + +#include "cmsis_compiler.h" /* CMSIS compiler specific defines */ + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_GENERIC */ + +#ifndef __CMSIS_GENERIC + +#ifndef __CORE_CA_H_DEPENDANT +#define __CORE_CA_H_DEPENDANT + +#ifdef __cplusplus + extern "C" { +#endif + + /* check device defines and use defaults */ +#if defined __CHECK_DEVICE_DEFINES + #ifndef __CA_REV + #define __CA_REV 0x0000U + #warning "__CA_REV not defined in device header file; using default!" + #endif + + #ifndef __FPU_PRESENT + #define __FPU_PRESENT 0U + #warning "__FPU_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __GIC_PRESENT + #define __GIC_PRESENT 1U + #warning "__GIC_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __TIM_PRESENT + #define __TIM_PRESENT 1U + #warning "__TIM_PRESENT not defined in device header file; using default!" + #endif + + #ifndef __L2C_PRESENT + #define __L2C_PRESENT 0U + #warning "__L2C_PRESENT not defined in device header file; using default!" + #endif +#endif + +/* IO definitions (access restrictions to peripheral registers) */ +#ifdef __cplusplus + #define __I volatile /*!< \brief Defines 'read only' permissions */ +#else + #define __I volatile const /*!< \brief Defines 'read only' permissions */ +#endif +#define __O volatile /*!< \brief Defines 'write only' permissions */ +#define __IO volatile /*!< \brief Defines 'read / write' permissions */ + +/* following defines should be used for structure members */ +#define __IM volatile const /*!< \brief Defines 'read only' structure member permissions */ +#define __OM volatile /*!< \brief Defines 'write only' structure member permissions */ +#define __IOM volatile /*!< \brief Defines 'read / write' structure member permissions */ +#define RESERVED(N, T) T RESERVED##N; // placeholder struct members used for "reserved" areas + + /******************************************************************************* + * Register Abstraction + Core Register contain: + - CPSR + - CP15 Registers + - L2C-310 Cache Controller + - Generic Interrupt Controller Distributor + - Generic Interrupt Controller Interface + ******************************************************************************/ + +/* Core Register CPSR */ +typedef union +{ + struct + { + uint32_t M:5; /*!< \brief bit: 0.. 4 Mode field */ + uint32_t T:1; /*!< \brief bit: 5 Thumb execution state bit */ + uint32_t F:1; /*!< \brief bit: 6 FIQ mask bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ mask bit */ + uint32_t A:1; /*!< \brief bit: 8 Asynchronous abort mask bit */ + uint32_t E:1; /*!< \brief bit: 9 Endianness execution state bit */ + uint32_t IT1:6; /*!< \brief bit: 10..15 If-Then execution state bits 2-7 */ + uint32_t GE:4; /*!< \brief bit: 16..19 Greater than or Equal flags */ + RESERVED(0:4, uint32_t) + uint32_t J:1; /*!< \brief bit: 24 Jazelle bit */ + uint32_t IT0:2; /*!< \brief bit: 25..26 If-Then execution state bits 0-1 */ + uint32_t Q:1; /*!< \brief bit: 27 Saturation condition flag */ + uint32_t V:1; /*!< \brief bit: 28 Overflow condition code flag */ + uint32_t C:1; /*!< \brief bit: 29 Carry condition code flag */ + uint32_t Z:1; /*!< \brief bit: 30 Zero condition code flag */ + uint32_t N:1; /*!< \brief bit: 31 Negative condition code flag */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPSR_Type; + + + +/* CPSR Register Definitions */ +#define CPSR_N_Pos 31U /*!< \brief CPSR: N Position */ +#define CPSR_N_Msk (1UL << CPSR_N_Pos) /*!< \brief CPSR: N Mask */ + +#define CPSR_Z_Pos 30U /*!< \brief CPSR: Z Position */ +#define CPSR_Z_Msk (1UL << CPSR_Z_Pos) /*!< \brief CPSR: Z Mask */ + +#define CPSR_C_Pos 29U /*!< \brief CPSR: C Position */ +#define CPSR_C_Msk (1UL << CPSR_C_Pos) /*!< \brief CPSR: C Mask */ + +#define CPSR_V_Pos 28U /*!< \brief CPSR: V Position */ +#define CPSR_V_Msk (1UL << CPSR_V_Pos) /*!< \brief CPSR: V Mask */ + +#define CPSR_Q_Pos 27U /*!< \brief CPSR: Q Position */ +#define CPSR_Q_Msk (1UL << CPSR_Q_Pos) /*!< \brief CPSR: Q Mask */ + +#define CPSR_IT0_Pos 25U /*!< \brief CPSR: IT0 Position */ +#define CPSR_IT0_Msk (3UL << CPSR_IT0_Pos) /*!< \brief CPSR: IT0 Mask */ + +#define CPSR_J_Pos 24U /*!< \brief CPSR: J Position */ +#define CPSR_J_Msk (1UL << CPSR_J_Pos) /*!< \brief CPSR: J Mask */ + +#define CPSR_GE_Pos 16U /*!< \brief CPSR: GE Position */ +#define CPSR_GE_Msk (0xFUL << CPSR_GE_Pos) /*!< \brief CPSR: GE Mask */ + +#define CPSR_IT1_Pos 10U /*!< \brief CPSR: IT1 Position */ +#define CPSR_IT1_Msk (0x3FUL << CPSR_IT1_Pos) /*!< \brief CPSR: IT1 Mask */ + +#define CPSR_E_Pos 9U /*!< \brief CPSR: E Position */ +#define CPSR_E_Msk (1UL << CPSR_E_Pos) /*!< \brief CPSR: E Mask */ + +#define CPSR_A_Pos 8U /*!< \brief CPSR: A Position */ +#define CPSR_A_Msk (1UL << CPSR_A_Pos) /*!< \brief CPSR: A Mask */ + +#define CPSR_I_Pos 7U /*!< \brief CPSR: I Position */ +#define CPSR_I_Msk (1UL << CPSR_I_Pos) /*!< \brief CPSR: I Mask */ + +#define CPSR_F_Pos 6U /*!< \brief CPSR: F Position */ +#define CPSR_F_Msk (1UL << CPSR_F_Pos) /*!< \brief CPSR: F Mask */ + +#define CPSR_T_Pos 5U /*!< \brief CPSR: T Position */ +#define CPSR_T_Msk (1UL << CPSR_T_Pos) /*!< \brief CPSR: T Mask */ + +#define CPSR_M_Pos 0U /*!< \brief CPSR: M Position */ +#define CPSR_M_Msk (0x1FUL << CPSR_M_Pos) /*!< \brief CPSR: M Mask */ + +#define CPSR_M_USR 0x10U /*!< \brief CPSR: M User mode (PL0) */ +#define CPSR_M_FIQ 0x11U /*!< \brief CPSR: M Fast Interrupt mode (PL1) */ +#define CPSR_M_IRQ 0x12U /*!< \brief CPSR: M Interrupt mode (PL1) */ +#define CPSR_M_SVC 0x13U /*!< \brief CPSR: M Supervisor mode (PL1) */ +#define CPSR_M_MON 0x16U /*!< \brief CPSR: M Monitor mode (PL1) */ +#define CPSR_M_ABT 0x17U /*!< \brief CPSR: M Abort mode (PL1) */ +#define CPSR_M_HYP 0x1AU /*!< \brief CPSR: M Hypervisor mode (PL2) */ +#define CPSR_M_UND 0x1BU /*!< \brief CPSR: M Undefined mode (PL1) */ +#define CPSR_M_SYS 0x1FU /*!< \brief CPSR: M System mode (PL1) */ + +/* CP15 Register SCTLR */ +typedef union +{ + struct + { + uint32_t M:1; /*!< \brief bit: 0 MMU enable */ + uint32_t A:1; /*!< \brief bit: 1 Alignment check enable */ + uint32_t C:1; /*!< \brief bit: 2 Cache enable */ + RESERVED(0:2, uint32_t) + uint32_t CP15BEN:1; /*!< \brief bit: 5 CP15 barrier enable */ + RESERVED(1:1, uint32_t) + uint32_t B:1; /*!< \brief bit: 7 Endianness model */ + RESERVED(2:2, uint32_t) + uint32_t SW:1; /*!< \brief bit: 10 SWP and SWPB enable */ + uint32_t Z:1; /*!< \brief bit: 11 Branch prediction enable */ + uint32_t I:1; /*!< \brief bit: 12 Instruction cache enable */ + uint32_t V:1; /*!< \brief bit: 13 Vectors bit */ + uint32_t RR:1; /*!< \brief bit: 14 Round Robin select */ + RESERVED(3:2, uint32_t) + uint32_t HA:1; /*!< \brief bit: 17 Hardware Access flag enable */ + RESERVED(4:1, uint32_t) + uint32_t WXN:1; /*!< \brief bit: 19 Write permission implies XN */ + uint32_t UWXN:1; /*!< \brief bit: 20 Unprivileged write permission implies PL1 XN */ + uint32_t FI:1; /*!< \brief bit: 21 Fast interrupts configuration enable */ + uint32_t U:1; /*!< \brief bit: 22 Alignment model */ + RESERVED(5:1, uint32_t) + uint32_t VE:1; /*!< \brief bit: 24 Interrupt Vectors Enable */ + uint32_t EE:1; /*!< \brief bit: 25 Exception Endianness */ + RESERVED(6:1, uint32_t) + uint32_t NMFI:1; /*!< \brief bit: 27 Non-maskable FIQ (NMFI) support */ + uint32_t TRE:1; /*!< \brief bit: 28 TEX remap enable. */ + uint32_t AFE:1; /*!< \brief bit: 29 Access flag enable */ + uint32_t TE:1; /*!< \brief bit: 30 Thumb Exception enable */ + RESERVED(7:1, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} SCTLR_Type; + +#define SCTLR_TE_Pos 30U /*!< \brief SCTLR: TE Position */ +#define SCTLR_TE_Msk (1UL << SCTLR_TE_Pos) /*!< \brief SCTLR: TE Mask */ + +#define SCTLR_AFE_Pos 29U /*!< \brief SCTLR: AFE Position */ +#define SCTLR_AFE_Msk (1UL << SCTLR_AFE_Pos) /*!< \brief SCTLR: AFE Mask */ + +#define SCTLR_TRE_Pos 28U /*!< \brief SCTLR: TRE Position */ +#define SCTLR_TRE_Msk (1UL << SCTLR_TRE_Pos) /*!< \brief SCTLR: TRE Mask */ + +#define SCTLR_NMFI_Pos 27U /*!< \brief SCTLR: NMFI Position */ +#define SCTLR_NMFI_Msk (1UL << SCTLR_NMFI_Pos) /*!< \brief SCTLR: NMFI Mask */ + +#define SCTLR_EE_Pos 25U /*!< \brief SCTLR: EE Position */ +#define SCTLR_EE_Msk (1UL << SCTLR_EE_Pos) /*!< \brief SCTLR: EE Mask */ + +#define SCTLR_VE_Pos 24U /*!< \brief SCTLR: VE Position */ +#define SCTLR_VE_Msk (1UL << SCTLR_VE_Pos) /*!< \brief SCTLR: VE Mask */ + +#define SCTLR_U_Pos 22U /*!< \brief SCTLR: U Position */ +#define SCTLR_U_Msk (1UL << SCTLR_U_Pos) /*!< \brief SCTLR: U Mask */ + +#define SCTLR_FI_Pos 21U /*!< \brief SCTLR: FI Position */ +#define SCTLR_FI_Msk (1UL << SCTLR_FI_Pos) /*!< \brief SCTLR: FI Mask */ + +#define SCTLR_UWXN_Pos 20U /*!< \brief SCTLR: UWXN Position */ +#define SCTLR_UWXN_Msk (1UL << SCTLR_UWXN_Pos) /*!< \brief SCTLR: UWXN Mask */ + +#define SCTLR_WXN_Pos 19U /*!< \brief SCTLR: WXN Position */ +#define SCTLR_WXN_Msk (1UL << SCTLR_WXN_Pos) /*!< \brief SCTLR: WXN Mask */ + +#define SCTLR_HA_Pos 17U /*!< \brief SCTLR: HA Position */ +#define SCTLR_HA_Msk (1UL << SCTLR_HA_Pos) /*!< \brief SCTLR: HA Mask */ + +#define SCTLR_RR_Pos 14U /*!< \brief SCTLR: RR Position */ +#define SCTLR_RR_Msk (1UL << SCTLR_RR_Pos) /*!< \brief SCTLR: RR Mask */ + +#define SCTLR_V_Pos 13U /*!< \brief SCTLR: V Position */ +#define SCTLR_V_Msk (1UL << SCTLR_V_Pos) /*!< \brief SCTLR: V Mask */ + +#define SCTLR_I_Pos 12U /*!< \brief SCTLR: I Position */ +#define SCTLR_I_Msk (1UL << SCTLR_I_Pos) /*!< \brief SCTLR: I Mask */ + +#define SCTLR_Z_Pos 11U /*!< \brief SCTLR: Z Position */ +#define SCTLR_Z_Msk (1UL << SCTLR_Z_Pos) /*!< \brief SCTLR: Z Mask */ + +#define SCTLR_SW_Pos 10U /*!< \brief SCTLR: SW Position */ +#define SCTLR_SW_Msk (1UL << SCTLR_SW_Pos) /*!< \brief SCTLR: SW Mask */ + +#define SCTLR_B_Pos 7U /*!< \brief SCTLR: B Position */ +#define SCTLR_B_Msk (1UL << SCTLR_B_Pos) /*!< \brief SCTLR: B Mask */ + +#define SCTLR_CP15BEN_Pos 5U /*!< \brief SCTLR: CP15BEN Position */ +#define SCTLR_CP15BEN_Msk (1UL << SCTLR_CP15BEN_Pos) /*!< \brief SCTLR: CP15BEN Mask */ + +#define SCTLR_C_Pos 2U /*!< \brief SCTLR: C Position */ +#define SCTLR_C_Msk (1UL << SCTLR_C_Pos) /*!< \brief SCTLR: C Mask */ + +#define SCTLR_A_Pos 1U /*!< \brief SCTLR: A Position */ +#define SCTLR_A_Msk (1UL << SCTLR_A_Pos) /*!< \brief SCTLR: A Mask */ + +#define SCTLR_M_Pos 0U /*!< \brief SCTLR: M Position */ +#define SCTLR_M_Msk (1UL << SCTLR_M_Pos) /*!< \brief SCTLR: M Mask */ + +/* CP15 Register ACTLR */ +typedef union +{ +#if __CORTEX_A == 5 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A5 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:5, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + RESERVED(1:2, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t DWBST:1; /*!< \brief bit: 11 AXI data write bursts to Normal memory */ + uint32_t RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t BP:2; /*!< \brief bit:16..15 Branch prediction policy */ + uint32_t RSDIS:1; /*!< \brief bit: 17 Disable return stack operation */ + uint32_t BTDIS:1; /*!< \brief bit: 18 Disable indirect Branch Target Address Cache (BTAC) */ + RESERVED(3:9, uint32_t) + uint32_t DBDI:1; /*!< \brief bit: 28 Disable branch dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 7 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A7 */ + struct + { + RESERVED(0:6, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + RESERVED(1:3, uint32_t) + uint32_t DODMBS:1; /*!< \brief bit: 10 Disable optimized data memory barrier behavior */ + uint32_t L2RADIS:1; /*!< \brief bit: 11 L2 Data Cache read-allocate mode disable */ + uint32_t L1RADIS:1; /*!< \brief bit: 12 L1 Data Cache read-allocate mode disable */ + uint32_t L1PCTL:2; /*!< \brief bit:13..14 L1 Data prefetch control */ + uint32_t DDVM:1; /*!< \brief bit: 15 Disable Distributed Virtual Memory (DVM) transactions */ + RESERVED(3:12, uint32_t) + uint32_t DDI:1; /*!< \brief bit: 28 Disable dual issue */ + RESERVED(7:3, uint32_t) + } b; +#endif +#if __CORTEX_A == 9 || defined(DOXYGEN) + /** \brief Structure used for bit access on Cortex-A9 */ + struct + { + uint32_t FW:1; /*!< \brief bit: 0 Cache and TLB maintenance broadcast */ + RESERVED(0:1, uint32_t) + uint32_t L1PE:1; /*!< \brief bit: 2 Dside prefetch */ + uint32_t WFLZM:1; /*!< \brief bit: 3 Cache and TLB maintenance broadcast */ + RESERVED(1:2, uint32_t) + uint32_t SMP:1; /*!< \brief bit: 6 Enables coherent requests to the processor */ + uint32_t EXCL:1; /*!< \brief bit: 7 Exclusive L1/L2 cache control */ + uint32_t AOW:1; /*!< \brief bit: 8 Enable allocation in one cache way only */ + uint32_t PARITY:1; /*!< \brief bit: 9 Support for parity checking, if implemented */ + RESERVED(7:22, uint32_t) + } b; +#endif + uint32_t w; /*!< \brief Type used for word access */ +} ACTLR_Type; + +#define ACTLR_DDI_Pos 28U /*!< \brief ACTLR: DDI Position */ +#define ACTLR_DDI_Msk (1UL << ACTLR_DDI_Pos) /*!< \brief ACTLR: DDI Mask */ + +#define ACTLR_DBDI_Pos 28U /*!< \brief ACTLR: DBDI Position */ +#define ACTLR_DBDI_Msk (1UL << ACTLR_DBDI_Pos) /*!< \brief ACTLR: DBDI Mask */ + +#define ACTLR_BTDIS_Pos 18U /*!< \brief ACTLR: BTDIS Position */ +#define ACTLR_BTDIS_Msk (1UL << ACTLR_BTDIS_Pos) /*!< \brief ACTLR: BTDIS Mask */ + +#define ACTLR_RSDIS_Pos 17U /*!< \brief ACTLR: RSDIS Position */ +#define ACTLR_RSDIS_Msk (1UL << ACTLR_RSDIS_Pos) /*!< \brief ACTLR: RSDIS Mask */ + +#define ACTLR_BP_Pos 15U /*!< \brief ACTLR: BP Position */ +#define ACTLR_BP_Msk (3UL << ACTLR_BP_Pos) /*!< \brief ACTLR: BP Mask */ + +#define ACTLR_DDVM_Pos 15U /*!< \brief ACTLR: DDVM Position */ +#define ACTLR_DDVM_Msk (1UL << ACTLR_DDVM_Pos) /*!< \brief ACTLR: DDVM Mask */ + +#define ACTLR_L1PCTL_Pos 13U /*!< \brief ACTLR: L1PCTL Position */ +#define ACTLR_L1PCTL_Msk (3UL << ACTLR_L1PCTL_Pos) /*!< \brief ACTLR: L1PCTL Mask */ + +#define ACTLR_RADIS_Pos 12U /*!< \brief ACTLR: RADIS Position */ +#define ACTLR_RADIS_Msk (1UL << ACTLR_RADIS_Pos) /*!< \brief ACTLR: RADIS Mask */ + +#define ACTLR_L1RADIS_Pos 12U /*!< \brief ACTLR: L1RADIS Position */ +#define ACTLR_L1RADIS_Msk (1UL << ACTLR_L1RADIS_Pos) /*!< \brief ACTLR: L1RADIS Mask */ + +#define ACTLR_DWBST_Pos 11U /*!< \brief ACTLR: DWBST Position */ +#define ACTLR_DWBST_Msk (1UL << ACTLR_DWBST_Pos) /*!< \brief ACTLR: DWBST Mask */ + +#define ACTLR_L2RADIS_Pos 11U /*!< \brief ACTLR: L2RADIS Position */ +#define ACTLR_L2RADIS_Msk (1UL << ACTLR_L2RADIS_Pos) /*!< \brief ACTLR: L2RADIS Mask */ + +#define ACTLR_DODMBS_Pos 10U /*!< \brief ACTLR: DODMBS Position */ +#define ACTLR_DODMBS_Msk (1UL << ACTLR_DODMBS_Pos) /*!< \brief ACTLR: DODMBS Mask */ + +#define ACTLR_PARITY_Pos 9U /*!< \brief ACTLR: PARITY Position */ +#define ACTLR_PARITY_Msk (1UL << ACTLR_PARITY_Pos) /*!< \brief ACTLR: PARITY Mask */ + +#define ACTLR_AOW_Pos 8U /*!< \brief ACTLR: AOW Position */ +#define ACTLR_AOW_Msk (1UL << ACTLR_AOW_Pos) /*!< \brief ACTLR: AOW Mask */ + +#define ACTLR_EXCL_Pos 7U /*!< \brief ACTLR: EXCL Position */ +#define ACTLR_EXCL_Msk (1UL << ACTLR_EXCL_Pos) /*!< \brief ACTLR: EXCL Mask */ + +#define ACTLR_SMP_Pos 6U /*!< \brief ACTLR: SMP Position */ +#define ACTLR_SMP_Msk (1UL << ACTLR_SMP_Pos) /*!< \brief ACTLR: SMP Mask */ + +#define ACTLR_WFLZM_Pos 3U /*!< \brief ACTLR: WFLZM Position */ +#define ACTLR_WFLZM_Msk (1UL << ACTLR_WFLZM_Pos) /*!< \brief ACTLR: WFLZM Mask */ + +#define ACTLR_L1PE_Pos 2U /*!< \brief ACTLR: L1PE Position */ +#define ACTLR_L1PE_Msk (1UL << ACTLR_L1PE_Pos) /*!< \brief ACTLR: L1PE Mask */ + +#define ACTLR_FW_Pos 0U /*!< \brief ACTLR: FW Position */ +#define ACTLR_FW_Msk (1UL << ACTLR_FW_Pos) /*!< \brief ACTLR: FW Mask */ + +/* CP15 Register CPACR */ +typedef union +{ + struct + { + uint32_t CP0:2; /*!< \brief bit: 0..1 Access rights for coprocessor 0 */ + uint32_t CP1:2; /*!< \brief bit: 2..3 Access rights for coprocessor 1 */ + uint32_t CP2:2; /*!< \brief bit: 4..5 Access rights for coprocessor 2 */ + uint32_t CP3:2; /*!< \brief bit: 6..7 Access rights for coprocessor 3 */ + uint32_t CP4:2; /*!< \brief bit: 8..9 Access rights for coprocessor 4 */ + uint32_t CP5:2; /*!< \brief bit:10..11 Access rights for coprocessor 5 */ + uint32_t CP6:2; /*!< \brief bit:12..13 Access rights for coprocessor 6 */ + uint32_t CP7:2; /*!< \brief bit:14..15 Access rights for coprocessor 7 */ + uint32_t CP8:2; /*!< \brief bit:16..17 Access rights for coprocessor 8 */ + uint32_t CP9:2; /*!< \brief bit:18..19 Access rights for coprocessor 9 */ + uint32_t CP10:2; /*!< \brief bit:20..21 Access rights for coprocessor 10 */ + uint32_t CP11:2; /*!< \brief bit:22..23 Access rights for coprocessor 11 */ + uint32_t CP12:2; /*!< \brief bit:24..25 Access rights for coprocessor 11 */ + uint32_t CP13:2; /*!< \brief bit:26..27 Access rights for coprocessor 11 */ + uint32_t TRCDIS:1; /*!< \brief bit: 28 Disable CP14 access to trace registers */ + RESERVED(0:1, uint32_t) + uint32_t D32DIS:1; /*!< \brief bit: 30 Disable use of registers D16-D31 of the VFP register file */ + uint32_t ASEDIS:1; /*!< \brief bit: 31 Disable Advanced SIMD Functionality */ + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CPACR_Type; + +#define CPACR_ASEDIS_Pos 31U /*!< \brief CPACR: ASEDIS Position */ +#define CPACR_ASEDIS_Msk (1UL << CPACR_ASEDIS_Pos) /*!< \brief CPACR: ASEDIS Mask */ + +#define CPACR_D32DIS_Pos 30U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_D32DIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_TRCDIS_Pos 28U /*!< \brief CPACR: D32DIS Position */ +#define CPACR_TRCDIS_Msk (1UL << CPACR_D32DIS_Pos) /*!< \brief CPACR: D32DIS Mask */ + +#define CPACR_CP_Pos_(n) (n*2U) /*!< \brief CPACR: CPn Position */ +#define CPACR_CP_Msk_(n) (3UL << CPACR_CP_Pos_(n)) /*!< \brief CPACR: CPn Mask */ + +#define CPACR_CP_NA 0U /*!< \brief CPACR CPn field: Access denied. */ +#define CPACR_CP_PL1 1U /*!< \brief CPACR CPn field: Accessible from PL1 only. */ +#define CPACR_CP_FA 3U /*!< \brief CPACR CPn field: Full access. */ + +/* CP15 Register DFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + uint32_t Domain:4; /*!< \brief bit: 4.. 7 Fault on which domain */ + RESERVED(0:1, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(1:18, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:5; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:1, uint32_t) + uint32_t WnR:1; /*!< \brief bit: 11 Write not Read bit */ + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + uint32_t CM:1; /*!< \brief bit: 13 Cache maintenance fault */ + RESERVED(2:18, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} DFSR_Type; + +#define DFSR_CM_Pos 13U /*!< \brief DFSR: CM Position */ +#define DFSR_CM_Msk (1UL << DFSR_CM_Pos) /*!< \brief DFSR: CM Mask */ + +#define DFSR_Ext_Pos 12U /*!< \brief DFSR: Ext Position */ +#define DFSR_Ext_Msk (1UL << DFSR_Ext_Pos) /*!< \brief DFSR: Ext Mask */ + +#define DFSR_WnR_Pos 11U /*!< \brief DFSR: WnR Position */ +#define DFSR_WnR_Msk (1UL << DFSR_WnR_Pos) /*!< \brief DFSR: WnR Mask */ + +#define DFSR_FS1_Pos 10U /*!< \brief DFSR: FS1 Position */ +#define DFSR_FS1_Msk (1UL << DFSR_FS1_Pos) /*!< \brief DFSR: FS1 Mask */ + +#define DFSR_LPAE_Pos 9U /*!< \brief DFSR: LPAE Position */ +#define DFSR_LPAE_Msk (1UL << DFSR_LPAE_Pos) /*!< \brief DFSR: LPAE Mask */ + +#define DFSR_Domain_Pos 4U /*!< \brief DFSR: Domain Position */ +#define DFSR_Domain_Msk (0xFUL << DFSR_Domain_Pos) /*!< \brief DFSR: Domain Mask */ + +#define DFSR_FS0_Pos 0U /*!< \brief DFSR: FS0 Position */ +#define DFSR_FS0_Msk (0xFUL << DFSR_FS0_Pos) /*!< \brief DFSR: FS0 Mask */ + +#define DFSR_STATUS_Pos 0U /*!< \brief DFSR: STATUS Position */ +#define DFSR_STATUS_Msk (0x3FUL << DFSR_STATUS_Pos) /*!< \brief DFSR: STATUS Mask */ + +/* CP15 Register IFSR */ +typedef union +{ + struct + { + uint32_t FS0:4; /*!< \brief bit: 0.. 3 Fault Status bits bit 0-3 */ + RESERVED(0:5, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + uint32_t FS1:1; /*!< \brief bit: 10 Fault Status bits bit 4 */ + RESERVED(1:1, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } s; /*!< \brief Structure used for bit access in short format */ + struct + { + uint32_t STATUS:6; /*!< \brief bit: 0.. 5 Fault Status bits */ + RESERVED(0:3, uint32_t) + uint32_t LPAE:1; /*!< \brief bit: 9 Large Physical Address Extension */ + RESERVED(1:2, uint32_t) + uint32_t ExT:1; /*!< \brief bit: 12 External abort type */ + RESERVED(2:19, uint32_t) + } l; /*!< \brief Structure used for bit access in long format */ + uint32_t w; /*!< \brief Type used for word access */ +} IFSR_Type; + +#define IFSR_ExT_Pos 12U /*!< \brief IFSR: ExT Position */ +#define IFSR_ExT_Msk (1UL << IFSR_ExT_Pos) /*!< \brief IFSR: ExT Mask */ + +#define IFSR_FS1_Pos 10U /*!< \brief IFSR: FS1 Position */ +#define IFSR_FS1_Msk (1UL << IFSR_FS1_Pos) /*!< \brief IFSR: FS1 Mask */ + +#define IFSR_LPAE_Pos 9U /*!< \brief IFSR: LPAE Position */ +#define IFSR_LPAE_Msk (0x1UL << IFSR_LPAE_Pos) /*!< \brief IFSR: LPAE Mask */ + +#define IFSR_FS0_Pos 0U /*!< \brief IFSR: FS0 Position */ +#define IFSR_FS0_Msk (0xFUL << IFSR_FS0_Pos) /*!< \brief IFSR: FS0 Mask */ + +#define IFSR_STATUS_Pos 0U /*!< \brief IFSR: STATUS Position */ +#define IFSR_STATUS_Msk (0x3FUL << IFSR_STATUS_Pos) /*!< \brief IFSR: STATUS Mask */ + +/* CP15 Register ISR */ +typedef union +{ + struct + { + RESERVED(0:6, uint32_t) + uint32_t F:1; /*!< \brief bit: 6 FIQ pending bit */ + uint32_t I:1; /*!< \brief bit: 7 IRQ pending bit */ + uint32_t A:1; /*!< \brief bit: 8 External abort pending bit */ + RESERVED(1:23, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} ISR_Type; + +#define ISR_A_Pos 13U /*!< \brief ISR: A Position */ +#define ISR_A_Msk (1UL << ISR_A_Pos) /*!< \brief ISR: A Mask */ + +#define ISR_I_Pos 12U /*!< \brief ISR: I Position */ +#define ISR_I_Msk (1UL << ISR_I_Pos) /*!< \brief ISR: I Mask */ + +#define ISR_F_Pos 11U /*!< \brief ISR: F Position */ +#define ISR_F_Msk (1UL << ISR_F_Pos) /*!< \brief ISR: F Mask */ + +/* DACR Register */ +#define DACR_D_Pos_(n) (2U*n) /*!< \brief DACR: Dn Position */ +#define DACR_D_Msk_(n) (3UL << DACR_D_Pos_(n)) /*!< \brief DACR: Dn Mask */ +#define DACR_Dn_NOACCESS 0U /*!< \brief DACR Dn field: No access */ +#define DACR_Dn_CLIENT 1U /*!< \brief DACR Dn field: Client */ +#define DACR_Dn_MANAGER 3U /*!< \brief DACR Dn field: Manager */ + +/** + \brief Mask and shift a bit field value for use in a register bit range. + \param [in] field Name of the register bit field. + \param [in] value Value of the bit field. This parameter is interpreted as an uint32_t type. + \return Masked and shifted value. +*/ +#define _VAL2FLD(field, value) (((uint32_t)(value) << field ## _Pos) & field ## _Msk) + +/** + \brief Mask and shift a register value to extract a bit filed value. + \param [in] field Name of the register bit field. + \param [in] value Value of register. This parameter is interpreted as an uint32_t type. + \return Masked and shifted bit field value. +*/ +#define _FLD2VAL(field, value) (((uint32_t)(value) & field ## _Msk) >> field ## _Pos) + + +/** + \brief Union type to access the L2C_310 Cache Controller. +*/ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +typedef struct +{ + __IM uint32_t CACHE_ID; /*!< \brief Offset: 0x0000 (R/ ) Cache ID Register */ + __IM uint32_t CACHE_TYPE; /*!< \brief Offset: 0x0004 (R/ ) Cache Type Register */ + RESERVED(0[0x3e], uint32_t) + __IOM uint32_t CONTROL; /*!< \brief Offset: 0x0100 (R/W) Control Register */ + __IOM uint32_t AUX_CNT; /*!< \brief Offset: 0x0104 (R/W) Auxiliary Control */ + RESERVED(1[0x3e], uint32_t) + __IOM uint32_t EVENT_CONTROL; /*!< \brief Offset: 0x0200 (R/W) Event Counter Control */ + __IOM uint32_t EVENT_COUNTER1_CONF; /*!< \brief Offset: 0x0204 (R/W) Event Counter 1 Configuration */ + __IOM uint32_t EVENT_COUNTER0_CONF; /*!< \brief Offset: 0x0208 (R/W) Event Counter 1 Configuration */ + RESERVED(2[0x2], uint32_t) + __IOM uint32_t INTERRUPT_MASK; /*!< \brief Offset: 0x0214 (R/W) Interrupt Mask */ + __IM uint32_t MASKED_INT_STATUS; /*!< \brief Offset: 0x0218 (R/ ) Masked Interrupt Status */ + __IM uint32_t RAW_INT_STATUS; /*!< \brief Offset: 0x021c (R/ ) Raw Interrupt Status */ + __OM uint32_t INTERRUPT_CLEAR; /*!< \brief Offset: 0x0220 ( /W) Interrupt Clear */ + RESERVED(3[0x143], uint32_t) + __IOM uint32_t CACHE_SYNC; /*!< \brief Offset: 0x0730 (R/W) Cache Sync */ + RESERVED(4[0xf], uint32_t) + __IOM uint32_t INV_LINE_PA; /*!< \brief Offset: 0x0770 (R/W) Invalidate Line By PA */ + RESERVED(6[2], uint32_t) + __IOM uint32_t INV_WAY; /*!< \brief Offset: 0x077c (R/W) Invalidate by Way */ + RESERVED(5[0xc], uint32_t) + __IOM uint32_t CLEAN_LINE_PA; /*!< \brief Offset: 0x07b0 (R/W) Clean Line by PA */ + RESERVED(7[1], uint32_t) + __IOM uint32_t CLEAN_LINE_INDEX_WAY; /*!< \brief Offset: 0x07b8 (R/W) Clean Line by Index/Way */ + __IOM uint32_t CLEAN_WAY; /*!< \brief Offset: 0x07bc (R/W) Clean by Way */ + RESERVED(8[0xc], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_PA; /*!< \brief Offset: 0x07f0 (R/W) Clean and Invalidate Line by PA */ + RESERVED(9[1], uint32_t) + __IOM uint32_t CLEAN_INV_LINE_INDEX_WAY; /*!< \brief Offset: 0x07f8 (R/W) Clean and Invalidate Line by Index/Way */ + __IOM uint32_t CLEAN_INV_WAY; /*!< \brief Offset: 0x07fc (R/W) Clean and Invalidate by Way */ + RESERVED(10[0x40], uint32_t) + __IOM uint32_t DATA_LOCK_0_WAY; /*!< \brief Offset: 0x0900 (R/W) Data Lockdown 0 by Way */ + __IOM uint32_t INST_LOCK_0_WAY; /*!< \brief Offset: 0x0904 (R/W) Instruction Lockdown 0 by Way */ + __IOM uint32_t DATA_LOCK_1_WAY; /*!< \brief Offset: 0x0908 (R/W) Data Lockdown 1 by Way */ + __IOM uint32_t INST_LOCK_1_WAY; /*!< \brief Offset: 0x090c (R/W) Instruction Lockdown 1 by Way */ + __IOM uint32_t DATA_LOCK_2_WAY; /*!< \brief Offset: 0x0910 (R/W) Data Lockdown 2 by Way */ + __IOM uint32_t INST_LOCK_2_WAY; /*!< \brief Offset: 0x0914 (R/W) Instruction Lockdown 2 by Way */ + __IOM uint32_t DATA_LOCK_3_WAY; /*!< \brief Offset: 0x0918 (R/W) Data Lockdown 3 by Way */ + __IOM uint32_t INST_LOCK_3_WAY; /*!< \brief Offset: 0x091c (R/W) Instruction Lockdown 3 by Way */ + __IOM uint32_t DATA_LOCK_4_WAY; /*!< \brief Offset: 0x0920 (R/W) Data Lockdown 4 by Way */ + __IOM uint32_t INST_LOCK_4_WAY; /*!< \brief Offset: 0x0924 (R/W) Instruction Lockdown 4 by Way */ + __IOM uint32_t DATA_LOCK_5_WAY; /*!< \brief Offset: 0x0928 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_5_WAY; /*!< \brief Offset: 0x092c (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_6_WAY; /*!< \brief Offset: 0x0930 (R/W) Data Lockdown 5 by Way */ + __IOM uint32_t INST_LOCK_6_WAY; /*!< \brief Offset: 0x0934 (R/W) Instruction Lockdown 5 by Way */ + __IOM uint32_t DATA_LOCK_7_WAY; /*!< \brief Offset: 0x0938 (R/W) Data Lockdown 6 by Way */ + __IOM uint32_t INST_LOCK_7_WAY; /*!< \brief Offset: 0x093c (R/W) Instruction Lockdown 6 by Way */ + RESERVED(11[0x4], uint32_t) + __IOM uint32_t LOCK_LINE_EN; /*!< \brief Offset: 0x0950 (R/W) Lockdown by Line Enable */ + __IOM uint32_t UNLOCK_ALL_BY_WAY; /*!< \brief Offset: 0x0954 (R/W) Unlock All Lines by Way */ + RESERVED(12[0xaa], uint32_t) + __IOM uint32_t ADDRESS_FILTER_START; /*!< \brief Offset: 0x0c00 (R/W) Address Filtering Start */ + __IOM uint32_t ADDRESS_FILTER_END; /*!< \brief Offset: 0x0c04 (R/W) Address Filtering End */ + RESERVED(13[0xce], uint32_t) + __IOM uint32_t DEBUG_CONTROL; /*!< \brief Offset: 0x0f40 (R/W) Debug Control Register */ +} L2C_310_TypeDef; + +#define L2C_310 ((L2C_310_TypeDef *)L2C_310_BASE) /*!< \brief L2C_310 register set access pointer */ +#endif + +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Structure type to access the Generic Interrupt Controller Distributor (GICD) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) Distributor Control Register */ + __IM uint32_t TYPER; /*!< \brief Offset: 0x004 (R/ ) Interrupt Controller Type Register */ + __IM uint32_t IIDR; /*!< \brief Offset: 0x008 (R/ ) Distributor Implementer Identification Register */ + RESERVED(0, uint32_t) + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x010 (R/W) Error Reporting Status Register, optional */ + RESERVED(1[11], uint32_t) + __OM uint32_t SETSPI_NSR; /*!< \brief Offset: 0x040 ( /W) Set SPI Register */ + RESERVED(2, uint32_t) + __OM uint32_t CLRSPI_NSR; /*!< \brief Offset: 0x048 ( /W) Clear SPI Register */ + RESERVED(3, uint32_t) + __OM uint32_t SETSPI_SR; /*!< \brief Offset: 0x050 ( /W) Set SPI, Secure Register */ + RESERVED(4, uint32_t) + __OM uint32_t CLRSPI_SR; /*!< \brief Offset: 0x058 ( /W) Clear SPI, Secure Register */ + RESERVED(5[9], uint32_t) + __IOM uint32_t IGROUPR[32]; /*!< \brief Offset: 0x080 (R/W) Interrupt Group Registers */ + __IOM uint32_t ISENABLER[32]; /*!< \brief Offset: 0x100 (R/W) Interrupt Set-Enable Registers */ + __IOM uint32_t ICENABLER[32]; /*!< \brief Offset: 0x180 (R/W) Interrupt Clear-Enable Registers */ + __IOM uint32_t ISPENDR[32]; /*!< \brief Offset: 0x200 (R/W) Interrupt Set-Pending Registers */ + __IOM uint32_t ICPENDR[32]; /*!< \brief Offset: 0x280 (R/W) Interrupt Clear-Pending Registers */ + __IOM uint32_t ISACTIVER[32]; /*!< \brief Offset: 0x300 (R/W) Interrupt Set-Active Registers */ + __IOM uint32_t ICACTIVER[32]; /*!< \brief Offset: 0x380 (R/W) Interrupt Clear-Active Registers */ + __IOM uint32_t IPRIORITYR[255]; /*!< \brief Offset: 0x400 (R/W) Interrupt Priority Registers */ + RESERVED(6, uint32_t) + __IOM uint32_t ITARGETSR[255]; /*!< \brief Offset: 0x800 (R/W) Interrupt Targets Registers */ + RESERVED(7, uint32_t) + __IOM uint32_t ICFGR[64]; /*!< \brief Offset: 0xC00 (R/W) Interrupt Configuration Registers */ + __IOM uint32_t IGRPMODR[32]; /*!< \brief Offset: 0xD00 (R/W) Interrupt Group Modifier Registers */ + RESERVED(8[32], uint32_t) + __IOM uint32_t NSACR[64]; /*!< \brief Offset: 0xE00 (R/W) Non-secure Access Control Registers */ + __OM uint32_t SGIR; /*!< \brief Offset: 0xF00 ( /W) Software Generated Interrupt Register */ + RESERVED(9[3], uint32_t) + __IOM uint32_t CPENDSGIR[4]; /*!< \brief Offset: 0xF10 (R/W) SGI Clear-Pending Registers */ + __IOM uint32_t SPENDSGIR[4]; /*!< \brief Offset: 0xF20 (R/W) SGI Set-Pending Registers */ + RESERVED(10[5236], uint32_t) + __IOM uint64_t IROUTER[988]; /*!< \brief Offset: 0x6100(R/W) Interrupt Routing Registers */ +} GICDistributor_Type; + +#define GICDistributor ((GICDistributor_Type *) GIC_DISTRIBUTOR_BASE ) /*!< \brief GIC Distributor register set access pointer */ + +/** \brief Structure type to access the Generic Interrupt Controller Interface (GICC) +*/ +typedef struct +{ + __IOM uint32_t CTLR; /*!< \brief Offset: 0x000 (R/W) CPU Interface Control Register */ + __IOM uint32_t PMR; /*!< \brief Offset: 0x004 (R/W) Interrupt Priority Mask Register */ + __IOM uint32_t BPR; /*!< \brief Offset: 0x008 (R/W) Binary Point Register */ + __IM uint32_t IAR; /*!< \brief Offset: 0x00C (R/ ) Interrupt Acknowledge Register */ + __OM uint32_t EOIR; /*!< \brief Offset: 0x010 ( /W) End Of Interrupt Register */ + __IM uint32_t RPR; /*!< \brief Offset: 0x014 (R/ ) Running Priority Register */ + __IM uint32_t HPPIR; /*!< \brief Offset: 0x018 (R/ ) Highest Priority Pending Interrupt Register */ + __IOM uint32_t ABPR; /*!< \brief Offset: 0x01C (R/W) Aliased Binary Point Register */ + __IM uint32_t AIAR; /*!< \brief Offset: 0x020 (R/ ) Aliased Interrupt Acknowledge Register */ + __OM uint32_t AEOIR; /*!< \brief Offset: 0x024 ( /W) Aliased End Of Interrupt Register */ + __IM uint32_t AHPPIR; /*!< \brief Offset: 0x028 (R/ ) Aliased Highest Priority Pending Interrupt Register */ + __IOM uint32_t STATUSR; /*!< \brief Offset: 0x02C (R/W) Error Reporting Status Register, optional */ + RESERVED(1[40], uint32_t) + __IOM uint32_t APR[4]; /*!< \brief Offset: 0x0D0 (R/W) Active Priority Register */ + __IOM uint32_t NSAPR[4]; /*!< \brief Offset: 0x0E0 (R/W) Non-secure Active Priority Register */ + RESERVED(2[3], uint32_t) + __IM uint32_t IIDR; /*!< \brief Offset: 0x0FC (R/ ) CPU Interface Identification Register */ + RESERVED(3[960], uint32_t) + __OM uint32_t DIR; /*!< \brief Offset: 0x1000( /W) Deactivate Interrupt Register */ +} GICInterface_Type; + +#define GICInterface ((GICInterface_Type *) GIC_INTERFACE_BASE ) /*!< \brief GIC Interface register set access pointer */ +#endif + +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Structure type to access the Private Timer +*/ +typedef struct +{ + __IOM uint32_t LOAD; //!< \brief Offset: 0x000 (R/W) Private Timer Load Register + __IOM uint32_t COUNTER; //!< \brief Offset: 0x004 (R/W) Private Timer Counter Register + __IOM uint32_t CONTROL; //!< \brief Offset: 0x008 (R/W) Private Timer Control Register + __IOM uint32_t ISR; //!< \brief Offset: 0x00C (R/W) Private Timer Interrupt Status Register + RESERVED(0[4], uint32_t) + __IOM uint32_t WLOAD; //!< \brief Offset: 0x020 (R/W) Watchdog Load Register + __IOM uint32_t WCOUNTER; //!< \brief Offset: 0x024 (R/W) Watchdog Counter Register + __IOM uint32_t WCONTROL; //!< \brief Offset: 0x028 (R/W) Watchdog Control Register + __IOM uint32_t WISR; //!< \brief Offset: 0x02C (R/W) Watchdog Interrupt Status Register + __IOM uint32_t WRESET; //!< \brief Offset: 0x030 (R/W) Watchdog Reset Status Register + __OM uint32_t WDISABLE; //!< \brief Offset: 0x034 ( /W) Watchdog Disable Register +} Timer_Type; +#define PTIM ((Timer_Type *) TIMER_BASE ) /*!< \brief Timer register struct */ +#endif +#endif + + /******************************************************************************* + * Hardware Abstraction Layer + Core Function Interface contains: + - L1 Cache Functions + - L2C-310 Cache Controller Functions + - PL1 Timer Functions + - GIC Functions + - MMU Functions + ******************************************************************************/ + +/* ########################## L1 Cache functions ################################# */ + +/** \brief Enable Caches by setting I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableCaches(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_I_Msk | SCTLR_C_Msk); + __ISB(); +} + +/** \brief Disable Caches by clearing I and C bits in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableCaches(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_I_Msk) & (~SCTLR_C_Msk)); + __ISB(); +} + +/** \brief Enable Branch Prediction by setting Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_EnableBTAC(void) { + __set_SCTLR( __get_SCTLR() | SCTLR_Z_Msk); + __ISB(); +} + +/** \brief Disable Branch Prediction by clearing Z bit in SCTLR register. +*/ +__STATIC_FORCEINLINE void L1C_DisableBTAC(void) { + __set_SCTLR( __get_SCTLR() & (~SCTLR_Z_Msk)); + __ISB(); +} + +/** \brief Invalidate entire branch predictor array +*/ +__STATIC_FORCEINLINE void L1C_InvalidateBTAC(void) { + __set_BPIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + +/** \brief Invalidate the whole instruction cache +*/ +__STATIC_FORCEINLINE void L1C_InvalidateICacheAll(void) { + __set_ICIALLU(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new I cache state +} + +/** \brief Clean data cache line by address. +* \param [in] va Pointer to data to clear the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanDCacheMVA(void *va) { + __set_DCCMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Invalidate data cache line by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheMVA(void *va) { + __set_DCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Clean and Invalidate data cache by address. +* \param [in] va Pointer to data to invalidate the cache for. +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheMVA(void *va) { + __set_DCCIMVAC((uint32_t)va); + __DMB(); //ensure the ordering of data cache maintenance operations and their effects +} + +/** \brief Calculate log2 rounded up +* - log(0) => 0 +* - log(1) => 0 +* - log(2) => 1 +* - log(3) => 2 +* - log(4) => 2 +* - log(5) => 3 +* : : +* - log(16) => 4 +* - log(32) => 5 +* : : +* \param [in] n input value parameter +* \return log2(n) +*/ +__STATIC_FORCEINLINE uint8_t __log2_up(uint32_t n) +{ + if (n < 2U) { + return 0U; + } + uint8_t log = 0U; + uint32_t t = n; + while(t > 1U) + { + log++; + t >>= 1U; + } + if (n & 1U) { log++; } + return log; +} + +/** \brief Apply cache maintenance to given cache level. +* \param [in] level cache level to be maintained +* \param [in] maint 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void __L1C_MaintainDCacheSetWay(uint32_t level, uint32_t maint) +{ + uint32_t Dummy; + uint32_t ccsidr; + uint32_t num_sets; + uint32_t num_ways; + uint32_t shift_way; + uint32_t log2_linesize; + int32_t log2_num_ways; + + Dummy = level << 1U; + /* set csselr, select ccsidr register */ + __set_CSSELR(Dummy); + /* get current ccsidr register */ + ccsidr = __get_CCSIDR(); + num_sets = ((ccsidr & 0x0FFFE000U) >> 13U) + 1U; + num_ways = ((ccsidr & 0x00001FF8U) >> 3U) + 1U; + log2_linesize = (ccsidr & 0x00000007U) + 2U + 2U; + log2_num_ways = __log2_up(num_ways); + if ((log2_num_ways < 0) || (log2_num_ways > 32)) { + return; // FATAL ERROR + } + shift_way = 32U - (uint32_t)log2_num_ways; + for(int32_t way = num_ways-1; way >= 0; way--) + { + for(int32_t set = num_sets-1; set >= 0; set--) + { + Dummy = (level << 1U) | (((uint32_t)set) << log2_linesize) | (((uint32_t)way) << shift_way); + switch (maint) + { + case 0U: __set_DCISW(Dummy); break; + case 1U: __set_DCCSW(Dummy); break; + default: __set_DCCISW(Dummy); break; + } + } + } + __DMB(); +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +*/ +__STATIC_FORCEINLINE void L1C_CleanInvalidateCache(uint32_t op) { + uint32_t clidr; + uint32_t cache_type; + clidr = __get_CLIDR(); + for(uint32_t i = 0U; i<7U; i++) + { + cache_type = (clidr >> i*3U) & 0x7UL; + if ((cache_type >= 2U) && (cache_type <= 4U)) + { + __L1C_MaintainDCacheSetWay(i, op); + } + } +} + +/** \brief Clean and Invalidate the entire data or unified cache +* Generic mechanism for cleaning/invalidating the entire data or unified cache to the point of coherency +* \param [in] op 0 - invalidate, 1 - clean, otherwise - invalidate and clean +* \deprecated Use generic L1C_CleanInvalidateCache instead. +*/ +CMSIS_DEPRECATED +__STATIC_FORCEINLINE void __L1C_CleanInvalidateCache(uint32_t op) { + L1C_CleanInvalidateCache(op); +} + +/** \brief Invalidate the whole data cache. +*/ +__STATIC_FORCEINLINE void L1C_InvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(0); +} + +/** \brief Clean the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanDCacheAll(void) { + L1C_CleanInvalidateCache(1); +} + +/** \brief Clean and invalidate the whole data cache. + */ +__STATIC_FORCEINLINE void L1C_CleanInvalidateDCacheAll(void) { + L1C_CleanInvalidateCache(2); +} + +/* ########################## L2 Cache functions ################################# */ +#if (__L2C_PRESENT == 1U) || defined(DOXYGEN) +/** \brief Cache Sync operation by writing CACHE_SYNC register. +*/ +__STATIC_INLINE void L2C_Sync(void) +{ + L2C_310->CACHE_SYNC = 0x0; +} + +/** \brief Read cache controller cache ID from CACHE_ID register. + * \return L2C_310_TypeDef::CACHE_ID + */ +__STATIC_INLINE int L2C_GetID (void) +{ + return L2C_310->CACHE_ID; +} + +/** \brief Read cache controller cache type from CACHE_TYPE register. +* \return L2C_310_TypeDef::CACHE_TYPE +*/ +__STATIC_INLINE int L2C_GetType (void) +{ + return L2C_310->CACHE_TYPE; +} + +/** \brief Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_InvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->INV_WAY = (1U << assoc) - 1U; + while(L2C_310->INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Clean and Invalidate all cache by way +*/ +__STATIC_INLINE void L2C_CleanInvAllByWay (void) +{ + unsigned int assoc; + + if (L2C_310->AUX_CNT & (1U << 16U)) { + assoc = 16U; + } else { + assoc = 8U; + } + + L2C_310->CLEAN_INV_WAY = (1U << assoc) - 1U; + while(L2C_310->CLEAN_INV_WAY & ((1U << assoc) - 1U)); //poll invalidate + + L2C_Sync(); +} + +/** \brief Enable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Enable(void) +{ + L2C_310->CONTROL = 0; + L2C_310->INTERRUPT_CLEAR = 0x000001FFuL; + L2C_310->DEBUG_CONTROL = 0; + L2C_310->DATA_LOCK_0_WAY = 0; + L2C_310->CACHE_SYNC = 0; + L2C_310->CONTROL = 0x01; + L2C_Sync(); +} + +/** \brief Disable Level 2 Cache +*/ +__STATIC_INLINE void L2C_Disable(void) +{ + L2C_310->CONTROL = 0x00; + L2C_Sync(); +} + +/** \brief Invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_InvPa (void *pa) +{ + L2C_310->INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanPa (void *pa) +{ + L2C_310->CLEAN_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} + +/** \brief Clean and invalidate cache by physical address +* \param [in] pa Pointer to data to invalidate cache for. +*/ +__STATIC_INLINE void L2C_CleanInvPa (void *pa) +{ + L2C_310->CLEAN_INV_LINE_PA = (unsigned int)pa; + L2C_Sync(); +} +#endif + +/* ########################## GIC functions ###################################### */ +#if (__GIC_PRESENT == 1U) || defined(DOXYGEN) + +/** \brief Enable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_EnableDistributor(void) +{ + GICDistributor->CTLR |= 1U; +} + +/** \brief Disable the interrupt distributor using the GIC's CTLR register. +*/ +__STATIC_INLINE void GIC_DisableDistributor(void) +{ + GICDistributor->CTLR &=~1U; +} + +/** \brief Read the GIC's TYPER register. +* \return GICDistributor_Type::TYPER +*/ +__STATIC_INLINE uint32_t GIC_DistributorInfo(void) +{ + return (GICDistributor->TYPER); +} + +/** \brief Reads the GIC's IIDR register. +* \return GICDistributor_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_DistributorImplementer(void) +{ + return (GICDistributor->IIDR); +} + +/** \brief Sets the GIC's ITARGETSR register for the given interrupt. +* \param [in] IRQn Interrupt to be configured. +* \param [in] cpu_target CPU interfaces to assign this interrupt to. +*/ +__STATIC_INLINE void GIC_SetTarget(IRQn_Type IRQn, uint32_t cpu_target) +{ + uint32_t mask = GICDistributor->ITARGETSR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->ITARGETSR[IRQn / 4U] = mask | ((cpu_target & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the GIC's ITARGETSR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return GICDistributor_Type::ITARGETSR +*/ +__STATIC_INLINE uint32_t GIC_GetTarget(IRQn_Type IRQn) +{ + return (GICDistributor->ITARGETSR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Enable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_EnableInterface(void) +{ + GICInterface->CTLR |= 1U; //enable interface +} + +/** \brief Disable the CPU's interrupt interface. +*/ +__STATIC_INLINE void GIC_DisableInterface(void) +{ + GICInterface->CTLR &=~1U; //disable distributor +} + +/** \brief Read the CPU's IAR register. +* \return GICInterface_Type::IAR +*/ +__STATIC_INLINE IRQn_Type GIC_AcknowledgePending(void) +{ + return (IRQn_Type)(GICInterface->IAR); +} + +/** \brief Writes the given interrupt number to the CPU's EOIR register. +* \param [in] IRQn The interrupt to be signaled as finished. +*/ +__STATIC_INLINE void GIC_EndInterrupt(IRQn_Type IRQn) +{ + GICInterface->EOIR = IRQn; +} + +/** \brief Enables the given interrupt using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_EnableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ISENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt enable status using GIC's ISENABLER register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not enabled, 1 - interrupt is enabled. +*/ +__STATIC_INLINE uint32_t GIC_GetEnableIRQ(IRQn_Type IRQn) +{ + return (GICDistributor->ISENABLER[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} + +/** \brief Disables the given interrupt using GIC's ICENABLER register. +* \param [in] IRQn The interrupt to be disabled. +*/ +__STATIC_INLINE void GIC_DisableIRQ(IRQn_Type IRQn) +{ + GICDistributor->ICENABLER[IRQn / 32U] = 1U << (IRQn % 32U); +} + +/** \brief Get interrupt pending status from GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - interrupt is not pending, 1 - interrupt is pendig. +*/ +__STATIC_INLINE uint32_t GIC_GetPendingIRQ(IRQn_Type IRQn) +{ + uint32_t pend; + + if (IRQn >= 16U) { + pend = (GICDistributor->ISPENDR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; + } else { + // INTID 0-15 Software Generated Interrupt + pend = (GICDistributor->SPENDSGIR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; + // No CPU identification offered + if (pend != 0U) { + pend = 1U; + } else { + pend = 0U; + } + } + + return (pend); +} + +/** \brief Sets the given interrupt as pending using GIC's ISPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_SetPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ISPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->SPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } +} + +/** \brief Clears the given interrupt from being pending using GIC's ICPENDR register. +* \param [in] IRQn The interrupt to be enabled. +*/ +__STATIC_INLINE void GIC_ClearPendingIRQ(IRQn_Type IRQn) +{ + if (IRQn >= 16U) { + GICDistributor->ICPENDR[IRQn / 32U] = 1U << (IRQn % 32U); + } else { + // INTID 0-15 Software Generated Interrupt + GICDistributor->CPENDSGIR[IRQn / 4U] = 1U << ((IRQn % 4U) * 8U); + } +} + +/** \brief Sets the interrupt configuration using GIC's ICFGR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] int_config Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE void GIC_SetConfiguration(IRQn_Type IRQn, uint32_t int_config) +{ + uint32_t icfgr = GICDistributor->ICFGR[IRQn / 16U]; + uint32_t shift = (IRQn % 16U) << 1U; + + icfgr &= (~(3U << shift)); + icfgr |= ( int_config << shift); + + GICDistributor->ICFGR[IRQn / 16U] = icfgr; +} + +/** \brief Get the interrupt configuration from the GIC's ICFGR register. +* \param [in] IRQn Interrupt to acquire the configuration for. +* \return Int_config field value. Bit 0: Reserved (0 - N-N model, 1 - 1-N model for some GIC before v1) +* Bit 1: 0 - level sensitive, 1 - edge triggered +*/ +__STATIC_INLINE uint32_t GIC_GetConfiguration(IRQn_Type IRQn) +{ + return (GICDistributor->ICFGR[IRQn / 16U] >> ((IRQn % 16U) >> 1U)); +} + +/** \brief Set the priority for the given interrupt in the GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be configured. +* \param [in] priority The priority for the interrupt, lower values denote higher priorities. +*/ +__STATIC_INLINE void GIC_SetPriority(IRQn_Type IRQn, uint32_t priority) +{ + uint32_t mask = GICDistributor->IPRIORITYR[IRQn / 4U] & ~(0xFFUL << ((IRQn % 4U) * 8U)); + GICDistributor->IPRIORITYR[IRQn / 4U] = mask | ((priority & 0xFFUL) << ((IRQn % 4U) * 8U)); +} + +/** \brief Read the current interrupt priority from GIC's IPRIORITYR register. +* \param [in] IRQn The interrupt to be queried. +*/ +__STATIC_INLINE uint32_t GIC_GetPriority(IRQn_Type IRQn) +{ + return (GICDistributor->IPRIORITYR[IRQn / 4U] >> ((IRQn % 4U) * 8U)) & 0xFFUL; +} + +/** \brief Set the interrupt priority mask using CPU's PMR register. +* \param [in] priority Priority mask to be set. +*/ +__STATIC_INLINE void GIC_SetInterfacePriorityMask(uint32_t priority) +{ + GICInterface->PMR = priority & 0xFFUL; //set priority mask +} + +/** \brief Read the current interrupt priority mask from CPU's PMR register. +* \result GICInterface_Type::PMR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfacePriorityMask(void) +{ + return GICInterface->PMR; +} + +/** \brief Configures the group priority and subpriority split point using CPU's BPR register. +* \param [in] binary_point Amount of bits used as subpriority. +*/ +__STATIC_INLINE void GIC_SetBinaryPoint(uint32_t binary_point) +{ + GICInterface->BPR = binary_point & 7U; //set binary point +} + +/** \brief Read the current group priority and subpriority split point from CPU's BPR register. +* \return GICInterface_Type::BPR +*/ +__STATIC_INLINE uint32_t GIC_GetBinaryPoint(void) +{ + return GICInterface->BPR; +} + +/** \brief Get the status for a given interrupt. +* \param [in] IRQn The interrupt to get status for. +* \return 0 - not pending/active, 1 - pending, 2 - active, 3 - pending and active +*/ +__STATIC_INLINE uint32_t GIC_GetIRQStatus(IRQn_Type IRQn) +{ + uint32_t pending, active; + + active = ((GICDistributor->ISACTIVER[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + pending = ((GICDistributor->ISPENDR[IRQn / 32U]) >> (IRQn % 32U)) & 1UL; + + return ((active<<1U) | pending); +} + +/** \brief Generate a software interrupt using GIC's SGIR register. +* \param [in] IRQn Software interrupt to be generated. +* \param [in] target_list List of CPUs the software interrupt should be forwarded to. +* \param [in] filter_list Filter to be applied to determine interrupt receivers. +*/ +__STATIC_INLINE void GIC_SendSGI(IRQn_Type IRQn, uint32_t target_list, uint32_t filter_list) +{ + GICDistributor->SGIR = ((filter_list & 3U) << 24U) | ((target_list & 0xFFUL) << 16U) | (IRQn & 0x0FUL); +} + +/** \brief Get the interrupt number of the highest interrupt pending from CPU's HPPIR register. +* \return GICInterface_Type::HPPIR +*/ +__STATIC_INLINE uint32_t GIC_GetHighPendingIRQ(void) +{ + return GICInterface->HPPIR; +} + +/** \brief Provides information about the implementer and revision of the CPU interface. +* \return GICInterface_Type::IIDR +*/ +__STATIC_INLINE uint32_t GIC_GetInterfaceId(void) +{ + return GICInterface->IIDR; +} + +/** \brief Set the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \param [in] group Interrupt group number: 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE void GIC_SetGroup(IRQn_Type IRQn, uint32_t group) +{ + uint32_t igroupr = GICDistributor->IGROUPR[IRQn / 32U]; + uint32_t shift = (IRQn % 32U); + + igroupr &= (~(1U << shift)); + igroupr |= ( (group & 1U) << shift); + + GICDistributor->IGROUPR[IRQn / 32U] = igroupr; +} +#define GIC_SetSecurity GIC_SetGroup + +/** \brief Get the interrupt group from the GIC's IGROUPR register. +* \param [in] IRQn The interrupt to be queried. +* \return 0 - Group 0, 1 - Group 1 +*/ +__STATIC_INLINE uint32_t GIC_GetGroup(IRQn_Type IRQn) +{ + return (GICDistributor->IGROUPR[IRQn / 32U] >> (IRQn % 32U)) & 1UL; +} +#define GIC_GetSecurity GIC_GetGroup + +/** \brief Initialize the interrupt distributor. +*/ +__STATIC_INLINE void GIC_DistInit(void) +{ + uint32_t i; + uint32_t num_irq = 0U; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableDistributor(); + //Get the maximum number of interrupts that the GIC supports + num_irq = 32U * ((GIC_DistributorInfo() & 0x1FU) + 1U); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + for (i = 32U; i < num_irq; i++) + { + //Disable the SPI interrupt + GIC_DisableIRQ((IRQn_Type)i); + //Set level-sensitive (and N-N model) + GIC_SetConfiguration((IRQn_Type)i, 0U); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + //Set target list to CPU0 + GIC_SetTarget((IRQn_Type)i, 1U); + } + //Enable distributor + GIC_EnableDistributor(); +} + +/** \brief Initialize the CPU's interrupt interface +*/ +__STATIC_INLINE void GIC_CPUInterfaceInit(void) +{ + uint32_t i; + uint32_t priority_field; + + //A reset sets all bits in the IGROUPRs corresponding to the SPIs to 0, + //configuring all of the interrupts as Secure. + + //Disable interrupt forwarding + GIC_DisableInterface(); + + /* Priority level is implementation defined. + To determine the number of priority bits implemented write 0xFF to an IPRIORITYR + priority field and read back the value stored.*/ + GIC_SetPriority((IRQn_Type)0U, 0xFFU); + priority_field = GIC_GetPriority((IRQn_Type)0U); + + //SGI and PPI + for (i = 0U; i < 32U; i++) + { + if(i > 15U) { + //Set level-sensitive (and N-N model) for PPI + GIC_SetConfiguration((IRQn_Type)i, 0U); + } + //Disable SGI and PPI interrupts + GIC_DisableIRQ((IRQn_Type)i); + //Set priority + GIC_SetPriority((IRQn_Type)i, priority_field/2U); + } + //Enable interface + GIC_EnableInterface(); + //Set binary point to 0 + GIC_SetBinaryPoint(0U); + //Set priority mask + GIC_SetInterfacePriorityMask(0xFFU); +} + +/** \brief Initialize and enable the GIC +*/ +__STATIC_INLINE void GIC_Enable(void) +{ + GIC_DistInit(); + GIC_CPUInterfaceInit(); //per CPU +} +#endif + +/* ########################## Generic Timer functions ############################ */ +#if (__TIM_PRESENT == 1U) || defined(DOXYGEN) + +/* PL1 Physical Timer */ +#if (__CORTEX_A == 7U) || defined(DOXYGEN) + +/** \brief Physical Timer Control register */ +typedef union +{ + struct + { + uint32_t ENABLE:1; /*!< \brief bit: 0 Enables the timer. */ + uint32_t IMASK:1; /*!< \brief bit: 1 Timer output signal mask bit. */ + uint32_t ISTATUS:1; /*!< \brief bit: 2 The status of the timer. */ + RESERVED(0:29, uint32_t) + } b; /*!< \brief Structure used for bit access */ + uint32_t w; /*!< \brief Type used for word access */ +} CNTP_CTL_Type; + +/** \brief Configures the frequency the timer shall run at. +* \param [in] value The timer frequency in Hz. +*/ +__STATIC_INLINE void PL1_SetCounterFrequency(uint32_t value) +{ + __set_CNTFRQ(value); + __ISB(); +} + +/** \brief Sets the reset value of the timer. +* \param [in] value The value the timer is loaded with. +*/ +__STATIC_INLINE void PL1_SetLoadValue(uint32_t value) +{ + __set_CNTP_TVAL(value); + __ISB(); +} + +/** \brief Get the current counter value. +* \return Current counter value. +*/ +__STATIC_INLINE uint32_t PL1_GetCurrentValue(void) +{ + return(__get_CNTP_TVAL()); +} + +/** \brief Get the current physical counter value. +* \return Current physical counter value. +*/ +__STATIC_INLINE uint64_t PL1_GetCurrentPhysicalValue(void) +{ + return(__get_CNTPCT()); +} + +/** \brief Set the physical compare value. +* \param [in] value New physical timer compare value. +*/ +__STATIC_INLINE void PL1_SetPhysicalCompareValue(uint64_t value) +{ + __set_CNTP_CVAL(value); + __ISB(); +} + +/** \brief Get the physical compare value. +* \return Physical compare value. +*/ +__STATIC_INLINE uint64_t PL1_GetPhysicalCompareValue(void) +{ + return(__get_CNTP_CVAL()); +} + +/** \brief Configure the timer by setting the control value. +* \param [in] value New timer control value. +*/ +__STATIC_INLINE void PL1_SetControl(uint32_t value) +{ + __set_CNTP_CTL(value); + __ISB(); +} + +/** \brief Get the control value. +* \return Control value. +*/ +__STATIC_INLINE uint32_t PL1_GetControl(void) +{ + return(__get_CNTP_CTL()); +} +#endif + +/* Private Timer */ +#if ((__CORTEX_A == 5U) || (__CORTEX_A == 9U)) || defined(DOXYGEN) +/** \brief Set the load value to timers LOAD register. +* \param [in] value The load value to be set. +*/ +__STATIC_INLINE void PTIM_SetLoadValue(uint32_t value) +{ + PTIM->LOAD = value; +} + +/** \brief Get the load value from timers LOAD register. +* \return Timer_Type::LOAD +*/ +__STATIC_INLINE uint32_t PTIM_GetLoadValue(void) +{ + return(PTIM->LOAD); +} + +/** \brief Set current counter value from its COUNTER register. +*/ +__STATIC_INLINE void PTIM_SetCurrentValue(uint32_t value) +{ + PTIM->COUNTER = value; +} + +/** \brief Get current counter value from timers COUNTER register. +* \result Timer_Type::COUNTER +*/ +__STATIC_INLINE uint32_t PTIM_GetCurrentValue(void) +{ + return(PTIM->COUNTER); +} + +/** \brief Configure the timer using its CONTROL register. +* \param [in] value The new configuration value to be set. +*/ +__STATIC_INLINE void PTIM_SetControl(uint32_t value) +{ + PTIM->CONTROL = value; +} + +/** ref Timer_Type::CONTROL Get the current timer configuration from its CONTROL register. +* \return Timer_Type::CONTROL +*/ +__STATIC_INLINE uint32_t PTIM_GetControl(void) +{ + return(PTIM->CONTROL); +} + +/** ref Timer_Type::CONTROL Get the event flag in timers ISR register. +* \return 0 - flag is not set, 1- flag is set +*/ +__STATIC_INLINE uint32_t PTIM_GetEventFlag(void) +{ + return (PTIM->ISR & 1UL); +} + +/** ref Timer_Type::CONTROL Clears the event flag in timers ISR register. +*/ +__STATIC_INLINE void PTIM_ClearEventFlag(void) +{ + PTIM->ISR = 1; +} +#endif +#endif + +/* ########################## MMU functions ###################################### */ + +#define SECTION_DESCRIPTOR (0x2) +#define SECTION_MASK (0xFFFFFFFC) + +#define SECTION_TEXCB_MASK (0xFFFF8FF3) +#define SECTION_B_SHIFT (2) +#define SECTION_C_SHIFT (3) +#define SECTION_TEX0_SHIFT (12) +#define SECTION_TEX1_SHIFT (13) +#define SECTION_TEX2_SHIFT (14) + +#define SECTION_XN_MASK (0xFFFFFFEF) +#define SECTION_XN_SHIFT (4) + +#define SECTION_DOMAIN_MASK (0xFFFFFE1F) +#define SECTION_DOMAIN_SHIFT (5) + +#define SECTION_P_MASK (0xFFFFFDFF) +#define SECTION_P_SHIFT (9) + +#define SECTION_AP_MASK (0xFFFF73FF) +#define SECTION_AP_SHIFT (10) +#define SECTION_AP2_SHIFT (15) + +#define SECTION_S_MASK (0xFFFEFFFF) +#define SECTION_S_SHIFT (16) + +#define SECTION_NG_MASK (0xFFFDFFFF) +#define SECTION_NG_SHIFT (17) + +#define SECTION_NS_MASK (0xFFF7FFFF) +#define SECTION_NS_SHIFT (19) + +#define PAGE_L1_DESCRIPTOR (0x1) +#define PAGE_L1_MASK (0xFFFFFFFC) + +#define PAGE_L2_4K_DESC (0x2) +#define PAGE_L2_4K_MASK (0xFFFFFFFD) + +#define PAGE_L2_64K_DESC (0x1) +#define PAGE_L2_64K_MASK (0xFFFFFFFC) + +#define PAGE_4K_TEXCB_MASK (0xFFFFFE33) +#define PAGE_4K_B_SHIFT (2) +#define PAGE_4K_C_SHIFT (3) +#define PAGE_4K_TEX0_SHIFT (6) +#define PAGE_4K_TEX1_SHIFT (7) +#define PAGE_4K_TEX2_SHIFT (8) + +#define PAGE_64K_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_64K_B_SHIFT (2) +#define PAGE_64K_C_SHIFT (3) +#define PAGE_64K_TEX0_SHIFT (12) +#define PAGE_64K_TEX1_SHIFT (13) +#define PAGE_64K_TEX2_SHIFT (14) + +#define PAGE_TEXCB_MASK (0xFFFF8FF3) +#define PAGE_B_SHIFT (2) +#define PAGE_C_SHIFT (3) +#define PAGE_TEX_SHIFT (12) + +#define PAGE_XN_4K_MASK (0xFFFFFFFE) +#define PAGE_XN_4K_SHIFT (0) +#define PAGE_XN_64K_MASK (0xFFFF7FFF) +#define PAGE_XN_64K_SHIFT (15) + +#define PAGE_DOMAIN_MASK (0xFFFFFE1F) +#define PAGE_DOMAIN_SHIFT (5) + +#define PAGE_P_MASK (0xFFFFFDFF) +#define PAGE_P_SHIFT (9) + +#define PAGE_AP_MASK (0xFFFFFDCF) +#define PAGE_AP_SHIFT (4) +#define PAGE_AP2_SHIFT (9) + +#define PAGE_S_MASK (0xFFFFFBFF) +#define PAGE_S_SHIFT (10) + +#define PAGE_NG_MASK (0xFFFFF7FF) +#define PAGE_NG_SHIFT (11) + +#define PAGE_NS_MASK (0xFFFFFFF7) +#define PAGE_NS_SHIFT (3) + +#define OFFSET_1M (0x00100000) +#define OFFSET_64K (0x00010000) +#define OFFSET_4K (0x00001000) + +#define DESCRIPTOR_FAULT (0x00000000) + +/* Attributes enumerations */ + +/* Region size attributes */ +typedef enum +{ + SECTION, + PAGE_4k, + PAGE_64k, +} mmu_region_size_Type; + +/* Region type attributes */ +typedef enum +{ + NORMAL, + DEVICE, + SHARED_DEVICE, + NON_SHARED_DEVICE, + STRONGLY_ORDERED +} mmu_memory_Type; + +/* Region cacheability attributes */ +typedef enum +{ + NON_CACHEABLE, + WB_WA, + WT, + WB_NO_WA, +} mmu_cacheability_Type; + +/* Region parity check attributes */ +typedef enum +{ + ECC_DISABLED, + ECC_ENABLED, +} mmu_ecc_check_Type; + +/* Region execution attributes */ +typedef enum +{ + EXECUTE, + NON_EXECUTE, +} mmu_execute_Type; + +/* Region global attributes */ +typedef enum +{ + GLOBAL, + NON_GLOBAL, +} mmu_global_Type; + +/* Region shareability attributes */ +typedef enum +{ + NON_SHARED, + SHARED, +} mmu_shared_Type; + +/* Region security attributes */ +typedef enum +{ + SECURE, + NON_SECURE, +} mmu_secure_Type; + +/* Region access attributes */ +typedef enum +{ + NO_ACCESS, + RW, + READ, +} mmu_access_Type; + +/* Memory Region definition */ +typedef struct RegionStruct { + mmu_region_size_Type rg_t; + mmu_memory_Type mem_t; + uint8_t domain; + mmu_cacheability_Type inner_norm_t; + mmu_cacheability_Type outer_norm_t; + mmu_ecc_check_Type e_t; + mmu_execute_Type xn_t; + mmu_global_Type g_t; + mmu_secure_Type sec_t; + mmu_access_Type priv_t; + mmu_access_Type user_t; + mmu_shared_Type sh_t; + +} mmu_region_attributes_Type; + +//Following macros define the descriptors and attributes +//Sect_Normal. Outer & inner wb/wa, non-shareable, executable, rw, domain 0 +#define section_normal(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_NC. Outer & inner non-cacheable, non-shareable, executable, rw, domain 0 +#define section_normal_nc(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_Cod. Outer & inner wb/wa, non-shareable, executable, ro, domain 0 +#define section_normal_cod(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RO. Sect_Normal_Cod, but not executable +#define section_normal_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Normal_RW. Sect_Normal_Cod, but writeable and not executable +#define section_normal_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = WB_WA; \ + region.outer_norm_t = WB_WA; \ + region.mem_t = NORMAL; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Sect_SO. Strongly-ordered (therefore shareable), not executable, rw, domain 0, base addr 0 +#define section_so(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RO. Device, non-shareable, non-executable, ro, domain 0, base addr 0 +#define section_device_ro(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = READ; \ + region.user_t = READ; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); + +//Sect_Device_RW. Sect_Device_RO, but writeable +#define section_device_rw(descriptor_l1, region) region.rg_t = SECTION; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = STRONGLY_ORDERED; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetSectionDescriptor(&descriptor_l1, region); +//Page_4k_Device_RW. Shared device, not executable, rw, domain 0 +#define page4k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_4k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +//Page_64k_Device_RW. Shared device, not executable, rw, domain 0 +#define page64k_device_rw(descriptor_l1, descriptor_l2, region) region.rg_t = PAGE_64k; \ + region.domain = 0x0; \ + region.e_t = ECC_DISABLED; \ + region.g_t = GLOBAL; \ + region.inner_norm_t = NON_CACHEABLE; \ + region.outer_norm_t = NON_CACHEABLE; \ + region.mem_t = SHARED_DEVICE; \ + region.sec_t = SECURE; \ + region.xn_t = NON_EXECUTE; \ + region.priv_t = RW; \ + region.user_t = RW; \ + region.sh_t = NON_SHARED; \ + MMU_GetPageDescriptor(&descriptor_l1, &descriptor_l2, region); + +/** \brief Set section execution-never attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] xn Section execution-never attribute : EXECUTE , NON_EXECUTE. + + \return 0 +*/ +__STATIC_INLINE int MMU_XNSection(uint32_t *descriptor_l1, mmu_execute_Type xn) +{ + *descriptor_l1 &= SECTION_XN_MASK; + *descriptor_l1 |= ((xn & 0x1) << SECTION_XN_SHIFT); + return 0; +} + +/** \brief Set section domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Section domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainSection(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= SECTION_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xF) << SECTION_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set section parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PSection(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set section access privileges + + \param [out] descriptor_l1 L1 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APSection(uint32_t *descriptor_l1, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l1 &= SECTION_AP_MASK; + *descriptor_l1 |= (ap & 0x3) << SECTION_AP_SHIFT; + *descriptor_l1 |= ((ap & 0x4)>>2) << SECTION_AP2_SHIFT; + + return 0; +} + +/** \brief Set section shareability + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedSection(uint32_t *descriptor_l1, mmu_shared_Type s_bit) +{ + *descriptor_l1 &= SECTION_S_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_S_SHIFT); + return 0; +} + +/** \brief Set section Global attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] g_bit Section attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalSection(uint32_t *descriptor_l1, mmu_global_Type g_bit) +{ + *descriptor_l1 &= SECTION_NG_MASK; + *descriptor_l1 |= ((g_bit & 0x1) << SECTION_NG_SHIFT); + return 0; +} + +/** \brief Set section Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit Section Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecureSection(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= SECTION_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << SECTION_NS_SHIFT); + return 0; +} + +/* Page 4k or 64k */ +/** \brief Set 4k/64k page execution-never attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] xn Page execution-never attribute : EXECUTE , NON_EXECUTE. + \param [in] page Page size: PAGE_4k, PAGE_64k, + + \return 0 +*/ +__STATIC_INLINE int MMU_XNPage(uint32_t *descriptor_l2, mmu_execute_Type xn, mmu_region_size_Type page) +{ + if (page == PAGE_4k) + { + *descriptor_l2 &= PAGE_XN_4K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_4K_SHIFT); + } + else + { + *descriptor_l2 &= PAGE_XN_64K_MASK; + *descriptor_l2 |= ((xn & 0x1) << PAGE_XN_64K_SHIFT); + } + return 0; +} + +/** \brief Set 4k/64k page domain + + \param [out] descriptor_l1 L1 descriptor. + \param [in] domain Page domain + + \return 0 +*/ +__STATIC_INLINE int MMU_DomainPage(uint32_t *descriptor_l1, uint8_t domain) +{ + *descriptor_l1 &= PAGE_DOMAIN_MASK; + *descriptor_l1 |= ((domain & 0xf) << PAGE_DOMAIN_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page parity check + + \param [out] descriptor_l1 L1 descriptor. + \param [in] p_bit Parity check: ECC_DISABLED, ECC_ENABLED + + \return 0 +*/ +__STATIC_INLINE int MMU_PPage(uint32_t *descriptor_l1, mmu_ecc_check_Type p_bit) +{ + *descriptor_l1 &= SECTION_P_MASK; + *descriptor_l1 |= ((p_bit & 0x1) << SECTION_P_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page access privileges + + \param [out] descriptor_l2 L2 descriptor. + \param [in] user User Level Access: NO_ACCESS, RW, READ + \param [in] priv Privilege Level Access: NO_ACCESS, RW, READ + \param [in] afe Access flag enable + + \return 0 +*/ +__STATIC_INLINE int MMU_APPage(uint32_t *descriptor_l2, mmu_access_Type user, mmu_access_Type priv, uint32_t afe) +{ + uint32_t ap = 0; + + if (afe == 0) { //full access + if ((priv == NO_ACCESS) && (user == NO_ACCESS)) { ap = 0x0; } + else if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == READ)) { ap = 0x2; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x6; } + } + + else { //Simplified access + if ((priv == RW) && (user == NO_ACCESS)) { ap = 0x1; } + else if ((priv == RW) && (user == RW)) { ap = 0x3; } + else if ((priv == READ) && (user == NO_ACCESS)) { ap = 0x5; } + else if ((priv == READ) && (user == READ)) { ap = 0x7; } + } + + *descriptor_l2 &= PAGE_AP_MASK; + *descriptor_l2 |= (ap & 0x3) << PAGE_AP_SHIFT; + *descriptor_l2 |= ((ap & 0x4)>>2) << PAGE_AP2_SHIFT; + + return 0; +} + +/** \brief Set 4k/64k page shareability + + \param [out] descriptor_l2 L2 descriptor. + \param [in] s_bit 4k/64k page shareability: NON_SHARED, SHARED + + \return 0 +*/ +__STATIC_INLINE int MMU_SharedPage(uint32_t *descriptor_l2, mmu_shared_Type s_bit) +{ + *descriptor_l2 &= PAGE_S_MASK; + *descriptor_l2 |= ((s_bit & 0x1) << PAGE_S_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Global attribute + + \param [out] descriptor_l2 L2 descriptor. + \param [in] g_bit 4k/64k page attribute: GLOBAL, NON_GLOBAL + + \return 0 +*/ +__STATIC_INLINE int MMU_GlobalPage(uint32_t *descriptor_l2, mmu_global_Type g_bit) +{ + *descriptor_l2 &= PAGE_NG_MASK; + *descriptor_l2 |= ((g_bit & 0x1) << PAGE_NG_SHIFT); + return 0; +} + +/** \brief Set 4k/64k page Security attribute + + \param [out] descriptor_l1 L1 descriptor. + \param [in] s_bit 4k/64k page Security attribute: SECURE, NON_SECURE + + \return 0 +*/ +__STATIC_INLINE int MMU_SecurePage(uint32_t *descriptor_l1, mmu_secure_Type s_bit) +{ + *descriptor_l1 &= PAGE_NS_MASK; + *descriptor_l1 |= ((s_bit & 0x1) << PAGE_NS_SHIFT); + return 0; +} + +/** \brief Set Section memory attributes + + \param [out] descriptor_l1 L1 descriptor. + \param [in] mem Section memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + + \return 0 +*/ +__STATIC_INLINE int MMU_MemorySection(uint32_t *descriptor_l1, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner) +{ + *descriptor_l1 &= SECTION_TEXCB_MASK; + + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l1 |= (1 << SECTION_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l1 |= 1 << SECTION_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_B_SHIFT) | (1 << SECTION_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT); + break; + case WT: + *descriptor_l1 |= 1 << SECTION_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l1 |= (1 << SECTION_TEX0_SHIFT) | (1 << SECTION_TEX0_SHIFT); + break; + } + } + return 0; +} + +/** \brief Set 4k/64k page memory attributes + + \param [out] descriptor_l2 L2 descriptor. + \param [in] mem 4k/64k page memory type: NORMAL, DEVICE, SHARED_DEVICE, NON_SHARED_DEVICE, STRONGLY_ORDERED + \param [in] outer Outer cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] inner Inner cacheability: NON_CACHEABLE, WB_WA, WT, WB_NO_WA, + \param [in] page Page size + + \return 0 +*/ +__STATIC_INLINE int MMU_MemoryPage(uint32_t *descriptor_l2, mmu_memory_Type mem, mmu_cacheability_Type outer, mmu_cacheability_Type inner, mmu_region_size_Type page) +{ + *descriptor_l2 &= PAGE_4K_TEXCB_MASK; + + if (page == PAGE_64k) + { + //same as section + MMU_MemorySection(descriptor_l2, mem, outer, inner); + } + else + { + if (STRONGLY_ORDERED == mem) + { + return 0; + } + else if (SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + } + else if (NON_SHARED_DEVICE == mem) + { + *descriptor_l2 |= (1 << PAGE_4K_TEX1_SHIFT); + } + else if (NORMAL == mem) + { + *descriptor_l2 |= 1 << PAGE_4K_TEX2_SHIFT; + switch(inner) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_C_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_B_SHIFT) | (1 << PAGE_4K_C_SHIFT); + break; + } + switch(outer) + { + case NON_CACHEABLE: + break; + case WB_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT); + break; + case WT: + *descriptor_l2 |= 1 << PAGE_4K_TEX1_SHIFT; + break; + case WB_NO_WA: + *descriptor_l2 |= (1 << PAGE_4K_TEX0_SHIFT) | (1 << PAGE_4K_TEX0_SHIFT); + break; + } + } + } + + return 0; +} + +/** \brief Create a L1 section descriptor + + \param [out] descriptor L1 descriptor + \param [in] reg Section attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetSectionDescriptor(uint32_t *descriptor, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + + MMU_MemorySection(descriptor, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t); + MMU_XNSection(descriptor,reg.xn_t); + MMU_DomainSection(descriptor, reg.domain); + MMU_PSection(descriptor, reg.e_t); + MMU_APSection(descriptor, reg.priv_t, reg.user_t, 1); + MMU_SharedSection(descriptor,reg.sh_t); + MMU_GlobalSection(descriptor,reg.g_t); + MMU_SecureSection(descriptor,reg.sec_t); + *descriptor &= SECTION_MASK; + *descriptor |= SECTION_DESCRIPTOR; + + return 0; +} + + +/** \brief Create a L1 and L2 4k/64k page descriptor + + \param [out] descriptor L1 descriptor + \param [out] descriptor2 L2 descriptor + \param [in] reg 4k/64k page attributes + + \return 0 +*/ +__STATIC_INLINE int MMU_GetPageDescriptor(uint32_t *descriptor, uint32_t *descriptor2, mmu_region_attributes_Type reg) +{ + *descriptor = 0; + *descriptor2 = 0; + + switch (reg.rg_t) + { + case PAGE_4k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_4k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_4k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_4K_MASK; + *descriptor2 |= PAGE_L2_4K_DESC; + break; + + case PAGE_64k: + MMU_MemoryPage(descriptor2, reg.mem_t, reg.outer_norm_t, reg.inner_norm_t, PAGE_64k); + MMU_XNPage(descriptor2, reg.xn_t, PAGE_64k); + MMU_DomainPage(descriptor, reg.domain); + MMU_PPage(descriptor, reg.e_t); + MMU_APPage(descriptor2, reg.priv_t, reg.user_t, 1); + MMU_SharedPage(descriptor2,reg.sh_t); + MMU_GlobalPage(descriptor2,reg.g_t); + MMU_SecurePage(descriptor,reg.sec_t); + *descriptor &= PAGE_L1_MASK; + *descriptor |= PAGE_L1_DESCRIPTOR; + *descriptor2 &= PAGE_L2_64K_MASK; + *descriptor2 |= PAGE_L2_64K_DESC; + break; + + case SECTION: + //error + break; + } + + return 0; +} + +/** \brief Create a 1MB Section + + \param [in] ttb Translation table base address + \param [in] base_address Section base address + \param [in] count Number of sections to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTSection(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1) +{ + uint32_t offset; + uint32_t entry; + uint32_t i; + + offset = base_address >> 20; + entry = (base_address & 0xFFF00000) | descriptor_l1; + + //4 bytes aligned + ttb = ttb + offset; + + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb++ = entry; + entry += OFFSET_1M; + } +} + +/** \brief Create a 4k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 4k base address + \param [in] count Number of 4k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage4k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i; + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFFF000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //4 bytes aligned + *ttb_l2++ = entry2; + entry2 += OFFSET_4K; + } +} + +/** \brief Create a 64k page entry + + \param [in] ttb L1 table base address + \param [in] base_address 64k base address + \param [in] count Number of 64k pages to create + \param [in] descriptor_l1 L1 descriptor (region attributes) + \param [in] ttb_l2 L2 table base address + \param [in] descriptor_l2 L2 descriptor (region attributes) + +*/ +__STATIC_INLINE void MMU_TTPage64k(uint32_t *ttb, uint32_t base_address, uint32_t count, uint32_t descriptor_l1, uint32_t *ttb_l2, uint32_t descriptor_l2 ) +{ + uint32_t offset, offset2; + uint32_t entry, entry2; + uint32_t i,j; + + + offset = base_address >> 20; + entry = ((int)ttb_l2 & 0xFFFFFC00) | descriptor_l1; + + //4 bytes aligned + ttb += offset; + //create l1_entry + *ttb = entry; + + offset2 = (base_address & 0xff000) >> 12; + ttb_l2 += offset2; + entry2 = (base_address & 0xFFFF0000) | descriptor_l2; + for (i = 0; i < count; i++ ) + { + //create 16 entries + for (j = 0; j < 16; j++) + { + //4 bytes aligned + *ttb_l2++ = entry2; + } + entry2 += OFFSET_64K; + } +} + +/** \brief Enable MMU +*/ +__STATIC_INLINE void MMU_Enable(void) +{ + // Set M bit 0 to enable the MMU + // Set AFE bit to enable simplified access permissions model + // Clear TRE bit to disable TEX remap and A bit to disable strict alignment fault checking + __set_SCTLR( (__get_SCTLR() & ~(1 << 28) & ~(1 << 1)) | 1 | (1 << 29)); + __ISB(); +} + +/** \brief Disable MMU +*/ +__STATIC_INLINE void MMU_Disable(void) +{ + // Clear M bit 0 to disable the MMU + __set_SCTLR( __get_SCTLR() & ~1); + __ISB(); +} + +/** \brief Invalidate entire unified TLB +*/ + +__STATIC_INLINE void MMU_InvalidateTLB(void) +{ + __set_TLBIALL(0); + __DSB(); //ensure completion of the invalidation + __ISB(); //ensure instruction fetch path sees new state +} + + +#ifdef __cplusplus +} +#endif + +#endif /* __CORE_CA_H_DEPENDANT */ + +#endif /* __CMSIS_GENERIC */ diff --git a/core/arm/CMSIS/Core_A/Include/irq_ctrl.h b/core/arm/CMSIS/Core_A/Include/irq_ctrl.h new file mode 100644 index 000000000..a6d313de7 --- /dev/null +++ b/core/arm/CMSIS/Core_A/Include/irq_ctrl.h @@ -0,0 +1,186 @@ +/**************************************************************************//** + * @file irq_ctrl.h + * @brief Interrupt Controller API header file + * @version V1.0.0 + * @date 23. June 2017 + ******************************************************************************/ +/* + * Copyright (c) 2017 ARM Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#if defined ( __ICCARM__ ) + #pragma system_include /* treat file as system include file for MISRA check */ +#elif defined (__clang__) + #pragma clang system_header /* treat file as system include file */ +#endif + +#ifndef IRQ_CTRL_H_ +#define IRQ_CTRL_H_ + +#include + +#ifndef IRQHANDLER_T +#define IRQHANDLER_T +/// Interrupt handler data type +typedef void (*IRQHandler_t) (void); +#endif + +#ifndef IRQN_ID_T +#define IRQN_ID_T +/// Interrupt ID number data type +typedef int32_t IRQn_ID_t; +#endif + +/* Interrupt mode bit-masks */ +#define IRQ_MODE_TRIG_Pos (0U) +#define IRQ_MODE_TRIG_Msk (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) +#define IRQ_MODE_TRIG_LEVEL (0x00UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_LOW (0x01UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: low level triggered interrupt +#define IRQ_MODE_TRIG_LEVEL_HIGH (0x02UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: high level triggered interrupt +#define IRQ_MODE_TRIG_EDGE (0x04UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_RISING (0x05UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_FALLING (0x06UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: falling edge triggered interrupt +#define IRQ_MODE_TRIG_EDGE_BOTH (0x07UL /*<< IRQ_MODE_TRIG_Pos*/) ///< Trigger: rising and falling edge triggered interrupt + +#define IRQ_MODE_TYPE_Pos (3U) +#define IRQ_MODE_TYPE_Msk (0x01UL << IRQ_MODE_TYPE_Pos) +#define IRQ_MODE_TYPE_IRQ (0x00UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU IRQ line +#define IRQ_MODE_TYPE_FIQ (0x01UL << IRQ_MODE_TYPE_Pos) ///< Type: interrupt source triggers CPU FIQ line + +#define IRQ_MODE_DOMAIN_Pos (4U) +#define IRQ_MODE_DOMAIN_Msk (0x01UL << IRQ_MODE_DOMAIN_Pos) +#define IRQ_MODE_DOMAIN_NONSECURE (0x00UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting non-secure domain +#define IRQ_MODE_DOMAIN_SECURE (0x01UL << IRQ_MODE_DOMAIN_Pos) ///< Domain: interrupt is targeting secure domain + +#define IRQ_MODE_CPU_Pos (5U) +#define IRQ_MODE_CPU_Msk (0xFFUL << IRQ_MODE_CPU_Pos) +#define IRQ_MODE_CPU_ALL (0x00UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets all CPUs +#define IRQ_MODE_CPU_0 (0x01UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 0 +#define IRQ_MODE_CPU_1 (0x02UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 1 +#define IRQ_MODE_CPU_2 (0x04UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 2 +#define IRQ_MODE_CPU_3 (0x08UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 3 +#define IRQ_MODE_CPU_4 (0x10UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 4 +#define IRQ_MODE_CPU_5 (0x20UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 5 +#define IRQ_MODE_CPU_6 (0x40UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 6 +#define IRQ_MODE_CPU_7 (0x80UL << IRQ_MODE_CPU_Pos) ///< CPU: interrupt targets CPU 7 + +#define IRQ_MODE_ERROR (0x80000000UL) ///< Bit indicating mode value error + +/* Interrupt priority bit-masks */ +#define IRQ_PRIORITY_Msk (0x0000FFFFUL) ///< Interrupt priority value bit-mask +#define IRQ_PRIORITY_ERROR (0x80000000UL) ///< Bit indicating priority value error + +/// Initialize interrupt controller. +/// \return 0 on success, -1 on error. +int32_t IRQ_Initialize (void); + +/// Register interrupt handler. +/// \param[in] irqn interrupt ID number +/// \param[in] handler interrupt handler function address +/// \return 0 on success, -1 on error. +int32_t IRQ_SetHandler (IRQn_ID_t irqn, IRQHandler_t handler); + +/// Get the registered interrupt handler. +/// \param[in] irqn interrupt ID number +/// \return registered interrupt handler function address. +IRQHandler_t IRQ_GetHandler (IRQn_ID_t irqn); + +/// Enable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Enable (IRQn_ID_t irqn); + +/// Disable interrupt. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_Disable (IRQn_ID_t irqn); + +/// Get interrupt enable state. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is disabled, 1 - interrupt is enabled. +uint32_t IRQ_GetEnableState (IRQn_ID_t irqn); + +/// Configure interrupt request mode. +/// \param[in] irqn interrupt ID number +/// \param[in] mode mode configuration +/// \return 0 on success, -1 on error. +int32_t IRQ_SetMode (IRQn_ID_t irqn, uint32_t mode); + +/// Get interrupt mode configuration. +/// \param[in] irqn interrupt ID number +/// \return current interrupt mode configuration with optional IRQ_MODE_ERROR bit set. +uint32_t IRQ_GetMode (IRQn_ID_t irqn); + +/// Get ID number of current interrupt request (IRQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveIRQ (void); + +/// Get ID number of current fast interrupt request (FIQ). +/// \return interrupt ID number. +IRQn_ID_t IRQ_GetActiveFIQ (void); + +/// Signal end of interrupt processing. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_EndOfInterrupt (IRQn_ID_t irqn); + +/// Set interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPending (IRQn_ID_t irqn); + +/// Get interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 - interrupt is not pending, 1 - interrupt is pending. +uint32_t IRQ_GetPending (IRQn_ID_t irqn); + +/// Clear interrupt pending flag. +/// \param[in] irqn interrupt ID number +/// \return 0 on success, -1 on error. +int32_t IRQ_ClearPending (IRQn_ID_t irqn); + +/// Set interrupt priority value. +/// \param[in] irqn interrupt ID number +/// \param[in] priority interrupt priority value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriority (IRQn_ID_t irqn, uint32_t priority); + +/// Get interrupt priority. +/// \param[in] irqn interrupt ID number +/// \return current interrupt priority value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriority (IRQn_ID_t irqn); + +/// Set priority masking threshold. +/// \param[in] priority priority masking threshold value +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityMask (uint32_t priority); + +/// Get priority masking threshold +/// \return current priority masking threshold value with optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityMask (void); + +/// Set priority grouping field split point +/// \param[in] bits number of MSB bits included in the group priority field comparison +/// \return 0 on success, -1 on error. +int32_t IRQ_SetPriorityGroupBits (uint32_t bits); + +/// Get priority grouping field split point +/// \return current number of MSB bits included in the group priority field comparison with +/// optional IRQ_PRIORITY_ERROR bit set. +uint32_t IRQ_GetPriorityGroupBits (void); + +#endif // IRQ_CTRL_H_ diff --git a/core/arm/README.md b/core/arm/README.md new file mode 100644 index 000000000..4731356c7 --- /dev/null +++ b/core/arm/README.md @@ -0,0 +1 @@ +[`CMSIS`](arm/CMSIS) and [`samd21a`](arm/samd21a) contain select files unzipped unmodified from [Atmel SAMD21 Series Device Support (1.3.395)](http://packs.download.atmel.com/#ATSAMD21E18A) and [CMSIS (Cortex Microcontroller Software Interface Standard) (5.4.0)](http://packs.download.atmel.com/#ARMCM0P) respectively. diff --git a/core/arm/samd21a/armcc/Device/SAMD21A/Source/system_samd21.c b/core/arm/samd21a/armcc/Device/SAMD21A/Source/system_samd21.c new file mode 100644 index 000000000..b711ba0b2 --- /dev/null +++ b/core/arm/samd21a/armcc/Device/SAMD21A/Source/system_samd21.c @@ -0,0 +1,78 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup. + * + * Copyright (c) 2015 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 "samd21.h" + +/** + * Initial system clock frequency. The System RC Oscillator (RCSYS) provides + * the source for the main clock at chip startup. + */ +#define __SYSTEM_CLOCK (1000000) + +uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/ + +/** + * Initialize the system + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +void SystemInit(void) +{ + // Keep the default device state after reset + SystemCoreClock = __SYSTEM_CLOCK; + return; +} + +/** + * Update SystemCoreClock variable + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + // Not implemented + SystemCoreClock = __SYSTEM_CLOCK; + return; +} diff --git a/core/arm/samd21a/atdf/ATSAMD21E18A.atdf b/core/arm/samd21a/atdf/ATSAMD21E18A.atdf new file mode 100644 index 000000000..9e9910d6a --- /dev/null +++ b/core/arm/samd21a/atdf/ATSAMD21E18A.atdf @@ -0,0 +1,5239 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/core/arm/samd21a/edc/ATSAMD21E18A.PIC b/core/arm/samd21a/edc/ATSAMD21E18A.PIC new file mode 100644 index 000000000..fc324b042 --- /dev/null +++ b/core/arm/samd21a/edc/ATSAMD21E18A.PIC @@ -0,0 +1,13425 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/core/arm/samd21a/gcc/gcc/samd21e18a_flash.ld b/core/arm/samd21a/gcc/gcc/samd21e18a_flash.ld new file mode 100644 index 000000000..3d254041b --- /dev/null +++ b/core/arm/samd21a/gcc/gcc/samd21e18a_flash.ld @@ -0,0 +1,143 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21E18A + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + rom (rx) : ORIGIN = 0x00000000, LENGTH = 0x00040000 + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; + +/* Section Definitions */ +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(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _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/core/arm/samd21a/gcc/gcc/samd21e18a_sram.ld b/core/arm/samd21a/gcc/gcc/samd21e18a_sram.ld new file mode 100644 index 000000000..c4875ab84 --- /dev/null +++ b/core/arm/samd21a/gcc/gcc/samd21e18a_sram.ld @@ -0,0 +1,142 @@ +/** + * \file + * + * \brief Linker script for running in internal SRAM on the SAMD21E18A + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + + +OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm") +OUTPUT_ARCH(arm) +SEARCH_DIR(.) + +/* Memory Spaces Definitions */ +MEMORY +{ + ram (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00008000 +} + +/* The stack size used by the application. NOTE: you need to adjust according to your application. */ +STACK_SIZE = DEFINED(STACK_SIZE) ? STACK_SIZE : DEFINED(__stack_size__) ? __stack_size__ : 0x2000; + +/* Section Definitions */ +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(4); + KEEP (*crtbegin.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*crtend.o(.ctors)) + + . = ALIGN(4); + KEEP(*(.fini)) + + . = ALIGN(4); + __fini_array_start = .; + KEEP (*(.fini_array)) + KEEP (*(SORT(.fini_array.*))) + __fini_array_end = .; + + KEEP (*crtbegin.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*crtend.o(.dtors)) + + . = ALIGN(4); + _efixed = .; /* End of text section */ + } > ram + + /* .ARM.exidx is sorted, so has to go in its own output section. */ + PROVIDE_HIDDEN (__exidx_start = .); + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > ram + 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/core/arm/samd21a/gcc/gcc/startup_samd21.c b/core/arm/samd21a/gcc/gcc/startup_samd21.c new file mode 100644 index 000000000..2341f7633 --- /dev/null +++ b/core/arm/samd21a/gcc/gcc/startup_samd21.c @@ -0,0 +1,255 @@ +/** + * \file + * + * \brief gcc starttup file for SAMD21 + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#include "samd21.h" + +/* 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); + +/* Default empty handler */ +void Dummy_Handler(void); + +/* Cortex-M0+ core handlers */ +void NonMaskableInt_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void HardFault_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SVCall_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void PendSV_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SysTick_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Peripherals handlers */ +void PM_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SYSCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void WDT_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void RTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void EIC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void NVMCTRL_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void DMAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_USB +void USB_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void EVSYS_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void SERCOM3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_SERCOM4 +void SERCOM4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_SERCOM5 +void SERCOM5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void TCC0_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC1_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TCC2_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC3_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC4_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +void TC5_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#ifdef ID_TC6 +void TC6_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_TC7 +void TC7_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_ADC +void ADC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_AC +void AC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_DAC +void DAC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +#ifdef ID_PTC +void PTC_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); +#endif +void I2S_Handler ( void ) __attribute__ ((weak, alias("Dummy_Handler"))); + +/* Exception Table */ +__attribute__ ((section(".vectors"))) +const DeviceVectors exception_table = { + + /* Configure Initial Stack Pointer, using linker-generated symbols */ + .pvStack = (void*) (&_estack), + + .pfnReset_Handler = (void*) Reset_Handler, + .pfnNonMaskableInt_Handler = (void*) NonMaskableInt_Handler, + .pfnHardFault_Handler = (void*) HardFault_Handler, + .pvReservedM12 = (void*) (0UL), /* Reserved */ + .pvReservedM11 = (void*) (0UL), /* Reserved */ + .pvReservedM10 = (void*) (0UL), /* Reserved */ + .pvReservedM9 = (void*) (0UL), /* Reserved */ + .pvReservedM8 = (void*) (0UL), /* Reserved */ + .pvReservedM7 = (void*) (0UL), /* Reserved */ + .pvReservedM6 = (void*) (0UL), /* Reserved */ + .pfnSVCall_Handler = (void*) SVCall_Handler, + .pvReservedM4 = (void*) (0UL), /* Reserved */ + .pvReservedM3 = (void*) (0UL), /* Reserved */ + .pfnPendSV_Handler = (void*) PendSV_Handler, + .pfnSysTick_Handler = (void*) SysTick_Handler, + + /* Configurable interrupts */ + .pfnPM_Handler = (void*) PM_Handler, /* 0 Power Manager */ + .pfnSYSCTRL_Handler = (void*) SYSCTRL_Handler, /* 1 System Control */ + .pfnWDT_Handler = (void*) WDT_Handler, /* 2 Watchdog Timer */ + .pfnRTC_Handler = (void*) RTC_Handler, /* 3 Real-Time Counter */ + .pfnEIC_Handler = (void*) EIC_Handler, /* 4 External Interrupt Controller */ + .pfnNVMCTRL_Handler = (void*) NVMCTRL_Handler, /* 5 Non-Volatile Memory Controller */ + .pfnDMAC_Handler = (void*) DMAC_Handler, /* 6 Direct Memory Access Controller */ +#ifdef ID_USB + .pfnUSB_Handler = (void*) USB_Handler, /* 7 Universal Serial Bus */ +#else + .pvReserved7 = (void*) (0UL), /* 7 Reserved */ +#endif + .pfnEVSYS_Handler = (void*) EVSYS_Handler, /* 8 Event System Interface */ + .pfnSERCOM0_Handler = (void*) SERCOM0_Handler, /* 9 Serial Communication Interface 0 */ + .pfnSERCOM1_Handler = (void*) SERCOM1_Handler, /* 10 Serial Communication Interface 1 */ + .pfnSERCOM2_Handler = (void*) SERCOM2_Handler, /* 11 Serial Communication Interface 2 */ + .pfnSERCOM3_Handler = (void*) SERCOM3_Handler, /* 12 Serial Communication Interface 3 */ +#ifdef ID_SERCOM4 + .pfnSERCOM4_Handler = (void*) SERCOM4_Handler, /* 13 Serial Communication Interface 4 */ +#else + .pvReserved13 = (void*) (0UL), /* 13 Reserved */ +#endif +#ifdef ID_SERCOM5 + .pfnSERCOM5_Handler = (void*) SERCOM5_Handler, /* 14 Serial Communication Interface 5 */ +#else + .pvReserved14 = (void*) (0UL), /* 14 Reserved */ +#endif + .pfnTCC0_Handler = (void*) TCC0_Handler, /* 15 Timer Counter Control 0 */ + .pfnTCC1_Handler = (void*) TCC1_Handler, /* 16 Timer Counter Control 1 */ + .pfnTCC2_Handler = (void*) TCC2_Handler, /* 17 Timer Counter Control 2 */ + .pfnTC3_Handler = (void*) TC3_Handler, /* 18 Basic Timer Counter 0 */ + .pfnTC4_Handler = (void*) TC4_Handler, /* 19 Basic Timer Counter 1 */ + .pfnTC5_Handler = (void*) TC5_Handler, /* 20 Basic Timer Counter 2 */ +#ifdef ID_TC6 + .pfnTC6_Handler = (void*) TC6_Handler, /* 21 Basic Timer Counter 3 */ +#else + .pvReserved21 = (void*) (0UL), /* 21 Reserved */ +#endif +#ifdef ID_TC7 + .pfnTC7_Handler = (void*) TC7_Handler, /* 22 Basic Timer Counter 4 */ +#else + .pvReserved22 = (void*) (0UL), /* 22 Reserved */ +#endif +#ifdef ID_ADC + .pfnADC_Handler = (void*) ADC_Handler, /* 23 Analog Digital Converter */ +#else + .pvReserved23 = (void*) (0UL), /* 23 Reserved */ +#endif +#ifdef ID_AC + .pfnAC_Handler = (void*) AC_Handler, /* 24 Analog Comparators */ +#else + .pvReserved24 = (void*) (0UL), /* 24 Reserved */ +#endif +#ifdef ID_DAC + .pfnDAC_Handler = (void*) DAC_Handler, /* 25 Digital Analog Converter */ +#else + .pvReserved25 = (void*) (0UL), /* 25 Reserved */ +#endif +#ifdef ID_PTC + .pfnPTC_Handler = (void*) PTC_Handler, /* 26 Peripheral Touch Controller */ +#else + .pvReserved26 = (void*) (0UL), /* 26 Reserved */ +#endif + .pfnI2S_Handler = (void*) I2S_Handler, /* 27 Inter-IC Sound Interface */ + .pvReserved28 = (void*) (0UL) /* 28 Reserved */ +}; + +/** + * \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); + + /* Change default QOS values to have the best performance and correct USB behaviour */ + SBMATRIX->SFR[SBMATRIX_SLAVE_HMCRAMC0].reg = 2; +#if defined(ID_USB) + USB->DEVICE.QOSCTRL.bit.CQOS = 2; + USB->DEVICE.QOSCTRL.bit.DQOS = 2; +#endif + DMAC->QOSCTRL.bit.DQOS = 2; + DMAC->QOSCTRL.bit.FQOS = 2; + DMAC->QOSCTRL.bit.WRBQOS = 2; + + /* Overwriting the default value of the NVMCTRL.CTRLB.MANW bit (errata reference 13134) */ + NVMCTRL->CTRLB.bit.MANW = 1; + + /* Initialize the C library */ + __libc_init_array(); + + /* Branch to main function */ + main(); + + /* Infinite loop */ + while (1); +} + +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Dummy_Handler(void) +{ + while (1) { + } +} diff --git a/core/arm/samd21a/gcc/system_samd21.c b/core/arm/samd21a/gcc/system_samd21.c new file mode 100644 index 000000000..d8287b91b --- /dev/null +++ b/core/arm/samd21a/gcc/system_samd21.c @@ -0,0 +1,64 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup. + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#include "samd21.h" + +/** + * Initial system clock frequency. The System RC Oscillator (RCSYS) provides + * the source for the main clock at chip startup. + */ +#define __SYSTEM_CLOCK (1000000) + +uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/ + +/** + * Initialize the system + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +void SystemInit(void) +{ + // Keep the default device state after reset + SystemCoreClock = __SYSTEM_CLOCK; + return; +} + +/** + * Update SystemCoreClock variable + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + // Not implemented + SystemCoreClock = __SYSTEM_CLOCK; + return; +} diff --git a/core/arm/samd21a/iar/config/debugger/Atmel/ATSAMD21E18A.ddf b/core/arm/samd21a/iar/config/debugger/Atmel/ATSAMD21E18A.ddf new file mode 100644 index 000000000..df72f9123 --- /dev/null +++ b/core/arm/samd21a/iar/config/debugger/Atmel/ATSAMD21E18A.ddf @@ -0,0 +1,26 @@ + +;; Memory information ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; +;; Used to define address zones within the ARM address space (Memory). +;; +;; Name may be almost anything +;; AdrSpace must be Memory +;; StartAdr start of memory block +;; EndAdr end of memory block +;; AccType type of access, read-only (R), read-write (RW) or SFR (W) + +[Memory] +;; Name AdrSpace StartAdr EndAdr AccType +Memory0 = FLASH Memory 0x00000000 0x0003FFFF R +Memory1 = HMCRAMC0 Memory 0x20000000 0x20007FFF RW +Memory2 = HPB0 Memory 0x40000000 0x4000FFFF W +Memory3 = HPB1 Memory 0x41000000 0x4100FFFF W +Memory4 = HPB2 Memory 0x42000000 0x4200FFFF W +Memory5 = PPB Memory 0xE0000000 0xE00FFFFF W +Memory6 = PORT_IOBUS Memory 0x60000000 0x600001FF W + +TrustedRanges = true +UseSfrFilter = true + +[SfrInclude] +File = ATSAMD21E18A.svd diff --git a/core/arm/samd21a/iar/config/debugger/Atmel/Trace_SAMD21.dmac b/core/arm/samd21a/iar/config/debugger/Atmel/Trace_SAMD21.dmac new file mode 100644 index 000000000..a4662337c --- /dev/null +++ b/core/arm/samd21a/iar/config/debugger/Atmel/Trace_SAMD21.dmac @@ -0,0 +1,78 @@ +// --------------------------------------------------------- +// ATMEL Microcontroller Software Support - NANTES - +// --------------------------------------------------------- +// The software is delivered "AS IS" without warranty or +// condition of any kind, either express, implied or +// statutory. This includes without limitation any warranty +// or condition with respect to merchantability or fitness +// for any particular purpose, or against the infringements of +// intellectual property rights of others. +// --------------------------------------------------------- +// File: Trace_SAMD21.dmac +// User setup file for CSPY debugger. +// --------------------------------------------------------- + +/********************************************************************* +* +* execUserReset() +* Called once after the target application is downloaded. +* Implement this macro to set up the memory map, breakpoints, +* interrupts, register macro files, etc. +* +*/ +execUserReset() +{ + __message "------------------------------ execUserReset ---------------------------------"; + __message "-------------------------------Set PC Reset ----------------------------------"; + __writeMemory32(0x05FA0004,0xE000ED0C,"Memory"); + //__hwReset(0); +} + +/********************************************************************* +* +* execUserPreload() +* Called after communication with the target system is established +* but before downloading the target application. +* Implement this macro to initialize memory locations and/or +* registers which are vital for loading data properly. +* +*/ +execUserPreload() +{ + __message "------------------------------ execUserPreload ---------------------------------"; + +} + +/********************************************************************* +* +* execUserFlashInit() +* +* Called once before the flash loader is downloaded to RAM. +* Implement this macro typically for setting up the memory map +* required by the flash loader. This macro is only called when you +* are programming flash, and it should only be used for flash loader +* functionality. +* +*/ + +execUserFlashInit() +{ + + __message "------------------------------ execUserFlashInit ---------------------------------"; + +} + + +/********************************************************************* +* +* execUserFlashExit() +* Called once when the debug session ends. +* Implement this macro to save status data etc. This macro is useful +* for flash loader functionality +* +*/ +execUserFlashExit() +{ + __message "------------------------------ execUserFlashExit ---------------------------------"; + //__hwReset(0); +} diff --git a/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.i79 b/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.i79 new file mode 100644 index 000000000..f674bae34 --- /dev/null +++ b/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.i79 @@ -0,0 +1,41 @@ +[FILEFORMAT] +rev=1.6 + +[CHIP] +// Chip name +name=ATSAMD21E18A + +// What endian modes does the chip support? (le_be8_be32(default), le_be8, le_be32, le, be8_be32, be8, be32) +endiansupport=le + +// Does the chip support the thumb instruction set? (true(default), false) +thumbsupport=true + +// Does the chip support the arm instruction set? (true(default), false) +armsupport=false + +// Does the chip have an FPU coprocessor? (VFPv1, VFPv2, VFPv4, VFPv5_SP, VFP9-S, MaverickCrunch, None(default)) +fpu=None + +// Chip specific macros +//DeviceMacros=$TOOLKIT_DIR$\config\debugger\Atmel\Trace_SAMD21.mac + +//Debugger interface, default JTAG=true, RTCK=true, SWD=true if Cortex cores, SWD=false if ARM cores, SWO_TraceD0=false +JTAG=false +RTCK=false +SWD=true +SWO_TraceD0=false + +[CORE] +// Name of ARM processor core +name=Cortex-M0+ + +[DDF FILE] +name=Atmel\ATSAMD21E18A.ddf + +[LINKER FILE] +//Name of the linker config file +name=$TOOLKIT_DIR$\config\linker\Atmel\samd21e18a\flash.icf + +[FLASH LOADER] +little=$TOOLKIT_DIR$\config\flashloader\Atmel\samd21e18a\samd21e18a-flash.board diff --git a/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.menu b/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.menu new file mode 100644 index 000000000..cc601824b --- /dev/null +++ b/core/arm/samd21a/iar/config/devices/Atmel/SAMD/ATSAMD21/ATSAMD21E18A.menu @@ -0,0 +1,7 @@ + + + + ATSAMD21E18A + Atmel ATSAMD21E18A + $CUR_DIR$\ATSAMD21E18A.i79 + diff --git a/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.board b/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.board new file mode 100644 index 000000000..47d8289b7 --- /dev/null +++ b/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.board @@ -0,0 +1,9 @@ + + + + + $TOOLKIT_DIR$\config\flashloader\Atmel\samd21e18a\samd21e18a-flash.flash + CODE 0x00000000 0x0003FFFF + 0x0 + + diff --git a/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.flash b/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.flash new file mode 100644 index 000000000..fbd65b519 --- /dev/null +++ b/core/arm/samd21a/iar/config/flashloader/Atmel/samd21e18a/samd21e18a-flash.flash @@ -0,0 +1,13 @@ + + + + $TOOLKIT_DIR$\config\flashloader\Atmel\samd21e18a\samd21e18a-flash.out + 0x00000000 + 64 + + 1 0x40000 + $TOOLKIT_DIR$\config\debugger\Atmel\Trace_SAMD21.mac + --flash + --flash : mandatory param + 1 + diff --git a/core/arm/samd21a/iar/iar/samd21e18a_flash.icf b/core/arm/samd21a/iar/iar/samd21e18a_flash.icf new file mode 100644 index 000000000..a99a8e8b2 --- /dev/null +++ b/core/arm/samd21a/iar/iar/samd21e18a_flash.icf @@ -0,0 +1,62 @@ +/** + * \file + * + * \brief Linker script for running in internal FLASH on the SAMD21E18A + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x0003FFFF; +/*-Sizes-*/ +if (!isdefinedsymbol(__ICFEDIT_size_cstack__)) { + define symbol __ICFEDIT_size_cstack__ = 0x2000; +} +if (!isdefinedsymbol(__ICFEDIT_size_heap__)) { + define symbol __ICFEDIT_size_heap__ = 0x0; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite }; +place at end of RAM_region { block CSTACK, block HEAP }; diff --git a/core/arm/samd21a/iar/iar/samd21e18a_sram.icf b/core/arm/samd21a/iar/iar/samd21e18a_sram.icf new file mode 100644 index 000000000..0418b891c --- /dev/null +++ b/core/arm/samd21a/iar/iar/samd21e18a_sram.icf @@ -0,0 +1,59 @@ +/** + * \file + * + * \brief Linker script for running in internal SRAM on the SAMD21E18A + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x20000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x20007FFF; +/*-Sizes-*/ +if (!isdefinedsymbol(__ICFEDIT_size_cstack__)) { + define symbol __ICFEDIT_size_cstack__ = 0x2000; +} +if (!isdefinedsymbol(__ICFEDIT_size_heap__)) { + define symbol __ICFEDIT_size_heap__ = 0x0; +} +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy with packing=none { readwrite }; +do not initialize { section .noinit }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in RAM_region { readonly }; +place in RAM_region { readwrite }; +place at end of RAM_region { block CSTACK, block HEAP }; diff --git a/core/arm/samd21a/iar/iar/startup_samd21.c b/core/arm/samd21a/iar/iar/startup_samd21.c new file mode 100644 index 000000000..9557c5aa1 --- /dev/null +++ b/core/arm/samd21a/iar/iar/startup_samd21.c @@ -0,0 +1,232 @@ +/** + * \file + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#include "samd21.h" + +typedef void (*intfunc) (void); +typedef union { intfunc __fun; void * __ptr; } intvec_elem; + +void __iar_program_start(void); +int __low_level_init(void); + +/* Default empty handler */ +void Dummy_Handler(void); + +/* Cortex-M0+ core handlers */ +#pragma weak NonMaskableInt_Handler = Dummy_Handler +#pragma weak HardFault_Handler = Dummy_Handler +#pragma weak SVCall_Handler = Dummy_Handler +#pragma weak PendSV_Handler = Dummy_Handler +#pragma weak SysTick_Handler = Dummy_Handler + +/* Peripherals handlers */ +#pragma weak PM_Handler = Dummy_Handler +#pragma weak SYSCTRL_Handler = Dummy_Handler +#pragma weak WDT_Handler = Dummy_Handler +#pragma weak RTC_Handler = Dummy_Handler +#pragma weak EIC_Handler = Dummy_Handler +#pragma weak NVMCTRL_Handler = Dummy_Handler +#pragma weak DMAC_Handler = Dummy_Handler +#ifdef ID_USB +#pragma weak USB_Handler = Dummy_Handler +#endif +#pragma weak EVSYS_Handler = Dummy_Handler +#pragma weak SERCOM0_Handler = Dummy_Handler +#pragma weak SERCOM1_Handler = Dummy_Handler +#pragma weak SERCOM2_Handler = Dummy_Handler +#pragma weak SERCOM3_Handler = Dummy_Handler +#ifdef ID_SERCOM4 +#pragma weak SERCOM4_Handler = Dummy_Handler +#endif +#ifdef ID_SERCOM5 +#pragma weak SERCOM5_Handler = Dummy_Handler +#endif +#pragma weak TCC0_Handler = Dummy_Handler +#pragma weak TCC1_Handler = Dummy_Handler +#pragma weak TCC2_Handler = Dummy_Handler +#pragma weak TC3_Handler = Dummy_Handler +#pragma weak TC4_Handler = Dummy_Handler +#pragma weak TC5_Handler = Dummy_Handler +#ifdef ID_TC6 +#pragma weak TC6_Handler = Dummy_Handler +#endif +#ifdef ID_TC7 +#pragma weak TC7_Handler = Dummy_Handler +#endif +#ifdef ID_ADC +#pragma weak ADC_Handler = Dummy_Handler +#endif +#ifdef ID_AC +#pragma weak AC_Handler = Dummy_Handler +#endif +#ifdef ID_DAC +#pragma weak DAC_Handler = Dummy_Handler +#endif +#ifdef ID_PTC +#pragma weak PTC_Handler = Dummy_Handler +#endif +#pragma weak I2S_Handler = Dummy_Handler + +/* Exception Table */ +#pragma language = extended +#pragma segment = "CSTACK" + +/* The name "__vector_table" has special meaning for C-SPY: */ +/* it is where the SP start value is found, and the NVIC vector */ +/* table register (VTOR) is initialized to this address if != 0 */ + +#pragma section = ".intvec" +#pragma location = ".intvec" +const DeviceVectors __vector_table[] = { + (void*) __sfe("CSTACK"), + (void*) Reset_Handler, + (void*) NonMaskableInt_Handler, + (void*) HardFault_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) SVCall_Handler, + (void*) (0UL), /* Reserved */ + (void*) (0UL), /* Reserved */ + (void*) PendSV_Handler, + (void*) SysTick_Handler, + + /* Configurable interrupts */ + (void*) PM_Handler, /* 0 Power Manager */ + (void*) SYSCTRL_Handler, /* 1 System Control */ + (void*) WDT_Handler, /* 2 Watchdog Timer */ + (void*) RTC_Handler, /* 3 Real-Time Counter */ + (void*) EIC_Handler, /* 4 External Interrupt Controller */ + (void*) NVMCTRL_Handler, /* 5 Non-Volatile Memory Controller */ + (void*) DMAC_Handler, /* 6 Direct Memory Access Controller */ +#ifdef ID_USB + (void*) USB_Handler, /* 7 Universal Serial Bus */ +#else + (void*) (0UL), /* 7 Reserved */ +#endif + (void*) EVSYS_Handler, /* 8 Event System Interface */ + (void*) SERCOM0_Handler, /* 9 Serial Communication Interface 0 */ + (void*) SERCOM1_Handler, /* 10 Serial Communication Interface 1 */ + (void*) SERCOM2_Handler, /* 11 Serial Communication Interface 2 */ + (void*) SERCOM3_Handler, /* 12 Serial Communication Interface 3 */ +#ifdef ID_SERCOM4 + (void*) SERCOM4_Handler, /* 13 Serial Communication Interface 4 */ +#else + (void*) (0UL), /* 13 Reserved */ +#endif +#ifdef ID_SERCOM5 + (void*) SERCOM5_Handler, /* 14 Serial Communication Interface 5 */ +#else + (void*) (0UL), /* 14 Reserved */ +#endif + (void*) TCC0_Handler, /* 15 Timer Counter Control 0 */ + (void*) TCC1_Handler, /* 16 Timer Counter Control 1 */ + (void*) TCC2_Handler, /* 17 Timer Counter Control 2 */ + (void*) TC3_Handler, /* 18 Basic Timer Counter 0 */ + (void*) TC4_Handler, /* 19 Basic Timer Counter 1 */ + (void*) TC5_Handler, /* 20 Basic Timer Counter 2 */ +#ifdef ID_TC6 + (void*) TC6_Handler, /* 21 Basic Timer Counter 3 */ +#else + (void*) (0UL), /* 21 Reserved */ +#endif +#ifdef ID_TC7 + (void*) TC7_Handler, /* 22 Basic Timer Counter 4 */ +#else + (void*) (0UL), /* 22 Reserved */ +#endif +#ifdef ID_ADC + (void*) ADC_Handler, /* 23 Analog Digital Converter */ +#else + (void*) (0UL), /* 23 Reserved */ +#endif +#ifdef ID_AC + (void*) AC_Handler, /* 24 Analog Comparators */ +#else + (void*) (0UL), /* 24 Reserved */ +#endif +#ifdef ID_DAC + (void*) DAC_Handler, /* 25 Digital Analog Converter */ +#else + (void*) (0UL), /* 25 Reserved */ +#endif +#ifdef ID_PTC + (void*) PTC_Handler, /* 26 Peripheral Touch Controller */ +#else + (void*) (0UL), /* 26 Reserved */ +#endif + (void*) I2S_Handler, /* 27 Inter-IC Sound Interface */ + (void*) (0UL) /* 28 Reserved */ +}; + +/**------------------------------------------------------------------------------ + * This is the code that gets called on processor reset. To initialize the + * device. + *------------------------------------------------------------------------------*/ +int __low_level_init(void) +{ + uint32_t *pSrc = __section_begin(".intvec"); + + SCB->VTOR = ((uint32_t) pSrc & SCB_VTOR_TBLOFF_Msk); + + return 1; /* if return 0, the data sections will not be initialized */ +} + +/**------------------------------------------------------------------------------ + * This is the code that gets called on processor reset. To initialize the + * device. + *------------------------------------------------------------------------------*/ +void Reset_Handler(void) +{ + /* Change default QOS values to have the best performance and correct USB behaviour */ + SBMATRIX->SFR[SBMATRIX_SLAVE_HMCRAMC0].reg = 2; +#if defined(ID_USB) + USB->DEVICE.QOSCTRL.bit.CQOS = 2; + USB->DEVICE.QOSCTRL.bit.DQOS = 2; +#endif + DMAC->QOSCTRL.bit.DQOS = 2; + DMAC->QOSCTRL.bit.FQOS = 2; + DMAC->QOSCTRL.bit.WRBQOS = 2; + + /* Overwriting the default value of the NVMCTRL.CTRLB.MANW bit (errata reference 13134) */ + NVMCTRL->CTRLB.bit.MANW = 1; + + __iar_program_start(); +} + +/** + * \brief Default interrupt handler for unused IRQs. + */ +void Dummy_Handler(void) +{ + while (1) { + } +} diff --git a/core/arm/samd21a/iar/system_samd21.c b/core/arm/samd21a/iar/system_samd21.c new file mode 100644 index 000000000..d8287b91b --- /dev/null +++ b/core/arm/samd21a/iar/system_samd21.c @@ -0,0 +1,64 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup. + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#include "samd21.h" + +/** + * Initial system clock frequency. The System RC Oscillator (RCSYS) provides + * the source for the main clock at chip startup. + */ +#define __SYSTEM_CLOCK (1000000) + +uint32_t SystemCoreClock = __SYSTEM_CLOCK;/*!< System Clock Frequency (Core Clock)*/ + +/** + * Initialize the system + * + * @brief Setup the microcontroller system. + * Initialize the System and update the SystemCoreClock variable. + */ +void SystemInit(void) +{ + // Keep the default device state after reset + SystemCoreClock = __SYSTEM_CLOCK; + return; +} + +/** + * Update SystemCoreClock variable + * + * @brief Updates the SystemCoreClock with current core Clock + * retrieved from cpu registers. + */ +void SystemCoreClockUpdate(void) +{ + // Not implemented + SystemCoreClock = __SYSTEM_CLOCK; + return; +} diff --git a/core/arm/samd21a/include/component-version.h b/core/arm/samd21a/include/component-version.h new file mode 100644 index 000000000..a869b7c4b --- /dev/null +++ b/core/arm/samd21a/include/component-version.h @@ -0,0 +1,64 @@ +/** + * \file + * + * \brief Component version header file + * + * Copyright (c) 2019 Atmel Corporation, a wholly owned subsidiary of Microchip Technology Inc. + * + * \license_start + * + * \page License + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \license_stop + * + */ + +#ifndef _COMPONENT_VERSION_H_INCLUDED +#define _COMPONENT_VERSION_H_INCLUDED + +#define COMPONENT_VERSION_MAJOR 1 +#define COMPONENT_VERSION_MINOR 3 + +// +// The COMPONENT_VERSION define is composed of the major and the minor version number. +// +// The last four digits of the COMPONENT_VERSION is the minor version with leading zeros. +// The rest of the COMPONENT_VERSION is the major version. +// +#define COMPONENT_VERSION 10003 + +// +// The build number does not refer to the component, but to the build number +// of the device pack that provides the component. +// +#define BUILD_NUMBER 395 + +// +// The COMPONENT_VERSION_STRING is a string (enclosed in ") that can be used for logging or embedding. +// +#define COMPONENT_VERSION_STRING "1.3" + +// +// The COMPONENT_DATE_STRING contains a timestamp of when the pack was generated. +// +// The COMPONENT_DATE_STRING is written out using the following strftime pattern. +// +// "%Y-%m-%d %H:%M:%S" +// +// +#define COMPONENT_DATE_STRING "2019-09-19 13:04:38" + +#endif/* #ifndef _COMPONENT_VERSION_H_INCLUDED */ + diff --git a/core/arm/samd21a/include/component/ac.h b/core/arm/samd21a/include/component/ac.h new file mode 100644 index 000000000..ac5923fc8 --- /dev/null +++ b/core/arm/samd21a/include/component/ac.h @@ -0,0 +1,545 @@ +/** + * \file + * + * \brief Component description for AC + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD21_AC_COMPONENT_ +#define _SAMD21_AC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR AC */ +/* ========================================================================== */ +/** \addtogroup SAMD21_AC Analog Comparators */ +/*@{*/ + +#define AC_U2205 +#define REV_AC 0x111 + +/* -------- AC_CTRLA : (AC Offset: 0x00) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :4; /*!< bit: 3.. 6 Reserved */ + uint8_t LPMUX:1; /*!< bit: 7 Low-Power Mux */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_CTRLA_OFFSET 0x00 /**< \brief (AC_CTRLA offset) Control A */ +#define AC_CTRLA_RESETVALUE _U_(0x00) /**< \brief (AC_CTRLA reset_value) Control A */ + +#define AC_CTRLA_SWRST_Pos 0 /**< \brief (AC_CTRLA) Software Reset */ +#define AC_CTRLA_SWRST (_U_(0x1) << AC_CTRLA_SWRST_Pos) +#define AC_CTRLA_ENABLE_Pos 1 /**< \brief (AC_CTRLA) Enable */ +#define AC_CTRLA_ENABLE (_U_(0x1) << AC_CTRLA_ENABLE_Pos) +#define AC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (AC_CTRLA) Run in Standby */ +#define AC_CTRLA_RUNSTDBY_Msk (_U_(0x1) << AC_CTRLA_RUNSTDBY_Pos) +#define AC_CTRLA_RUNSTDBY(value) (AC_CTRLA_RUNSTDBY_Msk & ((value) << AC_CTRLA_RUNSTDBY_Pos)) +#define AC_CTRLA_LPMUX_Pos 7 /**< \brief (AC_CTRLA) Low-Power Mux */ +#define AC_CTRLA_LPMUX (_U_(0x1) << AC_CTRLA_LPMUX_Pos) +#define AC_CTRLA_MASK _U_(0x87) /**< \brief (AC_CTRLA) MASK Register */ + +/* -------- AC_CTRLB : (AC Offset: 0x01) ( /W 8) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t START0:1; /*!< bit: 0 Comparator 0 Start Comparison */ + uint8_t START1:1; /*!< bit: 1 Comparator 1 Start Comparison */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t START:2; /*!< bit: 0.. 1 Comparator x Start Comparison */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_CTRLB_OFFSET 0x01 /**< \brief (AC_CTRLB offset) Control B */ +#define AC_CTRLB_RESETVALUE _U_(0x00) /**< \brief (AC_CTRLB reset_value) Control B */ + +#define AC_CTRLB_START0_Pos 0 /**< \brief (AC_CTRLB) Comparator 0 Start Comparison */ +#define AC_CTRLB_START0 (_U_(1) << AC_CTRLB_START0_Pos) +#define AC_CTRLB_START1_Pos 1 /**< \brief (AC_CTRLB) Comparator 1 Start Comparison */ +#define AC_CTRLB_START1 (_U_(1) << AC_CTRLB_START1_Pos) +#define AC_CTRLB_START_Pos 0 /**< \brief (AC_CTRLB) Comparator x Start Comparison */ +#define AC_CTRLB_START_Msk (_U_(0x3) << AC_CTRLB_START_Pos) +#define AC_CTRLB_START(value) (AC_CTRLB_START_Msk & ((value) << AC_CTRLB_START_Pos)) +#define AC_CTRLB_MASK _U_(0x03) /**< \brief (AC_CTRLB) MASK Register */ + +/* -------- AC_EVCTRL : (AC Offset: 0x02) (R/W 16) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t COMPEO0:1; /*!< bit: 0 Comparator 0 Event Output Enable */ + uint16_t COMPEO1:1; /*!< bit: 1 Comparator 1 Event Output Enable */ + uint16_t :2; /*!< bit: 2.. 3 Reserved */ + uint16_t WINEO0:1; /*!< bit: 4 Window 0 Event Output Enable */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t COMPEI0:1; /*!< bit: 8 Comparator 0 Event Input */ + uint16_t COMPEI1:1; /*!< bit: 9 Comparator 1 Event Input */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t COMPEO:2; /*!< bit: 0.. 1 Comparator x Event Output Enable */ + uint16_t :2; /*!< bit: 2.. 3 Reserved */ + uint16_t WINEO:1; /*!< bit: 4 Window x Event Output Enable */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t COMPEI:2; /*!< bit: 8.. 9 Comparator x Event Input */ + uint16_t :6; /*!< bit: 10..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} AC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_EVCTRL_OFFSET 0x02 /**< \brief (AC_EVCTRL offset) Event Control */ +#define AC_EVCTRL_RESETVALUE _U_(0x0000) /**< \brief (AC_EVCTRL reset_value) Event Control */ + +#define AC_EVCTRL_COMPEO0_Pos 0 /**< \brief (AC_EVCTRL) Comparator 0 Event Output Enable */ +#define AC_EVCTRL_COMPEO0 (_U_(1) << AC_EVCTRL_COMPEO0_Pos) +#define AC_EVCTRL_COMPEO1_Pos 1 /**< \brief (AC_EVCTRL) Comparator 1 Event Output Enable */ +#define AC_EVCTRL_COMPEO1 (_U_(1) << AC_EVCTRL_COMPEO1_Pos) +#define AC_EVCTRL_COMPEO_Pos 0 /**< \brief (AC_EVCTRL) Comparator x Event Output Enable */ +#define AC_EVCTRL_COMPEO_Msk (_U_(0x3) << AC_EVCTRL_COMPEO_Pos) +#define AC_EVCTRL_COMPEO(value) (AC_EVCTRL_COMPEO_Msk & ((value) << AC_EVCTRL_COMPEO_Pos)) +#define AC_EVCTRL_WINEO0_Pos 4 /**< \brief (AC_EVCTRL) Window 0 Event Output Enable */ +#define AC_EVCTRL_WINEO0 (_U_(1) << AC_EVCTRL_WINEO0_Pos) +#define AC_EVCTRL_WINEO_Pos 4 /**< \brief (AC_EVCTRL) Window x Event Output Enable */ +#define AC_EVCTRL_WINEO_Msk (_U_(0x1) << AC_EVCTRL_WINEO_Pos) +#define AC_EVCTRL_WINEO(value) (AC_EVCTRL_WINEO_Msk & ((value) << AC_EVCTRL_WINEO_Pos)) +#define AC_EVCTRL_COMPEI0_Pos 8 /**< \brief (AC_EVCTRL) Comparator 0 Event Input */ +#define AC_EVCTRL_COMPEI0 (_U_(1) << AC_EVCTRL_COMPEI0_Pos) +#define AC_EVCTRL_COMPEI1_Pos 9 /**< \brief (AC_EVCTRL) Comparator 1 Event Input */ +#define AC_EVCTRL_COMPEI1 (_U_(1) << AC_EVCTRL_COMPEI1_Pos) +#define AC_EVCTRL_COMPEI_Pos 8 /**< \brief (AC_EVCTRL) Comparator x Event Input */ +#define AC_EVCTRL_COMPEI_Msk (_U_(0x3) << AC_EVCTRL_COMPEI_Pos) +#define AC_EVCTRL_COMPEI(value) (AC_EVCTRL_COMPEI_Msk & ((value) << AC_EVCTRL_COMPEI_Pos)) +#define AC_EVCTRL_MASK _U_(0x0313) /**< \brief (AC_EVCTRL) MASK Register */ + +/* -------- AC_INTENCLR : (AC Offset: 0x04) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COMP0:1; /*!< bit: 0 Comparator 0 Interrupt Enable */ + uint8_t COMP1:1; /*!< bit: 1 Comparator 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN0:1; /*!< bit: 4 Window 0 Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN:1; /*!< bit: 4 Window x Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTENCLR_OFFSET 0x04 /**< \brief (AC_INTENCLR offset) Interrupt Enable Clear */ +#define AC_INTENCLR_RESETVALUE _U_(0x00) /**< \brief (AC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define AC_INTENCLR_COMP0_Pos 0 /**< \brief (AC_INTENCLR) Comparator 0 Interrupt Enable */ +#define AC_INTENCLR_COMP0 (_U_(1) << AC_INTENCLR_COMP0_Pos) +#define AC_INTENCLR_COMP1_Pos 1 /**< \brief (AC_INTENCLR) Comparator 1 Interrupt Enable */ +#define AC_INTENCLR_COMP1 (_U_(1) << AC_INTENCLR_COMP1_Pos) +#define AC_INTENCLR_COMP_Pos 0 /**< \brief (AC_INTENCLR) Comparator x Interrupt Enable */ +#define AC_INTENCLR_COMP_Msk (_U_(0x3) << AC_INTENCLR_COMP_Pos) +#define AC_INTENCLR_COMP(value) (AC_INTENCLR_COMP_Msk & ((value) << AC_INTENCLR_COMP_Pos)) +#define AC_INTENCLR_WIN0_Pos 4 /**< \brief (AC_INTENCLR) Window 0 Interrupt Enable */ +#define AC_INTENCLR_WIN0 (_U_(1) << AC_INTENCLR_WIN0_Pos) +#define AC_INTENCLR_WIN_Pos 4 /**< \brief (AC_INTENCLR) Window x Interrupt Enable */ +#define AC_INTENCLR_WIN_Msk (_U_(0x1) << AC_INTENCLR_WIN_Pos) +#define AC_INTENCLR_WIN(value) (AC_INTENCLR_WIN_Msk & ((value) << AC_INTENCLR_WIN_Pos)) +#define AC_INTENCLR_MASK _U_(0x13) /**< \brief (AC_INTENCLR) MASK Register */ + +/* -------- AC_INTENSET : (AC Offset: 0x05) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t COMP0:1; /*!< bit: 0 Comparator 0 Interrupt Enable */ + uint8_t COMP1:1; /*!< bit: 1 Comparator 1 Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN0:1; /*!< bit: 4 Window 0 Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x Interrupt Enable */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WIN:1; /*!< bit: 4 Window x Interrupt Enable */ + uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTENSET_OFFSET 0x05 /**< \brief (AC_INTENSET offset) Interrupt Enable Set */ +#define AC_INTENSET_RESETVALUE _U_(0x00) /**< \brief (AC_INTENSET reset_value) Interrupt Enable Set */ + +#define AC_INTENSET_COMP0_Pos 0 /**< \brief (AC_INTENSET) Comparator 0 Interrupt Enable */ +#define AC_INTENSET_COMP0 (_U_(1) << AC_INTENSET_COMP0_Pos) +#define AC_INTENSET_COMP1_Pos 1 /**< \brief (AC_INTENSET) Comparator 1 Interrupt Enable */ +#define AC_INTENSET_COMP1 (_U_(1) << AC_INTENSET_COMP1_Pos) +#define AC_INTENSET_COMP_Pos 0 /**< \brief (AC_INTENSET) Comparator x Interrupt Enable */ +#define AC_INTENSET_COMP_Msk (_U_(0x3) << AC_INTENSET_COMP_Pos) +#define AC_INTENSET_COMP(value) (AC_INTENSET_COMP_Msk & ((value) << AC_INTENSET_COMP_Pos)) +#define AC_INTENSET_WIN0_Pos 4 /**< \brief (AC_INTENSET) Window 0 Interrupt Enable */ +#define AC_INTENSET_WIN0 (_U_(1) << AC_INTENSET_WIN0_Pos) +#define AC_INTENSET_WIN_Pos 4 /**< \brief (AC_INTENSET) Window x Interrupt Enable */ +#define AC_INTENSET_WIN_Msk (_U_(0x1) << AC_INTENSET_WIN_Pos) +#define AC_INTENSET_WIN(value) (AC_INTENSET_WIN_Msk & ((value) << AC_INTENSET_WIN_Pos)) +#define AC_INTENSET_MASK _U_(0x13) /**< \brief (AC_INTENSET) MASK Register */ + +/* -------- AC_INTFLAG : (AC Offset: 0x06) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { // __I to avoid read-modify-write on write-to-clear register + struct { + __I uint8_t COMP0:1; /*!< bit: 0 Comparator 0 */ + __I uint8_t COMP1:1; /*!< bit: 1 Comparator 1 */ + __I uint8_t :2; /*!< bit: 2.. 3 Reserved */ + __I uint8_t WIN0:1; /*!< bit: 4 Window 0 */ + __I uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + __I uint8_t COMP:2; /*!< bit: 0.. 1 Comparator x */ + __I uint8_t :2; /*!< bit: 2.. 3 Reserved */ + __I uint8_t WIN:1; /*!< bit: 4 Window x */ + __I uint8_t :3; /*!< bit: 5.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_INTFLAG_OFFSET 0x06 /**< \brief (AC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define AC_INTFLAG_RESETVALUE _U_(0x00) /**< \brief (AC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define AC_INTFLAG_COMP0_Pos 0 /**< \brief (AC_INTFLAG) Comparator 0 */ +#define AC_INTFLAG_COMP0 (_U_(1) << AC_INTFLAG_COMP0_Pos) +#define AC_INTFLAG_COMP1_Pos 1 /**< \brief (AC_INTFLAG) Comparator 1 */ +#define AC_INTFLAG_COMP1 (_U_(1) << AC_INTFLAG_COMP1_Pos) +#define AC_INTFLAG_COMP_Pos 0 /**< \brief (AC_INTFLAG) Comparator x */ +#define AC_INTFLAG_COMP_Msk (_U_(0x3) << AC_INTFLAG_COMP_Pos) +#define AC_INTFLAG_COMP(value) (AC_INTFLAG_COMP_Msk & ((value) << AC_INTFLAG_COMP_Pos)) +#define AC_INTFLAG_WIN0_Pos 4 /**< \brief (AC_INTFLAG) Window 0 */ +#define AC_INTFLAG_WIN0 (_U_(1) << AC_INTFLAG_WIN0_Pos) +#define AC_INTFLAG_WIN_Pos 4 /**< \brief (AC_INTFLAG) Window x */ +#define AC_INTFLAG_WIN_Msk (_U_(0x1) << AC_INTFLAG_WIN_Pos) +#define AC_INTFLAG_WIN(value) (AC_INTFLAG_WIN_Msk & ((value) << AC_INTFLAG_WIN_Pos)) +#define AC_INTFLAG_MASK _U_(0x13) /**< \brief (AC_INTFLAG) MASK Register */ + +/* -------- AC_STATUSA : (AC Offset: 0x08) (R/ 8) Status A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STATE0:1; /*!< bit: 0 Comparator 0 Current State */ + uint8_t STATE1:1; /*!< bit: 1 Comparator 1 Current State */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WSTATE0:2; /*!< bit: 4.. 5 Window 0 Current State */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t STATE:2; /*!< bit: 0.. 1 Comparator x Current State */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSA_OFFSET 0x08 /**< \brief (AC_STATUSA offset) Status A */ +#define AC_STATUSA_RESETVALUE _U_(0x00) /**< \brief (AC_STATUSA reset_value) Status A */ + +#define AC_STATUSA_STATE0_Pos 0 /**< \brief (AC_STATUSA) Comparator 0 Current State */ +#define AC_STATUSA_STATE0 (_U_(1) << AC_STATUSA_STATE0_Pos) +#define AC_STATUSA_STATE1_Pos 1 /**< \brief (AC_STATUSA) Comparator 1 Current State */ +#define AC_STATUSA_STATE1 (_U_(1) << AC_STATUSA_STATE1_Pos) +#define AC_STATUSA_STATE_Pos 0 /**< \brief (AC_STATUSA) Comparator x Current State */ +#define AC_STATUSA_STATE_Msk (_U_(0x3) << AC_STATUSA_STATE_Pos) +#define AC_STATUSA_STATE(value) (AC_STATUSA_STATE_Msk & ((value) << AC_STATUSA_STATE_Pos)) +#define AC_STATUSA_WSTATE0_Pos 4 /**< \brief (AC_STATUSA) Window 0 Current State */ +#define AC_STATUSA_WSTATE0_Msk (_U_(0x3) << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0(value) (AC_STATUSA_WSTATE0_Msk & ((value) << AC_STATUSA_WSTATE0_Pos)) +#define AC_STATUSA_WSTATE0_ABOVE_Val _U_(0x0) /**< \brief (AC_STATUSA) Signal is above window */ +#define AC_STATUSA_WSTATE0_INSIDE_Val _U_(0x1) /**< \brief (AC_STATUSA) Signal is inside window */ +#define AC_STATUSA_WSTATE0_BELOW_Val _U_(0x2) /**< \brief (AC_STATUSA) Signal is below window */ +#define AC_STATUSA_WSTATE0_ABOVE (AC_STATUSA_WSTATE0_ABOVE_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0_INSIDE (AC_STATUSA_WSTATE0_INSIDE_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_WSTATE0_BELOW (AC_STATUSA_WSTATE0_BELOW_Val << AC_STATUSA_WSTATE0_Pos) +#define AC_STATUSA_MASK _U_(0x33) /**< \brief (AC_STATUSA) MASK Register */ + +/* -------- AC_STATUSB : (AC Offset: 0x09) (R/ 8) Status B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t READY0:1; /*!< bit: 0 Comparator 0 Ready */ + uint8_t READY1:1; /*!< bit: 1 Comparator 1 Ready */ + uint8_t :5; /*!< bit: 2.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t READY:2; /*!< bit: 0.. 1 Comparator x Ready */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSB_OFFSET 0x09 /**< \brief (AC_STATUSB offset) Status B */ +#define AC_STATUSB_RESETVALUE _U_(0x00) /**< \brief (AC_STATUSB reset_value) Status B */ + +#define AC_STATUSB_READY0_Pos 0 /**< \brief (AC_STATUSB) Comparator 0 Ready */ +#define AC_STATUSB_READY0 (_U_(1) << AC_STATUSB_READY0_Pos) +#define AC_STATUSB_READY1_Pos 1 /**< \brief (AC_STATUSB) Comparator 1 Ready */ +#define AC_STATUSB_READY1 (_U_(1) << AC_STATUSB_READY1_Pos) +#define AC_STATUSB_READY_Pos 0 /**< \brief (AC_STATUSB) Comparator x Ready */ +#define AC_STATUSB_READY_Msk (_U_(0x3) << AC_STATUSB_READY_Pos) +#define AC_STATUSB_READY(value) (AC_STATUSB_READY_Msk & ((value) << AC_STATUSB_READY_Pos)) +#define AC_STATUSB_SYNCBUSY_Pos 7 /**< \brief (AC_STATUSB) Synchronization Busy */ +#define AC_STATUSB_SYNCBUSY (_U_(0x1) << AC_STATUSB_SYNCBUSY_Pos) +#define AC_STATUSB_MASK _U_(0x83) /**< \brief (AC_STATUSB) MASK Register */ + +/* -------- AC_STATUSC : (AC Offset: 0x0A) (R/ 8) Status C -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STATE0:1; /*!< bit: 0 Comparator 0 Current State */ + uint8_t STATE1:1; /*!< bit: 1 Comparator 1 Current State */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t WSTATE0:2; /*!< bit: 4.. 5 Window 0 Current State */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint8_t STATE:2; /*!< bit: 0.. 1 Comparator x Current State */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } vec; /*!< Structure used for vec access */ + uint8_t reg; /*!< Type used for register access */ +} AC_STATUSC_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_STATUSC_OFFSET 0x0A /**< \brief (AC_STATUSC offset) Status C */ +#define AC_STATUSC_RESETVALUE _U_(0x00) /**< \brief (AC_STATUSC reset_value) Status C */ + +#define AC_STATUSC_STATE0_Pos 0 /**< \brief (AC_STATUSC) Comparator 0 Current State */ +#define AC_STATUSC_STATE0 (_U_(1) << AC_STATUSC_STATE0_Pos) +#define AC_STATUSC_STATE1_Pos 1 /**< \brief (AC_STATUSC) Comparator 1 Current State */ +#define AC_STATUSC_STATE1 (_U_(1) << AC_STATUSC_STATE1_Pos) +#define AC_STATUSC_STATE_Pos 0 /**< \brief (AC_STATUSC) Comparator x Current State */ +#define AC_STATUSC_STATE_Msk (_U_(0x3) << AC_STATUSC_STATE_Pos) +#define AC_STATUSC_STATE(value) (AC_STATUSC_STATE_Msk & ((value) << AC_STATUSC_STATE_Pos)) +#define AC_STATUSC_WSTATE0_Pos 4 /**< \brief (AC_STATUSC) Window 0 Current State */ +#define AC_STATUSC_WSTATE0_Msk (_U_(0x3) << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0(value) (AC_STATUSC_WSTATE0_Msk & ((value) << AC_STATUSC_WSTATE0_Pos)) +#define AC_STATUSC_WSTATE0_ABOVE_Val _U_(0x0) /**< \brief (AC_STATUSC) Signal is above window */ +#define AC_STATUSC_WSTATE0_INSIDE_Val _U_(0x1) /**< \brief (AC_STATUSC) Signal is inside window */ +#define AC_STATUSC_WSTATE0_BELOW_Val _U_(0x2) /**< \brief (AC_STATUSC) Signal is below window */ +#define AC_STATUSC_WSTATE0_ABOVE (AC_STATUSC_WSTATE0_ABOVE_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0_INSIDE (AC_STATUSC_WSTATE0_INSIDE_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_WSTATE0_BELOW (AC_STATUSC_WSTATE0_BELOW_Val << AC_STATUSC_WSTATE0_Pos) +#define AC_STATUSC_MASK _U_(0x33) /**< \brief (AC_STATUSC) MASK Register */ + +/* -------- AC_WINCTRL : (AC Offset: 0x0C) (R/W 8) Window Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t WEN0:1; /*!< bit: 0 Window 0 Mode Enable */ + uint8_t WINTSEL0:2; /*!< bit: 1.. 2 Window 0 Interrupt Selection */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_WINCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_WINCTRL_OFFSET 0x0C /**< \brief (AC_WINCTRL offset) Window Control */ +#define AC_WINCTRL_RESETVALUE _U_(0x00) /**< \brief (AC_WINCTRL reset_value) Window Control */ + +#define AC_WINCTRL_WEN0_Pos 0 /**< \brief (AC_WINCTRL) Window 0 Mode Enable */ +#define AC_WINCTRL_WEN0 (_U_(0x1) << AC_WINCTRL_WEN0_Pos) +#define AC_WINCTRL_WINTSEL0_Pos 1 /**< \brief (AC_WINCTRL) Window 0 Interrupt Selection */ +#define AC_WINCTRL_WINTSEL0_Msk (_U_(0x3) << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0(value) (AC_WINCTRL_WINTSEL0_Msk & ((value) << AC_WINCTRL_WINTSEL0_Pos)) +#define AC_WINCTRL_WINTSEL0_ABOVE_Val _U_(0x0) /**< \brief (AC_WINCTRL) Interrupt on signal above window */ +#define AC_WINCTRL_WINTSEL0_INSIDE_Val _U_(0x1) /**< \brief (AC_WINCTRL) Interrupt on signal inside window */ +#define AC_WINCTRL_WINTSEL0_BELOW_Val _U_(0x2) /**< \brief (AC_WINCTRL) Interrupt on signal below window */ +#define AC_WINCTRL_WINTSEL0_OUTSIDE_Val _U_(0x3) /**< \brief (AC_WINCTRL) Interrupt on signal outside window */ +#define AC_WINCTRL_WINTSEL0_ABOVE (AC_WINCTRL_WINTSEL0_ABOVE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_INSIDE (AC_WINCTRL_WINTSEL0_INSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_BELOW (AC_WINCTRL_WINTSEL0_BELOW_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_WINTSEL0_OUTSIDE (AC_WINCTRL_WINTSEL0_OUTSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) +#define AC_WINCTRL_MASK _U_(0x07) /**< \brief (AC_WINCTRL) MASK Register */ + +/* -------- AC_COMPCTRL : (AC Offset: 0x10) (R/W 32) Comparator Control n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t ENABLE:1; /*!< bit: 0 Enable */ + uint32_t SINGLE:1; /*!< bit: 1 Single-Shot Mode */ + uint32_t SPEED:2; /*!< bit: 2.. 3 Speed Selection */ + uint32_t :1; /*!< bit: 4 Reserved */ + uint32_t INTSEL:2; /*!< bit: 5.. 6 Interrupt Selection */ + uint32_t :1; /*!< bit: 7 Reserved */ + uint32_t MUXNEG:3; /*!< bit: 8..10 Negative Input Mux Selection */ + uint32_t :1; /*!< bit: 11 Reserved */ + uint32_t MUXPOS:2; /*!< bit: 12..13 Positive Input Mux Selection */ + uint32_t :1; /*!< bit: 14 Reserved */ + uint32_t SWAP:1; /*!< bit: 15 Swap Inputs and Invert */ + uint32_t OUT:2; /*!< bit: 16..17 Output */ + uint32_t :1; /*!< bit: 18 Reserved */ + uint32_t HYST:1; /*!< bit: 19 Hysteresis Enable */ + uint32_t :4; /*!< bit: 20..23 Reserved */ + uint32_t FLEN:3; /*!< bit: 24..26 Filter Length */ + uint32_t :5; /*!< bit: 27..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} AC_COMPCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_COMPCTRL_OFFSET 0x10 /**< \brief (AC_COMPCTRL offset) Comparator Control n */ +#define AC_COMPCTRL_RESETVALUE _U_(0x00000000) /**< \brief (AC_COMPCTRL reset_value) Comparator Control n */ + +#define AC_COMPCTRL_ENABLE_Pos 0 /**< \brief (AC_COMPCTRL) Enable */ +#define AC_COMPCTRL_ENABLE (_U_(0x1) << AC_COMPCTRL_ENABLE_Pos) +#define AC_COMPCTRL_SINGLE_Pos 1 /**< \brief (AC_COMPCTRL) Single-Shot Mode */ +#define AC_COMPCTRL_SINGLE (_U_(0x1) << AC_COMPCTRL_SINGLE_Pos) +#define AC_COMPCTRL_SPEED_Pos 2 /**< \brief (AC_COMPCTRL) Speed Selection */ +#define AC_COMPCTRL_SPEED_Msk (_U_(0x3) << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_SPEED(value) (AC_COMPCTRL_SPEED_Msk & ((value) << AC_COMPCTRL_SPEED_Pos)) +#define AC_COMPCTRL_SPEED_LOW_Val _U_(0x0) /**< \brief (AC_COMPCTRL) Low speed */ +#define AC_COMPCTRL_SPEED_HIGH_Val _U_(0x1) /**< \brief (AC_COMPCTRL) High speed */ +#define AC_COMPCTRL_SPEED_LOW (AC_COMPCTRL_SPEED_LOW_Val << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_SPEED_HIGH (AC_COMPCTRL_SPEED_HIGH_Val << AC_COMPCTRL_SPEED_Pos) +#define AC_COMPCTRL_INTSEL_Pos 5 /**< \brief (AC_COMPCTRL) Interrupt Selection */ +#define AC_COMPCTRL_INTSEL_Msk (_U_(0x3) << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL(value) (AC_COMPCTRL_INTSEL_Msk & ((value) << AC_COMPCTRL_INTSEL_Pos)) +#define AC_COMPCTRL_INTSEL_TOGGLE_Val _U_(0x0) /**< \brief (AC_COMPCTRL) Interrupt on comparator output toggle */ +#define AC_COMPCTRL_INTSEL_RISING_Val _U_(0x1) /**< \brief (AC_COMPCTRL) Interrupt on comparator output rising */ +#define AC_COMPCTRL_INTSEL_FALLING_Val _U_(0x2) /**< \brief (AC_COMPCTRL) Interrupt on comparator output falling */ +#define AC_COMPCTRL_INTSEL_EOC_Val _U_(0x3) /**< \brief (AC_COMPCTRL) Interrupt on end of comparison (single-shot mode only) */ +#define AC_COMPCTRL_INTSEL_TOGGLE (AC_COMPCTRL_INTSEL_TOGGLE_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_RISING (AC_COMPCTRL_INTSEL_RISING_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_FALLING (AC_COMPCTRL_INTSEL_FALLING_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_INTSEL_EOC (AC_COMPCTRL_INTSEL_EOC_Val << AC_COMPCTRL_INTSEL_Pos) +#define AC_COMPCTRL_MUXNEG_Pos 8 /**< \brief (AC_COMPCTRL) Negative Input Mux Selection */ +#define AC_COMPCTRL_MUXNEG_Msk (_U_(0x7) << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG(value) (AC_COMPCTRL_MUXNEG_Msk & ((value) << AC_COMPCTRL_MUXNEG_Pos)) +#define AC_COMPCTRL_MUXNEG_PIN0_Val _U_(0x0) /**< \brief (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXNEG_PIN1_Val _U_(0x1) /**< \brief (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXNEG_PIN2_Val _U_(0x2) /**< \brief (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXNEG_PIN3_Val _U_(0x3) /**< \brief (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXNEG_GND_Val _U_(0x4) /**< \brief (AC_COMPCTRL) Ground */ +#define AC_COMPCTRL_MUXNEG_VSCALE_Val _U_(0x5) /**< \brief (AC_COMPCTRL) VDD scaler */ +#define AC_COMPCTRL_MUXNEG_BANDGAP_Val _U_(0x6) /**< \brief (AC_COMPCTRL) Internal bandgap voltage */ +#define AC_COMPCTRL_MUXNEG_DAC_Val _U_(0x7) /**< \brief (AC_COMPCTRL) DAC output */ +#define AC_COMPCTRL_MUXNEG_PIN0 (AC_COMPCTRL_MUXNEG_PIN0_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN1 (AC_COMPCTRL_MUXNEG_PIN1_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN2 (AC_COMPCTRL_MUXNEG_PIN2_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_PIN3 (AC_COMPCTRL_MUXNEG_PIN3_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_GND (AC_COMPCTRL_MUXNEG_GND_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_VSCALE (AC_COMPCTRL_MUXNEG_VSCALE_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_BANDGAP (AC_COMPCTRL_MUXNEG_BANDGAP_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXNEG_DAC (AC_COMPCTRL_MUXNEG_DAC_Val << AC_COMPCTRL_MUXNEG_Pos) +#define AC_COMPCTRL_MUXPOS_Pos 12 /**< \brief (AC_COMPCTRL) Positive Input Mux Selection */ +#define AC_COMPCTRL_MUXPOS_Msk (_U_(0x3) << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS(value) (AC_COMPCTRL_MUXPOS_Msk & ((value) << AC_COMPCTRL_MUXPOS_Pos)) +#define AC_COMPCTRL_MUXPOS_PIN0_Val _U_(0x0) /**< \brief (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXPOS_PIN1_Val _U_(0x1) /**< \brief (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXPOS_PIN2_Val _U_(0x2) /**< \brief (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXPOS_PIN3_Val _U_(0x3) /**< \brief (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXPOS_PIN0 (AC_COMPCTRL_MUXPOS_PIN0_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN1 (AC_COMPCTRL_MUXPOS_PIN1_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN2 (AC_COMPCTRL_MUXPOS_PIN2_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_MUXPOS_PIN3 (AC_COMPCTRL_MUXPOS_PIN3_Val << AC_COMPCTRL_MUXPOS_Pos) +#define AC_COMPCTRL_SWAP_Pos 15 /**< \brief (AC_COMPCTRL) Swap Inputs and Invert */ +#define AC_COMPCTRL_SWAP (_U_(0x1) << AC_COMPCTRL_SWAP_Pos) +#define AC_COMPCTRL_OUT_Pos 16 /**< \brief (AC_COMPCTRL) Output */ +#define AC_COMPCTRL_OUT_Msk (_U_(0x3) << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos)) +#define AC_COMPCTRL_OUT_OFF_Val _U_(0x0) /**< \brief (AC_COMPCTRL) The output of COMPn is not routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_ASYNC_Val _U_(0x1) /**< \brief (AC_COMPCTRL) The asynchronous output of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_SYNC_Val _U_(0x2) /**< \brief (AC_COMPCTRL) The synchronous output (including filtering) of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_OFF (AC_COMPCTRL_OUT_OFF_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT_ASYNC (AC_COMPCTRL_OUT_ASYNC_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_OUT_SYNC (AC_COMPCTRL_OUT_SYNC_Val << AC_COMPCTRL_OUT_Pos) +#define AC_COMPCTRL_HYST_Pos 19 /**< \brief (AC_COMPCTRL) Hysteresis Enable */ +#define AC_COMPCTRL_HYST (_U_(0x1) << AC_COMPCTRL_HYST_Pos) +#define AC_COMPCTRL_FLEN_Pos 24 /**< \brief (AC_COMPCTRL) Filter Length */ +#define AC_COMPCTRL_FLEN_Msk (_U_(0x7) << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN(value) (AC_COMPCTRL_FLEN_Msk & ((value) << AC_COMPCTRL_FLEN_Pos)) +#define AC_COMPCTRL_FLEN_OFF_Val _U_(0x0) /**< \brief (AC_COMPCTRL) No filtering */ +#define AC_COMPCTRL_FLEN_MAJ3_Val _U_(0x1) /**< \brief (AC_COMPCTRL) 3-bit majority function (2 of 3) */ +#define AC_COMPCTRL_FLEN_MAJ5_Val _U_(0x2) /**< \brief (AC_COMPCTRL) 5-bit majority function (3 of 5) */ +#define AC_COMPCTRL_FLEN_OFF (AC_COMPCTRL_FLEN_OFF_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN_MAJ3 (AC_COMPCTRL_FLEN_MAJ3_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_FLEN_MAJ5 (AC_COMPCTRL_FLEN_MAJ5_Val << AC_COMPCTRL_FLEN_Pos) +#define AC_COMPCTRL_MASK _U_(0x070BB76F) /**< \brief (AC_COMPCTRL) MASK Register */ + +/* -------- AC_SCALER : (AC Offset: 0x20) (R/W 8) Scaler n -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t VALUE:6; /*!< bit: 0.. 5 Scaler Value */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} AC_SCALER_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define AC_SCALER_OFFSET 0x20 /**< \brief (AC_SCALER offset) Scaler n */ +#define AC_SCALER_RESETVALUE _U_(0x00) /**< \brief (AC_SCALER reset_value) Scaler n */ + +#define AC_SCALER_VALUE_Pos 0 /**< \brief (AC_SCALER) Scaler Value */ +#define AC_SCALER_VALUE_Msk (_U_(0x3F) << AC_SCALER_VALUE_Pos) +#define AC_SCALER_VALUE(value) (AC_SCALER_VALUE_Msk & ((value) << AC_SCALER_VALUE_Pos)) +#define AC_SCALER_MASK _U_(0x3F) /**< \brief (AC_SCALER) MASK Register */ + +/** \brief AC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO AC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 8) Control A */ + __O AC_CTRLB_Type CTRLB; /**< \brief Offset: 0x01 ( /W 8) Control B */ + __IO AC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x02 (R/W 16) Event Control */ + __IO AC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x04 (R/W 8) Interrupt Enable Clear */ + __IO AC_INTENSET_Type INTENSET; /**< \brief Offset: 0x05 (R/W 8) Interrupt Enable Set */ + __IO AC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x06 (R/W 8) Interrupt Flag Status and Clear */ + RoReg8 Reserved1[0x1]; + __I AC_STATUSA_Type STATUSA; /**< \brief Offset: 0x08 (R/ 8) Status A */ + __I AC_STATUSB_Type STATUSB; /**< \brief Offset: 0x09 (R/ 8) Status B */ + __I AC_STATUSC_Type STATUSC; /**< \brief Offset: 0x0A (R/ 8) Status C */ + RoReg8 Reserved2[0x1]; + __IO AC_WINCTRL_Type WINCTRL; /**< \brief Offset: 0x0C (R/W 8) Window Control */ + RoReg8 Reserved3[0x3]; + __IO AC_COMPCTRL_Type COMPCTRL[2]; /**< \brief Offset: 0x10 (R/W 32) Comparator Control n */ + RoReg8 Reserved4[0x8]; + __IO AC_SCALER_Type SCALER[2]; /**< \brief Offset: 0x20 (R/W 8) Scaler n */ +} Ac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD21_AC_COMPONENT_ */ diff --git a/core/arm/samd21a/include/component/adc.h b/core/arm/samd21a/include/component/adc.h new file mode 100644 index 000000000..4ed49e8b4 --- /dev/null +++ b/core/arm/samd21a/include/component/adc.h @@ -0,0 +1,685 @@ +/** + * \file + * + * \brief Component description for ADC + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD21_ADC_COMPONENT_ +#define _SAMD21_ADC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR ADC */ +/* ========================================================================== */ +/** \addtogroup SAMD21_ADC Analog Digital Converter */ +/*@{*/ + +#define ADC_U2204 +#define REV_ADC 0x120 + +/* -------- ADC_CTRLA : (ADC Offset: 0x00) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CTRLA_OFFSET 0x00 /**< \brief (ADC_CTRLA offset) Control A */ +#define ADC_CTRLA_RESETVALUE _U_(0x00) /**< \brief (ADC_CTRLA reset_value) Control A */ + +#define ADC_CTRLA_SWRST_Pos 0 /**< \brief (ADC_CTRLA) Software Reset */ +#define ADC_CTRLA_SWRST (_U_(0x1) << ADC_CTRLA_SWRST_Pos) +#define ADC_CTRLA_ENABLE_Pos 1 /**< \brief (ADC_CTRLA) Enable */ +#define ADC_CTRLA_ENABLE (_U_(0x1) << ADC_CTRLA_ENABLE_Pos) +#define ADC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (ADC_CTRLA) Run in Standby */ +#define ADC_CTRLA_RUNSTDBY (_U_(0x1) << ADC_CTRLA_RUNSTDBY_Pos) +#define ADC_CTRLA_MASK _U_(0x07) /**< \brief (ADC_CTRLA) MASK Register */ + +/* -------- ADC_REFCTRL : (ADC Offset: 0x01) (R/W 8) Reference Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t REFSEL:4; /*!< bit: 0.. 3 Reference Selection */ + uint8_t :3; /*!< bit: 4.. 6 Reserved */ + uint8_t REFCOMP:1; /*!< bit: 7 Reference Buffer Offset Compensation Enable */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_REFCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_REFCTRL_OFFSET 0x01 /**< \brief (ADC_REFCTRL offset) Reference Control */ +#define ADC_REFCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_REFCTRL reset_value) Reference Control */ + +#define ADC_REFCTRL_REFSEL_Pos 0 /**< \brief (ADC_REFCTRL) Reference Selection */ +#define ADC_REFCTRL_REFSEL_Msk (_U_(0xF) << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL(value) (ADC_REFCTRL_REFSEL_Msk & ((value) << ADC_REFCTRL_REFSEL_Pos)) +#define ADC_REFCTRL_REFSEL_INT1V_Val _U_(0x0) /**< \brief (ADC_REFCTRL) 1.0V voltage reference */ +#define ADC_REFCTRL_REFSEL_INTVCC0_Val _U_(0x1) /**< \brief (ADC_REFCTRL) 1/1.48 VDDANA */ +#define ADC_REFCTRL_REFSEL_INTVCC1_Val _U_(0x2) /**< \brief (ADC_REFCTRL) 1/2 VDDANA (only for VDDANA > 2.0V) */ +#define ADC_REFCTRL_REFSEL_AREFA_Val _U_(0x3) /**< \brief (ADC_REFCTRL) External reference */ +#define ADC_REFCTRL_REFSEL_AREFB_Val _U_(0x4) /**< \brief (ADC_REFCTRL) External reference */ +#define ADC_REFCTRL_REFSEL_INT1V (ADC_REFCTRL_REFSEL_INT1V_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_INTVCC0 (ADC_REFCTRL_REFSEL_INTVCC0_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_INTVCC1 (ADC_REFCTRL_REFSEL_INTVCC1_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_AREFA (ADC_REFCTRL_REFSEL_AREFA_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFSEL_AREFB (ADC_REFCTRL_REFSEL_AREFB_Val << ADC_REFCTRL_REFSEL_Pos) +#define ADC_REFCTRL_REFCOMP_Pos 7 /**< \brief (ADC_REFCTRL) Reference Buffer Offset Compensation Enable */ +#define ADC_REFCTRL_REFCOMP (_U_(0x1) << ADC_REFCTRL_REFCOMP_Pos) +#define ADC_REFCTRL_MASK _U_(0x8F) /**< \brief (ADC_REFCTRL) MASK Register */ + +/* -------- ADC_AVGCTRL : (ADC Offset: 0x02) (R/W 8) Average Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SAMPLENUM:4; /*!< bit: 0.. 3 Number of Samples to be Collected */ + uint8_t ADJRES:3; /*!< bit: 4.. 6 Adjusting Result / Division Coefficient */ + uint8_t :1; /*!< bit: 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_AVGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_AVGCTRL_OFFSET 0x02 /**< \brief (ADC_AVGCTRL offset) Average Control */ +#define ADC_AVGCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_AVGCTRL reset_value) Average Control */ + +#define ADC_AVGCTRL_SAMPLENUM_Pos 0 /**< \brief (ADC_AVGCTRL) Number of Samples to be Collected */ +#define ADC_AVGCTRL_SAMPLENUM_Msk (_U_(0xF) << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM(value) (ADC_AVGCTRL_SAMPLENUM_Msk & ((value) << ADC_AVGCTRL_SAMPLENUM_Pos)) +#define ADC_AVGCTRL_SAMPLENUM_1_Val _U_(0x0) /**< \brief (ADC_AVGCTRL) 1 sample */ +#define ADC_AVGCTRL_SAMPLENUM_2_Val _U_(0x1) /**< \brief (ADC_AVGCTRL) 2 samples */ +#define ADC_AVGCTRL_SAMPLENUM_4_Val _U_(0x2) /**< \brief (ADC_AVGCTRL) 4 samples */ +#define ADC_AVGCTRL_SAMPLENUM_8_Val _U_(0x3) /**< \brief (ADC_AVGCTRL) 8 samples */ +#define ADC_AVGCTRL_SAMPLENUM_16_Val _U_(0x4) /**< \brief (ADC_AVGCTRL) 16 samples */ +#define ADC_AVGCTRL_SAMPLENUM_32_Val _U_(0x5) /**< \brief (ADC_AVGCTRL) 32 samples */ +#define ADC_AVGCTRL_SAMPLENUM_64_Val _U_(0x6) /**< \brief (ADC_AVGCTRL) 64 samples */ +#define ADC_AVGCTRL_SAMPLENUM_128_Val _U_(0x7) /**< \brief (ADC_AVGCTRL) 128 samples */ +#define ADC_AVGCTRL_SAMPLENUM_256_Val _U_(0x8) /**< \brief (ADC_AVGCTRL) 256 samples */ +#define ADC_AVGCTRL_SAMPLENUM_512_Val _U_(0x9) /**< \brief (ADC_AVGCTRL) 512 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1024_Val _U_(0xA) /**< \brief (ADC_AVGCTRL) 1024 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1 (ADC_AVGCTRL_SAMPLENUM_1_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_2 (ADC_AVGCTRL_SAMPLENUM_2_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_4 (ADC_AVGCTRL_SAMPLENUM_4_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_8 (ADC_AVGCTRL_SAMPLENUM_8_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_16 (ADC_AVGCTRL_SAMPLENUM_16_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_32 (ADC_AVGCTRL_SAMPLENUM_32_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_64 (ADC_AVGCTRL_SAMPLENUM_64_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_128 (ADC_AVGCTRL_SAMPLENUM_128_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_256 (ADC_AVGCTRL_SAMPLENUM_256_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_512 (ADC_AVGCTRL_SAMPLENUM_512_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_SAMPLENUM_1024 (ADC_AVGCTRL_SAMPLENUM_1024_Val << ADC_AVGCTRL_SAMPLENUM_Pos) +#define ADC_AVGCTRL_ADJRES_Pos 4 /**< \brief (ADC_AVGCTRL) Adjusting Result / Division Coefficient */ +#define ADC_AVGCTRL_ADJRES_Msk (_U_(0x7) << ADC_AVGCTRL_ADJRES_Pos) +#define ADC_AVGCTRL_ADJRES(value) (ADC_AVGCTRL_ADJRES_Msk & ((value) << ADC_AVGCTRL_ADJRES_Pos)) +#define ADC_AVGCTRL_MASK _U_(0x7F) /**< \brief (ADC_AVGCTRL) MASK Register */ + +/* -------- ADC_SAMPCTRL : (ADC Offset: 0x03) (R/W 8) Sampling Time Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SAMPLEN:6; /*!< bit: 0.. 5 Sampling Time Length */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_SAMPCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_SAMPCTRL_OFFSET 0x03 /**< \brief (ADC_SAMPCTRL offset) Sampling Time Control */ +#define ADC_SAMPCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_SAMPCTRL reset_value) Sampling Time Control */ + +#define ADC_SAMPCTRL_SAMPLEN_Pos 0 /**< \brief (ADC_SAMPCTRL) Sampling Time Length */ +#define ADC_SAMPCTRL_SAMPLEN_Msk (_U_(0x3F) << ADC_SAMPCTRL_SAMPLEN_Pos) +#define ADC_SAMPCTRL_SAMPLEN(value) (ADC_SAMPCTRL_SAMPLEN_Msk & ((value) << ADC_SAMPCTRL_SAMPLEN_Pos)) +#define ADC_SAMPCTRL_MASK _U_(0x3F) /**< \brief (ADC_SAMPCTRL) MASK Register */ + +/* -------- ADC_CTRLB : (ADC Offset: 0x04) (R/W 16) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DIFFMODE:1; /*!< bit: 0 Differential Mode */ + uint16_t LEFTADJ:1; /*!< bit: 1 Left-Adjusted Result */ + uint16_t FREERUN:1; /*!< bit: 2 Free Running Mode */ + uint16_t CORREN:1; /*!< bit: 3 Digital Correction Logic Enabled */ + uint16_t RESSEL:2; /*!< bit: 4.. 5 Conversion Result Resolution */ + uint16_t :2; /*!< bit: 6.. 7 Reserved */ + uint16_t PRESCALER:3; /*!< bit: 8..10 Prescaler Configuration */ + uint16_t :5; /*!< bit: 11..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CTRLB_OFFSET 0x04 /**< \brief (ADC_CTRLB offset) Control B */ +#define ADC_CTRLB_RESETVALUE _U_(0x0000) /**< \brief (ADC_CTRLB reset_value) Control B */ + +#define ADC_CTRLB_DIFFMODE_Pos 0 /**< \brief (ADC_CTRLB) Differential Mode */ +#define ADC_CTRLB_DIFFMODE (_U_(0x1) << ADC_CTRLB_DIFFMODE_Pos) +#define ADC_CTRLB_LEFTADJ_Pos 1 /**< \brief (ADC_CTRLB) Left-Adjusted Result */ +#define ADC_CTRLB_LEFTADJ (_U_(0x1) << ADC_CTRLB_LEFTADJ_Pos) +#define ADC_CTRLB_FREERUN_Pos 2 /**< \brief (ADC_CTRLB) Free Running Mode */ +#define ADC_CTRLB_FREERUN (_U_(0x1) << ADC_CTRLB_FREERUN_Pos) +#define ADC_CTRLB_CORREN_Pos 3 /**< \brief (ADC_CTRLB) Digital Correction Logic Enabled */ +#define ADC_CTRLB_CORREN (_U_(0x1) << ADC_CTRLB_CORREN_Pos) +#define ADC_CTRLB_RESSEL_Pos 4 /**< \brief (ADC_CTRLB) Conversion Result Resolution */ +#define ADC_CTRLB_RESSEL_Msk (_U_(0x3) << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL(value) (ADC_CTRLB_RESSEL_Msk & ((value) << ADC_CTRLB_RESSEL_Pos)) +#define ADC_CTRLB_RESSEL_12BIT_Val _U_(0x0) /**< \brief (ADC_CTRLB) 12-bit result */ +#define ADC_CTRLB_RESSEL_16BIT_Val _U_(0x1) /**< \brief (ADC_CTRLB) For averaging mode output */ +#define ADC_CTRLB_RESSEL_10BIT_Val _U_(0x2) /**< \brief (ADC_CTRLB) 10-bit result */ +#define ADC_CTRLB_RESSEL_8BIT_Val _U_(0x3) /**< \brief (ADC_CTRLB) 8-bit result */ +#define ADC_CTRLB_RESSEL_12BIT (ADC_CTRLB_RESSEL_12BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_16BIT (ADC_CTRLB_RESSEL_16BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_10BIT (ADC_CTRLB_RESSEL_10BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_RESSEL_8BIT (ADC_CTRLB_RESSEL_8BIT_Val << ADC_CTRLB_RESSEL_Pos) +#define ADC_CTRLB_PRESCALER_Pos 8 /**< \brief (ADC_CTRLB) Prescaler Configuration */ +#define ADC_CTRLB_PRESCALER_Msk (_U_(0x7) << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER(value) (ADC_CTRLB_PRESCALER_Msk & ((value) << ADC_CTRLB_PRESCALER_Pos)) +#define ADC_CTRLB_PRESCALER_DIV4_Val _U_(0x0) /**< \brief (ADC_CTRLB) Peripheral clock divided by 4 */ +#define ADC_CTRLB_PRESCALER_DIV8_Val _U_(0x1) /**< \brief (ADC_CTRLB) Peripheral clock divided by 8 */ +#define ADC_CTRLB_PRESCALER_DIV16_Val _U_(0x2) /**< \brief (ADC_CTRLB) Peripheral clock divided by 16 */ +#define ADC_CTRLB_PRESCALER_DIV32_Val _U_(0x3) /**< \brief (ADC_CTRLB) Peripheral clock divided by 32 */ +#define ADC_CTRLB_PRESCALER_DIV64_Val _U_(0x4) /**< \brief (ADC_CTRLB) Peripheral clock divided by 64 */ +#define ADC_CTRLB_PRESCALER_DIV128_Val _U_(0x5) /**< \brief (ADC_CTRLB) Peripheral clock divided by 128 */ +#define ADC_CTRLB_PRESCALER_DIV256_Val _U_(0x6) /**< \brief (ADC_CTRLB) Peripheral clock divided by 256 */ +#define ADC_CTRLB_PRESCALER_DIV512_Val _U_(0x7) /**< \brief (ADC_CTRLB) Peripheral clock divided by 512 */ +#define ADC_CTRLB_PRESCALER_DIV4 (ADC_CTRLB_PRESCALER_DIV4_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV8 (ADC_CTRLB_PRESCALER_DIV8_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV16 (ADC_CTRLB_PRESCALER_DIV16_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV32 (ADC_CTRLB_PRESCALER_DIV32_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV64 (ADC_CTRLB_PRESCALER_DIV64_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV128 (ADC_CTRLB_PRESCALER_DIV128_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV256 (ADC_CTRLB_PRESCALER_DIV256_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_PRESCALER_DIV512 (ADC_CTRLB_PRESCALER_DIV512_Val << ADC_CTRLB_PRESCALER_Pos) +#define ADC_CTRLB_MASK _U_(0x073F) /**< \brief (ADC_CTRLB) MASK Register */ + +/* -------- ADC_WINCTRL : (ADC Offset: 0x08) (R/W 8) Window Monitor Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t WINMODE:3; /*!< bit: 0.. 2 Window Monitor Mode */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_WINCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINCTRL_OFFSET 0x08 /**< \brief (ADC_WINCTRL offset) Window Monitor Control */ +#define ADC_WINCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_WINCTRL reset_value) Window Monitor Control */ + +#define ADC_WINCTRL_WINMODE_Pos 0 /**< \brief (ADC_WINCTRL) Window Monitor Mode */ +#define ADC_WINCTRL_WINMODE_Msk (_U_(0x7) << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE(value) (ADC_WINCTRL_WINMODE_Msk & ((value) << ADC_WINCTRL_WINMODE_Pos)) +#define ADC_WINCTRL_WINMODE_DISABLE_Val _U_(0x0) /**< \brief (ADC_WINCTRL) No window mode (default) */ +#define ADC_WINCTRL_WINMODE_MODE1_Val _U_(0x1) /**< \brief (ADC_WINCTRL) Mode 1: RESULT > WINLT */ +#define ADC_WINCTRL_WINMODE_MODE2_Val _U_(0x2) /**< \brief (ADC_WINCTRL) Mode 2: RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE3_Val _U_(0x3) /**< \brief (ADC_WINCTRL) Mode 3: WINLT < RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE4_Val _U_(0x4) /**< \brief (ADC_WINCTRL) Mode 4: !(WINLT < RESULT < WINUT) */ +#define ADC_WINCTRL_WINMODE_DISABLE (ADC_WINCTRL_WINMODE_DISABLE_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE1 (ADC_WINCTRL_WINMODE_MODE1_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE2 (ADC_WINCTRL_WINMODE_MODE2_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE3 (ADC_WINCTRL_WINMODE_MODE3_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_WINMODE_MODE4 (ADC_WINCTRL_WINMODE_MODE4_Val << ADC_WINCTRL_WINMODE_Pos) +#define ADC_WINCTRL_MASK _U_(0x07) /**< \brief (ADC_WINCTRL) MASK Register */ + +/* -------- ADC_SWTRIG : (ADC Offset: 0x0C) (R/W 8) Software Trigger -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t FLUSH:1; /*!< bit: 0 ADC Conversion Flush */ + uint8_t START:1; /*!< bit: 1 ADC Start Conversion */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_SWTRIG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_SWTRIG_OFFSET 0x0C /**< \brief (ADC_SWTRIG offset) Software Trigger */ +#define ADC_SWTRIG_RESETVALUE _U_(0x00) /**< \brief (ADC_SWTRIG reset_value) Software Trigger */ + +#define ADC_SWTRIG_FLUSH_Pos 0 /**< \brief (ADC_SWTRIG) ADC Conversion Flush */ +#define ADC_SWTRIG_FLUSH (_U_(0x1) << ADC_SWTRIG_FLUSH_Pos) +#define ADC_SWTRIG_START_Pos 1 /**< \brief (ADC_SWTRIG) ADC Start Conversion */ +#define ADC_SWTRIG_START (_U_(0x1) << ADC_SWTRIG_START_Pos) +#define ADC_SWTRIG_MASK _U_(0x03) /**< \brief (ADC_SWTRIG) MASK Register */ + +/* -------- ADC_INPUTCTRL : (ADC Offset: 0x10) (R/W 32) Input Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t MUXPOS:5; /*!< bit: 0.. 4 Positive Mux Input Selection */ + uint32_t :3; /*!< bit: 5.. 7 Reserved */ + uint32_t MUXNEG:5; /*!< bit: 8..12 Negative Mux Input Selection */ + uint32_t :3; /*!< bit: 13..15 Reserved */ + uint32_t INPUTSCAN:4; /*!< bit: 16..19 Number of Input Channels Included in Scan */ + uint32_t INPUTOFFSET:4; /*!< bit: 20..23 Positive Mux Setting Offset */ + uint32_t GAIN:4; /*!< bit: 24..27 Gain Factor Selection */ + uint32_t :4; /*!< bit: 28..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} ADC_INPUTCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INPUTCTRL_OFFSET 0x10 /**< \brief (ADC_INPUTCTRL offset) Input Control */ +#define ADC_INPUTCTRL_RESETVALUE _U_(0x00000000) /**< \brief (ADC_INPUTCTRL reset_value) Input Control */ + +#define ADC_INPUTCTRL_MUXPOS_Pos 0 /**< \brief (ADC_INPUTCTRL) Positive Mux Input Selection */ +#define ADC_INPUTCTRL_MUXPOS_Msk (_U_(0x1F) << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS(value) (ADC_INPUTCTRL_MUXPOS_Msk & ((value) << ADC_INPUTCTRL_MUXPOS_Pos)) +#define ADC_INPUTCTRL_MUXPOS_PIN0_Val _U_(0x0) /**< \brief (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN1_Val _U_(0x1) /**< \brief (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN2_Val _U_(0x2) /**< \brief (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN3_Val _U_(0x3) /**< \brief (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN4_Val _U_(0x4) /**< \brief (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN5_Val _U_(0x5) /**< \brief (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN6_Val _U_(0x6) /**< \brief (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN7_Val _U_(0x7) /**< \brief (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN8_Val _U_(0x8) /**< \brief (ADC_INPUTCTRL) ADC AIN8 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN9_Val _U_(0x9) /**< \brief (ADC_INPUTCTRL) ADC AIN9 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN10_Val _U_(0xA) /**< \brief (ADC_INPUTCTRL) ADC AIN10 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN11_Val _U_(0xB) /**< \brief (ADC_INPUTCTRL) ADC AIN11 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN12_Val _U_(0xC) /**< \brief (ADC_INPUTCTRL) ADC AIN12 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN13_Val _U_(0xD) /**< \brief (ADC_INPUTCTRL) ADC AIN13 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN14_Val _U_(0xE) /**< \brief (ADC_INPUTCTRL) ADC AIN14 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN15_Val _U_(0xF) /**< \brief (ADC_INPUTCTRL) ADC AIN15 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN16_Val _U_(0x10) /**< \brief (ADC_INPUTCTRL) ADC AIN16 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN17_Val _U_(0x11) /**< \brief (ADC_INPUTCTRL) ADC AIN17 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN18_Val _U_(0x12) /**< \brief (ADC_INPUTCTRL) ADC AIN18 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN19_Val _U_(0x13) /**< \brief (ADC_INPUTCTRL) ADC AIN19 Pin */ +#define ADC_INPUTCTRL_MUXPOS_TEMP_Val _U_(0x18) /**< \brief (ADC_INPUTCTRL) Temperature Reference */ +#define ADC_INPUTCTRL_MUXPOS_BANDGAP_Val _U_(0x19) /**< \brief (ADC_INPUTCTRL) Bandgap Voltage */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val _U_(0x1A) /**< \brief (ADC_INPUTCTRL) 1/4 Scaled Core Supply */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val _U_(0x1B) /**< \brief (ADC_INPUTCTRL) 1/4 Scaled I/O Supply */ +#define ADC_INPUTCTRL_MUXPOS_DAC_Val _U_(0x1C) /**< \brief (ADC_INPUTCTRL) DAC Output */ +#define ADC_INPUTCTRL_MUXPOS_PIN0 (ADC_INPUTCTRL_MUXPOS_PIN0_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN1 (ADC_INPUTCTRL_MUXPOS_PIN1_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN2 (ADC_INPUTCTRL_MUXPOS_PIN2_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN3 (ADC_INPUTCTRL_MUXPOS_PIN3_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN4 (ADC_INPUTCTRL_MUXPOS_PIN4_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN5 (ADC_INPUTCTRL_MUXPOS_PIN5_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN6 (ADC_INPUTCTRL_MUXPOS_PIN6_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN7 (ADC_INPUTCTRL_MUXPOS_PIN7_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN8 (ADC_INPUTCTRL_MUXPOS_PIN8_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN9 (ADC_INPUTCTRL_MUXPOS_PIN9_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN10 (ADC_INPUTCTRL_MUXPOS_PIN10_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN11 (ADC_INPUTCTRL_MUXPOS_PIN11_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN12 (ADC_INPUTCTRL_MUXPOS_PIN12_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN13 (ADC_INPUTCTRL_MUXPOS_PIN13_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN14 (ADC_INPUTCTRL_MUXPOS_PIN14_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN15 (ADC_INPUTCTRL_MUXPOS_PIN15_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN16 (ADC_INPUTCTRL_MUXPOS_PIN16_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN17 (ADC_INPUTCTRL_MUXPOS_PIN17_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN18 (ADC_INPUTCTRL_MUXPOS_PIN18_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_PIN19 (ADC_INPUTCTRL_MUXPOS_PIN19_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_TEMP (ADC_INPUTCTRL_MUXPOS_TEMP_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_BANDGAP (ADC_INPUTCTRL_MUXPOS_BANDGAP_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC (ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC (ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXPOS_DAC (ADC_INPUTCTRL_MUXPOS_DAC_Val << ADC_INPUTCTRL_MUXPOS_Pos) +#define ADC_INPUTCTRL_MUXNEG_Pos 8 /**< \brief (ADC_INPUTCTRL) Negative Mux Input Selection */ +#define ADC_INPUTCTRL_MUXNEG_Msk (_U_(0x1F) << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG(value) (ADC_INPUTCTRL_MUXNEG_Msk & ((value) << ADC_INPUTCTRL_MUXNEG_Pos)) +#define ADC_INPUTCTRL_MUXNEG_PIN0_Val _U_(0x0) /**< \brief (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN1_Val _U_(0x1) /**< \brief (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN2_Val _U_(0x2) /**< \brief (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN3_Val _U_(0x3) /**< \brief (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN4_Val _U_(0x4) /**< \brief (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN5_Val _U_(0x5) /**< \brief (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN6_Val _U_(0x6) /**< \brief (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN7_Val _U_(0x7) /**< \brief (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXNEG_GND_Val _U_(0x18) /**< \brief (ADC_INPUTCTRL) Internal Ground */ +#define ADC_INPUTCTRL_MUXNEG_IOGND_Val _U_(0x19) /**< \brief (ADC_INPUTCTRL) I/O Ground */ +#define ADC_INPUTCTRL_MUXNEG_PIN0 (ADC_INPUTCTRL_MUXNEG_PIN0_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN1 (ADC_INPUTCTRL_MUXNEG_PIN1_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN2 (ADC_INPUTCTRL_MUXNEG_PIN2_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN3 (ADC_INPUTCTRL_MUXNEG_PIN3_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN4 (ADC_INPUTCTRL_MUXNEG_PIN4_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN5 (ADC_INPUTCTRL_MUXNEG_PIN5_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN6 (ADC_INPUTCTRL_MUXNEG_PIN6_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_PIN7 (ADC_INPUTCTRL_MUXNEG_PIN7_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_GND (ADC_INPUTCTRL_MUXNEG_GND_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_MUXNEG_IOGND (ADC_INPUTCTRL_MUXNEG_IOGND_Val << ADC_INPUTCTRL_MUXNEG_Pos) +#define ADC_INPUTCTRL_INPUTSCAN_Pos 16 /**< \brief (ADC_INPUTCTRL) Number of Input Channels Included in Scan */ +#define ADC_INPUTCTRL_INPUTSCAN_Msk (_U_(0xF) << ADC_INPUTCTRL_INPUTSCAN_Pos) +#define ADC_INPUTCTRL_INPUTSCAN(value) (ADC_INPUTCTRL_INPUTSCAN_Msk & ((value) << ADC_INPUTCTRL_INPUTSCAN_Pos)) +#define ADC_INPUTCTRL_INPUTOFFSET_Pos 20 /**< \brief (ADC_INPUTCTRL) Positive Mux Setting Offset */ +#define ADC_INPUTCTRL_INPUTOFFSET_Msk (_U_(0xF) << ADC_INPUTCTRL_INPUTOFFSET_Pos) +#define ADC_INPUTCTRL_INPUTOFFSET(value) (ADC_INPUTCTRL_INPUTOFFSET_Msk & ((value) << ADC_INPUTCTRL_INPUTOFFSET_Pos)) +#define ADC_INPUTCTRL_GAIN_Pos 24 /**< \brief (ADC_INPUTCTRL) Gain Factor Selection */ +#define ADC_INPUTCTRL_GAIN_Msk (_U_(0xF) << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN(value) (ADC_INPUTCTRL_GAIN_Msk & ((value) << ADC_INPUTCTRL_GAIN_Pos)) +#define ADC_INPUTCTRL_GAIN_1X_Val _U_(0x0) /**< \brief (ADC_INPUTCTRL) 1x */ +#define ADC_INPUTCTRL_GAIN_2X_Val _U_(0x1) /**< \brief (ADC_INPUTCTRL) 2x */ +#define ADC_INPUTCTRL_GAIN_4X_Val _U_(0x2) /**< \brief (ADC_INPUTCTRL) 4x */ +#define ADC_INPUTCTRL_GAIN_8X_Val _U_(0x3) /**< \brief (ADC_INPUTCTRL) 8x */ +#define ADC_INPUTCTRL_GAIN_16X_Val _U_(0x4) /**< \brief (ADC_INPUTCTRL) 16x */ +#define ADC_INPUTCTRL_GAIN_DIV2_Val _U_(0xF) /**< \brief (ADC_INPUTCTRL) 1/2x */ +#define ADC_INPUTCTRL_GAIN_1X (ADC_INPUTCTRL_GAIN_1X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_2X (ADC_INPUTCTRL_GAIN_2X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_4X (ADC_INPUTCTRL_GAIN_4X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_8X (ADC_INPUTCTRL_GAIN_8X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_16X (ADC_INPUTCTRL_GAIN_16X_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_GAIN_DIV2 (ADC_INPUTCTRL_GAIN_DIV2_Val << ADC_INPUTCTRL_GAIN_Pos) +#define ADC_INPUTCTRL_MASK _U_(0x0FFF1F1F) /**< \brief (ADC_INPUTCTRL) MASK Register */ + +/* -------- ADC_EVCTRL : (ADC Offset: 0x14) (R/W 8) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STARTEI:1; /*!< bit: 0 Start Conversion Event In */ + uint8_t SYNCEI:1; /*!< bit: 1 Synchronization Event In */ + uint8_t :2; /*!< bit: 2.. 3 Reserved */ + uint8_t RESRDYEO:1; /*!< bit: 4 Result Ready Event Out */ + uint8_t WINMONEO:1; /*!< bit: 5 Window Monitor Event Out */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_EVCTRL_OFFSET 0x14 /**< \brief (ADC_EVCTRL offset) Event Control */ +#define ADC_EVCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_EVCTRL reset_value) Event Control */ + +#define ADC_EVCTRL_STARTEI_Pos 0 /**< \brief (ADC_EVCTRL) Start Conversion Event In */ +#define ADC_EVCTRL_STARTEI (_U_(0x1) << ADC_EVCTRL_STARTEI_Pos) +#define ADC_EVCTRL_SYNCEI_Pos 1 /**< \brief (ADC_EVCTRL) Synchronization Event In */ +#define ADC_EVCTRL_SYNCEI (_U_(0x1) << ADC_EVCTRL_SYNCEI_Pos) +#define ADC_EVCTRL_RESRDYEO_Pos 4 /**< \brief (ADC_EVCTRL) Result Ready Event Out */ +#define ADC_EVCTRL_RESRDYEO (_U_(0x1) << ADC_EVCTRL_RESRDYEO_Pos) +#define ADC_EVCTRL_WINMONEO_Pos 5 /**< \brief (ADC_EVCTRL) Window Monitor Event Out */ +#define ADC_EVCTRL_WINMONEO (_U_(0x1) << ADC_EVCTRL_WINMONEO_Pos) +#define ADC_EVCTRL_MASK _U_(0x33) /**< \brief (ADC_EVCTRL) MASK Register */ + +/* -------- ADC_INTENCLR : (ADC Offset: 0x16) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t RESRDY:1; /*!< bit: 0 Result Ready Interrupt Enable */ + uint8_t OVERRUN:1; /*!< bit: 1 Overrun Interrupt Enable */ + uint8_t WINMON:1; /*!< bit: 2 Window Monitor Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTENCLR_OFFSET 0x16 /**< \brief (ADC_INTENCLR offset) Interrupt Enable Clear */ +#define ADC_INTENCLR_RESETVALUE _U_(0x00) /**< \brief (ADC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define ADC_INTENCLR_RESRDY_Pos 0 /**< \brief (ADC_INTENCLR) Result Ready Interrupt Enable */ +#define ADC_INTENCLR_RESRDY (_U_(0x1) << ADC_INTENCLR_RESRDY_Pos) +#define ADC_INTENCLR_OVERRUN_Pos 1 /**< \brief (ADC_INTENCLR) Overrun Interrupt Enable */ +#define ADC_INTENCLR_OVERRUN (_U_(0x1) << ADC_INTENCLR_OVERRUN_Pos) +#define ADC_INTENCLR_WINMON_Pos 2 /**< \brief (ADC_INTENCLR) Window Monitor Interrupt Enable */ +#define ADC_INTENCLR_WINMON (_U_(0x1) << ADC_INTENCLR_WINMON_Pos) +#define ADC_INTENCLR_SYNCRDY_Pos 3 /**< \brief (ADC_INTENCLR) Synchronization Ready Interrupt Enable */ +#define ADC_INTENCLR_SYNCRDY (_U_(0x1) << ADC_INTENCLR_SYNCRDY_Pos) +#define ADC_INTENCLR_MASK _U_(0x0F) /**< \brief (ADC_INTENCLR) MASK Register */ + +/* -------- ADC_INTENSET : (ADC Offset: 0x17) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t RESRDY:1; /*!< bit: 0 Result Ready Interrupt Enable */ + uint8_t OVERRUN:1; /*!< bit: 1 Overrun Interrupt Enable */ + uint8_t WINMON:1; /*!< bit: 2 Window Monitor Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready Interrupt Enable */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTENSET_OFFSET 0x17 /**< \brief (ADC_INTENSET offset) Interrupt Enable Set */ +#define ADC_INTENSET_RESETVALUE _U_(0x00) /**< \brief (ADC_INTENSET reset_value) Interrupt Enable Set */ + +#define ADC_INTENSET_RESRDY_Pos 0 /**< \brief (ADC_INTENSET) Result Ready Interrupt Enable */ +#define ADC_INTENSET_RESRDY (_U_(0x1) << ADC_INTENSET_RESRDY_Pos) +#define ADC_INTENSET_OVERRUN_Pos 1 /**< \brief (ADC_INTENSET) Overrun Interrupt Enable */ +#define ADC_INTENSET_OVERRUN (_U_(0x1) << ADC_INTENSET_OVERRUN_Pos) +#define ADC_INTENSET_WINMON_Pos 2 /**< \brief (ADC_INTENSET) Window Monitor Interrupt Enable */ +#define ADC_INTENSET_WINMON (_U_(0x1) << ADC_INTENSET_WINMON_Pos) +#define ADC_INTENSET_SYNCRDY_Pos 3 /**< \brief (ADC_INTENSET) Synchronization Ready Interrupt Enable */ +#define ADC_INTENSET_SYNCRDY (_U_(0x1) << ADC_INTENSET_SYNCRDY_Pos) +#define ADC_INTENSET_MASK _U_(0x0F) /**< \brief (ADC_INTENSET) MASK Register */ + +/* -------- ADC_INTFLAG : (ADC Offset: 0x18) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { // __I to avoid read-modify-write on write-to-clear register + struct { + __I uint8_t RESRDY:1; /*!< bit: 0 Result Ready */ + __I uint8_t OVERRUN:1; /*!< bit: 1 Overrun */ + __I uint8_t WINMON:1; /*!< bit: 2 Window Monitor */ + __I uint8_t SYNCRDY:1; /*!< bit: 3 Synchronization Ready */ + __I uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_INTFLAG_OFFSET 0x18 /**< \brief (ADC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define ADC_INTFLAG_RESETVALUE _U_(0x00) /**< \brief (ADC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define ADC_INTFLAG_RESRDY_Pos 0 /**< \brief (ADC_INTFLAG) Result Ready */ +#define ADC_INTFLAG_RESRDY (_U_(0x1) << ADC_INTFLAG_RESRDY_Pos) +#define ADC_INTFLAG_OVERRUN_Pos 1 /**< \brief (ADC_INTFLAG) Overrun */ +#define ADC_INTFLAG_OVERRUN (_U_(0x1) << ADC_INTFLAG_OVERRUN_Pos) +#define ADC_INTFLAG_WINMON_Pos 2 /**< \brief (ADC_INTFLAG) Window Monitor */ +#define ADC_INTFLAG_WINMON (_U_(0x1) << ADC_INTFLAG_WINMON_Pos) +#define ADC_INTFLAG_SYNCRDY_Pos 3 /**< \brief (ADC_INTFLAG) Synchronization Ready */ +#define ADC_INTFLAG_SYNCRDY (_U_(0x1) << ADC_INTFLAG_SYNCRDY_Pos) +#define ADC_INTFLAG_MASK _U_(0x0F) /**< \brief (ADC_INTFLAG) MASK Register */ + +/* -------- ADC_STATUS : (ADC Offset: 0x19) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_STATUS_OFFSET 0x19 /**< \brief (ADC_STATUS offset) Status */ +#define ADC_STATUS_RESETVALUE _U_(0x00) /**< \brief (ADC_STATUS reset_value) Status */ + +#define ADC_STATUS_SYNCBUSY_Pos 7 /**< \brief (ADC_STATUS) Synchronization Busy */ +#define ADC_STATUS_SYNCBUSY (_U_(0x1) << ADC_STATUS_SYNCBUSY_Pos) +#define ADC_STATUS_MASK _U_(0x80) /**< \brief (ADC_STATUS) MASK Register */ + +/* -------- ADC_RESULT : (ADC Offset: 0x1A) (R/ 16) Result -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t RESULT:16; /*!< bit: 0..15 Result Conversion Value */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_RESULT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_RESULT_OFFSET 0x1A /**< \brief (ADC_RESULT offset) Result */ +#define ADC_RESULT_RESETVALUE _U_(0x0000) /**< \brief (ADC_RESULT reset_value) Result */ + +#define ADC_RESULT_RESULT_Pos 0 /**< \brief (ADC_RESULT) Result Conversion Value */ +#define ADC_RESULT_RESULT_Msk (_U_(0xFFFF) << ADC_RESULT_RESULT_Pos) +#define ADC_RESULT_RESULT(value) (ADC_RESULT_RESULT_Msk & ((value) << ADC_RESULT_RESULT_Pos)) +#define ADC_RESULT_MASK _U_(0xFFFF) /**< \brief (ADC_RESULT) MASK Register */ + +/* -------- ADC_WINLT : (ADC Offset: 0x1C) (R/W 16) Window Monitor Lower Threshold -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t WINLT:16; /*!< bit: 0..15 Window Lower Threshold */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_WINLT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINLT_OFFSET 0x1C /**< \brief (ADC_WINLT offset) Window Monitor Lower Threshold */ +#define ADC_WINLT_RESETVALUE _U_(0x0000) /**< \brief (ADC_WINLT reset_value) Window Monitor Lower Threshold */ + +#define ADC_WINLT_WINLT_Pos 0 /**< \brief (ADC_WINLT) Window Lower Threshold */ +#define ADC_WINLT_WINLT_Msk (_U_(0xFFFF) << ADC_WINLT_WINLT_Pos) +#define ADC_WINLT_WINLT(value) (ADC_WINLT_WINLT_Msk & ((value) << ADC_WINLT_WINLT_Pos)) +#define ADC_WINLT_MASK _U_(0xFFFF) /**< \brief (ADC_WINLT) MASK Register */ + +/* -------- ADC_WINUT : (ADC Offset: 0x20) (R/W 16) Window Monitor Upper Threshold -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t WINUT:16; /*!< bit: 0..15 Window Upper Threshold */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_WINUT_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_WINUT_OFFSET 0x20 /**< \brief (ADC_WINUT offset) Window Monitor Upper Threshold */ +#define ADC_WINUT_RESETVALUE _U_(0x0000) /**< \brief (ADC_WINUT reset_value) Window Monitor Upper Threshold */ + +#define ADC_WINUT_WINUT_Pos 0 /**< \brief (ADC_WINUT) Window Upper Threshold */ +#define ADC_WINUT_WINUT_Msk (_U_(0xFFFF) << ADC_WINUT_WINUT_Pos) +#define ADC_WINUT_WINUT(value) (ADC_WINUT_WINUT_Msk & ((value) << ADC_WINUT_WINUT_Pos)) +#define ADC_WINUT_MASK _U_(0xFFFF) /**< \brief (ADC_WINUT) MASK Register */ + +/* -------- ADC_GAINCORR : (ADC Offset: 0x24) (R/W 16) Gain Correction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t GAINCORR:12; /*!< bit: 0..11 Gain Correction Value */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_GAINCORR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_GAINCORR_OFFSET 0x24 /**< \brief (ADC_GAINCORR offset) Gain Correction */ +#define ADC_GAINCORR_RESETVALUE _U_(0x0000) /**< \brief (ADC_GAINCORR reset_value) Gain Correction */ + +#define ADC_GAINCORR_GAINCORR_Pos 0 /**< \brief (ADC_GAINCORR) Gain Correction Value */ +#define ADC_GAINCORR_GAINCORR_Msk (_U_(0xFFF) << ADC_GAINCORR_GAINCORR_Pos) +#define ADC_GAINCORR_GAINCORR(value) (ADC_GAINCORR_GAINCORR_Msk & ((value) << ADC_GAINCORR_GAINCORR_Pos)) +#define ADC_GAINCORR_MASK _U_(0x0FFF) /**< \brief (ADC_GAINCORR) MASK Register */ + +/* -------- ADC_OFFSETCORR : (ADC Offset: 0x26) (R/W 16) Offset Correction -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t OFFSETCORR:12; /*!< bit: 0..11 Offset Correction Value */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_OFFSETCORR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_OFFSETCORR_OFFSET 0x26 /**< \brief (ADC_OFFSETCORR offset) Offset Correction */ +#define ADC_OFFSETCORR_RESETVALUE _U_(0x0000) /**< \brief (ADC_OFFSETCORR reset_value) Offset Correction */ + +#define ADC_OFFSETCORR_OFFSETCORR_Pos 0 /**< \brief (ADC_OFFSETCORR) Offset Correction Value */ +#define ADC_OFFSETCORR_OFFSETCORR_Msk (_U_(0xFFF) << ADC_OFFSETCORR_OFFSETCORR_Pos) +#define ADC_OFFSETCORR_OFFSETCORR(value) (ADC_OFFSETCORR_OFFSETCORR_Msk & ((value) << ADC_OFFSETCORR_OFFSETCORR_Pos)) +#define ADC_OFFSETCORR_MASK _U_(0x0FFF) /**< \brief (ADC_OFFSETCORR) MASK Register */ + +/* -------- ADC_CALIB : (ADC Offset: 0x28) (R/W 16) Calibration -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t LINEARITY_CAL:8; /*!< bit: 0.. 7 Linearity Calibration Value */ + uint16_t BIAS_CAL:3; /*!< bit: 8..10 Bias Calibration Value */ + uint16_t :5; /*!< bit: 11..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} ADC_CALIB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_CALIB_OFFSET 0x28 /**< \brief (ADC_CALIB offset) Calibration */ +#define ADC_CALIB_RESETVALUE _U_(0x0000) /**< \brief (ADC_CALIB reset_value) Calibration */ + +#define ADC_CALIB_LINEARITY_CAL_Pos 0 /**< \brief (ADC_CALIB) Linearity Calibration Value */ +#define ADC_CALIB_LINEARITY_CAL_Msk (_U_(0xFF) << ADC_CALIB_LINEARITY_CAL_Pos) +#define ADC_CALIB_LINEARITY_CAL(value) (ADC_CALIB_LINEARITY_CAL_Msk & ((value) << ADC_CALIB_LINEARITY_CAL_Pos)) +#define ADC_CALIB_BIAS_CAL_Pos 8 /**< \brief (ADC_CALIB) Bias Calibration Value */ +#define ADC_CALIB_BIAS_CAL_Msk (_U_(0x7) << ADC_CALIB_BIAS_CAL_Pos) +#define ADC_CALIB_BIAS_CAL(value) (ADC_CALIB_BIAS_CAL_Msk & ((value) << ADC_CALIB_BIAS_CAL_Pos)) +#define ADC_CALIB_MASK _U_(0x07FF) /**< \brief (ADC_CALIB) MASK Register */ + +/* -------- ADC_DBGCTRL : (ADC Offset: 0x2A) (R/W 8) Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGRUN:1; /*!< bit: 0 Debug Run */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} ADC_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define ADC_DBGCTRL_OFFSET 0x2A /**< \brief (ADC_DBGCTRL offset) Debug Control */ +#define ADC_DBGCTRL_RESETVALUE _U_(0x00) /**< \brief (ADC_DBGCTRL reset_value) Debug Control */ + +#define ADC_DBGCTRL_DBGRUN_Pos 0 /**< \brief (ADC_DBGCTRL) Debug Run */ +#define ADC_DBGCTRL_DBGRUN (_U_(0x1) << ADC_DBGCTRL_DBGRUN_Pos) +#define ADC_DBGCTRL_MASK _U_(0x01) /**< \brief (ADC_DBGCTRL) MASK Register */ + +/** \brief ADC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO ADC_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 8) Control A */ + __IO ADC_REFCTRL_Type REFCTRL; /**< \brief Offset: 0x01 (R/W 8) Reference Control */ + __IO ADC_AVGCTRL_Type AVGCTRL; /**< \brief Offset: 0x02 (R/W 8) Average Control */ + __IO ADC_SAMPCTRL_Type SAMPCTRL; /**< \brief Offset: 0x03 (R/W 8) Sampling Time Control */ + __IO ADC_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 16) Control B */ + RoReg8 Reserved1[0x2]; + __IO ADC_WINCTRL_Type WINCTRL; /**< \brief Offset: 0x08 (R/W 8) Window Monitor Control */ + RoReg8 Reserved2[0x3]; + __IO ADC_SWTRIG_Type SWTRIG; /**< \brief Offset: 0x0C (R/W 8) Software Trigger */ + RoReg8 Reserved3[0x3]; + __IO ADC_INPUTCTRL_Type INPUTCTRL; /**< \brief Offset: 0x10 (R/W 32) Input Control */ + __IO ADC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x14 (R/W 8) Event Control */ + RoReg8 Reserved4[0x1]; + __IO ADC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x16 (R/W 8) Interrupt Enable Clear */ + __IO ADC_INTENSET_Type INTENSET; /**< \brief Offset: 0x17 (R/W 8) Interrupt Enable Set */ + __IO ADC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x18 (R/W 8) Interrupt Flag Status and Clear */ + __I ADC_STATUS_Type STATUS; /**< \brief Offset: 0x19 (R/ 8) Status */ + __I ADC_RESULT_Type RESULT; /**< \brief Offset: 0x1A (R/ 16) Result */ + __IO ADC_WINLT_Type WINLT; /**< \brief Offset: 0x1C (R/W 16) Window Monitor Lower Threshold */ + RoReg8 Reserved5[0x2]; + __IO ADC_WINUT_Type WINUT; /**< \brief Offset: 0x20 (R/W 16) Window Monitor Upper Threshold */ + RoReg8 Reserved6[0x2]; + __IO ADC_GAINCORR_Type GAINCORR; /**< \brief Offset: 0x24 (R/W 16) Gain Correction */ + __IO ADC_OFFSETCORR_Type OFFSETCORR; /**< \brief Offset: 0x26 (R/W 16) Offset Correction */ + __IO ADC_CALIB_Type CALIB; /**< \brief Offset: 0x28 (R/W 16) Calibration */ + __IO ADC_DBGCTRL_Type DBGCTRL; /**< \brief Offset: 0x2A (R/W 8) Debug Control */ +} Adc; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD21_ADC_COMPONENT_ */ diff --git a/core/arm/samd21a/include/component/dac.h b/core/arm/samd21a/include/component/dac.h new file mode 100644 index 000000000..824dde664 --- /dev/null +++ b/core/arm/samd21a/include/component/dac.h @@ -0,0 +1,272 @@ +/** + * \file + * + * \brief Component description for DAC + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD21_DAC_COMPONENT_ +#define _SAMD21_DAC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR DAC */ +/* ========================================================================== */ +/** \addtogroup SAMD21_DAC Digital Analog Converter */ +/*@{*/ + +#define DAC_U2214 +#define REV_DAC 0x110 + +/* -------- DAC_CTRLA : (DAC Offset: 0x0) (R/W 8) Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Enable */ + uint8_t RUNSTDBY:1; /*!< bit: 2 Run in Standby */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_CTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_CTRLA_OFFSET 0x0 /**< \brief (DAC_CTRLA offset) Control A */ +#define DAC_CTRLA_RESETVALUE _U_(0x00) /**< \brief (DAC_CTRLA reset_value) Control A */ + +#define DAC_CTRLA_SWRST_Pos 0 /**< \brief (DAC_CTRLA) Software Reset */ +#define DAC_CTRLA_SWRST (_U_(0x1) << DAC_CTRLA_SWRST_Pos) +#define DAC_CTRLA_ENABLE_Pos 1 /**< \brief (DAC_CTRLA) Enable */ +#define DAC_CTRLA_ENABLE (_U_(0x1) << DAC_CTRLA_ENABLE_Pos) +#define DAC_CTRLA_RUNSTDBY_Pos 2 /**< \brief (DAC_CTRLA) Run in Standby */ +#define DAC_CTRLA_RUNSTDBY (_U_(0x1) << DAC_CTRLA_RUNSTDBY_Pos) +#define DAC_CTRLA_MASK _U_(0x07) /**< \brief (DAC_CTRLA) MASK Register */ + +/* -------- DAC_CTRLB : (DAC Offset: 0x1) (R/W 8) Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t EOEN:1; /*!< bit: 0 External Output Enable */ + uint8_t IOEN:1; /*!< bit: 1 Internal Output Enable */ + uint8_t LEFTADJ:1; /*!< bit: 2 Left Adjusted Data */ + uint8_t VPD:1; /*!< bit: 3 Voltage Pump Disable */ + uint8_t BDWP:1; /*!< bit: 4 Bypass DATABUF Write Protection */ + uint8_t :1; /*!< bit: 5 Reserved */ + uint8_t REFSEL:2; /*!< bit: 6.. 7 Reference Selection */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_CTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_CTRLB_OFFSET 0x1 /**< \brief (DAC_CTRLB offset) Control B */ +#define DAC_CTRLB_RESETVALUE _U_(0x00) /**< \brief (DAC_CTRLB reset_value) Control B */ + +#define DAC_CTRLB_EOEN_Pos 0 /**< \brief (DAC_CTRLB) External Output Enable */ +#define DAC_CTRLB_EOEN (_U_(0x1) << DAC_CTRLB_EOEN_Pos) +#define DAC_CTRLB_IOEN_Pos 1 /**< \brief (DAC_CTRLB) Internal Output Enable */ +#define DAC_CTRLB_IOEN (_U_(0x1) << DAC_CTRLB_IOEN_Pos) +#define DAC_CTRLB_LEFTADJ_Pos 2 /**< \brief (DAC_CTRLB) Left Adjusted Data */ +#define DAC_CTRLB_LEFTADJ (_U_(0x1) << DAC_CTRLB_LEFTADJ_Pos) +#define DAC_CTRLB_VPD_Pos 3 /**< \brief (DAC_CTRLB) Voltage Pump Disable */ +#define DAC_CTRLB_VPD (_U_(0x1) << DAC_CTRLB_VPD_Pos) +#define DAC_CTRLB_BDWP_Pos 4 /**< \brief (DAC_CTRLB) Bypass DATABUF Write Protection */ +#define DAC_CTRLB_BDWP (_U_(0x1) << DAC_CTRLB_BDWP_Pos) +#define DAC_CTRLB_REFSEL_Pos 6 /**< \brief (DAC_CTRLB) Reference Selection */ +#define DAC_CTRLB_REFSEL_Msk (_U_(0x3) << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL(value) (DAC_CTRLB_REFSEL_Msk & ((value) << DAC_CTRLB_REFSEL_Pos)) +#define DAC_CTRLB_REFSEL_INT1V_Val _U_(0x0) /**< \brief (DAC_CTRLB) Internal 1.0V reference */ +#define DAC_CTRLB_REFSEL_AVCC_Val _U_(0x1) /**< \brief (DAC_CTRLB) AVCC */ +#define DAC_CTRLB_REFSEL_VREFP_Val _U_(0x2) /**< \brief (DAC_CTRLB) External reference */ +#define DAC_CTRLB_REFSEL_INT1V (DAC_CTRLB_REFSEL_INT1V_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL_AVCC (DAC_CTRLB_REFSEL_AVCC_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_REFSEL_VREFP (DAC_CTRLB_REFSEL_VREFP_Val << DAC_CTRLB_REFSEL_Pos) +#define DAC_CTRLB_MASK _U_(0xDF) /**< \brief (DAC_CTRLB) MASK Register */ + +/* -------- DAC_EVCTRL : (DAC Offset: 0x2) (R/W 8) Event Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t STARTEI:1; /*!< bit: 0 Start Conversion Event Input */ + uint8_t EMPTYEO:1; /*!< bit: 1 Data Buffer Empty Event Output */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_EVCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_EVCTRL_OFFSET 0x2 /**< \brief (DAC_EVCTRL offset) Event Control */ +#define DAC_EVCTRL_RESETVALUE _U_(0x00) /**< \brief (DAC_EVCTRL reset_value) Event Control */ + +#define DAC_EVCTRL_STARTEI_Pos 0 /**< \brief (DAC_EVCTRL) Start Conversion Event Input */ +#define DAC_EVCTRL_STARTEI (_U_(0x1) << DAC_EVCTRL_STARTEI_Pos) +#define DAC_EVCTRL_EMPTYEO_Pos 1 /**< \brief (DAC_EVCTRL) Data Buffer Empty Event Output */ +#define DAC_EVCTRL_EMPTYEO (_U_(0x1) << DAC_EVCTRL_EMPTYEO_Pos) +#define DAC_EVCTRL_MASK _U_(0x03) /**< \brief (DAC_EVCTRL) MASK Register */ + +/* -------- DAC_INTENCLR : (DAC Offset: 0x4) (R/W 8) Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t UNDERRUN:1; /*!< bit: 0 Underrun Interrupt Enable */ + uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTENCLR_OFFSET 0x4 /**< \brief (DAC_INTENCLR offset) Interrupt Enable Clear */ +#define DAC_INTENCLR_RESETVALUE _U_(0x00) /**< \brief (DAC_INTENCLR reset_value) Interrupt Enable Clear */ + +#define DAC_INTENCLR_UNDERRUN_Pos 0 /**< \brief (DAC_INTENCLR) Underrun Interrupt Enable */ +#define DAC_INTENCLR_UNDERRUN (_U_(0x1) << DAC_INTENCLR_UNDERRUN_Pos) +#define DAC_INTENCLR_EMPTY_Pos 1 /**< \brief (DAC_INTENCLR) Data Buffer Empty Interrupt Enable */ +#define DAC_INTENCLR_EMPTY (_U_(0x1) << DAC_INTENCLR_EMPTY_Pos) +#define DAC_INTENCLR_SYNCRDY_Pos 2 /**< \brief (DAC_INTENCLR) Synchronization Ready Interrupt Enable */ +#define DAC_INTENCLR_SYNCRDY (_U_(0x1) << DAC_INTENCLR_SYNCRDY_Pos) +#define DAC_INTENCLR_MASK _U_(0x07) /**< \brief (DAC_INTENCLR) MASK Register */ + +/* -------- DAC_INTENSET : (DAC Offset: 0x5) (R/W 8) Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t UNDERRUN:1; /*!< bit: 0 Underrun Interrupt Enable */ + uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty Interrupt Enable */ + uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTENSET_OFFSET 0x5 /**< \brief (DAC_INTENSET offset) Interrupt Enable Set */ +#define DAC_INTENSET_RESETVALUE _U_(0x00) /**< \brief (DAC_INTENSET reset_value) Interrupt Enable Set */ + +#define DAC_INTENSET_UNDERRUN_Pos 0 /**< \brief (DAC_INTENSET) Underrun Interrupt Enable */ +#define DAC_INTENSET_UNDERRUN (_U_(0x1) << DAC_INTENSET_UNDERRUN_Pos) +#define DAC_INTENSET_EMPTY_Pos 1 /**< \brief (DAC_INTENSET) Data Buffer Empty Interrupt Enable */ +#define DAC_INTENSET_EMPTY (_U_(0x1) << DAC_INTENSET_EMPTY_Pos) +#define DAC_INTENSET_SYNCRDY_Pos 2 /**< \brief (DAC_INTENSET) Synchronization Ready Interrupt Enable */ +#define DAC_INTENSET_SYNCRDY (_U_(0x1) << DAC_INTENSET_SYNCRDY_Pos) +#define DAC_INTENSET_MASK _U_(0x07) /**< \brief (DAC_INTENSET) MASK Register */ + +/* -------- DAC_INTFLAG : (DAC Offset: 0x6) (R/W 8) Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { // __I to avoid read-modify-write on write-to-clear register + struct { + __I uint8_t UNDERRUN:1; /*!< bit: 0 Underrun */ + __I uint8_t EMPTY:1; /*!< bit: 1 Data Buffer Empty */ + __I uint8_t SYNCRDY:1; /*!< bit: 2 Synchronization Ready */ + __I uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_INTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_INTFLAG_OFFSET 0x6 /**< \brief (DAC_INTFLAG offset) Interrupt Flag Status and Clear */ +#define DAC_INTFLAG_RESETVALUE _U_(0x00) /**< \brief (DAC_INTFLAG reset_value) Interrupt Flag Status and Clear */ + +#define DAC_INTFLAG_UNDERRUN_Pos 0 /**< \brief (DAC_INTFLAG) Underrun */ +#define DAC_INTFLAG_UNDERRUN (_U_(0x1) << DAC_INTFLAG_UNDERRUN_Pos) +#define DAC_INTFLAG_EMPTY_Pos 1 /**< \brief (DAC_INTFLAG) Data Buffer Empty */ +#define DAC_INTFLAG_EMPTY (_U_(0x1) << DAC_INTFLAG_EMPTY_Pos) +#define DAC_INTFLAG_SYNCRDY_Pos 2 /**< \brief (DAC_INTFLAG) Synchronization Ready */ +#define DAC_INTFLAG_SYNCRDY (_U_(0x1) << DAC_INTFLAG_SYNCRDY_Pos) +#define DAC_INTFLAG_MASK _U_(0x07) /**< \brief (DAC_INTFLAG) MASK Register */ + +/* -------- DAC_STATUS : (DAC Offset: 0x7) (R/ 8) Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t :7; /*!< bit: 0.. 6 Reserved */ + uint8_t SYNCBUSY:1; /*!< bit: 7 Synchronization Busy Status */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DAC_STATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_STATUS_OFFSET 0x7 /**< \brief (DAC_STATUS offset) Status */ +#define DAC_STATUS_RESETVALUE _U_(0x00) /**< \brief (DAC_STATUS reset_value) Status */ + +#define DAC_STATUS_SYNCBUSY_Pos 7 /**< \brief (DAC_STATUS) Synchronization Busy Status */ +#define DAC_STATUS_SYNCBUSY (_U_(0x1) << DAC_STATUS_SYNCBUSY_Pos) +#define DAC_STATUS_MASK _U_(0x80) /**< \brief (DAC_STATUS) MASK Register */ + +/* -------- DAC_DATA : (DAC Offset: 0x8) (R/W 16) Data -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATA:16; /*!< bit: 0..15 Data value to be converted */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DAC_DATA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_DATA_OFFSET 0x8 /**< \brief (DAC_DATA offset) Data */ +#define DAC_DATA_RESETVALUE _U_(0x0000) /**< \brief (DAC_DATA reset_value) Data */ + +#define DAC_DATA_DATA_Pos 0 /**< \brief (DAC_DATA) Data value to be converted */ +#define DAC_DATA_DATA_Msk (_U_(0xFFFF) << DAC_DATA_DATA_Pos) +#define DAC_DATA_DATA(value) (DAC_DATA_DATA_Msk & ((value) << DAC_DATA_DATA_Pos)) +#define DAC_DATA_MASK _U_(0xFFFF) /**< \brief (DAC_DATA) MASK Register */ + +/* -------- DAC_DATABUF : (DAC Offset: 0xC) (R/W 16) Data Buffer -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t DATABUF:16; /*!< bit: 0..15 Data Buffer */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DAC_DATABUF_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DAC_DATABUF_OFFSET 0xC /**< \brief (DAC_DATABUF offset) Data Buffer */ +#define DAC_DATABUF_RESETVALUE _U_(0x0000) /**< \brief (DAC_DATABUF reset_value) Data Buffer */ + +#define DAC_DATABUF_DATABUF_Pos 0 /**< \brief (DAC_DATABUF) Data Buffer */ +#define DAC_DATABUF_DATABUF_Msk (_U_(0xFFFF) << DAC_DATABUF_DATABUF_Pos) +#define DAC_DATABUF_DATABUF(value) (DAC_DATABUF_DATABUF_Msk & ((value) << DAC_DATABUF_DATABUF_Pos)) +#define DAC_DATABUF_MASK _U_(0xFFFF) /**< \brief (DAC_DATABUF) MASK Register */ + +/** \brief DAC hardware registers */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct { + __IO DAC_CTRLA_Type CTRLA; /**< \brief Offset: 0x0 (R/W 8) Control A */ + __IO DAC_CTRLB_Type CTRLB; /**< \brief Offset: 0x1 (R/W 8) Control B */ + __IO DAC_EVCTRL_Type EVCTRL; /**< \brief Offset: 0x2 (R/W 8) Event Control */ + RoReg8 Reserved1[0x1]; + __IO DAC_INTENCLR_Type INTENCLR; /**< \brief Offset: 0x4 (R/W 8) Interrupt Enable Clear */ + __IO DAC_INTENSET_Type INTENSET; /**< \brief Offset: 0x5 (R/W 8) Interrupt Enable Set */ + __IO DAC_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x6 (R/W 8) Interrupt Flag Status and Clear */ + __I DAC_STATUS_Type STATUS; /**< \brief Offset: 0x7 (R/ 8) Status */ + __IO DAC_DATA_Type DATA; /**< \brief Offset: 0x8 (R/W 16) Data */ + RoReg8 Reserved2[0x2]; + __IO DAC_DATABUF_Type DATABUF; /**< \brief Offset: 0xC (R/W 16) Data Buffer */ +} Dac; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/*@}*/ + +#endif /* _SAMD21_DAC_COMPONENT_ */ diff --git a/core/arm/samd21a/include/component/dmac.h b/core/arm/samd21a/include/component/dmac.h new file mode 100644 index 000000000..c09402aa5 --- /dev/null +++ b/core/arm/samd21a/include/component/dmac.h @@ -0,0 +1,1073 @@ +/** + * \file + * + * \brief Component description for DMAC + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#ifndef _SAMD21_DMAC_COMPONENT_ +#define _SAMD21_DMAC_COMPONENT_ + +/* ========================================================================== */ +/** SOFTWARE API DEFINITION FOR DMAC */ +/* ========================================================================== */ +/** \addtogroup SAMD21_DMAC Direct Memory Access Controller */ +/*@{*/ + +#define DMAC_U2223 +#define REV_DMAC 0x100 + +/* -------- DMAC_CTRL : (DMAC Offset: 0x00) (R/W 16) Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t SWRST:1; /*!< bit: 0 Software Reset */ + uint16_t DMAENABLE:1; /*!< bit: 1 DMA Enable */ + uint16_t CRCENABLE:1; /*!< bit: 2 CRC Enable */ + uint16_t :5; /*!< bit: 3.. 7 Reserved */ + uint16_t LVLEN0:1; /*!< bit: 8 Priority Level 0 Enable */ + uint16_t LVLEN1:1; /*!< bit: 9 Priority Level 1 Enable */ + uint16_t LVLEN2:1; /*!< bit: 10 Priority Level 2 Enable */ + uint16_t LVLEN3:1; /*!< bit: 11 Priority Level 3 Enable */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint16_t :8; /*!< bit: 0.. 7 Reserved */ + uint16_t LVLEN:4; /*!< bit: 8..11 Priority Level x Enable */ + uint16_t :4; /*!< bit: 12..15 Reserved */ + } vec; /*!< Structure used for vec access */ + uint16_t reg; /*!< Type used for register access */ +} DMAC_CTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CTRL_OFFSET 0x00 /**< \brief (DMAC_CTRL offset) Control */ +#define DMAC_CTRL_RESETVALUE _U_(0x0000) /**< \brief (DMAC_CTRL reset_value) Control */ + +#define DMAC_CTRL_SWRST_Pos 0 /**< \brief (DMAC_CTRL) Software Reset */ +#define DMAC_CTRL_SWRST (_U_(0x1) << DMAC_CTRL_SWRST_Pos) +#define DMAC_CTRL_DMAENABLE_Pos 1 /**< \brief (DMAC_CTRL) DMA Enable */ +#define DMAC_CTRL_DMAENABLE (_U_(0x1) << DMAC_CTRL_DMAENABLE_Pos) +#define DMAC_CTRL_CRCENABLE_Pos 2 /**< \brief (DMAC_CTRL) CRC Enable */ +#define DMAC_CTRL_CRCENABLE (_U_(0x1) << DMAC_CTRL_CRCENABLE_Pos) +#define DMAC_CTRL_LVLEN0_Pos 8 /**< \brief (DMAC_CTRL) Priority Level 0 Enable */ +#define DMAC_CTRL_LVLEN0 (_U_(1) << DMAC_CTRL_LVLEN0_Pos) +#define DMAC_CTRL_LVLEN1_Pos 9 /**< \brief (DMAC_CTRL) Priority Level 1 Enable */ +#define DMAC_CTRL_LVLEN1 (_U_(1) << DMAC_CTRL_LVLEN1_Pos) +#define DMAC_CTRL_LVLEN2_Pos 10 /**< \brief (DMAC_CTRL) Priority Level 2 Enable */ +#define DMAC_CTRL_LVLEN2 (_U_(1) << DMAC_CTRL_LVLEN2_Pos) +#define DMAC_CTRL_LVLEN3_Pos 11 /**< \brief (DMAC_CTRL) Priority Level 3 Enable */ +#define DMAC_CTRL_LVLEN3 (_U_(1) << DMAC_CTRL_LVLEN3_Pos) +#define DMAC_CTRL_LVLEN_Pos 8 /**< \brief (DMAC_CTRL) Priority Level x Enable */ +#define DMAC_CTRL_LVLEN_Msk (_U_(0xF) << DMAC_CTRL_LVLEN_Pos) +#define DMAC_CTRL_LVLEN(value) (DMAC_CTRL_LVLEN_Msk & ((value) << DMAC_CTRL_LVLEN_Pos)) +#define DMAC_CTRL_MASK _U_(0x0F07) /**< \brief (DMAC_CTRL) MASK Register */ + +/* -------- DMAC_CRCCTRL : (DMAC Offset: 0x02) (R/W 16) CRC Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t CRCBEATSIZE:2; /*!< bit: 0.. 1 CRC Beat Size */ + uint16_t CRCPOLY:2; /*!< bit: 2.. 3 CRC Polynomial Type */ + uint16_t :4; /*!< bit: 4.. 7 Reserved */ + uint16_t CRCSRC:6; /*!< bit: 8..13 CRC Input Source */ + uint16_t :2; /*!< bit: 14..15 Reserved */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DMAC_CRCCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CRCCTRL_OFFSET 0x02 /**< \brief (DMAC_CRCCTRL offset) CRC Control */ +#define DMAC_CRCCTRL_RESETVALUE _U_(0x0000) /**< \brief (DMAC_CRCCTRL reset_value) CRC Control */ + +#define DMAC_CRCCTRL_CRCBEATSIZE_Pos 0 /**< \brief (DMAC_CRCCTRL) CRC Beat Size */ +#define DMAC_CRCCTRL_CRCBEATSIZE_Msk (_U_(0x3) << DMAC_CRCCTRL_CRCBEATSIZE_Pos) +#define DMAC_CRCCTRL_CRCBEATSIZE(value) (DMAC_CRCCTRL_CRCBEATSIZE_Msk & ((value) << DMAC_CRCCTRL_CRCBEATSIZE_Pos)) +#define DMAC_CRCCTRL_CRCBEATSIZE_BYTE_Val _U_(0x0) /**< \brief (DMAC_CRCCTRL) 8-bit bus transfer */ +#define DMAC_CRCCTRL_CRCBEATSIZE_HWORD_Val _U_(0x1) /**< \brief (DMAC_CRCCTRL) 16-bit bus transfer */ +#define DMAC_CRCCTRL_CRCBEATSIZE_WORD_Val _U_(0x2) /**< \brief (DMAC_CRCCTRL) 32-bit bus transfer */ +#define DMAC_CRCCTRL_CRCBEATSIZE_BYTE (DMAC_CRCCTRL_CRCBEATSIZE_BYTE_Val << DMAC_CRCCTRL_CRCBEATSIZE_Pos) +#define DMAC_CRCCTRL_CRCBEATSIZE_HWORD (DMAC_CRCCTRL_CRCBEATSIZE_HWORD_Val << DMAC_CRCCTRL_CRCBEATSIZE_Pos) +#define DMAC_CRCCTRL_CRCBEATSIZE_WORD (DMAC_CRCCTRL_CRCBEATSIZE_WORD_Val << DMAC_CRCCTRL_CRCBEATSIZE_Pos) +#define DMAC_CRCCTRL_CRCPOLY_Pos 2 /**< \brief (DMAC_CRCCTRL) CRC Polynomial Type */ +#define DMAC_CRCCTRL_CRCPOLY_Msk (_U_(0x3) << DMAC_CRCCTRL_CRCPOLY_Pos) +#define DMAC_CRCCTRL_CRCPOLY(value) (DMAC_CRCCTRL_CRCPOLY_Msk & ((value) << DMAC_CRCCTRL_CRCPOLY_Pos)) +#define DMAC_CRCCTRL_CRCPOLY_CRC16_Val _U_(0x0) /**< \brief (DMAC_CRCCTRL) CRC-16 (CRC-CCITT) */ +#define DMAC_CRCCTRL_CRCPOLY_CRC32_Val _U_(0x1) /**< \brief (DMAC_CRCCTRL) CRC32 (IEEE 802.3) */ +#define DMAC_CRCCTRL_CRCPOLY_CRC16 (DMAC_CRCCTRL_CRCPOLY_CRC16_Val << DMAC_CRCCTRL_CRCPOLY_Pos) +#define DMAC_CRCCTRL_CRCPOLY_CRC32 (DMAC_CRCCTRL_CRCPOLY_CRC32_Val << DMAC_CRCCTRL_CRCPOLY_Pos) +#define DMAC_CRCCTRL_CRCSRC_Pos 8 /**< \brief (DMAC_CRCCTRL) CRC Input Source */ +#define DMAC_CRCCTRL_CRCSRC_Msk (_U_(0x3F) << DMAC_CRCCTRL_CRCSRC_Pos) +#define DMAC_CRCCTRL_CRCSRC(value) (DMAC_CRCCTRL_CRCSRC_Msk & ((value) << DMAC_CRCCTRL_CRCSRC_Pos)) +#define DMAC_CRCCTRL_CRCSRC_NOACT_Val _U_(0x0) /**< \brief (DMAC_CRCCTRL) No action */ +#define DMAC_CRCCTRL_CRCSRC_IO_Val _U_(0x1) /**< \brief (DMAC_CRCCTRL) I/O interface */ +#define DMAC_CRCCTRL_CRCSRC_NOACT (DMAC_CRCCTRL_CRCSRC_NOACT_Val << DMAC_CRCCTRL_CRCSRC_Pos) +#define DMAC_CRCCTRL_CRCSRC_IO (DMAC_CRCCTRL_CRCSRC_IO_Val << DMAC_CRCCTRL_CRCSRC_Pos) +#define DMAC_CRCCTRL_MASK _U_(0x3F0F) /**< \brief (DMAC_CRCCTRL) MASK Register */ + +/* -------- DMAC_CRCDATAIN : (DMAC Offset: 0x04) (R/W 32) CRC Data Input -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CRCDATAIN:32; /*!< bit: 0..31 CRC Data Input */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_CRCDATAIN_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CRCDATAIN_OFFSET 0x04 /**< \brief (DMAC_CRCDATAIN offset) CRC Data Input */ +#define DMAC_CRCDATAIN_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_CRCDATAIN reset_value) CRC Data Input */ + +#define DMAC_CRCDATAIN_CRCDATAIN_Pos 0 /**< \brief (DMAC_CRCDATAIN) CRC Data Input */ +#define DMAC_CRCDATAIN_CRCDATAIN_Msk (_U_(0xFFFFFFFF) << DMAC_CRCDATAIN_CRCDATAIN_Pos) +#define DMAC_CRCDATAIN_CRCDATAIN(value) (DMAC_CRCDATAIN_CRCDATAIN_Msk & ((value) << DMAC_CRCDATAIN_CRCDATAIN_Pos)) +#define DMAC_CRCDATAIN_MASK _U_(0xFFFFFFFF) /**< \brief (DMAC_CRCDATAIN) MASK Register */ + +/* -------- DMAC_CRCCHKSUM : (DMAC Offset: 0x08) (R/W 32) CRC Checksum -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CRCCHKSUM:32; /*!< bit: 0..31 CRC Checksum */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_CRCCHKSUM_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CRCCHKSUM_OFFSET 0x08 /**< \brief (DMAC_CRCCHKSUM offset) CRC Checksum */ +#define DMAC_CRCCHKSUM_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_CRCCHKSUM reset_value) CRC Checksum */ + +#define DMAC_CRCCHKSUM_CRCCHKSUM_Pos 0 /**< \brief (DMAC_CRCCHKSUM) CRC Checksum */ +#define DMAC_CRCCHKSUM_CRCCHKSUM_Msk (_U_(0xFFFFFFFF) << DMAC_CRCCHKSUM_CRCCHKSUM_Pos) +#define DMAC_CRCCHKSUM_CRCCHKSUM(value) (DMAC_CRCCHKSUM_CRCCHKSUM_Msk & ((value) << DMAC_CRCCHKSUM_CRCCHKSUM_Pos)) +#define DMAC_CRCCHKSUM_MASK _U_(0xFFFFFFFF) /**< \brief (DMAC_CRCCHKSUM) MASK Register */ + +/* -------- DMAC_CRCSTATUS : (DMAC Offset: 0x0C) (R/W 8) CRC Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t CRCBUSY:1; /*!< bit: 0 CRC Module Busy */ + uint8_t CRCZERO:1; /*!< bit: 1 CRC Zero */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CRCSTATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CRCSTATUS_OFFSET 0x0C /**< \brief (DMAC_CRCSTATUS offset) CRC Status */ +#define DMAC_CRCSTATUS_RESETVALUE _U_(0x00) /**< \brief (DMAC_CRCSTATUS reset_value) CRC Status */ + +#define DMAC_CRCSTATUS_CRCBUSY_Pos 0 /**< \brief (DMAC_CRCSTATUS) CRC Module Busy */ +#define DMAC_CRCSTATUS_CRCBUSY (_U_(0x1) << DMAC_CRCSTATUS_CRCBUSY_Pos) +#define DMAC_CRCSTATUS_CRCZERO_Pos 1 /**< \brief (DMAC_CRCSTATUS) CRC Zero */ +#define DMAC_CRCSTATUS_CRCZERO (_U_(0x1) << DMAC_CRCSTATUS_CRCZERO_Pos) +#define DMAC_CRCSTATUS_MASK _U_(0x03) /**< \brief (DMAC_CRCSTATUS) MASK Register */ + +/* -------- DMAC_DBGCTRL : (DMAC Offset: 0x0D) (R/W 8) Debug Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t DBGRUN:1; /*!< bit: 0 Debug Run */ + uint8_t :7; /*!< bit: 1.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_DBGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_DBGCTRL_OFFSET 0x0D /**< \brief (DMAC_DBGCTRL offset) Debug Control */ +#define DMAC_DBGCTRL_RESETVALUE _U_(0x00) /**< \brief (DMAC_DBGCTRL reset_value) Debug Control */ + +#define DMAC_DBGCTRL_DBGRUN_Pos 0 /**< \brief (DMAC_DBGCTRL) Debug Run */ +#define DMAC_DBGCTRL_DBGRUN (_U_(0x1) << DMAC_DBGCTRL_DBGRUN_Pos) +#define DMAC_DBGCTRL_MASK _U_(0x01) /**< \brief (DMAC_DBGCTRL) MASK Register */ + +/* -------- DMAC_QOSCTRL : (DMAC Offset: 0x0E) (R/W 8) QOS Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t WRBQOS:2; /*!< bit: 0.. 1 Write-Back Quality of Service */ + uint8_t FQOS:2; /*!< bit: 2.. 3 Fetch Quality of Service */ + uint8_t DQOS:2; /*!< bit: 4.. 5 Data Transfer Quality of Service */ + uint8_t :2; /*!< bit: 6.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_QOSCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_QOSCTRL_OFFSET 0x0E /**< \brief (DMAC_QOSCTRL offset) QOS Control */ +#define DMAC_QOSCTRL_RESETVALUE _U_(0x15) /**< \brief (DMAC_QOSCTRL reset_value) QOS Control */ + +#define DMAC_QOSCTRL_WRBQOS_Pos 0 /**< \brief (DMAC_QOSCTRL) Write-Back Quality of Service */ +#define DMAC_QOSCTRL_WRBQOS_Msk (_U_(0x3) << DMAC_QOSCTRL_WRBQOS_Pos) +#define DMAC_QOSCTRL_WRBQOS(value) (DMAC_QOSCTRL_WRBQOS_Msk & ((value) << DMAC_QOSCTRL_WRBQOS_Pos)) +#define DMAC_QOSCTRL_WRBQOS_DISABLE_Val _U_(0x0) /**< \brief (DMAC_QOSCTRL) Background (no sensitive operation) */ +#define DMAC_QOSCTRL_WRBQOS_LOW_Val _U_(0x1) /**< \brief (DMAC_QOSCTRL) Sensitive Bandwidth */ +#define DMAC_QOSCTRL_WRBQOS_MEDIUM_Val _U_(0x2) /**< \brief (DMAC_QOSCTRL) Sensitive Latency */ +#define DMAC_QOSCTRL_WRBQOS_HIGH_Val _U_(0x3) /**< \brief (DMAC_QOSCTRL) Critical Latency */ +#define DMAC_QOSCTRL_WRBQOS_DISABLE (DMAC_QOSCTRL_WRBQOS_DISABLE_Val << DMAC_QOSCTRL_WRBQOS_Pos) +#define DMAC_QOSCTRL_WRBQOS_LOW (DMAC_QOSCTRL_WRBQOS_LOW_Val << DMAC_QOSCTRL_WRBQOS_Pos) +#define DMAC_QOSCTRL_WRBQOS_MEDIUM (DMAC_QOSCTRL_WRBQOS_MEDIUM_Val << DMAC_QOSCTRL_WRBQOS_Pos) +#define DMAC_QOSCTRL_WRBQOS_HIGH (DMAC_QOSCTRL_WRBQOS_HIGH_Val << DMAC_QOSCTRL_WRBQOS_Pos) +#define DMAC_QOSCTRL_FQOS_Pos 2 /**< \brief (DMAC_QOSCTRL) Fetch Quality of Service */ +#define DMAC_QOSCTRL_FQOS_Msk (_U_(0x3) << DMAC_QOSCTRL_FQOS_Pos) +#define DMAC_QOSCTRL_FQOS(value) (DMAC_QOSCTRL_FQOS_Msk & ((value) << DMAC_QOSCTRL_FQOS_Pos)) +#define DMAC_QOSCTRL_FQOS_DISABLE_Val _U_(0x0) /**< \brief (DMAC_QOSCTRL) Background (no sensitive operation) */ +#define DMAC_QOSCTRL_FQOS_LOW_Val _U_(0x1) /**< \brief (DMAC_QOSCTRL) Sensitive Bandwidth */ +#define DMAC_QOSCTRL_FQOS_MEDIUM_Val _U_(0x2) /**< \brief (DMAC_QOSCTRL) Sensitive Latency */ +#define DMAC_QOSCTRL_FQOS_HIGH_Val _U_(0x3) /**< \brief (DMAC_QOSCTRL) Critical Latency */ +#define DMAC_QOSCTRL_FQOS_DISABLE (DMAC_QOSCTRL_FQOS_DISABLE_Val << DMAC_QOSCTRL_FQOS_Pos) +#define DMAC_QOSCTRL_FQOS_LOW (DMAC_QOSCTRL_FQOS_LOW_Val << DMAC_QOSCTRL_FQOS_Pos) +#define DMAC_QOSCTRL_FQOS_MEDIUM (DMAC_QOSCTRL_FQOS_MEDIUM_Val << DMAC_QOSCTRL_FQOS_Pos) +#define DMAC_QOSCTRL_FQOS_HIGH (DMAC_QOSCTRL_FQOS_HIGH_Val << DMAC_QOSCTRL_FQOS_Pos) +#define DMAC_QOSCTRL_DQOS_Pos 4 /**< \brief (DMAC_QOSCTRL) Data Transfer Quality of Service */ +#define DMAC_QOSCTRL_DQOS_Msk (_U_(0x3) << DMAC_QOSCTRL_DQOS_Pos) +#define DMAC_QOSCTRL_DQOS(value) (DMAC_QOSCTRL_DQOS_Msk & ((value) << DMAC_QOSCTRL_DQOS_Pos)) +#define DMAC_QOSCTRL_DQOS_DISABLE_Val _U_(0x0) /**< \brief (DMAC_QOSCTRL) Background (no sensitive operation) */ +#define DMAC_QOSCTRL_DQOS_LOW_Val _U_(0x1) /**< \brief (DMAC_QOSCTRL) Sensitive Bandwidth */ +#define DMAC_QOSCTRL_DQOS_MEDIUM_Val _U_(0x2) /**< \brief (DMAC_QOSCTRL) Sensitive Latency */ +#define DMAC_QOSCTRL_DQOS_HIGH_Val _U_(0x3) /**< \brief (DMAC_QOSCTRL) Critical Latency */ +#define DMAC_QOSCTRL_DQOS_DISABLE (DMAC_QOSCTRL_DQOS_DISABLE_Val << DMAC_QOSCTRL_DQOS_Pos) +#define DMAC_QOSCTRL_DQOS_LOW (DMAC_QOSCTRL_DQOS_LOW_Val << DMAC_QOSCTRL_DQOS_Pos) +#define DMAC_QOSCTRL_DQOS_MEDIUM (DMAC_QOSCTRL_DQOS_MEDIUM_Val << DMAC_QOSCTRL_DQOS_Pos) +#define DMAC_QOSCTRL_DQOS_HIGH (DMAC_QOSCTRL_DQOS_HIGH_Val << DMAC_QOSCTRL_DQOS_Pos) +#define DMAC_QOSCTRL_MASK _U_(0x3F) /**< \brief (DMAC_QOSCTRL) MASK Register */ + +/* -------- DMAC_SWTRIGCTRL : (DMAC Offset: 0x10) (R/W 32) Software Trigger Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t SWTRIG0:1; /*!< bit: 0 Channel 0 Software Trigger */ + uint32_t SWTRIG1:1; /*!< bit: 1 Channel 1 Software Trigger */ + uint32_t SWTRIG2:1; /*!< bit: 2 Channel 2 Software Trigger */ + uint32_t SWTRIG3:1; /*!< bit: 3 Channel 3 Software Trigger */ + uint32_t SWTRIG4:1; /*!< bit: 4 Channel 4 Software Trigger */ + uint32_t SWTRIG5:1; /*!< bit: 5 Channel 5 Software Trigger */ + uint32_t SWTRIG6:1; /*!< bit: 6 Channel 6 Software Trigger */ + uint32_t SWTRIG7:1; /*!< bit: 7 Channel 7 Software Trigger */ + uint32_t SWTRIG8:1; /*!< bit: 8 Channel 8 Software Trigger */ + uint32_t SWTRIG9:1; /*!< bit: 9 Channel 9 Software Trigger */ + uint32_t SWTRIG10:1; /*!< bit: 10 Channel 10 Software Trigger */ + uint32_t SWTRIG11:1; /*!< bit: 11 Channel 11 Software Trigger */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t SWTRIG:12; /*!< bit: 0..11 Channel x Software Trigger */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_SWTRIGCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_SWTRIGCTRL_OFFSET 0x10 /**< \brief (DMAC_SWTRIGCTRL offset) Software Trigger Control */ +#define DMAC_SWTRIGCTRL_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_SWTRIGCTRL reset_value) Software Trigger Control */ + +#define DMAC_SWTRIGCTRL_SWTRIG0_Pos 0 /**< \brief (DMAC_SWTRIGCTRL) Channel 0 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG0 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG0_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG1_Pos 1 /**< \brief (DMAC_SWTRIGCTRL) Channel 1 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG1 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG1_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG2_Pos 2 /**< \brief (DMAC_SWTRIGCTRL) Channel 2 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG2 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG2_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG3_Pos 3 /**< \brief (DMAC_SWTRIGCTRL) Channel 3 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG3 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG3_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG4_Pos 4 /**< \brief (DMAC_SWTRIGCTRL) Channel 4 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG4 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG4_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG5_Pos 5 /**< \brief (DMAC_SWTRIGCTRL) Channel 5 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG5 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG5_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG6_Pos 6 /**< \brief (DMAC_SWTRIGCTRL) Channel 6 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG6 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG6_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG7_Pos 7 /**< \brief (DMAC_SWTRIGCTRL) Channel 7 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG7 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG7_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG8_Pos 8 /**< \brief (DMAC_SWTRIGCTRL) Channel 8 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG8 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG8_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG9_Pos 9 /**< \brief (DMAC_SWTRIGCTRL) Channel 9 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG9 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG9_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG10_Pos 10 /**< \brief (DMAC_SWTRIGCTRL) Channel 10 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG10 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG10_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG11_Pos 11 /**< \brief (DMAC_SWTRIGCTRL) Channel 11 Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG11 (_U_(1) << DMAC_SWTRIGCTRL_SWTRIG11_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG_Pos 0 /**< \brief (DMAC_SWTRIGCTRL) Channel x Software Trigger */ +#define DMAC_SWTRIGCTRL_SWTRIG_Msk (_U_(0xFFF) << DMAC_SWTRIGCTRL_SWTRIG_Pos) +#define DMAC_SWTRIGCTRL_SWTRIG(value) (DMAC_SWTRIGCTRL_SWTRIG_Msk & ((value) << DMAC_SWTRIGCTRL_SWTRIG_Pos)) +#define DMAC_SWTRIGCTRL_MASK _U_(0x00000FFF) /**< \brief (DMAC_SWTRIGCTRL) MASK Register */ + +/* -------- DMAC_PRICTRL0 : (DMAC Offset: 0x14) (R/W 32) Priority Control 0 -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t LVLPRI0:4; /*!< bit: 0.. 3 Level 0 Channel Priority Number */ + uint32_t :3; /*!< bit: 4.. 6 Reserved */ + uint32_t RRLVLEN0:1; /*!< bit: 7 Level 0 Round-Robin Scheduling Enable */ + uint32_t LVLPRI1:4; /*!< bit: 8..11 Level 1 Channel Priority Number */ + uint32_t :3; /*!< bit: 12..14 Reserved */ + uint32_t RRLVLEN1:1; /*!< bit: 15 Level 1 Round-Robin Scheduling Enable */ + uint32_t LVLPRI2:4; /*!< bit: 16..19 Level 2 Channel Priority Number */ + uint32_t :3; /*!< bit: 20..22 Reserved */ + uint32_t RRLVLEN2:1; /*!< bit: 23 Level 2 Round-Robin Scheduling Enable */ + uint32_t LVLPRI3:4; /*!< bit: 24..27 Level 3 Channel Priority Number */ + uint32_t :3; /*!< bit: 28..30 Reserved */ + uint32_t RRLVLEN3:1; /*!< bit: 31 Level 3 Round-Robin Scheduling Enable */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_PRICTRL0_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_PRICTRL0_OFFSET 0x14 /**< \brief (DMAC_PRICTRL0 offset) Priority Control 0 */ +#define DMAC_PRICTRL0_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_PRICTRL0 reset_value) Priority Control 0 */ + +#define DMAC_PRICTRL0_LVLPRI0_Pos 0 /**< \brief (DMAC_PRICTRL0) Level 0 Channel Priority Number */ +#define DMAC_PRICTRL0_LVLPRI0_Msk (_U_(0xF) << DMAC_PRICTRL0_LVLPRI0_Pos) +#define DMAC_PRICTRL0_LVLPRI0(value) (DMAC_PRICTRL0_LVLPRI0_Msk & ((value) << DMAC_PRICTRL0_LVLPRI0_Pos)) +#define DMAC_PRICTRL0_RRLVLEN0_Pos 7 /**< \brief (DMAC_PRICTRL0) Level 0 Round-Robin Scheduling Enable */ +#define DMAC_PRICTRL0_RRLVLEN0 (_U_(0x1) << DMAC_PRICTRL0_RRLVLEN0_Pos) +#define DMAC_PRICTRL0_LVLPRI1_Pos 8 /**< \brief (DMAC_PRICTRL0) Level 1 Channel Priority Number */ +#define DMAC_PRICTRL0_LVLPRI1_Msk (_U_(0xF) << DMAC_PRICTRL0_LVLPRI1_Pos) +#define DMAC_PRICTRL0_LVLPRI1(value) (DMAC_PRICTRL0_LVLPRI1_Msk & ((value) << DMAC_PRICTRL0_LVLPRI1_Pos)) +#define DMAC_PRICTRL0_RRLVLEN1_Pos 15 /**< \brief (DMAC_PRICTRL0) Level 1 Round-Robin Scheduling Enable */ +#define DMAC_PRICTRL0_RRLVLEN1 (_U_(0x1) << DMAC_PRICTRL0_RRLVLEN1_Pos) +#define DMAC_PRICTRL0_LVLPRI2_Pos 16 /**< \brief (DMAC_PRICTRL0) Level 2 Channel Priority Number */ +#define DMAC_PRICTRL0_LVLPRI2_Msk (_U_(0xF) << DMAC_PRICTRL0_LVLPRI2_Pos) +#define DMAC_PRICTRL0_LVLPRI2(value) (DMAC_PRICTRL0_LVLPRI2_Msk & ((value) << DMAC_PRICTRL0_LVLPRI2_Pos)) +#define DMAC_PRICTRL0_RRLVLEN2_Pos 23 /**< \brief (DMAC_PRICTRL0) Level 2 Round-Robin Scheduling Enable */ +#define DMAC_PRICTRL0_RRLVLEN2 (_U_(0x1) << DMAC_PRICTRL0_RRLVLEN2_Pos) +#define DMAC_PRICTRL0_LVLPRI3_Pos 24 /**< \brief (DMAC_PRICTRL0) Level 3 Channel Priority Number */ +#define DMAC_PRICTRL0_LVLPRI3_Msk (_U_(0xF) << DMAC_PRICTRL0_LVLPRI3_Pos) +#define DMAC_PRICTRL0_LVLPRI3(value) (DMAC_PRICTRL0_LVLPRI3_Msk & ((value) << DMAC_PRICTRL0_LVLPRI3_Pos)) +#define DMAC_PRICTRL0_RRLVLEN3_Pos 31 /**< \brief (DMAC_PRICTRL0) Level 3 Round-Robin Scheduling Enable */ +#define DMAC_PRICTRL0_RRLVLEN3 (_U_(0x1) << DMAC_PRICTRL0_RRLVLEN3_Pos) +#define DMAC_PRICTRL0_MASK _U_(0x8F8F8F8F) /**< \brief (DMAC_PRICTRL0) MASK Register */ + +/* -------- DMAC_INTPEND : (DMAC Offset: 0x20) (R/W 16) Interrupt Pending -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t ID:4; /*!< bit: 0.. 3 Channel ID */ + uint16_t :4; /*!< bit: 4.. 7 Reserved */ + uint16_t TERR:1; /*!< bit: 8 Transfer Error */ + uint16_t TCMPL:1; /*!< bit: 9 Transfer Complete */ + uint16_t SUSP:1; /*!< bit: 10 Channel Suspend */ + uint16_t :2; /*!< bit: 11..12 Reserved */ + uint16_t FERR:1; /*!< bit: 13 Fetch Error */ + uint16_t BUSY:1; /*!< bit: 14 Busy */ + uint16_t PEND:1; /*!< bit: 15 Pending */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DMAC_INTPEND_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_INTPEND_OFFSET 0x20 /**< \brief (DMAC_INTPEND offset) Interrupt Pending */ +#define DMAC_INTPEND_RESETVALUE _U_(0x0000) /**< \brief (DMAC_INTPEND reset_value) Interrupt Pending */ + +#define DMAC_INTPEND_ID_Pos 0 /**< \brief (DMAC_INTPEND) Channel ID */ +#define DMAC_INTPEND_ID_Msk (_U_(0xF) << DMAC_INTPEND_ID_Pos) +#define DMAC_INTPEND_ID(value) (DMAC_INTPEND_ID_Msk & ((value) << DMAC_INTPEND_ID_Pos)) +#define DMAC_INTPEND_TERR_Pos 8 /**< \brief (DMAC_INTPEND) Transfer Error */ +#define DMAC_INTPEND_TERR (_U_(0x1) << DMAC_INTPEND_TERR_Pos) +#define DMAC_INTPEND_TCMPL_Pos 9 /**< \brief (DMAC_INTPEND) Transfer Complete */ +#define DMAC_INTPEND_TCMPL (_U_(0x1) << DMAC_INTPEND_TCMPL_Pos) +#define DMAC_INTPEND_SUSP_Pos 10 /**< \brief (DMAC_INTPEND) Channel Suspend */ +#define DMAC_INTPEND_SUSP (_U_(0x1) << DMAC_INTPEND_SUSP_Pos) +#define DMAC_INTPEND_FERR_Pos 13 /**< \brief (DMAC_INTPEND) Fetch Error */ +#define DMAC_INTPEND_FERR (_U_(0x1) << DMAC_INTPEND_FERR_Pos) +#define DMAC_INTPEND_BUSY_Pos 14 /**< \brief (DMAC_INTPEND) Busy */ +#define DMAC_INTPEND_BUSY (_U_(0x1) << DMAC_INTPEND_BUSY_Pos) +#define DMAC_INTPEND_PEND_Pos 15 /**< \brief (DMAC_INTPEND) Pending */ +#define DMAC_INTPEND_PEND (_U_(0x1) << DMAC_INTPEND_PEND_Pos) +#define DMAC_INTPEND_MASK _U_(0xE70F) /**< \brief (DMAC_INTPEND) MASK Register */ + +/* -------- DMAC_INTSTATUS : (DMAC Offset: 0x24) (R/ 32) Interrupt Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t CHINT0:1; /*!< bit: 0 Channel 0 Pending Interrupt */ + uint32_t CHINT1:1; /*!< bit: 1 Channel 1 Pending Interrupt */ + uint32_t CHINT2:1; /*!< bit: 2 Channel 2 Pending Interrupt */ + uint32_t CHINT3:1; /*!< bit: 3 Channel 3 Pending Interrupt */ + uint32_t CHINT4:1; /*!< bit: 4 Channel 4 Pending Interrupt */ + uint32_t CHINT5:1; /*!< bit: 5 Channel 5 Pending Interrupt */ + uint32_t CHINT6:1; /*!< bit: 6 Channel 6 Pending Interrupt */ + uint32_t CHINT7:1; /*!< bit: 7 Channel 7 Pending Interrupt */ + uint32_t CHINT8:1; /*!< bit: 8 Channel 8 Pending Interrupt */ + uint32_t CHINT9:1; /*!< bit: 9 Channel 9 Pending Interrupt */ + uint32_t CHINT10:1; /*!< bit: 10 Channel 10 Pending Interrupt */ + uint32_t CHINT11:1; /*!< bit: 11 Channel 11 Pending Interrupt */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t CHINT:12; /*!< bit: 0..11 Channel x Pending Interrupt */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_INTSTATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_INTSTATUS_OFFSET 0x24 /**< \brief (DMAC_INTSTATUS offset) Interrupt Status */ +#define DMAC_INTSTATUS_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_INTSTATUS reset_value) Interrupt Status */ + +#define DMAC_INTSTATUS_CHINT0_Pos 0 /**< \brief (DMAC_INTSTATUS) Channel 0 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT0 (_U_(1) << DMAC_INTSTATUS_CHINT0_Pos) +#define DMAC_INTSTATUS_CHINT1_Pos 1 /**< \brief (DMAC_INTSTATUS) Channel 1 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT1 (_U_(1) << DMAC_INTSTATUS_CHINT1_Pos) +#define DMAC_INTSTATUS_CHINT2_Pos 2 /**< \brief (DMAC_INTSTATUS) Channel 2 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT2 (_U_(1) << DMAC_INTSTATUS_CHINT2_Pos) +#define DMAC_INTSTATUS_CHINT3_Pos 3 /**< \brief (DMAC_INTSTATUS) Channel 3 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT3 (_U_(1) << DMAC_INTSTATUS_CHINT3_Pos) +#define DMAC_INTSTATUS_CHINT4_Pos 4 /**< \brief (DMAC_INTSTATUS) Channel 4 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT4 (_U_(1) << DMAC_INTSTATUS_CHINT4_Pos) +#define DMAC_INTSTATUS_CHINT5_Pos 5 /**< \brief (DMAC_INTSTATUS) Channel 5 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT5 (_U_(1) << DMAC_INTSTATUS_CHINT5_Pos) +#define DMAC_INTSTATUS_CHINT6_Pos 6 /**< \brief (DMAC_INTSTATUS) Channel 6 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT6 (_U_(1) << DMAC_INTSTATUS_CHINT6_Pos) +#define DMAC_INTSTATUS_CHINT7_Pos 7 /**< \brief (DMAC_INTSTATUS) Channel 7 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT7 (_U_(1) << DMAC_INTSTATUS_CHINT7_Pos) +#define DMAC_INTSTATUS_CHINT8_Pos 8 /**< \brief (DMAC_INTSTATUS) Channel 8 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT8 (_U_(1) << DMAC_INTSTATUS_CHINT8_Pos) +#define DMAC_INTSTATUS_CHINT9_Pos 9 /**< \brief (DMAC_INTSTATUS) Channel 9 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT9 (_U_(1) << DMAC_INTSTATUS_CHINT9_Pos) +#define DMAC_INTSTATUS_CHINT10_Pos 10 /**< \brief (DMAC_INTSTATUS) Channel 10 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT10 (_U_(1) << DMAC_INTSTATUS_CHINT10_Pos) +#define DMAC_INTSTATUS_CHINT11_Pos 11 /**< \brief (DMAC_INTSTATUS) Channel 11 Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT11 (_U_(1) << DMAC_INTSTATUS_CHINT11_Pos) +#define DMAC_INTSTATUS_CHINT_Pos 0 /**< \brief (DMAC_INTSTATUS) Channel x Pending Interrupt */ +#define DMAC_INTSTATUS_CHINT_Msk (_U_(0xFFF) << DMAC_INTSTATUS_CHINT_Pos) +#define DMAC_INTSTATUS_CHINT(value) (DMAC_INTSTATUS_CHINT_Msk & ((value) << DMAC_INTSTATUS_CHINT_Pos)) +#define DMAC_INTSTATUS_MASK _U_(0x00000FFF) /**< \brief (DMAC_INTSTATUS) MASK Register */ + +/* -------- DMAC_BUSYCH : (DMAC Offset: 0x28) (R/ 32) Busy Channels -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t BUSYCH0:1; /*!< bit: 0 Busy Channel 0 */ + uint32_t BUSYCH1:1; /*!< bit: 1 Busy Channel 1 */ + uint32_t BUSYCH2:1; /*!< bit: 2 Busy Channel 2 */ + uint32_t BUSYCH3:1; /*!< bit: 3 Busy Channel 3 */ + uint32_t BUSYCH4:1; /*!< bit: 4 Busy Channel 4 */ + uint32_t BUSYCH5:1; /*!< bit: 5 Busy Channel 5 */ + uint32_t BUSYCH6:1; /*!< bit: 6 Busy Channel 6 */ + uint32_t BUSYCH7:1; /*!< bit: 7 Busy Channel 7 */ + uint32_t BUSYCH8:1; /*!< bit: 8 Busy Channel 8 */ + uint32_t BUSYCH9:1; /*!< bit: 9 Busy Channel 9 */ + uint32_t BUSYCH10:1; /*!< bit: 10 Busy Channel 10 */ + uint32_t BUSYCH11:1; /*!< bit: 11 Busy Channel 11 */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t BUSYCH:12; /*!< bit: 0..11 Busy Channel x */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_BUSYCH_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_BUSYCH_OFFSET 0x28 /**< \brief (DMAC_BUSYCH offset) Busy Channels */ +#define DMAC_BUSYCH_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_BUSYCH reset_value) Busy Channels */ + +#define DMAC_BUSYCH_BUSYCH0_Pos 0 /**< \brief (DMAC_BUSYCH) Busy Channel 0 */ +#define DMAC_BUSYCH_BUSYCH0 (_U_(1) << DMAC_BUSYCH_BUSYCH0_Pos) +#define DMAC_BUSYCH_BUSYCH1_Pos 1 /**< \brief (DMAC_BUSYCH) Busy Channel 1 */ +#define DMAC_BUSYCH_BUSYCH1 (_U_(1) << DMAC_BUSYCH_BUSYCH1_Pos) +#define DMAC_BUSYCH_BUSYCH2_Pos 2 /**< \brief (DMAC_BUSYCH) Busy Channel 2 */ +#define DMAC_BUSYCH_BUSYCH2 (_U_(1) << DMAC_BUSYCH_BUSYCH2_Pos) +#define DMAC_BUSYCH_BUSYCH3_Pos 3 /**< \brief (DMAC_BUSYCH) Busy Channel 3 */ +#define DMAC_BUSYCH_BUSYCH3 (_U_(1) << DMAC_BUSYCH_BUSYCH3_Pos) +#define DMAC_BUSYCH_BUSYCH4_Pos 4 /**< \brief (DMAC_BUSYCH) Busy Channel 4 */ +#define DMAC_BUSYCH_BUSYCH4 (_U_(1) << DMAC_BUSYCH_BUSYCH4_Pos) +#define DMAC_BUSYCH_BUSYCH5_Pos 5 /**< \brief (DMAC_BUSYCH) Busy Channel 5 */ +#define DMAC_BUSYCH_BUSYCH5 (_U_(1) << DMAC_BUSYCH_BUSYCH5_Pos) +#define DMAC_BUSYCH_BUSYCH6_Pos 6 /**< \brief (DMAC_BUSYCH) Busy Channel 6 */ +#define DMAC_BUSYCH_BUSYCH6 (_U_(1) << DMAC_BUSYCH_BUSYCH6_Pos) +#define DMAC_BUSYCH_BUSYCH7_Pos 7 /**< \brief (DMAC_BUSYCH) Busy Channel 7 */ +#define DMAC_BUSYCH_BUSYCH7 (_U_(1) << DMAC_BUSYCH_BUSYCH7_Pos) +#define DMAC_BUSYCH_BUSYCH8_Pos 8 /**< \brief (DMAC_BUSYCH) Busy Channel 8 */ +#define DMAC_BUSYCH_BUSYCH8 (_U_(1) << DMAC_BUSYCH_BUSYCH8_Pos) +#define DMAC_BUSYCH_BUSYCH9_Pos 9 /**< \brief (DMAC_BUSYCH) Busy Channel 9 */ +#define DMAC_BUSYCH_BUSYCH9 (_U_(1) << DMAC_BUSYCH_BUSYCH9_Pos) +#define DMAC_BUSYCH_BUSYCH10_Pos 10 /**< \brief (DMAC_BUSYCH) Busy Channel 10 */ +#define DMAC_BUSYCH_BUSYCH10 (_U_(1) << DMAC_BUSYCH_BUSYCH10_Pos) +#define DMAC_BUSYCH_BUSYCH11_Pos 11 /**< \brief (DMAC_BUSYCH) Busy Channel 11 */ +#define DMAC_BUSYCH_BUSYCH11 (_U_(1) << DMAC_BUSYCH_BUSYCH11_Pos) +#define DMAC_BUSYCH_BUSYCH_Pos 0 /**< \brief (DMAC_BUSYCH) Busy Channel x */ +#define DMAC_BUSYCH_BUSYCH_Msk (_U_(0xFFF) << DMAC_BUSYCH_BUSYCH_Pos) +#define DMAC_BUSYCH_BUSYCH(value) (DMAC_BUSYCH_BUSYCH_Msk & ((value) << DMAC_BUSYCH_BUSYCH_Pos)) +#define DMAC_BUSYCH_MASK _U_(0x00000FFF) /**< \brief (DMAC_BUSYCH) MASK Register */ + +/* -------- DMAC_PENDCH : (DMAC Offset: 0x2C) (R/ 32) Pending Channels -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t PENDCH0:1; /*!< bit: 0 Pending Channel 0 */ + uint32_t PENDCH1:1; /*!< bit: 1 Pending Channel 1 */ + uint32_t PENDCH2:1; /*!< bit: 2 Pending Channel 2 */ + uint32_t PENDCH3:1; /*!< bit: 3 Pending Channel 3 */ + uint32_t PENDCH4:1; /*!< bit: 4 Pending Channel 4 */ + uint32_t PENDCH5:1; /*!< bit: 5 Pending Channel 5 */ + uint32_t PENDCH6:1; /*!< bit: 6 Pending Channel 6 */ + uint32_t PENDCH7:1; /*!< bit: 7 Pending Channel 7 */ + uint32_t PENDCH8:1; /*!< bit: 8 Pending Channel 8 */ + uint32_t PENDCH9:1; /*!< bit: 9 Pending Channel 9 */ + uint32_t PENDCH10:1; /*!< bit: 10 Pending Channel 10 */ + uint32_t PENDCH11:1; /*!< bit: 11 Pending Channel 11 */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t PENDCH:12; /*!< bit: 0..11 Pending Channel x */ + uint32_t :20; /*!< bit: 12..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_PENDCH_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_PENDCH_OFFSET 0x2C /**< \brief (DMAC_PENDCH offset) Pending Channels */ +#define DMAC_PENDCH_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_PENDCH reset_value) Pending Channels */ + +#define DMAC_PENDCH_PENDCH0_Pos 0 /**< \brief (DMAC_PENDCH) Pending Channel 0 */ +#define DMAC_PENDCH_PENDCH0 (_U_(1) << DMAC_PENDCH_PENDCH0_Pos) +#define DMAC_PENDCH_PENDCH1_Pos 1 /**< \brief (DMAC_PENDCH) Pending Channel 1 */ +#define DMAC_PENDCH_PENDCH1 (_U_(1) << DMAC_PENDCH_PENDCH1_Pos) +#define DMAC_PENDCH_PENDCH2_Pos 2 /**< \brief (DMAC_PENDCH) Pending Channel 2 */ +#define DMAC_PENDCH_PENDCH2 (_U_(1) << DMAC_PENDCH_PENDCH2_Pos) +#define DMAC_PENDCH_PENDCH3_Pos 3 /**< \brief (DMAC_PENDCH) Pending Channel 3 */ +#define DMAC_PENDCH_PENDCH3 (_U_(1) << DMAC_PENDCH_PENDCH3_Pos) +#define DMAC_PENDCH_PENDCH4_Pos 4 /**< \brief (DMAC_PENDCH) Pending Channel 4 */ +#define DMAC_PENDCH_PENDCH4 (_U_(1) << DMAC_PENDCH_PENDCH4_Pos) +#define DMAC_PENDCH_PENDCH5_Pos 5 /**< \brief (DMAC_PENDCH) Pending Channel 5 */ +#define DMAC_PENDCH_PENDCH5 (_U_(1) << DMAC_PENDCH_PENDCH5_Pos) +#define DMAC_PENDCH_PENDCH6_Pos 6 /**< \brief (DMAC_PENDCH) Pending Channel 6 */ +#define DMAC_PENDCH_PENDCH6 (_U_(1) << DMAC_PENDCH_PENDCH6_Pos) +#define DMAC_PENDCH_PENDCH7_Pos 7 /**< \brief (DMAC_PENDCH) Pending Channel 7 */ +#define DMAC_PENDCH_PENDCH7 (_U_(1) << DMAC_PENDCH_PENDCH7_Pos) +#define DMAC_PENDCH_PENDCH8_Pos 8 /**< \brief (DMAC_PENDCH) Pending Channel 8 */ +#define DMAC_PENDCH_PENDCH8 (_U_(1) << DMAC_PENDCH_PENDCH8_Pos) +#define DMAC_PENDCH_PENDCH9_Pos 9 /**< \brief (DMAC_PENDCH) Pending Channel 9 */ +#define DMAC_PENDCH_PENDCH9 (_U_(1) << DMAC_PENDCH_PENDCH9_Pos) +#define DMAC_PENDCH_PENDCH10_Pos 10 /**< \brief (DMAC_PENDCH) Pending Channel 10 */ +#define DMAC_PENDCH_PENDCH10 (_U_(1) << DMAC_PENDCH_PENDCH10_Pos) +#define DMAC_PENDCH_PENDCH11_Pos 11 /**< \brief (DMAC_PENDCH) Pending Channel 11 */ +#define DMAC_PENDCH_PENDCH11 (_U_(1) << DMAC_PENDCH_PENDCH11_Pos) +#define DMAC_PENDCH_PENDCH_Pos 0 /**< \brief (DMAC_PENDCH) Pending Channel x */ +#define DMAC_PENDCH_PENDCH_Msk (_U_(0xFFF) << DMAC_PENDCH_PENDCH_Pos) +#define DMAC_PENDCH_PENDCH(value) (DMAC_PENDCH_PENDCH_Msk & ((value) << DMAC_PENDCH_PENDCH_Pos)) +#define DMAC_PENDCH_MASK _U_(0x00000FFF) /**< \brief (DMAC_PENDCH) MASK Register */ + +/* -------- DMAC_ACTIVE : (DMAC Offset: 0x30) (R/ 32) Active Channel and Levels -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t LVLEX0:1; /*!< bit: 0 Level 0 Channel Trigger Request Executing */ + uint32_t LVLEX1:1; /*!< bit: 1 Level 1 Channel Trigger Request Executing */ + uint32_t LVLEX2:1; /*!< bit: 2 Level 2 Channel Trigger Request Executing */ + uint32_t LVLEX3:1; /*!< bit: 3 Level 3 Channel Trigger Request Executing */ + uint32_t :4; /*!< bit: 4.. 7 Reserved */ + uint32_t ID:5; /*!< bit: 8..12 Active Channel ID */ + uint32_t :2; /*!< bit: 13..14 Reserved */ + uint32_t ABUSY:1; /*!< bit: 15 Active Channel Busy */ + uint32_t BTCNT:16; /*!< bit: 16..31 Active Channel Block Transfer Count */ + } bit; /*!< Structure used for bit access */ + struct { + uint32_t LVLEX:4; /*!< bit: 0.. 3 Level x Channel Trigger Request Executing */ + uint32_t :28; /*!< bit: 4..31 Reserved */ + } vec; /*!< Structure used for vec access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_ACTIVE_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_ACTIVE_OFFSET 0x30 /**< \brief (DMAC_ACTIVE offset) Active Channel and Levels */ +#define DMAC_ACTIVE_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_ACTIVE reset_value) Active Channel and Levels */ + +#define DMAC_ACTIVE_LVLEX0_Pos 0 /**< \brief (DMAC_ACTIVE) Level 0 Channel Trigger Request Executing */ +#define DMAC_ACTIVE_LVLEX0 (_U_(1) << DMAC_ACTIVE_LVLEX0_Pos) +#define DMAC_ACTIVE_LVLEX1_Pos 1 /**< \brief (DMAC_ACTIVE) Level 1 Channel Trigger Request Executing */ +#define DMAC_ACTIVE_LVLEX1 (_U_(1) << DMAC_ACTIVE_LVLEX1_Pos) +#define DMAC_ACTIVE_LVLEX2_Pos 2 /**< \brief (DMAC_ACTIVE) Level 2 Channel Trigger Request Executing */ +#define DMAC_ACTIVE_LVLEX2 (_U_(1) << DMAC_ACTIVE_LVLEX2_Pos) +#define DMAC_ACTIVE_LVLEX3_Pos 3 /**< \brief (DMAC_ACTIVE) Level 3 Channel Trigger Request Executing */ +#define DMAC_ACTIVE_LVLEX3 (_U_(1) << DMAC_ACTIVE_LVLEX3_Pos) +#define DMAC_ACTIVE_LVLEX_Pos 0 /**< \brief (DMAC_ACTIVE) Level x Channel Trigger Request Executing */ +#define DMAC_ACTIVE_LVLEX_Msk (_U_(0xF) << DMAC_ACTIVE_LVLEX_Pos) +#define DMAC_ACTIVE_LVLEX(value) (DMAC_ACTIVE_LVLEX_Msk & ((value) << DMAC_ACTIVE_LVLEX_Pos)) +#define DMAC_ACTIVE_ID_Pos 8 /**< \brief (DMAC_ACTIVE) Active Channel ID */ +#define DMAC_ACTIVE_ID_Msk (_U_(0x1F) << DMAC_ACTIVE_ID_Pos) +#define DMAC_ACTIVE_ID(value) (DMAC_ACTIVE_ID_Msk & ((value) << DMAC_ACTIVE_ID_Pos)) +#define DMAC_ACTIVE_ABUSY_Pos 15 /**< \brief (DMAC_ACTIVE) Active Channel Busy */ +#define DMAC_ACTIVE_ABUSY (_U_(0x1) << DMAC_ACTIVE_ABUSY_Pos) +#define DMAC_ACTIVE_BTCNT_Pos 16 /**< \brief (DMAC_ACTIVE) Active Channel Block Transfer Count */ +#define DMAC_ACTIVE_BTCNT_Msk (_U_(0xFFFF) << DMAC_ACTIVE_BTCNT_Pos) +#define DMAC_ACTIVE_BTCNT(value) (DMAC_ACTIVE_BTCNT_Msk & ((value) << DMAC_ACTIVE_BTCNT_Pos)) +#define DMAC_ACTIVE_MASK _U_(0xFFFF9F0F) /**< \brief (DMAC_ACTIVE) MASK Register */ + +/* -------- DMAC_BASEADDR : (DMAC Offset: 0x34) (R/W 32) Descriptor Memory Section Base Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t BASEADDR:32; /*!< bit: 0..31 Descriptor Memory Base Address */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_BASEADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_BASEADDR_OFFSET 0x34 /**< \brief (DMAC_BASEADDR offset) Descriptor Memory Section Base Address */ +#define DMAC_BASEADDR_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_BASEADDR reset_value) Descriptor Memory Section Base Address */ + +#define DMAC_BASEADDR_BASEADDR_Pos 0 /**< \brief (DMAC_BASEADDR) Descriptor Memory Base Address */ +#define DMAC_BASEADDR_BASEADDR_Msk (_U_(0xFFFFFFFF) << DMAC_BASEADDR_BASEADDR_Pos) +#define DMAC_BASEADDR_BASEADDR(value) (DMAC_BASEADDR_BASEADDR_Msk & ((value) << DMAC_BASEADDR_BASEADDR_Pos)) +#define DMAC_BASEADDR_MASK _U_(0xFFFFFFFF) /**< \brief (DMAC_BASEADDR) MASK Register */ + +/* -------- DMAC_WRBADDR : (DMAC Offset: 0x38) (R/W 32) Write-Back Memory Section Base Address -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t WRBADDR:32; /*!< bit: 0..31 Write-Back Memory Base Address */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_WRBADDR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_WRBADDR_OFFSET 0x38 /**< \brief (DMAC_WRBADDR offset) Write-Back Memory Section Base Address */ +#define DMAC_WRBADDR_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_WRBADDR reset_value) Write-Back Memory Section Base Address */ + +#define DMAC_WRBADDR_WRBADDR_Pos 0 /**< \brief (DMAC_WRBADDR) Write-Back Memory Base Address */ +#define DMAC_WRBADDR_WRBADDR_Msk (_U_(0xFFFFFFFF) << DMAC_WRBADDR_WRBADDR_Pos) +#define DMAC_WRBADDR_WRBADDR(value) (DMAC_WRBADDR_WRBADDR_Msk & ((value) << DMAC_WRBADDR_WRBADDR_Pos)) +#define DMAC_WRBADDR_MASK _U_(0xFFFFFFFF) /**< \brief (DMAC_WRBADDR) MASK Register */ + +/* -------- DMAC_CHID : (DMAC Offset: 0x3F) (R/W 8) Channel ID -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t ID:4; /*!< bit: 0.. 3 Channel ID */ + uint8_t :4; /*!< bit: 4.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHID_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHID_OFFSET 0x3F /**< \brief (DMAC_CHID offset) Channel ID */ +#define DMAC_CHID_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHID reset_value) Channel ID */ + +#define DMAC_CHID_ID_Pos 0 /**< \brief (DMAC_CHID) Channel ID */ +#define DMAC_CHID_ID_Msk (_U_(0xF) << DMAC_CHID_ID_Pos) +#define DMAC_CHID_ID(value) (DMAC_CHID_ID_Msk & ((value) << DMAC_CHID_ID_Pos)) +#define DMAC_CHID_MASK _U_(0x0F) /**< \brief (DMAC_CHID) MASK Register */ + +/* -------- DMAC_CHCTRLA : (DMAC Offset: 0x40) (R/W 8) Channel Control A -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t SWRST:1; /*!< bit: 0 Channel Software Reset */ + uint8_t ENABLE:1; /*!< bit: 1 Channel Enable */ + uint8_t :6; /*!< bit: 2.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHCTRLA_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHCTRLA_OFFSET 0x40 /**< \brief (DMAC_CHCTRLA offset) Channel Control A */ +#define DMAC_CHCTRLA_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHCTRLA reset_value) Channel Control A */ + +#define DMAC_CHCTRLA_SWRST_Pos 0 /**< \brief (DMAC_CHCTRLA) Channel Software Reset */ +#define DMAC_CHCTRLA_SWRST (_U_(0x1) << DMAC_CHCTRLA_SWRST_Pos) +#define DMAC_CHCTRLA_ENABLE_Pos 1 /**< \brief (DMAC_CHCTRLA) Channel Enable */ +#define DMAC_CHCTRLA_ENABLE (_U_(0x1) << DMAC_CHCTRLA_ENABLE_Pos) +#define DMAC_CHCTRLA_MASK _U_(0x03) /**< \brief (DMAC_CHCTRLA) MASK Register */ + +/* -------- DMAC_CHCTRLB : (DMAC Offset: 0x44) (R/W 32) Channel Control B -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint32_t EVACT:3; /*!< bit: 0.. 2 Event Input Action */ + uint32_t EVIE:1; /*!< bit: 3 Channel Event Input Enable */ + uint32_t EVOE:1; /*!< bit: 4 Channel Event Output Enable */ + uint32_t LVL:2; /*!< bit: 5.. 6 Channel Arbitration Level */ + uint32_t :1; /*!< bit: 7 Reserved */ + uint32_t TRIGSRC:6; /*!< bit: 8..13 Trigger Source */ + uint32_t :8; /*!< bit: 14..21 Reserved */ + uint32_t TRIGACT:2; /*!< bit: 22..23 Trigger Action */ + uint32_t CMD:2; /*!< bit: 24..25 Software Command */ + uint32_t :6; /*!< bit: 26..31 Reserved */ + } bit; /*!< Structure used for bit access */ + uint32_t reg; /*!< Type used for register access */ +} DMAC_CHCTRLB_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHCTRLB_OFFSET 0x44 /**< \brief (DMAC_CHCTRLB offset) Channel Control B */ +#define DMAC_CHCTRLB_RESETVALUE _U_(0x00000000) /**< \brief (DMAC_CHCTRLB reset_value) Channel Control B */ + +#define DMAC_CHCTRLB_EVACT_Pos 0 /**< \brief (DMAC_CHCTRLB) Event Input Action */ +#define DMAC_CHCTRLB_EVACT_Msk (_U_(0x7) << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT(value) (DMAC_CHCTRLB_EVACT_Msk & ((value) << DMAC_CHCTRLB_EVACT_Pos)) +#define DMAC_CHCTRLB_EVACT_NOACT_Val _U_(0x0) /**< \brief (DMAC_CHCTRLB) No action */ +#define DMAC_CHCTRLB_EVACT_TRIG_Val _U_(0x1) /**< \brief (DMAC_CHCTRLB) Transfer and periodic transfer trigger */ +#define DMAC_CHCTRLB_EVACT_CTRIG_Val _U_(0x2) /**< \brief (DMAC_CHCTRLB) Conditional transfer trigger */ +#define DMAC_CHCTRLB_EVACT_CBLOCK_Val _U_(0x3) /**< \brief (DMAC_CHCTRLB) Conditional block transfer */ +#define DMAC_CHCTRLB_EVACT_SUSPEND_Val _U_(0x4) /**< \brief (DMAC_CHCTRLB) Channel suspend operation */ +#define DMAC_CHCTRLB_EVACT_RESUME_Val _U_(0x5) /**< \brief (DMAC_CHCTRLB) Channel resume operation */ +#define DMAC_CHCTRLB_EVACT_SSKIP_Val _U_(0x6) /**< \brief (DMAC_CHCTRLB) Skip next block suspend action */ +#define DMAC_CHCTRLB_EVACT_NOACT (DMAC_CHCTRLB_EVACT_NOACT_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_TRIG (DMAC_CHCTRLB_EVACT_TRIG_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_CTRIG (DMAC_CHCTRLB_EVACT_CTRIG_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_CBLOCK (DMAC_CHCTRLB_EVACT_CBLOCK_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_SUSPEND (DMAC_CHCTRLB_EVACT_SUSPEND_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_RESUME (DMAC_CHCTRLB_EVACT_RESUME_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVACT_SSKIP (DMAC_CHCTRLB_EVACT_SSKIP_Val << DMAC_CHCTRLB_EVACT_Pos) +#define DMAC_CHCTRLB_EVIE_Pos 3 /**< \brief (DMAC_CHCTRLB) Channel Event Input Enable */ +#define DMAC_CHCTRLB_EVIE (_U_(0x1) << DMAC_CHCTRLB_EVIE_Pos) +#define DMAC_CHCTRLB_EVOE_Pos 4 /**< \brief (DMAC_CHCTRLB) Channel Event Output Enable */ +#define DMAC_CHCTRLB_EVOE (_U_(0x1) << DMAC_CHCTRLB_EVOE_Pos) +#define DMAC_CHCTRLB_LVL_Pos 5 /**< \brief (DMAC_CHCTRLB) Channel Arbitration Level */ +#define DMAC_CHCTRLB_LVL_Msk (_U_(0x3) << DMAC_CHCTRLB_LVL_Pos) +#define DMAC_CHCTRLB_LVL(value) (DMAC_CHCTRLB_LVL_Msk & ((value) << DMAC_CHCTRLB_LVL_Pos)) +#define DMAC_CHCTRLB_LVL_LVL0_Val _U_(0x0) /**< \brief (DMAC_CHCTRLB) Channel Priority Level 0 */ +#define DMAC_CHCTRLB_LVL_LVL1_Val _U_(0x1) /**< \brief (DMAC_CHCTRLB) Channel Priority Level 1 */ +#define DMAC_CHCTRLB_LVL_LVL2_Val _U_(0x2) /**< \brief (DMAC_CHCTRLB) Channel Priority Level 2 */ +#define DMAC_CHCTRLB_LVL_LVL3_Val _U_(0x3) /**< \brief (DMAC_CHCTRLB) Channel Priority Level 3 */ +#define DMAC_CHCTRLB_LVL_LVL0 (DMAC_CHCTRLB_LVL_LVL0_Val << DMAC_CHCTRLB_LVL_Pos) +#define DMAC_CHCTRLB_LVL_LVL1 (DMAC_CHCTRLB_LVL_LVL1_Val << DMAC_CHCTRLB_LVL_Pos) +#define DMAC_CHCTRLB_LVL_LVL2 (DMAC_CHCTRLB_LVL_LVL2_Val << DMAC_CHCTRLB_LVL_Pos) +#define DMAC_CHCTRLB_LVL_LVL3 (DMAC_CHCTRLB_LVL_LVL3_Val << DMAC_CHCTRLB_LVL_Pos) +#define DMAC_CHCTRLB_TRIGSRC_Pos 8 /**< \brief (DMAC_CHCTRLB) Trigger Source */ +#define DMAC_CHCTRLB_TRIGSRC_Msk (_U_(0x3F) << DMAC_CHCTRLB_TRIGSRC_Pos) +#define DMAC_CHCTRLB_TRIGSRC(value) (DMAC_CHCTRLB_TRIGSRC_Msk & ((value) << DMAC_CHCTRLB_TRIGSRC_Pos)) +#define DMAC_CHCTRLB_TRIGSRC_DISABLE_Val _U_(0x0) /**< \brief (DMAC_CHCTRLB) Only software/event triggers */ +#define DMAC_CHCTRLB_TRIGSRC_DISABLE (DMAC_CHCTRLB_TRIGSRC_DISABLE_Val << DMAC_CHCTRLB_TRIGSRC_Pos) +#define DMAC_CHCTRLB_TRIGACT_Pos 22 /**< \brief (DMAC_CHCTRLB) Trigger Action */ +#define DMAC_CHCTRLB_TRIGACT_Msk (_U_(0x3) << DMAC_CHCTRLB_TRIGACT_Pos) +#define DMAC_CHCTRLB_TRIGACT(value) (DMAC_CHCTRLB_TRIGACT_Msk & ((value) << DMAC_CHCTRLB_TRIGACT_Pos)) +#define DMAC_CHCTRLB_TRIGACT_BLOCK_Val _U_(0x0) /**< \brief (DMAC_CHCTRLB) One trigger required for each block transfer */ +#define DMAC_CHCTRLB_TRIGACT_BEAT_Val _U_(0x2) /**< \brief (DMAC_CHCTRLB) One trigger required for each beat transfer */ +#define DMAC_CHCTRLB_TRIGACT_TRANSACTION_Val _U_(0x3) /**< \brief (DMAC_CHCTRLB) One trigger required for each transaction */ +#define DMAC_CHCTRLB_TRIGACT_BLOCK (DMAC_CHCTRLB_TRIGACT_BLOCK_Val << DMAC_CHCTRLB_TRIGACT_Pos) +#define DMAC_CHCTRLB_TRIGACT_BEAT (DMAC_CHCTRLB_TRIGACT_BEAT_Val << DMAC_CHCTRLB_TRIGACT_Pos) +#define DMAC_CHCTRLB_TRIGACT_TRANSACTION (DMAC_CHCTRLB_TRIGACT_TRANSACTION_Val << DMAC_CHCTRLB_TRIGACT_Pos) +#define DMAC_CHCTRLB_CMD_Pos 24 /**< \brief (DMAC_CHCTRLB) Software Command */ +#define DMAC_CHCTRLB_CMD_Msk (_U_(0x3) << DMAC_CHCTRLB_CMD_Pos) +#define DMAC_CHCTRLB_CMD(value) (DMAC_CHCTRLB_CMD_Msk & ((value) << DMAC_CHCTRLB_CMD_Pos)) +#define DMAC_CHCTRLB_CMD_NOACT_Val _U_(0x0) /**< \brief (DMAC_CHCTRLB) No action */ +#define DMAC_CHCTRLB_CMD_SUSPEND_Val _U_(0x1) /**< \brief (DMAC_CHCTRLB) Channel suspend operation */ +#define DMAC_CHCTRLB_CMD_RESUME_Val _U_(0x2) /**< \brief (DMAC_CHCTRLB) Channel resume operation */ +#define DMAC_CHCTRLB_CMD_NOACT (DMAC_CHCTRLB_CMD_NOACT_Val << DMAC_CHCTRLB_CMD_Pos) +#define DMAC_CHCTRLB_CMD_SUSPEND (DMAC_CHCTRLB_CMD_SUSPEND_Val << DMAC_CHCTRLB_CMD_Pos) +#define DMAC_CHCTRLB_CMD_RESUME (DMAC_CHCTRLB_CMD_RESUME_Val << DMAC_CHCTRLB_CMD_Pos) +#define DMAC_CHCTRLB_MASK _U_(0x03C03F7F) /**< \brief (DMAC_CHCTRLB) MASK Register */ + +/* -------- DMAC_CHINTENCLR : (DMAC Offset: 0x4C) (R/W 8) Channel Interrupt Enable Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t TERR:1; /*!< bit: 0 Channel Transfer Error Interrupt Enable */ + uint8_t TCMPL:1; /*!< bit: 1 Channel Transfer Complete Interrupt Enable */ + uint8_t SUSP:1; /*!< bit: 2 Channel Suspend Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHINTENCLR_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHINTENCLR_OFFSET 0x4C /**< \brief (DMAC_CHINTENCLR offset) Channel Interrupt Enable Clear */ +#define DMAC_CHINTENCLR_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHINTENCLR reset_value) Channel Interrupt Enable Clear */ + +#define DMAC_CHINTENCLR_TERR_Pos 0 /**< \brief (DMAC_CHINTENCLR) Channel Transfer Error Interrupt Enable */ +#define DMAC_CHINTENCLR_TERR (_U_(0x1) << DMAC_CHINTENCLR_TERR_Pos) +#define DMAC_CHINTENCLR_TCMPL_Pos 1 /**< \brief (DMAC_CHINTENCLR) Channel Transfer Complete Interrupt Enable */ +#define DMAC_CHINTENCLR_TCMPL (_U_(0x1) << DMAC_CHINTENCLR_TCMPL_Pos) +#define DMAC_CHINTENCLR_SUSP_Pos 2 /**< \brief (DMAC_CHINTENCLR) Channel Suspend Interrupt Enable */ +#define DMAC_CHINTENCLR_SUSP (_U_(0x1) << DMAC_CHINTENCLR_SUSP_Pos) +#define DMAC_CHINTENCLR_MASK _U_(0x07) /**< \brief (DMAC_CHINTENCLR) MASK Register */ + +/* -------- DMAC_CHINTENSET : (DMAC Offset: 0x4D) (R/W 8) Channel Interrupt Enable Set -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t TERR:1; /*!< bit: 0 Channel Transfer Error Interrupt Enable */ + uint8_t TCMPL:1; /*!< bit: 1 Channel Transfer Complete Interrupt Enable */ + uint8_t SUSP:1; /*!< bit: 2 Channel Suspend Interrupt Enable */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHINTENSET_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHINTENSET_OFFSET 0x4D /**< \brief (DMAC_CHINTENSET offset) Channel Interrupt Enable Set */ +#define DMAC_CHINTENSET_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHINTENSET reset_value) Channel Interrupt Enable Set */ + +#define DMAC_CHINTENSET_TERR_Pos 0 /**< \brief (DMAC_CHINTENSET) Channel Transfer Error Interrupt Enable */ +#define DMAC_CHINTENSET_TERR (_U_(0x1) << DMAC_CHINTENSET_TERR_Pos) +#define DMAC_CHINTENSET_TCMPL_Pos 1 /**< \brief (DMAC_CHINTENSET) Channel Transfer Complete Interrupt Enable */ +#define DMAC_CHINTENSET_TCMPL (_U_(0x1) << DMAC_CHINTENSET_TCMPL_Pos) +#define DMAC_CHINTENSET_SUSP_Pos 2 /**< \brief (DMAC_CHINTENSET) Channel Suspend Interrupt Enable */ +#define DMAC_CHINTENSET_SUSP (_U_(0x1) << DMAC_CHINTENSET_SUSP_Pos) +#define DMAC_CHINTENSET_MASK _U_(0x07) /**< \brief (DMAC_CHINTENSET) MASK Register */ + +/* -------- DMAC_CHINTFLAG : (DMAC Offset: 0x4E) (R/W 8) Channel Interrupt Flag Status and Clear -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { // __I to avoid read-modify-write on write-to-clear register + struct { + __I uint8_t TERR:1; /*!< bit: 0 Channel Transfer Error */ + __I uint8_t TCMPL:1; /*!< bit: 1 Channel Transfer Complete */ + __I uint8_t SUSP:1; /*!< bit: 2 Channel Suspend */ + __I uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHINTFLAG_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHINTFLAG_OFFSET 0x4E /**< \brief (DMAC_CHINTFLAG offset) Channel Interrupt Flag Status and Clear */ +#define DMAC_CHINTFLAG_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHINTFLAG reset_value) Channel Interrupt Flag Status and Clear */ + +#define DMAC_CHINTFLAG_TERR_Pos 0 /**< \brief (DMAC_CHINTFLAG) Channel Transfer Error */ +#define DMAC_CHINTFLAG_TERR (_U_(0x1) << DMAC_CHINTFLAG_TERR_Pos) +#define DMAC_CHINTFLAG_TCMPL_Pos 1 /**< \brief (DMAC_CHINTFLAG) Channel Transfer Complete */ +#define DMAC_CHINTFLAG_TCMPL (_U_(0x1) << DMAC_CHINTFLAG_TCMPL_Pos) +#define DMAC_CHINTFLAG_SUSP_Pos 2 /**< \brief (DMAC_CHINTFLAG) Channel Suspend */ +#define DMAC_CHINTFLAG_SUSP (_U_(0x1) << DMAC_CHINTFLAG_SUSP_Pos) +#define DMAC_CHINTFLAG_MASK _U_(0x07) /**< \brief (DMAC_CHINTFLAG) MASK Register */ + +/* -------- DMAC_CHSTATUS : (DMAC Offset: 0x4F) (R/ 8) Channel Status -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint8_t PEND:1; /*!< bit: 0 Channel Pending */ + uint8_t BUSY:1; /*!< bit: 1 Channel Busy */ + uint8_t FERR:1; /*!< bit: 2 Channel Fetch Error */ + uint8_t :5; /*!< bit: 3.. 7 Reserved */ + } bit; /*!< Structure used for bit access */ + uint8_t reg; /*!< Type used for register access */ +} DMAC_CHSTATUS_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_CHSTATUS_OFFSET 0x4F /**< \brief (DMAC_CHSTATUS offset) Channel Status */ +#define DMAC_CHSTATUS_RESETVALUE _U_(0x00) /**< \brief (DMAC_CHSTATUS reset_value) Channel Status */ + +#define DMAC_CHSTATUS_PEND_Pos 0 /**< \brief (DMAC_CHSTATUS) Channel Pending */ +#define DMAC_CHSTATUS_PEND (_U_(0x1) << DMAC_CHSTATUS_PEND_Pos) +#define DMAC_CHSTATUS_BUSY_Pos 1 /**< \brief (DMAC_CHSTATUS) Channel Busy */ +#define DMAC_CHSTATUS_BUSY (_U_(0x1) << DMAC_CHSTATUS_BUSY_Pos) +#define DMAC_CHSTATUS_FERR_Pos 2 /**< \brief (DMAC_CHSTATUS) Channel Fetch Error */ +#define DMAC_CHSTATUS_FERR (_U_(0x1) << DMAC_CHSTATUS_FERR_Pos) +#define DMAC_CHSTATUS_MASK _U_(0x07) /**< \brief (DMAC_CHSTATUS) MASK Register */ + +/* -------- DMAC_BTCTRL : (DMAC Offset: 0x00) (R/W 16) Block Transfer Control -------- */ +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +typedef union { + struct { + uint16_t VALID:1; /*!< bit: 0 Descriptor Valid */ + uint16_t EVOSEL:2; /*!< bit: 1.. 2 Event Output Selection */ + uint16_t BLOCKACT:2; /*!< bit: 3.. 4 Block Action */ + uint16_t :3; /*!< bit: 5.. 7 Reserved */ + uint16_t BEATSIZE:2; /*!< bit: 8.. 9 Beat Size */ + uint16_t SRCINC:1; /*!< bit: 10 Source Address Increment Enable */ + uint16_t DSTINC:1; /*!< bit: 11 Destination Address Increment Enable */ + uint16_t STEPSEL:1; /*!< bit: 12 Step Selection */ + uint16_t STEPSIZE:3; /*!< bit: 13..15 Address Increment Step Size */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} DMAC_BTCTRL_Type; +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#define DMAC_BTCTRL_OFFSET 0x00 /**< \brief (DMAC_BTCTRL offset) Block Transfer Control */ +#define DMAC_BTCTRL_RESETVALUE _U_(0x0000) /**< \brief (DMAC_BTCTRL reset_value) Block Transfer Control */ + +#define DMAC_BTCTRL_VALID_Pos 0 /**< \brief (DMAC_BTCTRL) Descriptor Valid */ +#define DMAC_BTCTRL_VALID (_U_(0x1) << DMAC_BTCTRL_VALID_Pos) +#define DMAC_BTCTRL_EVOSEL_Pos 1 /**< \brief (DMAC_BTCTRL) Event Output Selection */ +#define DMAC_BTCTRL_EVOSEL_Msk (_U_(0x3) << DMAC_BTCTRL_EVOSEL_Pos) +#define DMAC_BTCTRL_EVOSEL(value) (DMAC_BTCTRL_EVOSEL_Msk & ((value) << DMAC_BTCTRL_EVOSEL_Pos)) +#define DMAC_BTCTRL_EVOSEL_DISABLE_Val _U_(0x0) /**< \brief (DMAC_BTCTRL) Event generation disabled */ +#define DMAC_BTCTRL_EVOSEL_BLOCK_Val _U_(0x1) /**< \brief (DMAC_BTCTRL) Event strobe when block transfer complete */ +#define DMAC_BTCTRL_EVOSEL_BEAT_Val _U_(0x3) /**< \brief (DMAC_BTCTRL) Event strobe when beat transfer complete */ +#define DMAC_BTCTRL_EVOSEL_DISABLE (DMAC_BTCTRL_EVOSEL_DISABLE_Val << DMAC_BTCTRL_EVOSEL_Pos) +#define DMAC_BTCTRL_EVOSEL_BLOCK (DMAC_BTCTRL_EVOSEL_BLOCK_Val << DMAC_BTCTRL_EVOSEL_Pos) +#define DMAC_BTCTRL_EVOSEL_BEAT (DMAC_BTCTRL_EVOSEL_BEAT_Val << DMAC_BTCTRL_EVOSEL_Pos) +#define DMAC_BTCTRL_BLOCKACT_Pos 3 /**< \brief (DMAC_BTCTRL) Block Action */ +#define DMAC_BTCTRL_BLOCKACT_Msk (_U_(0x3) << DMAC_BTCTRL_BLOCKACT_Pos) +#define DMAC_BTCTRL_BLOCKACT(value) (DMAC_BTCTRL_BLOCKACT_Msk & ((value) << DMAC_BTCTRL_BLOCKACT_Pos)) +#define DMAC_BTCTRL_BLOCKACT_NOACT_Val _U_(0x0) /**< \brief (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction */ +#define DMAC_BTCTRL_BLOCKACT_INT_Val _U_(0x1) /**< \brief (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction and block interrupt */ +#define DMAC_BTCTRL_BLOCKACT_SUSPEND_Val _U_(0x2) /**< \brief (DMAC_BTCTRL) Channel suspend operation is completed */ +#define DMAC_BTCTRL_BLOCKACT_BOTH_Val _U_(0x3) /**< \brief (DMAC_BTCTRL) Both channel suspend operation and block interrupt */ +#define DMAC_BTCTRL_BLOCKACT_NOACT (DMAC_BTCTRL_BLOCKACT_NOACT_Val << DMAC_BTCTRL_BLOCKACT_Pos) +#define DMAC_BTCTRL_BLOCKACT_INT (DMAC_BTCTRL_BLOCKACT_INT_Val << DMAC_BTCTRL_BLOCKACT_Pos) +#define DMAC_BTCTRL_BLOCKACT_SUSPEND (DMAC_BTCTRL_BLOCKACT_SUSPEND_Val << DMAC_BTCTRL_BLOCKACT_Pos) +#define DMAC_BTCTRL_BLOCKACT_BOTH (DMAC_BTCTRL_BLOCKACT_BOTH_Val << DMAC_BTCTRL_BLOCKACT_Pos) +#define DMAC_BTCTRL_BEATSIZE_Pos 8 /**< \brief (DMAC_BTCTRL) Beat Size */ +#define DMAC_BTCTRL_BEATSIZE_Msk (_U_(0x3) << DMAC_BTCTRL_BEATSIZE_Pos) +#define DMAC_BTCTRL_BEATSIZE(value) (DMAC_BTCTRL_BEATSIZE_Msk & ((value) << DMAC_BTCTRL_BEATSIZE_Pos)) +#define DMAC_BTCTRL_BEATSIZE_BYTE_Val _U_(0x0) /**< \brief (DMAC_BTCTRL) 8-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_HWORD_Val _U_(0x1) /**< \brief (DMAC_BTCTRL) 16-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_WORD_Val _U_(0x2) /**< \brief (DMAC_BTCTRL) 32-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_BYTE (DMAC_BTCTRL_BEATSIZE_BYTE_Val << DMAC_BTCTRL_BEATSIZE_Pos) +#define DMAC_BTCTRL_BEATSIZE_HWORD (DMAC_BTCTRL_BEATSIZE_HWORD_Val << DMAC_BTCTRL_BEATSIZE_Pos) +#define DMAC_BTCTRL_BEATSIZE_WORD (DMAC_BTCTRL_BEATSIZE_WORD_Val << DMAC_BTCTRL_BEATSIZE_Pos) +#define DMAC_BTCTRL_SRCINC_Pos 10 /**< \brief (DMAC_BTCTRL) Source Address Increment Enable */ +#define DMAC_BTCTRL_SRCINC (_U_(0x1) << DMAC_BTCTRL_SRCINC_Pos) +#define DMAC_BTCTRL_DSTINC_Pos 11 /**< \brief (DMAC_BTCTRL) Destination Address Increment Enable */ +#define DMAC_BTCTRL_DSTINC (_U_(0x1) << DMAC_BTCTRL_DSTINC_Pos) +#define DMAC_BTCTRL_STEPSEL_Pos 12 /**< \brief (DMAC_BTCTRL) Step Selection */ +#define DMAC_BTCTRL_STEPSEL (_U_(0x1) << DMAC_BTCTRL_STEPSEL_Pos) +#define DMAC_BTCTRL_STEPSEL_DST_Val _U_(0x0) /**< \brief (DMAC_BTCTRL) Step size settings apply to the destination address */ +#define DMAC_BTCTRL_STEPSEL_SRC_Val _U_(0x1) /**< \brief (DMAC_BTCTRL) Step size settings apply to the source address */ +#define DMAC_BTCTRL_STEPSEL_DST (DMAC_BTCTRL_STEPSEL_DST_Val << DMAC_BTCTRL_STEPSEL_Pos) +#define DMAC_BTCTRL_STEPSEL_SRC (DMAC_BTCTRL_STEPSEL_SRC_Val << DMAC_BTCTRL_STEPSEL_Pos) +#define DMAC_BTCTRL_STEPSIZE_Pos 13 /**< \brief (DMAC_BTCTRL) Address Increment Step Size */ +#define DMAC_BTCTRL_STEPSIZE_Msk (_U_(0x7) << DMAC_BTCTRL_STEPSIZE_Pos) +#define DMAC_BTCTRL_STEPSIZE(value) (DMAC_BTCTRL_STEPSIZE_Msk & ((value) << DMAC_BTCTRL_STEPSIZE_Pos)) +#define DMAC_BTCTRL_STEPSIZE_X1_Val _U_(0x0) /**< \brief (DMAC_BTCTRL) Next ADDR = ADDR + (1< +#ifndef __cplusplus +typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile const uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#else +typedef volatile uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef volatile uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef volatile uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +#endif +typedef volatile uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#endif + +#if !defined(SKIP_INTEGER_LITERALS) +#if defined(_U_) || defined(_L_) || defined(_UL_) + #error "Integer Literals macros already defined elsewhere" +#endif + +#if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +/* Macros that deal with adding suffixes to integer literal constants for C/C++ */ +#define _U_(x) x ## U /**< C code: Unsigned integer literal constant value */ +#define _L_(x) x ## L /**< C code: Long integer literal constant value */ +#define _UL_(x) x ## UL /**< C code: Unsigned Long integer literal constant value */ +#else /* Assembler */ +#define _U_(x) x /**< Assembler: Unsigned integer literal constant value */ +#define _L_(x) x /**< Assembler: Long integer literal constant value */ +#define _UL_(x) x /**< Assembler: Unsigned Long integer literal constant value */ +#endif /* !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +#endif /* SKIP_INTEGER_LITERALS */ + +/* ************************************************************************** */ +/** CMSIS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_cmsis CMSIS Definitions */ +/*@{*/ + +/** Interrupt Number Definition */ +typedef enum IRQn +{ + /****** Cortex-M0+ Processor Exceptions Numbers *******************/ + NonMaskableInt_IRQn = -14,/**< 2 Non Maskable Interrupt */ + HardFault_IRQn = -13,/**< 3 Hard Fault Interrupt */ + SVCall_IRQn = -5, /**< 11 SV Call Interrupt */ + PendSV_IRQn = -2, /**< 14 Pend SV Interrupt */ + SysTick_IRQn = -1, /**< 15 System Tick Interrupt */ + /****** SAMD21E18A-specific Interrupt Numbers *********************/ + PM_IRQn = 0, /**< 0 SAMD21E18A Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 SAMD21E18A System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 SAMD21E18A Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 SAMD21E18A Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 SAMD21E18A External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 SAMD21E18A Non-Volatile Memory Controller (NVMCTRL) */ + DMAC_IRQn = 6, /**< 6 SAMD21E18A Direct Memory Access Controller (DMAC) */ + USB_IRQn = 7, /**< 7 SAMD21E18A Universal Serial Bus (USB) */ + EVSYS_IRQn = 8, /**< 8 SAMD21E18A Event System Interface (EVSYS) */ + SERCOM0_IRQn = 9, /**< 9 SAMD21E18A Serial Communication Interface 0 (SERCOM0) */ + SERCOM1_IRQn = 10, /**< 10 SAMD21E18A Serial Communication Interface 1 (SERCOM1) */ + SERCOM2_IRQn = 11, /**< 11 SAMD21E18A Serial Communication Interface 2 (SERCOM2) */ + SERCOM3_IRQn = 12, /**< 12 SAMD21E18A Serial Communication Interface 3 (SERCOM3) */ + TCC0_IRQn = 15, /**< 15 SAMD21E18A Timer Counter Control 0 (TCC0) */ + TCC1_IRQn = 16, /**< 16 SAMD21E18A Timer Counter Control 1 (TCC1) */ + TCC2_IRQn = 17, /**< 17 SAMD21E18A Timer Counter Control 2 (TCC2) */ + TC3_IRQn = 18, /**< 18 SAMD21E18A Basic Timer Counter 3 (TC3) */ + TC4_IRQn = 19, /**< 19 SAMD21E18A Basic Timer Counter 4 (TC4) */ + TC5_IRQn = 20, /**< 20 SAMD21E18A Basic Timer Counter 5 (TC5) */ + ADC_IRQn = 23, /**< 23 SAMD21E18A Analog Digital Converter (ADC) */ + AC_IRQn = 24, /**< 24 SAMD21E18A Analog Comparators (AC) */ + DAC_IRQn = 25, /**< 25 SAMD21E18A Digital Analog Converter (DAC) */ + PTC_IRQn = 26, /**< 26 SAMD21E18A Peripheral Touch Controller (PTC) */ + I2S_IRQn = 27, /**< 27 SAMD21E18A Inter-IC Sound Interface (I2S) */ + + PERIPH_COUNT_IRQn = 28 /**< Number of peripheral IDs */ +} IRQn_Type; + +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + + /* Cortex-M handlers */ + void* pfnReset_Handler; + void* pfnNonMaskableInt_Handler; + void* pfnHardFault_Handler; + void* pvReservedM12; + void* pvReservedM11; + void* pvReservedM10; + void* pvReservedM9; + void* pvReservedM8; + void* pvReservedM7; + void* pvReservedM6; + void* pfnSVCall_Handler; + void* pvReservedM4; + void* pvReservedM3; + void* pfnPendSV_Handler; + void* pfnSysTick_Handler; + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager */ + void* pfnSYSCTRL_Handler; /* 1 System Control */ + void* pfnWDT_Handler; /* 2 Watchdog Timer */ + void* pfnRTC_Handler; /* 3 Real-Time Counter */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller */ + void* pfnDMAC_Handler; /* 6 Direct Memory Access Controller */ + void* pfnUSB_Handler; /* 7 Universal Serial Bus */ + void* pfnEVSYS_Handler; /* 8 Event System Interface */ + void* pfnSERCOM0_Handler; /* 9 Serial Communication Interface 0 */ + void* pfnSERCOM1_Handler; /* 10 Serial Communication Interface 1 */ + void* pfnSERCOM2_Handler; /* 11 Serial Communication Interface 2 */ + void* pfnSERCOM3_Handler; /* 12 Serial Communication Interface 3 */ + void* pvReserved13; + void* pvReserved14; + void* pfnTCC0_Handler; /* 15 Timer Counter Control 0 */ + void* pfnTCC1_Handler; /* 16 Timer Counter Control 1 */ + void* pfnTCC2_Handler; /* 17 Timer Counter Control 2 */ + void* pfnTC3_Handler; /* 18 Basic Timer Counter 3 */ + void* pfnTC4_Handler; /* 19 Basic Timer Counter 4 */ + void* pfnTC5_Handler; /* 20 Basic Timer Counter 5 */ + void* pvReserved21; + void* pvReserved22; + void* pfnADC_Handler; /* 23 Analog Digital Converter */ + void* pfnAC_Handler; /* 24 Analog Comparators */ + void* pfnDAC_Handler; /* 25 Digital Analog Converter */ + void* pfnPTC_Handler; /* 26 Peripheral Touch Controller */ + void* pfnI2S_Handler; /* 27 Inter-IC Sound Interface */ + void* pvReserved28; +} DeviceVectors; + +/* Cortex-M0+ processor handlers */ +void Reset_Handler ( void ); +void NonMaskableInt_Handler ( void ); +void HardFault_Handler ( void ); +void SVCall_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); + +/* Peripherals handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void DMAC_Handler ( void ); +void USB_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TCC0_Handler ( void ); +void TCC1_Handler ( void ); +void TCC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); +void I2S_Handler ( void ); + +/* + * \brief Configuration of the Cortex-M0+ Processor and Core Peripherals + */ + +#define __CM0PLUS_REV 1 /*!< Core revision r0p1 */ +#define __MPU_PRESENT 0 /*!< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /*!< Number of bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /*!< VTOR present or not */ +#define __Vendor_SysTickConfig 0 /*!< Set to 1 if different SysTick Config is used */ + +/** + * \brief CMSIS includes + */ + +#include +#if !defined DONT_USE_CMSIS_INIT +#include "system_samd21.h" +#endif /* DONT_USE_CMSIS_INIT */ + +/*@}*/ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_api Peripheral Software API */ +/*@{*/ + +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dmac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/hmatrixb.h" +#include "component/i2s.h" +#include "component/mtb.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/tcc.h" +#include "component/usb.h" +#include "component/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** REGISTERS ACCESS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_reg Registers Access Definitions */ +/*@{*/ + +#include "instance/ac.h" +#include "instance/adc.h" +#include "instance/dac.h" +#include "instance/dmac.h" +#include "instance/dsu.h" +#include "instance/eic.h" +#include "instance/evsys.h" +#include "instance/gclk.h" +#include "instance/sbmatrix.h" +#include "instance/i2s.h" +#include "instance/mtb.h" +#include "instance/nvmctrl.h" +#include "instance/pac0.h" +#include "instance/pac1.h" +#include "instance/pac2.h" +#include "instance/pm.h" +#include "instance/port.h" +#include "instance/ptc.h" +#include "instance/rtc.h" +#include "instance/sercom0.h" +#include "instance/sercom1.h" +#include "instance/sercom2.h" +#include "instance/sercom3.h" +#include "instance/sysctrl.h" +#include "instance/tc3.h" +#include "instance/tc4.h" +#include "instance/tc5.h" +#include "instance/tcc0.h" +#include "instance/tcc1.h" +#include "instance/tcc2.h" +#include "instance/usb.h" +#include "instance/wdt.h" +/*@}*/ + +/* ************************************************************************** */ +/** PERIPHERAL ID DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_id Peripheral Ids Definitions */ +/*@{*/ + +// Peripheral instances on HPB0 bridge +#define ID_PAC0 0 /**< \brief Peripheral Access Controller 0 (PAC0) */ +#define ID_PM 1 /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL 2 /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK 3 /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT 4 /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC 5 /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC 6 /**< \brief External Interrupt Controller (EIC) */ + +// Peripheral instances on HPB1 bridge +#define ID_PAC1 32 /**< \brief Peripheral Access Controller 1 (PAC1) */ +#define ID_DSU 33 /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL 34 /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT 35 /**< \brief Port Module (PORT) */ +#define ID_DMAC 36 /**< \brief Direct Memory Access Controller (DMAC) */ +#define ID_USB 37 /**< \brief Universal Serial Bus (USB) */ +#define ID_MTB 38 /**< \brief Cortex-M0+ Micro-Trace Buffer (MTB) */ +#define ID_SBMATRIX 39 /**< \brief HSB Matrix (SBMATRIX) */ + +// Peripheral instances on HPB2 bridge +#define ID_PAC2 64 /**< \brief Peripheral Access Controller 2 (PAC2) */ +#define ID_EVSYS 65 /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 66 /**< \brief Serial Communication Interface 0 (SERCOM0) */ +#define ID_SERCOM1 67 /**< \brief Serial Communication Interface 1 (SERCOM1) */ +#define ID_SERCOM2 68 /**< \brief Serial Communication Interface 2 (SERCOM2) */ +#define ID_SERCOM3 69 /**< \brief Serial Communication Interface 3 (SERCOM3) */ +#define ID_TCC0 72 /**< \brief Timer Counter Control 0 (TCC0) */ +#define ID_TCC1 73 /**< \brief Timer Counter Control 1 (TCC1) */ +#define ID_TCC2 74 /**< \brief Timer Counter Control 2 (TCC2) */ +#define ID_TC3 75 /**< \brief Basic Timer Counter 3 (TC3) */ +#define ID_TC4 76 /**< \brief Basic Timer Counter 4 (TC4) */ +#define ID_TC5 77 /**< \brief Basic Timer Counter 5 (TC5) */ +#define ID_ADC 80 /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC 81 /**< \brief Analog Comparators (AC) */ +#define ID_DAC 82 /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC 83 /**< \brief Peripheral Touch Controller (PTC) */ +#define ID_I2S 84 /**< \brief Inter-IC Sound Interface (I2S) */ + +#define ID_PERIPH_COUNT 85 /**< \brief Max number of peripheral IDs */ +/*@}*/ + +/* ************************************************************************** */ +/** BASE ADDRESS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_base Peripheral Base Address Definitions */ +/*@{*/ + +#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#define AC (0x42004400) /**< \brief (AC) APB Base Address */ +#define ADC (0x42004000) /**< \brief (ADC) APB Base Address */ +#define DAC (0x42004800) /**< \brief (DAC) APB Base Address */ +#define DMAC (0x41004800) /**< \brief (DMAC) APB Base Address */ +#define DSU (0x41002000) /**< \brief (DSU) APB Base Address */ +#define EIC (0x40001800) /**< \brief (EIC) APB Base Address */ +#define EVSYS (0x42000400) /**< \brief (EVSYS) APB Base Address */ +#define GCLK (0x40000C00) /**< \brief (GCLK) APB Base Address */ +#define SBMATRIX (0x41007000) /**< \brief (SBMATRIX) APB Base Address */ +#define I2S (0x42005000) /**< \brief (I2S) APB Base Address */ +#define MTB (0x41006000) /**< \brief (MTB) APB Base Address */ +#define NVMCTRL (0x41004000) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000) /**< \brief (NVMCTRL) USER Base Address */ +#define PAC0 (0x40000000) /**< \brief (PAC0) APB Base Address */ +#define PAC1 (0x41000000) /**< \brief (PAC1) APB Base Address */ +#define PAC2 (0x42000000) /**< \brief (PAC2) APB Base Address */ +#define PM (0x40000400) /**< \brief (PM) APB Base Address */ +#define PORT (0x41004400) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS (0x60000000) /**< \brief (PORT) IOBUS Base Address */ +#define PTC (0x42004C00) /**< \brief (PTC) APB Base Address */ +#define RTC (0x40001400) /**< \brief (RTC) APB Base Address */ +#define SERCOM0 (0x42000800) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 (0x42000C00) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 (0x42001000) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 (0x42001400) /**< \brief (SERCOM3) APB Base Address */ +#define SYSCTRL (0x40000800) /**< \brief (SYSCTRL) APB Base Address */ +#define TC3 (0x42002C00) /**< \brief (TC3) APB Base Address */ +#define TC4 (0x42003000) /**< \brief (TC4) APB Base Address */ +#define TC5 (0x42003400) /**< \brief (TC5) APB Base Address */ +#define TCC0 (0x42002000) /**< \brief (TCC0) APB Base Address */ +#define TCC1 (0x42002400) /**< \brief (TCC1) APB Base Address */ +#define TCC2 (0x42002800) /**< \brief (TCC2) APB Base Address */ +#define USB (0x41005000) /**< \brief (USB) APB Base Address */ +#define WDT (0x40001000) /**< \brief (WDT) APB Base Address */ +#else +#define AC ((Ac *)0x42004400UL) /**< \brief (AC) APB Base Address */ +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define AC_INSTS { AC } /**< \brief (AC) Instances List */ + +#define ADC ((Adc *)0x42004000UL) /**< \brief (ADC) APB Base Address */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define ADC_INSTS { ADC } /**< \brief (ADC) Instances List */ + +#define DAC ((Dac *)0x42004800UL) /**< \brief (DAC) APB Base Address */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DAC_INSTS { DAC } /**< \brief (DAC) Instances List */ + +#define DMAC ((Dmac *)0x41004800UL) /**< \brief (DMAC) APB Base Address */ +#define DMAC_INST_NUM 1 /**< \brief (DMAC) Number of instances */ +#define DMAC_INSTS { DMAC } /**< \brief (DMAC) Instances List */ + +#define DSU ((Dsu *)0x41002000UL) /**< \brief (DSU) APB Base Address */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define DSU_INSTS { DSU } /**< \brief (DSU) Instances List */ + +#define EIC ((Eic *)0x40001800UL) /**< \brief (EIC) APB Base Address */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EIC_INSTS { EIC } /**< \brief (EIC) Instances List */ + +#define EVSYS ((Evsys *)0x42000400UL) /**< \brief (EVSYS) APB Base Address */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define EVSYS_INSTS { EVSYS } /**< \brief (EVSYS) Instances List */ + +#define GCLK ((Gclk *)0x40000C00UL) /**< \brief (GCLK) APB Base Address */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define GCLK_INSTS { GCLK } /**< \brief (GCLK) Instances List */ + +#define SBMATRIX ((Hmatrixb *)0x41007000UL) /**< \brief (SBMATRIX) APB Base Address */ +#define HMATRIXB_INST_NUM 1 /**< \brief (HMATRIXB) Number of instances */ +#define HMATRIXB_INSTS { SBMATRIX } /**< \brief (HMATRIXB) Instances List */ + +#define I2S ((I2s *)0x42005000UL) /**< \brief (I2S) APB Base Address */ +#define I2S_INST_NUM 1 /**< \brief (I2S) Number of instances */ +#define I2S_INSTS { I2S } /**< \brief (I2S) Instances List */ + +#define MTB ((Mtb *)0x41006000UL) /**< \brief (MTB) APB Base Address */ +#define MTB_INST_NUM 1 /**< \brief (MTB) Number of instances */ +#define MTB_INSTS { MTB } /**< \brief (MTB) Instances List */ + +#define NVMCTRL ((Nvmctrl *)0x41004000UL) /**< \brief (NVMCTRL) APB Base Address */ +#define NVMCTRL_CAL (0x00800000UL) /**< \brief (NVMCTRL) CAL Base Address */ +#define NVMCTRL_LOCKBIT (0x00802000UL) /**< \brief (NVMCTRL) LOCKBIT Base Address */ +#define NVMCTRL_OTP1 (0x00806000UL) /**< \brief (NVMCTRL) OTP1 Base Address */ +#define NVMCTRL_OTP2 (0x00806008UL) /**< \brief (NVMCTRL) OTP2 Base Address */ +#define NVMCTRL_OTP4 (0x00806020UL) /**< \brief (NVMCTRL) OTP4 Base Address */ +#define NVMCTRL_TEMP_LOG (0x00806030UL) /**< \brief (NVMCTRL) TEMP_LOG Base Address */ +#define NVMCTRL_USER (0x00804000UL) /**< \brief (NVMCTRL) USER Base Address */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define NVMCTRL_INSTS { NVMCTRL } /**< \brief (NVMCTRL) Instances List */ + +#define PAC0 ((Pac *)0x40000000UL) /**< \brief (PAC0) APB Base Address */ +#define PAC1 ((Pac *)0x41000000UL) /**< \brief (PAC1) APB Base Address */ +#define PAC2 ((Pac *)0x42000000UL) /**< \brief (PAC2) APB Base Address */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PAC_INSTS { PAC0, PAC1, PAC2 } /**< \brief (PAC) Instances List */ + +#define PM ((Pm *)0x40000400UL) /**< \brief (PM) APB Base Address */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PM_INSTS { PM } /**< \brief (PM) Instances List */ + +#define PORT ((Port *)0x41004400UL) /**< \brief (PORT) APB Base Address */ +#define PORT_IOBUS ((Port *)0x60000000UL) /**< \brief (PORT) IOBUS Base Address */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_INSTS { PORT } /**< \brief (PORT) Instances List */ +#define PORT_IOBUS_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_IOBUS_INSTS { PORT_IOBUS } /**< \brief (PORT) Instances List */ + +#define PTC ((void *)0x42004C00UL) /**< \brief (PTC) APB Base Address */ +#define PTC_GCLK_ID 34 +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define PTC_INSTS { PTC } /**< \brief (PTC) Instances List */ + +#define RTC ((Rtc *)0x40001400UL) /**< \brief (RTC) APB Base Address */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define RTC_INSTS { RTC } /**< \brief (RTC) Instances List */ + +#define SERCOM0 ((Sercom *)0x42000800UL) /**< \brief (SERCOM0) APB Base Address */ +#define SERCOM1 ((Sercom *)0x42000C00UL) /**< \brief (SERCOM1) APB Base Address */ +#define SERCOM2 ((Sercom *)0x42001000UL) /**< \brief (SERCOM2) APB Base Address */ +#define SERCOM3 ((Sercom *)0x42001400UL) /**< \brief (SERCOM3) APB Base Address */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SERCOM_INSTS { SERCOM0, SERCOM1, SERCOM2, SERCOM3 } /**< \brief (SERCOM) Instances List */ + +#define SYSCTRL ((Sysctrl *)0x40000800UL) /**< \brief (SYSCTRL) APB Base Address */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define SYSCTRL_INSTS { SYSCTRL } /**< \brief (SYSCTRL) Instances List */ + +#define TC3 ((Tc *)0x42002C00UL) /**< \brief (TC3) APB Base Address */ +#define TC4 ((Tc *)0x42003000UL) /**< \brief (TC4) APB Base Address */ +#define TC5 ((Tc *)0x42003400UL) /**< \brief (TC5) APB Base Address */ +#define TC_INST_NUM 3 /**< \brief (TC) Number of instances */ +#define TC_INSTS { TC3, TC4, TC5 } /**< \brief (TC) Instances List */ + +#define TCC0 ((Tcc *)0x42002000UL) /**< \brief (TCC0) APB Base Address */ +#define TCC1 ((Tcc *)0x42002400UL) /**< \brief (TCC1) APB Base Address */ +#define TCC2 ((Tcc *)0x42002800UL) /**< \brief (TCC2) APB Base Address */ +#define TCC_INST_NUM 3 /**< \brief (TCC) Number of instances */ +#define TCC_INSTS { TCC0, TCC1, TCC2 } /**< \brief (TCC) Instances List */ + +#define USB ((Usb *)0x41005000UL) /**< \brief (USB) APB Base Address */ +#define USB_INST_NUM 1 /**< \brief (USB) Number of instances */ +#define USB_INSTS { USB } /**< \brief (USB) Instances List */ + +#define WDT ((Wdt *)0x40001000UL) /**< \brief (WDT) APB Base Address */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ +#define WDT_INSTS { WDT } /**< \brief (WDT) Instances List */ + +#endif /* (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) */ +/*@}*/ + +/* ************************************************************************** */ +/** PORT DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +/** \defgroup SAMD21E18A_port PORT Definitions */ +/*@{*/ + +#include "pio/samd21e18a.h" +/*@}*/ + +/* ************************************************************************** */ +/** MEMORY MAPPING DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ + +#define FLASH_SIZE _UL_(0x00040000) /* 256 kB */ +#define FLASH_PAGE_SIZE 64 +#define FLASH_NB_OF_PAGES 4096 +#define FLASH_USER_PAGE_SIZE 64 +#define HMCRAMC0_SIZE _UL_(0x00008000) /* 32 kB */ + +#define FLASH_ADDR _UL_(0x00000000) /**< FLASH base address */ +#define FLASH_USER_PAGE_ADDR _UL_(0x00800000) /**< FLASH_USER_PAGE base address */ +#define HMCRAMC0_ADDR _UL_(0x20000000) /**< HMCRAMC0 base address */ +#define HPB0_ADDR _UL_(0x40000000) /**< HPB0 base address */ +#define HPB1_ADDR _UL_(0x41000000) /**< HPB1 base address */ +#define HPB2_ADDR _UL_(0x42000000) /**< HPB2 base address */ +#define PPB_ADDR _UL_(0xE0000000) /**< PPB base address */ + +#define DSU_DID_RESETVALUE _UL_(0x1001030A) +#define EIC_EXTINT_NUM 16 +#define PORT_GROUPS 1 + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ + + +#ifdef __cplusplus +} +#endif + +/*@}*/ + +#endif /* SAMD21E18A_H */ diff --git a/core/arm/samd21a/include/system_samd21.h b/core/arm/samd21a/include/system_samd21.h new file mode 100644 index 000000000..de6f4f1ed --- /dev/null +++ b/core/arm/samd21a/include/system_samd21.h @@ -0,0 +1,48 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon chip startup + * + * Copyright (c) 2018 Microchip Technology Inc. + * + * \asf_license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the Licence at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an AS IS BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \asf_license_stop + * + */ + +#ifndef _SYSTEM_SAMD21_H_INCLUDED_ +#define _SYSTEM_SAMD21_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +void SystemInit(void); +void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_SAMD21_H_INCLUDED */ diff --git a/core/arm/samd21a/include_mcc/component-version.h b/core/arm/samd21a/include_mcc/component-version.h new file mode 100644 index 000000000..944b87022 --- /dev/null +++ b/core/arm/samd21a/include_mcc/component-version.h @@ -0,0 +1,64 @@ +/** + * \file + * + * \brief Component version header file + * + * Copyright (c) 2019 Atmel Corporation, a wholly owned subsidiary of Microchip Technology Inc. + * + * \license_start + * + * \page License + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \license_stop + * + */ + +#ifndef _COMPONENT_VERSION_H_INCLUDED +#define _COMPONENT_VERSION_H_INCLUDED + +#define COMPONENT_VERSION_MAJOR 1 +#define COMPONENT_VERSION_MINOR 3 + +// +// The COMPONENT_VERSION define is composed of the major and the minor version number. +// +// The last four digits of the COMPONENT_VERSION is the minor version with leading zeros. +// The rest of the COMPONENT_VERSION is the major version. +// +#define COMPONENT_VERSION 10003 + +// +// The build number does not refer to the component, but to the build number +// of the device pack that provides the component. +// +#define BUILD_NUMBER 395 + +// +// The COMPONENT_VERSION_STRING is a string (enclosed in ") that can be used for logging or embedding. +// +#define COMPONENT_VERSION_STRING "1.3" + +// +// The COMPONENT_DATE_STRING contains a timestamp of when the pack was generated. +// +// The COMPONENT_DATE_STRING is written out using the following strftime pattern. +// +// "%Y-%m-%d %H:%M:%S" +// +// +#define COMPONENT_DATE_STRING "2019-09-19 13:04:39" + +#endif/* #ifndef _COMPONENT_VERSION_H_INCLUDED */ + diff --git a/core/arm/samd21a/include_mcc/component/ac.h b/core/arm/samd21a/include_mcc/component/ac.h new file mode 100644 index 000000000..e88b0e165 --- /dev/null +++ b/core/arm/samd21a/include_mcc/component/ac.h @@ -0,0 +1,377 @@ +/** + * \brief Component description for AC + * + * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries. + * + * Subject to your compliance with these terms, you may use Microchip software and any derivatives + * exclusively with Microchip products. It is your responsibility to comply with third party license + * terms applicable to your use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, + * APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND + * FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT + * EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + */ + +/* file generated from device description version 2019-05-20T21:16:53Z */ +#ifndef _SAMD21_AC_COMPONENT_H_ +#define _SAMD21_AC_COMPONENT_H_ + +/* ************************************************************************** */ +/* SOFTWARE API DEFINITION FOR AC */ +/* ************************************************************************** */ + +/* -------- AC_CTRLA : (AC Offset: 0x00) (R/W 8) Control A -------- */ +#define AC_CTRLA_RESETVALUE _U_(0x00) /**< (AC_CTRLA) Control A Reset Value */ + +#define AC_CTRLA_SWRST_Pos _U_(0) /**< (AC_CTRLA) Software Reset Position */ +#define AC_CTRLA_SWRST_Msk (_U_(0x1) << AC_CTRLA_SWRST_Pos) /**< (AC_CTRLA) Software Reset Mask */ +#define AC_CTRLA_SWRST(value) (AC_CTRLA_SWRST_Msk & ((value) << AC_CTRLA_SWRST_Pos)) +#define AC_CTRLA_ENABLE_Pos _U_(1) /**< (AC_CTRLA) Enable Position */ +#define AC_CTRLA_ENABLE_Msk (_U_(0x1) << AC_CTRLA_ENABLE_Pos) /**< (AC_CTRLA) Enable Mask */ +#define AC_CTRLA_ENABLE(value) (AC_CTRLA_ENABLE_Msk & ((value) << AC_CTRLA_ENABLE_Pos)) +#define AC_CTRLA_RUNSTDBY_Pos _U_(2) /**< (AC_CTRLA) Run in Standby Position */ +#define AC_CTRLA_RUNSTDBY_Msk (_U_(0x1) << AC_CTRLA_RUNSTDBY_Pos) /**< (AC_CTRLA) Run in Standby Mask */ +#define AC_CTRLA_RUNSTDBY(value) (AC_CTRLA_RUNSTDBY_Msk & ((value) << AC_CTRLA_RUNSTDBY_Pos)) +#define AC_CTRLA_LPMUX_Pos _U_(7) /**< (AC_CTRLA) Low-Power Mux Position */ +#define AC_CTRLA_LPMUX_Msk (_U_(0x1) << AC_CTRLA_LPMUX_Pos) /**< (AC_CTRLA) Low-Power Mux Mask */ +#define AC_CTRLA_LPMUX(value) (AC_CTRLA_LPMUX_Msk & ((value) << AC_CTRLA_LPMUX_Pos)) +#define AC_CTRLA_Msk _U_(0x87) /**< (AC_CTRLA) Register Mask */ + + +/* -------- AC_CTRLB : (AC Offset: 0x01) ( /W 8) Control B -------- */ +#define AC_CTRLB_RESETVALUE _U_(0x00) /**< (AC_CTRLB) Control B Reset Value */ + +#define AC_CTRLB_START0_Pos _U_(0) /**< (AC_CTRLB) Comparator 0 Start Comparison Position */ +#define AC_CTRLB_START0_Msk (_U_(0x1) << AC_CTRLB_START0_Pos) /**< (AC_CTRLB) Comparator 0 Start Comparison Mask */ +#define AC_CTRLB_START0(value) (AC_CTRLB_START0_Msk & ((value) << AC_CTRLB_START0_Pos)) +#define AC_CTRLB_START1_Pos _U_(1) /**< (AC_CTRLB) Comparator 1 Start Comparison Position */ +#define AC_CTRLB_START1_Msk (_U_(0x1) << AC_CTRLB_START1_Pos) /**< (AC_CTRLB) Comparator 1 Start Comparison Mask */ +#define AC_CTRLB_START1(value) (AC_CTRLB_START1_Msk & ((value) << AC_CTRLB_START1_Pos)) +#define AC_CTRLB_Msk _U_(0x03) /**< (AC_CTRLB) Register Mask */ + +#define AC_CTRLB_START_Pos _U_(0) /**< (AC_CTRLB Position) Comparator x Start Comparison */ +#define AC_CTRLB_START_Msk (_U_(0x3) << AC_CTRLB_START_Pos) /**< (AC_CTRLB Mask) START */ +#define AC_CTRLB_START(value) (AC_CTRLB_START_Msk & ((value) << AC_CTRLB_START_Pos)) + +/* -------- AC_EVCTRL : (AC Offset: 0x02) (R/W 16) Event Control -------- */ +#define AC_EVCTRL_RESETVALUE _U_(0x00) /**< (AC_EVCTRL) Event Control Reset Value */ + +#define AC_EVCTRL_COMPEO0_Pos _U_(0) /**< (AC_EVCTRL) Comparator 0 Event Output Enable Position */ +#define AC_EVCTRL_COMPEO0_Msk (_U_(0x1) << AC_EVCTRL_COMPEO0_Pos) /**< (AC_EVCTRL) Comparator 0 Event Output Enable Mask */ +#define AC_EVCTRL_COMPEO0(value) (AC_EVCTRL_COMPEO0_Msk & ((value) << AC_EVCTRL_COMPEO0_Pos)) +#define AC_EVCTRL_COMPEO1_Pos _U_(1) /**< (AC_EVCTRL) Comparator 1 Event Output Enable Position */ +#define AC_EVCTRL_COMPEO1_Msk (_U_(0x1) << AC_EVCTRL_COMPEO1_Pos) /**< (AC_EVCTRL) Comparator 1 Event Output Enable Mask */ +#define AC_EVCTRL_COMPEO1(value) (AC_EVCTRL_COMPEO1_Msk & ((value) << AC_EVCTRL_COMPEO1_Pos)) +#define AC_EVCTRL_WINEO0_Pos _U_(4) /**< (AC_EVCTRL) Window 0 Event Output Enable Position */ +#define AC_EVCTRL_WINEO0_Msk (_U_(0x1) << AC_EVCTRL_WINEO0_Pos) /**< (AC_EVCTRL) Window 0 Event Output Enable Mask */ +#define AC_EVCTRL_WINEO0(value) (AC_EVCTRL_WINEO0_Msk & ((value) << AC_EVCTRL_WINEO0_Pos)) +#define AC_EVCTRL_COMPEI0_Pos _U_(8) /**< (AC_EVCTRL) Comparator 0 Event Input Position */ +#define AC_EVCTRL_COMPEI0_Msk (_U_(0x1) << AC_EVCTRL_COMPEI0_Pos) /**< (AC_EVCTRL) Comparator 0 Event Input Mask */ +#define AC_EVCTRL_COMPEI0(value) (AC_EVCTRL_COMPEI0_Msk & ((value) << AC_EVCTRL_COMPEI0_Pos)) +#define AC_EVCTRL_COMPEI1_Pos _U_(9) /**< (AC_EVCTRL) Comparator 1 Event Input Position */ +#define AC_EVCTRL_COMPEI1_Msk (_U_(0x1) << AC_EVCTRL_COMPEI1_Pos) /**< (AC_EVCTRL) Comparator 1 Event Input Mask */ +#define AC_EVCTRL_COMPEI1(value) (AC_EVCTRL_COMPEI1_Msk & ((value) << AC_EVCTRL_COMPEI1_Pos)) +#define AC_EVCTRL_Msk _U_(0x0313) /**< (AC_EVCTRL) Register Mask */ + +#define AC_EVCTRL_COMPEO_Pos _U_(0) /**< (AC_EVCTRL Position) Comparator x Event Output Enable */ +#define AC_EVCTRL_COMPEO_Msk (_U_(0x3) << AC_EVCTRL_COMPEO_Pos) /**< (AC_EVCTRL Mask) COMPEO */ +#define AC_EVCTRL_COMPEO(value) (AC_EVCTRL_COMPEO_Msk & ((value) << AC_EVCTRL_COMPEO_Pos)) +#define AC_EVCTRL_WINEO_Pos _U_(4) /**< (AC_EVCTRL Position) Window x Event Output Enable */ +#define AC_EVCTRL_WINEO_Msk (_U_(0x1) << AC_EVCTRL_WINEO_Pos) /**< (AC_EVCTRL Mask) WINEO */ +#define AC_EVCTRL_WINEO(value) (AC_EVCTRL_WINEO_Msk & ((value) << AC_EVCTRL_WINEO_Pos)) +#define AC_EVCTRL_COMPEI_Pos _U_(8) /**< (AC_EVCTRL Position) Comparator x Event Input */ +#define AC_EVCTRL_COMPEI_Msk (_U_(0x3) << AC_EVCTRL_COMPEI_Pos) /**< (AC_EVCTRL Mask) COMPEI */ +#define AC_EVCTRL_COMPEI(value) (AC_EVCTRL_COMPEI_Msk & ((value) << AC_EVCTRL_COMPEI_Pos)) + +/* -------- AC_INTENCLR : (AC Offset: 0x04) (R/W 8) Interrupt Enable Clear -------- */ +#define AC_INTENCLR_RESETVALUE _U_(0x00) /**< (AC_INTENCLR) Interrupt Enable Clear Reset Value */ + +#define AC_INTENCLR_COMP0_Pos _U_(0) /**< (AC_INTENCLR) Comparator 0 Interrupt Enable Position */ +#define AC_INTENCLR_COMP0_Msk (_U_(0x1) << AC_INTENCLR_COMP0_Pos) /**< (AC_INTENCLR) Comparator 0 Interrupt Enable Mask */ +#define AC_INTENCLR_COMP0(value) (AC_INTENCLR_COMP0_Msk & ((value) << AC_INTENCLR_COMP0_Pos)) +#define AC_INTENCLR_COMP1_Pos _U_(1) /**< (AC_INTENCLR) Comparator 1 Interrupt Enable Position */ +#define AC_INTENCLR_COMP1_Msk (_U_(0x1) << AC_INTENCLR_COMP1_Pos) /**< (AC_INTENCLR) Comparator 1 Interrupt Enable Mask */ +#define AC_INTENCLR_COMP1(value) (AC_INTENCLR_COMP1_Msk & ((value) << AC_INTENCLR_COMP1_Pos)) +#define AC_INTENCLR_WIN0_Pos _U_(4) /**< (AC_INTENCLR) Window 0 Interrupt Enable Position */ +#define AC_INTENCLR_WIN0_Msk (_U_(0x1) << AC_INTENCLR_WIN0_Pos) /**< (AC_INTENCLR) Window 0 Interrupt Enable Mask */ +#define AC_INTENCLR_WIN0(value) (AC_INTENCLR_WIN0_Msk & ((value) << AC_INTENCLR_WIN0_Pos)) +#define AC_INTENCLR_Msk _U_(0x13) /**< (AC_INTENCLR) Register Mask */ + +#define AC_INTENCLR_COMP_Pos _U_(0) /**< (AC_INTENCLR Position) Comparator x Interrupt Enable */ +#define AC_INTENCLR_COMP_Msk (_U_(0x3) << AC_INTENCLR_COMP_Pos) /**< (AC_INTENCLR Mask) COMP */ +#define AC_INTENCLR_COMP(value) (AC_INTENCLR_COMP_Msk & ((value) << AC_INTENCLR_COMP_Pos)) +#define AC_INTENCLR_WIN_Pos _U_(4) /**< (AC_INTENCLR Position) Window x Interrupt Enable */ +#define AC_INTENCLR_WIN_Msk (_U_(0x1) << AC_INTENCLR_WIN_Pos) /**< (AC_INTENCLR Mask) WIN */ +#define AC_INTENCLR_WIN(value) (AC_INTENCLR_WIN_Msk & ((value) << AC_INTENCLR_WIN_Pos)) + +/* -------- AC_INTENSET : (AC Offset: 0x05) (R/W 8) Interrupt Enable Set -------- */ +#define AC_INTENSET_RESETVALUE _U_(0x00) /**< (AC_INTENSET) Interrupt Enable Set Reset Value */ + +#define AC_INTENSET_COMP0_Pos _U_(0) /**< (AC_INTENSET) Comparator 0 Interrupt Enable Position */ +#define AC_INTENSET_COMP0_Msk (_U_(0x1) << AC_INTENSET_COMP0_Pos) /**< (AC_INTENSET) Comparator 0 Interrupt Enable Mask */ +#define AC_INTENSET_COMP0(value) (AC_INTENSET_COMP0_Msk & ((value) << AC_INTENSET_COMP0_Pos)) +#define AC_INTENSET_COMP1_Pos _U_(1) /**< (AC_INTENSET) Comparator 1 Interrupt Enable Position */ +#define AC_INTENSET_COMP1_Msk (_U_(0x1) << AC_INTENSET_COMP1_Pos) /**< (AC_INTENSET) Comparator 1 Interrupt Enable Mask */ +#define AC_INTENSET_COMP1(value) (AC_INTENSET_COMP1_Msk & ((value) << AC_INTENSET_COMP1_Pos)) +#define AC_INTENSET_WIN0_Pos _U_(4) /**< (AC_INTENSET) Window 0 Interrupt Enable Position */ +#define AC_INTENSET_WIN0_Msk (_U_(0x1) << AC_INTENSET_WIN0_Pos) /**< (AC_INTENSET) Window 0 Interrupt Enable Mask */ +#define AC_INTENSET_WIN0(value) (AC_INTENSET_WIN0_Msk & ((value) << AC_INTENSET_WIN0_Pos)) +#define AC_INTENSET_Msk _U_(0x13) /**< (AC_INTENSET) Register Mask */ + +#define AC_INTENSET_COMP_Pos _U_(0) /**< (AC_INTENSET Position) Comparator x Interrupt Enable */ +#define AC_INTENSET_COMP_Msk (_U_(0x3) << AC_INTENSET_COMP_Pos) /**< (AC_INTENSET Mask) COMP */ +#define AC_INTENSET_COMP(value) (AC_INTENSET_COMP_Msk & ((value) << AC_INTENSET_COMP_Pos)) +#define AC_INTENSET_WIN_Pos _U_(4) /**< (AC_INTENSET Position) Window x Interrupt Enable */ +#define AC_INTENSET_WIN_Msk (_U_(0x1) << AC_INTENSET_WIN_Pos) /**< (AC_INTENSET Mask) WIN */ +#define AC_INTENSET_WIN(value) (AC_INTENSET_WIN_Msk & ((value) << AC_INTENSET_WIN_Pos)) + +/* -------- AC_INTFLAG : (AC Offset: 0x06) (R/W 8) Interrupt Flag Status and Clear -------- */ +#define AC_INTFLAG_RESETVALUE _U_(0x00) /**< (AC_INTFLAG) Interrupt Flag Status and Clear Reset Value */ + +#define AC_INTFLAG_COMP0_Pos _U_(0) /**< (AC_INTFLAG) Comparator 0 Position */ +#define AC_INTFLAG_COMP0_Msk (_U_(0x1) << AC_INTFLAG_COMP0_Pos) /**< (AC_INTFLAG) Comparator 0 Mask */ +#define AC_INTFLAG_COMP0(value) (AC_INTFLAG_COMP0_Msk & ((value) << AC_INTFLAG_COMP0_Pos)) +#define AC_INTFLAG_COMP1_Pos _U_(1) /**< (AC_INTFLAG) Comparator 1 Position */ +#define AC_INTFLAG_COMP1_Msk (_U_(0x1) << AC_INTFLAG_COMP1_Pos) /**< (AC_INTFLAG) Comparator 1 Mask */ +#define AC_INTFLAG_COMP1(value) (AC_INTFLAG_COMP1_Msk & ((value) << AC_INTFLAG_COMP1_Pos)) +#define AC_INTFLAG_WIN0_Pos _U_(4) /**< (AC_INTFLAG) Window 0 Position */ +#define AC_INTFLAG_WIN0_Msk (_U_(0x1) << AC_INTFLAG_WIN0_Pos) /**< (AC_INTFLAG) Window 0 Mask */ +#define AC_INTFLAG_WIN0(value) (AC_INTFLAG_WIN0_Msk & ((value) << AC_INTFLAG_WIN0_Pos)) +#define AC_INTFLAG_Msk _U_(0x13) /**< (AC_INTFLAG) Register Mask */ + +#define AC_INTFLAG_COMP_Pos _U_(0) /**< (AC_INTFLAG Position) Comparator x */ +#define AC_INTFLAG_COMP_Msk (_U_(0x3) << AC_INTFLAG_COMP_Pos) /**< (AC_INTFLAG Mask) COMP */ +#define AC_INTFLAG_COMP(value) (AC_INTFLAG_COMP_Msk & ((value) << AC_INTFLAG_COMP_Pos)) +#define AC_INTFLAG_WIN_Pos _U_(4) /**< (AC_INTFLAG Position) Window x */ +#define AC_INTFLAG_WIN_Msk (_U_(0x1) << AC_INTFLAG_WIN_Pos) /**< (AC_INTFLAG Mask) WIN */ +#define AC_INTFLAG_WIN(value) (AC_INTFLAG_WIN_Msk & ((value) << AC_INTFLAG_WIN_Pos)) + +/* -------- AC_STATUSA : (AC Offset: 0x08) ( R/ 8) Status A -------- */ +#define AC_STATUSA_RESETVALUE _U_(0x00) /**< (AC_STATUSA) Status A Reset Value */ + +#define AC_STATUSA_STATE0_Pos _U_(0) /**< (AC_STATUSA) Comparator 0 Current State Position */ +#define AC_STATUSA_STATE0_Msk (_U_(0x1) << AC_STATUSA_STATE0_Pos) /**< (AC_STATUSA) Comparator 0 Current State Mask */ +#define AC_STATUSA_STATE0(value) (AC_STATUSA_STATE0_Msk & ((value) << AC_STATUSA_STATE0_Pos)) +#define AC_STATUSA_STATE1_Pos _U_(1) /**< (AC_STATUSA) Comparator 1 Current State Position */ +#define AC_STATUSA_STATE1_Msk (_U_(0x1) << AC_STATUSA_STATE1_Pos) /**< (AC_STATUSA) Comparator 1 Current State Mask */ +#define AC_STATUSA_STATE1(value) (AC_STATUSA_STATE1_Msk & ((value) << AC_STATUSA_STATE1_Pos)) +#define AC_STATUSA_WSTATE0_Pos _U_(4) /**< (AC_STATUSA) Window 0 Current State Position */ +#define AC_STATUSA_WSTATE0_Msk (_U_(0x3) << AC_STATUSA_WSTATE0_Pos) /**< (AC_STATUSA) Window 0 Current State Mask */ +#define AC_STATUSA_WSTATE0(value) (AC_STATUSA_WSTATE0_Msk & ((value) << AC_STATUSA_WSTATE0_Pos)) +#define AC_STATUSA_WSTATE0_ABOVE_Val _U_(0x0) /**< (AC_STATUSA) Signal is above window */ +#define AC_STATUSA_WSTATE0_INSIDE_Val _U_(0x1) /**< (AC_STATUSA) Signal is inside window */ +#define AC_STATUSA_WSTATE0_BELOW_Val _U_(0x2) /**< (AC_STATUSA) Signal is below window */ +#define AC_STATUSA_WSTATE0_ABOVE (AC_STATUSA_WSTATE0_ABOVE_Val << AC_STATUSA_WSTATE0_Pos) /**< (AC_STATUSA) Signal is above window Position */ +#define AC_STATUSA_WSTATE0_INSIDE (AC_STATUSA_WSTATE0_INSIDE_Val << AC_STATUSA_WSTATE0_Pos) /**< (AC_STATUSA) Signal is inside window Position */ +#define AC_STATUSA_WSTATE0_BELOW (AC_STATUSA_WSTATE0_BELOW_Val << AC_STATUSA_WSTATE0_Pos) /**< (AC_STATUSA) Signal is below window Position */ +#define AC_STATUSA_Msk _U_(0x33) /**< (AC_STATUSA) Register Mask */ + +#define AC_STATUSA_STATE_Pos _U_(0) /**< (AC_STATUSA Position) Comparator x Current State */ +#define AC_STATUSA_STATE_Msk (_U_(0x3) << AC_STATUSA_STATE_Pos) /**< (AC_STATUSA Mask) STATE */ +#define AC_STATUSA_STATE(value) (AC_STATUSA_STATE_Msk & ((value) << AC_STATUSA_STATE_Pos)) + +/* -------- AC_STATUSB : (AC Offset: 0x09) ( R/ 8) Status B -------- */ +#define AC_STATUSB_RESETVALUE _U_(0x00) /**< (AC_STATUSB) Status B Reset Value */ + +#define AC_STATUSB_READY0_Pos _U_(0) /**< (AC_STATUSB) Comparator 0 Ready Position */ +#define AC_STATUSB_READY0_Msk (_U_(0x1) << AC_STATUSB_READY0_Pos) /**< (AC_STATUSB) Comparator 0 Ready Mask */ +#define AC_STATUSB_READY0(value) (AC_STATUSB_READY0_Msk & ((value) << AC_STATUSB_READY0_Pos)) +#define AC_STATUSB_READY1_Pos _U_(1) /**< (AC_STATUSB) Comparator 1 Ready Position */ +#define AC_STATUSB_READY1_Msk (_U_(0x1) << AC_STATUSB_READY1_Pos) /**< (AC_STATUSB) Comparator 1 Ready Mask */ +#define AC_STATUSB_READY1(value) (AC_STATUSB_READY1_Msk & ((value) << AC_STATUSB_READY1_Pos)) +#define AC_STATUSB_SYNCBUSY_Pos _U_(7) /**< (AC_STATUSB) Synchronization Busy Position */ +#define AC_STATUSB_SYNCBUSY_Msk (_U_(0x1) << AC_STATUSB_SYNCBUSY_Pos) /**< (AC_STATUSB) Synchronization Busy Mask */ +#define AC_STATUSB_SYNCBUSY(value) (AC_STATUSB_SYNCBUSY_Msk & ((value) << AC_STATUSB_SYNCBUSY_Pos)) +#define AC_STATUSB_Msk _U_(0x83) /**< (AC_STATUSB) Register Mask */ + +#define AC_STATUSB_READY_Pos _U_(0) /**< (AC_STATUSB Position) Comparator x Ready */ +#define AC_STATUSB_READY_Msk (_U_(0x3) << AC_STATUSB_READY_Pos) /**< (AC_STATUSB Mask) READY */ +#define AC_STATUSB_READY(value) (AC_STATUSB_READY_Msk & ((value) << AC_STATUSB_READY_Pos)) + +/* -------- AC_STATUSC : (AC Offset: 0x0A) ( R/ 8) Status C -------- */ +#define AC_STATUSC_RESETVALUE _U_(0x00) /**< (AC_STATUSC) Status C Reset Value */ + +#define AC_STATUSC_STATE0_Pos _U_(0) /**< (AC_STATUSC) Comparator 0 Current State Position */ +#define AC_STATUSC_STATE0_Msk (_U_(0x1) << AC_STATUSC_STATE0_Pos) /**< (AC_STATUSC) Comparator 0 Current State Mask */ +#define AC_STATUSC_STATE0(value) (AC_STATUSC_STATE0_Msk & ((value) << AC_STATUSC_STATE0_Pos)) +#define AC_STATUSC_STATE1_Pos _U_(1) /**< (AC_STATUSC) Comparator 1 Current State Position */ +#define AC_STATUSC_STATE1_Msk (_U_(0x1) << AC_STATUSC_STATE1_Pos) /**< (AC_STATUSC) Comparator 1 Current State Mask */ +#define AC_STATUSC_STATE1(value) (AC_STATUSC_STATE1_Msk & ((value) << AC_STATUSC_STATE1_Pos)) +#define AC_STATUSC_WSTATE0_Pos _U_(4) /**< (AC_STATUSC) Window 0 Current State Position */ +#define AC_STATUSC_WSTATE0_Msk (_U_(0x3) << AC_STATUSC_WSTATE0_Pos) /**< (AC_STATUSC) Window 0 Current State Mask */ +#define AC_STATUSC_WSTATE0(value) (AC_STATUSC_WSTATE0_Msk & ((value) << AC_STATUSC_WSTATE0_Pos)) +#define AC_STATUSC_WSTATE0_ABOVE_Val _U_(0x0) /**< (AC_STATUSC) Signal is above window */ +#define AC_STATUSC_WSTATE0_INSIDE_Val _U_(0x1) /**< (AC_STATUSC) Signal is inside window */ +#define AC_STATUSC_WSTATE0_BELOW_Val _U_(0x2) /**< (AC_STATUSC) Signal is below window */ +#define AC_STATUSC_WSTATE0_ABOVE (AC_STATUSC_WSTATE0_ABOVE_Val << AC_STATUSC_WSTATE0_Pos) /**< (AC_STATUSC) Signal is above window Position */ +#define AC_STATUSC_WSTATE0_INSIDE (AC_STATUSC_WSTATE0_INSIDE_Val << AC_STATUSC_WSTATE0_Pos) /**< (AC_STATUSC) Signal is inside window Position */ +#define AC_STATUSC_WSTATE0_BELOW (AC_STATUSC_WSTATE0_BELOW_Val << AC_STATUSC_WSTATE0_Pos) /**< (AC_STATUSC) Signal is below window Position */ +#define AC_STATUSC_Msk _U_(0x33) /**< (AC_STATUSC) Register Mask */ + +#define AC_STATUSC_STATE_Pos _U_(0) /**< (AC_STATUSC Position) Comparator x Current State */ +#define AC_STATUSC_STATE_Msk (_U_(0x3) << AC_STATUSC_STATE_Pos) /**< (AC_STATUSC Mask) STATE */ +#define AC_STATUSC_STATE(value) (AC_STATUSC_STATE_Msk & ((value) << AC_STATUSC_STATE_Pos)) + +/* -------- AC_WINCTRL : (AC Offset: 0x0C) (R/W 8) Window Control -------- */ +#define AC_WINCTRL_RESETVALUE _U_(0x00) /**< (AC_WINCTRL) Window Control Reset Value */ + +#define AC_WINCTRL_WEN0_Pos _U_(0) /**< (AC_WINCTRL) Window 0 Mode Enable Position */ +#define AC_WINCTRL_WEN0_Msk (_U_(0x1) << AC_WINCTRL_WEN0_Pos) /**< (AC_WINCTRL) Window 0 Mode Enable Mask */ +#define AC_WINCTRL_WEN0(value) (AC_WINCTRL_WEN0_Msk & ((value) << AC_WINCTRL_WEN0_Pos)) +#define AC_WINCTRL_WINTSEL0_Pos _U_(1) /**< (AC_WINCTRL) Window 0 Interrupt Selection Position */ +#define AC_WINCTRL_WINTSEL0_Msk (_U_(0x3) << AC_WINCTRL_WINTSEL0_Pos) /**< (AC_WINCTRL) Window 0 Interrupt Selection Mask */ +#define AC_WINCTRL_WINTSEL0(value) (AC_WINCTRL_WINTSEL0_Msk & ((value) << AC_WINCTRL_WINTSEL0_Pos)) +#define AC_WINCTRL_WINTSEL0_ABOVE_Val _U_(0x0) /**< (AC_WINCTRL) Interrupt on signal above window */ +#define AC_WINCTRL_WINTSEL0_INSIDE_Val _U_(0x1) /**< (AC_WINCTRL) Interrupt on signal inside window */ +#define AC_WINCTRL_WINTSEL0_BELOW_Val _U_(0x2) /**< (AC_WINCTRL) Interrupt on signal below window */ +#define AC_WINCTRL_WINTSEL0_OUTSIDE_Val _U_(0x3) /**< (AC_WINCTRL) Interrupt on signal outside window */ +#define AC_WINCTRL_WINTSEL0_ABOVE (AC_WINCTRL_WINTSEL0_ABOVE_Val << AC_WINCTRL_WINTSEL0_Pos) /**< (AC_WINCTRL) Interrupt on signal above window Position */ +#define AC_WINCTRL_WINTSEL0_INSIDE (AC_WINCTRL_WINTSEL0_INSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) /**< (AC_WINCTRL) Interrupt on signal inside window Position */ +#define AC_WINCTRL_WINTSEL0_BELOW (AC_WINCTRL_WINTSEL0_BELOW_Val << AC_WINCTRL_WINTSEL0_Pos) /**< (AC_WINCTRL) Interrupt on signal below window Position */ +#define AC_WINCTRL_WINTSEL0_OUTSIDE (AC_WINCTRL_WINTSEL0_OUTSIDE_Val << AC_WINCTRL_WINTSEL0_Pos) /**< (AC_WINCTRL) Interrupt on signal outside window Position */ +#define AC_WINCTRL_Msk _U_(0x07) /**< (AC_WINCTRL) Register Mask */ + +#define AC_WINCTRL_WEN_Pos _U_(0) /**< (AC_WINCTRL Position) Window x Mode Enable */ +#define AC_WINCTRL_WEN_Msk (_U_(0x1) << AC_WINCTRL_WEN_Pos) /**< (AC_WINCTRL Mask) WEN */ +#define AC_WINCTRL_WEN(value) (AC_WINCTRL_WEN_Msk & ((value) << AC_WINCTRL_WEN_Pos)) + +/* -------- AC_COMPCTRL : (AC Offset: 0x10) (R/W 32) Comparator Control n -------- */ +#define AC_COMPCTRL_RESETVALUE _U_(0x00) /**< (AC_COMPCTRL) Comparator Control n Reset Value */ + +#define AC_COMPCTRL_ENABLE_Pos _U_(0) /**< (AC_COMPCTRL) Enable Position */ +#define AC_COMPCTRL_ENABLE_Msk (_U_(0x1) << AC_COMPCTRL_ENABLE_Pos) /**< (AC_COMPCTRL) Enable Mask */ +#define AC_COMPCTRL_ENABLE(value) (AC_COMPCTRL_ENABLE_Msk & ((value) << AC_COMPCTRL_ENABLE_Pos)) +#define AC_COMPCTRL_SINGLE_Pos _U_(1) /**< (AC_COMPCTRL) Single-Shot Mode Position */ +#define AC_COMPCTRL_SINGLE_Msk (_U_(0x1) << AC_COMPCTRL_SINGLE_Pos) /**< (AC_COMPCTRL) Single-Shot Mode Mask */ +#define AC_COMPCTRL_SINGLE(value) (AC_COMPCTRL_SINGLE_Msk & ((value) << AC_COMPCTRL_SINGLE_Pos)) +#define AC_COMPCTRL_SPEED_Pos _U_(2) /**< (AC_COMPCTRL) Speed Selection Position */ +#define AC_COMPCTRL_SPEED_Msk (_U_(0x3) << AC_COMPCTRL_SPEED_Pos) /**< (AC_COMPCTRL) Speed Selection Mask */ +#define AC_COMPCTRL_SPEED(value) (AC_COMPCTRL_SPEED_Msk & ((value) << AC_COMPCTRL_SPEED_Pos)) +#define AC_COMPCTRL_SPEED_LOW_Val _U_(0x0) /**< (AC_COMPCTRL) Low speed */ +#define AC_COMPCTRL_SPEED_HIGH_Val _U_(0x1) /**< (AC_COMPCTRL) High speed */ +#define AC_COMPCTRL_SPEED_LOW (AC_COMPCTRL_SPEED_LOW_Val << AC_COMPCTRL_SPEED_Pos) /**< (AC_COMPCTRL) Low speed Position */ +#define AC_COMPCTRL_SPEED_HIGH (AC_COMPCTRL_SPEED_HIGH_Val << AC_COMPCTRL_SPEED_Pos) /**< (AC_COMPCTRL) High speed Position */ +#define AC_COMPCTRL_INTSEL_Pos _U_(5) /**< (AC_COMPCTRL) Interrupt Selection Position */ +#define AC_COMPCTRL_INTSEL_Msk (_U_(0x3) << AC_COMPCTRL_INTSEL_Pos) /**< (AC_COMPCTRL) Interrupt Selection Mask */ +#define AC_COMPCTRL_INTSEL(value) (AC_COMPCTRL_INTSEL_Msk & ((value) << AC_COMPCTRL_INTSEL_Pos)) +#define AC_COMPCTRL_INTSEL_TOGGLE_Val _U_(0x0) /**< (AC_COMPCTRL) Interrupt on comparator output toggle */ +#define AC_COMPCTRL_INTSEL_RISING_Val _U_(0x1) /**< (AC_COMPCTRL) Interrupt on comparator output rising */ +#define AC_COMPCTRL_INTSEL_FALLING_Val _U_(0x2) /**< (AC_COMPCTRL) Interrupt on comparator output falling */ +#define AC_COMPCTRL_INTSEL_EOC_Val _U_(0x3) /**< (AC_COMPCTRL) Interrupt on end of comparison (single-shot mode only) */ +#define AC_COMPCTRL_INTSEL_TOGGLE (AC_COMPCTRL_INTSEL_TOGGLE_Val << AC_COMPCTRL_INTSEL_Pos) /**< (AC_COMPCTRL) Interrupt on comparator output toggle Position */ +#define AC_COMPCTRL_INTSEL_RISING (AC_COMPCTRL_INTSEL_RISING_Val << AC_COMPCTRL_INTSEL_Pos) /**< (AC_COMPCTRL) Interrupt on comparator output rising Position */ +#define AC_COMPCTRL_INTSEL_FALLING (AC_COMPCTRL_INTSEL_FALLING_Val << AC_COMPCTRL_INTSEL_Pos) /**< (AC_COMPCTRL) Interrupt on comparator output falling Position */ +#define AC_COMPCTRL_INTSEL_EOC (AC_COMPCTRL_INTSEL_EOC_Val << AC_COMPCTRL_INTSEL_Pos) /**< (AC_COMPCTRL) Interrupt on end of comparison (single-shot mode only) Position */ +#define AC_COMPCTRL_MUXNEG_Pos _U_(8) /**< (AC_COMPCTRL) Negative Input Mux Selection Position */ +#define AC_COMPCTRL_MUXNEG_Msk (_U_(0x7) << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) Negative Input Mux Selection Mask */ +#define AC_COMPCTRL_MUXNEG(value) (AC_COMPCTRL_MUXNEG_Msk & ((value) << AC_COMPCTRL_MUXNEG_Pos)) +#define AC_COMPCTRL_MUXNEG_PIN0_Val _U_(0x0) /**< (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXNEG_PIN1_Val _U_(0x1) /**< (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXNEG_PIN2_Val _U_(0x2) /**< (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXNEG_PIN3_Val _U_(0x3) /**< (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXNEG_GND_Val _U_(0x4) /**< (AC_COMPCTRL) Ground */ +#define AC_COMPCTRL_MUXNEG_VSCALE_Val _U_(0x5) /**< (AC_COMPCTRL) VDD scaler */ +#define AC_COMPCTRL_MUXNEG_BANDGAP_Val _U_(0x6) /**< (AC_COMPCTRL) Internal bandgap voltage */ +#define AC_COMPCTRL_MUXNEG_DAC_Val _U_(0x7) /**< (AC_COMPCTRL) DAC output */ +#define AC_COMPCTRL_MUXNEG_PIN0 (AC_COMPCTRL_MUXNEG_PIN0_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) I/O pin 0 Position */ +#define AC_COMPCTRL_MUXNEG_PIN1 (AC_COMPCTRL_MUXNEG_PIN1_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) I/O pin 1 Position */ +#define AC_COMPCTRL_MUXNEG_PIN2 (AC_COMPCTRL_MUXNEG_PIN2_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) I/O pin 2 Position */ +#define AC_COMPCTRL_MUXNEG_PIN3 (AC_COMPCTRL_MUXNEG_PIN3_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) I/O pin 3 Position */ +#define AC_COMPCTRL_MUXNEG_GND (AC_COMPCTRL_MUXNEG_GND_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) Ground Position */ +#define AC_COMPCTRL_MUXNEG_VSCALE (AC_COMPCTRL_MUXNEG_VSCALE_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) VDD scaler Position */ +#define AC_COMPCTRL_MUXNEG_BANDGAP (AC_COMPCTRL_MUXNEG_BANDGAP_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) Internal bandgap voltage Position */ +#define AC_COMPCTRL_MUXNEG_DAC (AC_COMPCTRL_MUXNEG_DAC_Val << AC_COMPCTRL_MUXNEG_Pos) /**< (AC_COMPCTRL) DAC output Position */ +#define AC_COMPCTRL_MUXPOS_Pos _U_(12) /**< (AC_COMPCTRL) Positive Input Mux Selection Position */ +#define AC_COMPCTRL_MUXPOS_Msk (_U_(0x3) << AC_COMPCTRL_MUXPOS_Pos) /**< (AC_COMPCTRL) Positive Input Mux Selection Mask */ +#define AC_COMPCTRL_MUXPOS(value) (AC_COMPCTRL_MUXPOS_Msk & ((value) << AC_COMPCTRL_MUXPOS_Pos)) +#define AC_COMPCTRL_MUXPOS_PIN0_Val _U_(0x0) /**< (AC_COMPCTRL) I/O pin 0 */ +#define AC_COMPCTRL_MUXPOS_PIN1_Val _U_(0x1) /**< (AC_COMPCTRL) I/O pin 1 */ +#define AC_COMPCTRL_MUXPOS_PIN2_Val _U_(0x2) /**< (AC_COMPCTRL) I/O pin 2 */ +#define AC_COMPCTRL_MUXPOS_PIN3_Val _U_(0x3) /**< (AC_COMPCTRL) I/O pin 3 */ +#define AC_COMPCTRL_MUXPOS_PIN0 (AC_COMPCTRL_MUXPOS_PIN0_Val << AC_COMPCTRL_MUXPOS_Pos) /**< (AC_COMPCTRL) I/O pin 0 Position */ +#define AC_COMPCTRL_MUXPOS_PIN1 (AC_COMPCTRL_MUXPOS_PIN1_Val << AC_COMPCTRL_MUXPOS_Pos) /**< (AC_COMPCTRL) I/O pin 1 Position */ +#define AC_COMPCTRL_MUXPOS_PIN2 (AC_COMPCTRL_MUXPOS_PIN2_Val << AC_COMPCTRL_MUXPOS_Pos) /**< (AC_COMPCTRL) I/O pin 2 Position */ +#define AC_COMPCTRL_MUXPOS_PIN3 (AC_COMPCTRL_MUXPOS_PIN3_Val << AC_COMPCTRL_MUXPOS_Pos) /**< (AC_COMPCTRL) I/O pin 3 Position */ +#define AC_COMPCTRL_SWAP_Pos _U_(15) /**< (AC_COMPCTRL) Swap Inputs and Invert Position */ +#define AC_COMPCTRL_SWAP_Msk (_U_(0x1) << AC_COMPCTRL_SWAP_Pos) /**< (AC_COMPCTRL) Swap Inputs and Invert Mask */ +#define AC_COMPCTRL_SWAP(value) (AC_COMPCTRL_SWAP_Msk & ((value) << AC_COMPCTRL_SWAP_Pos)) +#define AC_COMPCTRL_OUT_Pos _U_(16) /**< (AC_COMPCTRL) Output Position */ +#define AC_COMPCTRL_OUT_Msk (_U_(0x3) << AC_COMPCTRL_OUT_Pos) /**< (AC_COMPCTRL) Output Mask */ +#define AC_COMPCTRL_OUT(value) (AC_COMPCTRL_OUT_Msk & ((value) << AC_COMPCTRL_OUT_Pos)) +#define AC_COMPCTRL_OUT_OFF_Val _U_(0x0) /**< (AC_COMPCTRL) The output of COMPn is not routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_ASYNC_Val _U_(0x1) /**< (AC_COMPCTRL) The asynchronous output of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_SYNC_Val _U_(0x2) /**< (AC_COMPCTRL) The synchronous output (including filtering) of COMPn is routed to the COMPn I/O port */ +#define AC_COMPCTRL_OUT_OFF (AC_COMPCTRL_OUT_OFF_Val << AC_COMPCTRL_OUT_Pos) /**< (AC_COMPCTRL) The output of COMPn is not routed to the COMPn I/O port Position */ +#define AC_COMPCTRL_OUT_ASYNC (AC_COMPCTRL_OUT_ASYNC_Val << AC_COMPCTRL_OUT_Pos) /**< (AC_COMPCTRL) The asynchronous output of COMPn is routed to the COMPn I/O port Position */ +#define AC_COMPCTRL_OUT_SYNC (AC_COMPCTRL_OUT_SYNC_Val << AC_COMPCTRL_OUT_Pos) /**< (AC_COMPCTRL) The synchronous output (including filtering) of COMPn is routed to the COMPn I/O port Position */ +#define AC_COMPCTRL_HYST_Pos _U_(19) /**< (AC_COMPCTRL) Hysteresis Enable Position */ +#define AC_COMPCTRL_HYST_Msk (_U_(0x1) << AC_COMPCTRL_HYST_Pos) /**< (AC_COMPCTRL) Hysteresis Enable Mask */ +#define AC_COMPCTRL_HYST(value) (AC_COMPCTRL_HYST_Msk & ((value) << AC_COMPCTRL_HYST_Pos)) +#define AC_COMPCTRL_FLEN_Pos _U_(24) /**< (AC_COMPCTRL) Filter Length Position */ +#define AC_COMPCTRL_FLEN_Msk (_U_(0x7) << AC_COMPCTRL_FLEN_Pos) /**< (AC_COMPCTRL) Filter Length Mask */ +#define AC_COMPCTRL_FLEN(value) (AC_COMPCTRL_FLEN_Msk & ((value) << AC_COMPCTRL_FLEN_Pos)) +#define AC_COMPCTRL_FLEN_OFF_Val _U_(0x0) /**< (AC_COMPCTRL) No filtering */ +#define AC_COMPCTRL_FLEN_MAJ3_Val _U_(0x1) /**< (AC_COMPCTRL) 3-bit majority function (2 of 3) */ +#define AC_COMPCTRL_FLEN_MAJ5_Val _U_(0x2) /**< (AC_COMPCTRL) 5-bit majority function (3 of 5) */ +#define AC_COMPCTRL_FLEN_OFF (AC_COMPCTRL_FLEN_OFF_Val << AC_COMPCTRL_FLEN_Pos) /**< (AC_COMPCTRL) No filtering Position */ +#define AC_COMPCTRL_FLEN_MAJ3 (AC_COMPCTRL_FLEN_MAJ3_Val << AC_COMPCTRL_FLEN_Pos) /**< (AC_COMPCTRL) 3-bit majority function (2 of 3) Position */ +#define AC_COMPCTRL_FLEN_MAJ5 (AC_COMPCTRL_FLEN_MAJ5_Val << AC_COMPCTRL_FLEN_Pos) /**< (AC_COMPCTRL) 5-bit majority function (3 of 5) Position */ +#define AC_COMPCTRL_Msk _U_(0x070BB76F) /**< (AC_COMPCTRL) Register Mask */ + + +/* -------- AC_SCALER : (AC Offset: 0x20) (R/W 8) Scaler n -------- */ +#define AC_SCALER_RESETVALUE _U_(0x00) /**< (AC_SCALER) Scaler n Reset Value */ + +#define AC_SCALER_VALUE_Pos _U_(0) /**< (AC_SCALER) Scaler Value Position */ +#define AC_SCALER_VALUE_Msk (_U_(0x3F) << AC_SCALER_VALUE_Pos) /**< (AC_SCALER) Scaler Value Mask */ +#define AC_SCALER_VALUE(value) (AC_SCALER_VALUE_Msk & ((value) << AC_SCALER_VALUE_Pos)) +#define AC_SCALER_Msk _U_(0x3F) /**< (AC_SCALER) Register Mask */ + + +/** \brief AC register offsets definitions */ +#define AC_CTRLA_REG_OFST (0x00) /**< (AC_CTRLA) Control A Offset */ +#define AC_CTRLB_REG_OFST (0x01) /**< (AC_CTRLB) Control B Offset */ +#define AC_EVCTRL_REG_OFST (0x02) /**< (AC_EVCTRL) Event Control Offset */ +#define AC_INTENCLR_REG_OFST (0x04) /**< (AC_INTENCLR) Interrupt Enable Clear Offset */ +#define AC_INTENSET_REG_OFST (0x05) /**< (AC_INTENSET) Interrupt Enable Set Offset */ +#define AC_INTFLAG_REG_OFST (0x06) /**< (AC_INTFLAG) Interrupt Flag Status and Clear Offset */ +#define AC_STATUSA_REG_OFST (0x08) /**< (AC_STATUSA) Status A Offset */ +#define AC_STATUSB_REG_OFST (0x09) /**< (AC_STATUSB) Status B Offset */ +#define AC_STATUSC_REG_OFST (0x0A) /**< (AC_STATUSC) Status C Offset */ +#define AC_WINCTRL_REG_OFST (0x0C) /**< (AC_WINCTRL) Window Control Offset */ +#define AC_COMPCTRL_REG_OFST (0x10) /**< (AC_COMPCTRL) Comparator Control n Offset */ +#define AC_SCALER_REG_OFST (0x20) /**< (AC_SCALER) Scaler n Offset */ + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief AC register API structure */ +typedef struct +{ /* Analog Comparators */ + __IO uint8_t AC_CTRLA; /**< Offset: 0x00 (R/W 8) Control A */ + __O uint8_t AC_CTRLB; /**< Offset: 0x01 ( /W 8) Control B */ + __IO uint16_t AC_EVCTRL; /**< Offset: 0x02 (R/W 16) Event Control */ + __IO uint8_t AC_INTENCLR; /**< Offset: 0x04 (R/W 8) Interrupt Enable Clear */ + __IO uint8_t AC_INTENSET; /**< Offset: 0x05 (R/W 8) Interrupt Enable Set */ + __IO uint8_t AC_INTFLAG; /**< Offset: 0x06 (R/W 8) Interrupt Flag Status and Clear */ + __I uint8_t Reserved1[0x01]; + __I uint8_t AC_STATUSA; /**< Offset: 0x08 (R/ 8) Status A */ + __I uint8_t AC_STATUSB; /**< Offset: 0x09 (R/ 8) Status B */ + __I uint8_t AC_STATUSC; /**< Offset: 0x0A (R/ 8) Status C */ + __I uint8_t Reserved2[0x01]; + __IO uint8_t AC_WINCTRL; /**< Offset: 0x0C (R/W 8) Window Control */ + __I uint8_t Reserved3[0x03]; + __IO uint32_t AC_COMPCTRL[2]; /**< Offset: 0x10 (R/W 32) Comparator Control n */ + __I uint8_t Reserved4[0x08]; + __IO uint8_t AC_SCALER[2]; /**< Offset: 0x20 (R/W 8) Scaler n */ +} ac_registers_t; + + +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ +#endif /* _SAMD21_AC_COMPONENT_H_ */ diff --git a/core/arm/samd21a/include_mcc/component/adc.h b/core/arm/samd21a/include_mcc/component/adc.h new file mode 100644 index 000000000..bc0136aa0 --- /dev/null +++ b/core/arm/samd21a/include_mcc/component/adc.h @@ -0,0 +1,496 @@ +/** + * \brief Component description for ADC + * + * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries. + * + * Subject to your compliance with these terms, you may use Microchip software and any derivatives + * exclusively with Microchip products. It is your responsibility to comply with third party license + * terms applicable to your use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, + * APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND + * FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT + * EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + */ + +/* file generated from device description version 2019-05-20T21:16:53Z */ +#ifndef _SAMD21_ADC_COMPONENT_H_ +#define _SAMD21_ADC_COMPONENT_H_ + +/* ************************************************************************** */ +/* SOFTWARE API DEFINITION FOR ADC */ +/* ************************************************************************** */ + +/* -------- ADC_CTRLA : (ADC Offset: 0x00) (R/W 8) Control A -------- */ +#define ADC_CTRLA_RESETVALUE _U_(0x00) /**< (ADC_CTRLA) Control A Reset Value */ + +#define ADC_CTRLA_SWRST_Pos _U_(0) /**< (ADC_CTRLA) Software Reset Position */ +#define ADC_CTRLA_SWRST_Msk (_U_(0x1) << ADC_CTRLA_SWRST_Pos) /**< (ADC_CTRLA) Software Reset Mask */ +#define ADC_CTRLA_SWRST(value) (ADC_CTRLA_SWRST_Msk & ((value) << ADC_CTRLA_SWRST_Pos)) +#define ADC_CTRLA_ENABLE_Pos _U_(1) /**< (ADC_CTRLA) Enable Position */ +#define ADC_CTRLA_ENABLE_Msk (_U_(0x1) << ADC_CTRLA_ENABLE_Pos) /**< (ADC_CTRLA) Enable Mask */ +#define ADC_CTRLA_ENABLE(value) (ADC_CTRLA_ENABLE_Msk & ((value) << ADC_CTRLA_ENABLE_Pos)) +#define ADC_CTRLA_RUNSTDBY_Pos _U_(2) /**< (ADC_CTRLA) Run in Standby Position */ +#define ADC_CTRLA_RUNSTDBY_Msk (_U_(0x1) << ADC_CTRLA_RUNSTDBY_Pos) /**< (ADC_CTRLA) Run in Standby Mask */ +#define ADC_CTRLA_RUNSTDBY(value) (ADC_CTRLA_RUNSTDBY_Msk & ((value) << ADC_CTRLA_RUNSTDBY_Pos)) +#define ADC_CTRLA_Msk _U_(0x07) /**< (ADC_CTRLA) Register Mask */ + + +/* -------- ADC_REFCTRL : (ADC Offset: 0x01) (R/W 8) Reference Control -------- */ +#define ADC_REFCTRL_RESETVALUE _U_(0x00) /**< (ADC_REFCTRL) Reference Control Reset Value */ + +#define ADC_REFCTRL_REFSEL_Pos _U_(0) /**< (ADC_REFCTRL) Reference Selection Position */ +#define ADC_REFCTRL_REFSEL_Msk (_U_(0xF) << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) Reference Selection Mask */ +#define ADC_REFCTRL_REFSEL(value) (ADC_REFCTRL_REFSEL_Msk & ((value) << ADC_REFCTRL_REFSEL_Pos)) +#define ADC_REFCTRL_REFSEL_INT1V_Val _U_(0x0) /**< (ADC_REFCTRL) 1.0V voltage reference */ +#define ADC_REFCTRL_REFSEL_INTVCC0_Val _U_(0x1) /**< (ADC_REFCTRL) 1/1.48 VDDANA */ +#define ADC_REFCTRL_REFSEL_INTVCC1_Val _U_(0x2) /**< (ADC_REFCTRL) 1/2 VDDANA (only for VDDANA > 2.0V) */ +#define ADC_REFCTRL_REFSEL_AREFA_Val _U_(0x3) /**< (ADC_REFCTRL) External reference A */ +#define ADC_REFCTRL_REFSEL_AREFB_Val _U_(0x4) /**< (ADC_REFCTRL) External reference B */ +#define ADC_REFCTRL_REFSEL_INT1V (ADC_REFCTRL_REFSEL_INT1V_Val << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) 1.0V voltage reference Position */ +#define ADC_REFCTRL_REFSEL_INTVCC0 (ADC_REFCTRL_REFSEL_INTVCC0_Val << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) 1/1.48 VDDANA Position */ +#define ADC_REFCTRL_REFSEL_INTVCC1 (ADC_REFCTRL_REFSEL_INTVCC1_Val << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) 1/2 VDDANA (only for VDDANA > 2.0V) Position */ +#define ADC_REFCTRL_REFSEL_AREFA (ADC_REFCTRL_REFSEL_AREFA_Val << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) External reference A Position */ +#define ADC_REFCTRL_REFSEL_AREFB (ADC_REFCTRL_REFSEL_AREFB_Val << ADC_REFCTRL_REFSEL_Pos) /**< (ADC_REFCTRL) External reference B Position */ +#define ADC_REFCTRL_REFCOMP_Pos _U_(7) /**< (ADC_REFCTRL) Reference Buffer Offset Compensation Enable Position */ +#define ADC_REFCTRL_REFCOMP_Msk (_U_(0x1) << ADC_REFCTRL_REFCOMP_Pos) /**< (ADC_REFCTRL) Reference Buffer Offset Compensation Enable Mask */ +#define ADC_REFCTRL_REFCOMP(value) (ADC_REFCTRL_REFCOMP_Msk & ((value) << ADC_REFCTRL_REFCOMP_Pos)) +#define ADC_REFCTRL_Msk _U_(0x8F) /**< (ADC_REFCTRL) Register Mask */ + + +/* -------- ADC_AVGCTRL : (ADC Offset: 0x02) (R/W 8) Average Control -------- */ +#define ADC_AVGCTRL_RESETVALUE _U_(0x00) /**< (ADC_AVGCTRL) Average Control Reset Value */ + +#define ADC_AVGCTRL_SAMPLENUM_Pos _U_(0) /**< (ADC_AVGCTRL) Number of Samples to be Collected Position */ +#define ADC_AVGCTRL_SAMPLENUM_Msk (_U_(0xF) << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) Number of Samples to be Collected Mask */ +#define ADC_AVGCTRL_SAMPLENUM(value) (ADC_AVGCTRL_SAMPLENUM_Msk & ((value) << ADC_AVGCTRL_SAMPLENUM_Pos)) +#define ADC_AVGCTRL_SAMPLENUM_1_Val _U_(0x0) /**< (ADC_AVGCTRL) 1 sample */ +#define ADC_AVGCTRL_SAMPLENUM_2_Val _U_(0x1) /**< (ADC_AVGCTRL) 2 samples */ +#define ADC_AVGCTRL_SAMPLENUM_4_Val _U_(0x2) /**< (ADC_AVGCTRL) 4 samples */ +#define ADC_AVGCTRL_SAMPLENUM_8_Val _U_(0x3) /**< (ADC_AVGCTRL) 8 samples */ +#define ADC_AVGCTRL_SAMPLENUM_16_Val _U_(0x4) /**< (ADC_AVGCTRL) 16 samples */ +#define ADC_AVGCTRL_SAMPLENUM_32_Val _U_(0x5) /**< (ADC_AVGCTRL) 32 samples */ +#define ADC_AVGCTRL_SAMPLENUM_64_Val _U_(0x6) /**< (ADC_AVGCTRL) 64 samples */ +#define ADC_AVGCTRL_SAMPLENUM_128_Val _U_(0x7) /**< (ADC_AVGCTRL) 128 samples */ +#define ADC_AVGCTRL_SAMPLENUM_256_Val _U_(0x8) /**< (ADC_AVGCTRL) 256 samples */ +#define ADC_AVGCTRL_SAMPLENUM_512_Val _U_(0x9) /**< (ADC_AVGCTRL) 512 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1024_Val _U_(0xA) /**< (ADC_AVGCTRL) 1024 samples */ +#define ADC_AVGCTRL_SAMPLENUM_1 (ADC_AVGCTRL_SAMPLENUM_1_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 1 sample Position */ +#define ADC_AVGCTRL_SAMPLENUM_2 (ADC_AVGCTRL_SAMPLENUM_2_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 2 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_4 (ADC_AVGCTRL_SAMPLENUM_4_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 4 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_8 (ADC_AVGCTRL_SAMPLENUM_8_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 8 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_16 (ADC_AVGCTRL_SAMPLENUM_16_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 16 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_32 (ADC_AVGCTRL_SAMPLENUM_32_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 32 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_64 (ADC_AVGCTRL_SAMPLENUM_64_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 64 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_128 (ADC_AVGCTRL_SAMPLENUM_128_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 128 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_256 (ADC_AVGCTRL_SAMPLENUM_256_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 256 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_512 (ADC_AVGCTRL_SAMPLENUM_512_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 512 samples Position */ +#define ADC_AVGCTRL_SAMPLENUM_1024 (ADC_AVGCTRL_SAMPLENUM_1024_Val << ADC_AVGCTRL_SAMPLENUM_Pos) /**< (ADC_AVGCTRL) 1024 samples Position */ +#define ADC_AVGCTRL_ADJRES_Pos _U_(4) /**< (ADC_AVGCTRL) Adjusting Result / Division Coefficient Position */ +#define ADC_AVGCTRL_ADJRES_Msk (_U_(0x7) << ADC_AVGCTRL_ADJRES_Pos) /**< (ADC_AVGCTRL) Adjusting Result / Division Coefficient Mask */ +#define ADC_AVGCTRL_ADJRES(value) (ADC_AVGCTRL_ADJRES_Msk & ((value) << ADC_AVGCTRL_ADJRES_Pos)) +#define ADC_AVGCTRL_Msk _U_(0x7F) /**< (ADC_AVGCTRL) Register Mask */ + + +/* -------- ADC_SAMPCTRL : (ADC Offset: 0x03) (R/W 8) Sampling Time Control -------- */ +#define ADC_SAMPCTRL_RESETVALUE _U_(0x00) /**< (ADC_SAMPCTRL) Sampling Time Control Reset Value */ + +#define ADC_SAMPCTRL_SAMPLEN_Pos _U_(0) /**< (ADC_SAMPCTRL) Sampling Time Length Position */ +#define ADC_SAMPCTRL_SAMPLEN_Msk (_U_(0x3F) << ADC_SAMPCTRL_SAMPLEN_Pos) /**< (ADC_SAMPCTRL) Sampling Time Length Mask */ +#define ADC_SAMPCTRL_SAMPLEN(value) (ADC_SAMPCTRL_SAMPLEN_Msk & ((value) << ADC_SAMPCTRL_SAMPLEN_Pos)) +#define ADC_SAMPCTRL_Msk _U_(0x3F) /**< (ADC_SAMPCTRL) Register Mask */ + + +/* -------- ADC_CTRLB : (ADC Offset: 0x04) (R/W 16) Control B -------- */ +#define ADC_CTRLB_RESETVALUE _U_(0x00) /**< (ADC_CTRLB) Control B Reset Value */ + +#define ADC_CTRLB_DIFFMODE_Pos _U_(0) /**< (ADC_CTRLB) Differential Mode Position */ +#define ADC_CTRLB_DIFFMODE_Msk (_U_(0x1) << ADC_CTRLB_DIFFMODE_Pos) /**< (ADC_CTRLB) Differential Mode Mask */ +#define ADC_CTRLB_DIFFMODE(value) (ADC_CTRLB_DIFFMODE_Msk & ((value) << ADC_CTRLB_DIFFMODE_Pos)) +#define ADC_CTRLB_LEFTADJ_Pos _U_(1) /**< (ADC_CTRLB) Left-Adjusted Result Position */ +#define ADC_CTRLB_LEFTADJ_Msk (_U_(0x1) << ADC_CTRLB_LEFTADJ_Pos) /**< (ADC_CTRLB) Left-Adjusted Result Mask */ +#define ADC_CTRLB_LEFTADJ(value) (ADC_CTRLB_LEFTADJ_Msk & ((value) << ADC_CTRLB_LEFTADJ_Pos)) +#define ADC_CTRLB_FREERUN_Pos _U_(2) /**< (ADC_CTRLB) Free Running Mode Position */ +#define ADC_CTRLB_FREERUN_Msk (_U_(0x1) << ADC_CTRLB_FREERUN_Pos) /**< (ADC_CTRLB) Free Running Mode Mask */ +#define ADC_CTRLB_FREERUN(value) (ADC_CTRLB_FREERUN_Msk & ((value) << ADC_CTRLB_FREERUN_Pos)) +#define ADC_CTRLB_CORREN_Pos _U_(3) /**< (ADC_CTRLB) Digital Correction Logic Enabled Position */ +#define ADC_CTRLB_CORREN_Msk (_U_(0x1) << ADC_CTRLB_CORREN_Pos) /**< (ADC_CTRLB) Digital Correction Logic Enabled Mask */ +#define ADC_CTRLB_CORREN(value) (ADC_CTRLB_CORREN_Msk & ((value) << ADC_CTRLB_CORREN_Pos)) +#define ADC_CTRLB_RESSEL_Pos _U_(4) /**< (ADC_CTRLB) Conversion Result Resolution Position */ +#define ADC_CTRLB_RESSEL_Msk (_U_(0x3) << ADC_CTRLB_RESSEL_Pos) /**< (ADC_CTRLB) Conversion Result Resolution Mask */ +#define ADC_CTRLB_RESSEL(value) (ADC_CTRLB_RESSEL_Msk & ((value) << ADC_CTRLB_RESSEL_Pos)) +#define ADC_CTRLB_RESSEL_12BIT_Val _U_(0x0) /**< (ADC_CTRLB) 12-bit result */ +#define ADC_CTRLB_RESSEL_16BIT_Val _U_(0x1) /**< (ADC_CTRLB) 16-bit averaging mode */ +#define ADC_CTRLB_RESSEL_10BIT_Val _U_(0x2) /**< (ADC_CTRLB) 10-bit result */ +#define ADC_CTRLB_RESSEL_8BIT_Val _U_(0x3) /**< (ADC_CTRLB) 8-bit result */ +#define ADC_CTRLB_RESSEL_12BIT (ADC_CTRLB_RESSEL_12BIT_Val << ADC_CTRLB_RESSEL_Pos) /**< (ADC_CTRLB) 12-bit result Position */ +#define ADC_CTRLB_RESSEL_16BIT (ADC_CTRLB_RESSEL_16BIT_Val << ADC_CTRLB_RESSEL_Pos) /**< (ADC_CTRLB) 16-bit averaging mode Position */ +#define ADC_CTRLB_RESSEL_10BIT (ADC_CTRLB_RESSEL_10BIT_Val << ADC_CTRLB_RESSEL_Pos) /**< (ADC_CTRLB) 10-bit result Position */ +#define ADC_CTRLB_RESSEL_8BIT (ADC_CTRLB_RESSEL_8BIT_Val << ADC_CTRLB_RESSEL_Pos) /**< (ADC_CTRLB) 8-bit result Position */ +#define ADC_CTRLB_PRESCALER_Pos _U_(8) /**< (ADC_CTRLB) Prescaler Configuration Position */ +#define ADC_CTRLB_PRESCALER_Msk (_U_(0x7) << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Prescaler Configuration Mask */ +#define ADC_CTRLB_PRESCALER(value) (ADC_CTRLB_PRESCALER_Msk & ((value) << ADC_CTRLB_PRESCALER_Pos)) +#define ADC_CTRLB_PRESCALER_DIV4_Val _U_(0x0) /**< (ADC_CTRLB) Peripheral clock divided by 4 */ +#define ADC_CTRLB_PRESCALER_DIV8_Val _U_(0x1) /**< (ADC_CTRLB) Peripheral clock divided by 8 */ +#define ADC_CTRLB_PRESCALER_DIV16_Val _U_(0x2) /**< (ADC_CTRLB) Peripheral clock divided by 16 */ +#define ADC_CTRLB_PRESCALER_DIV32_Val _U_(0x3) /**< (ADC_CTRLB) Peripheral clock divided by 32 */ +#define ADC_CTRLB_PRESCALER_DIV64_Val _U_(0x4) /**< (ADC_CTRLB) Peripheral clock divided by 64 */ +#define ADC_CTRLB_PRESCALER_DIV128_Val _U_(0x5) /**< (ADC_CTRLB) Peripheral clock divided by 128 */ +#define ADC_CTRLB_PRESCALER_DIV256_Val _U_(0x6) /**< (ADC_CTRLB) Peripheral clock divided by 256 */ +#define ADC_CTRLB_PRESCALER_DIV512_Val _U_(0x7) /**< (ADC_CTRLB) Peripheral clock divided by 512 */ +#define ADC_CTRLB_PRESCALER_DIV4 (ADC_CTRLB_PRESCALER_DIV4_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 4 Position */ +#define ADC_CTRLB_PRESCALER_DIV8 (ADC_CTRLB_PRESCALER_DIV8_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 8 Position */ +#define ADC_CTRLB_PRESCALER_DIV16 (ADC_CTRLB_PRESCALER_DIV16_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 16 Position */ +#define ADC_CTRLB_PRESCALER_DIV32 (ADC_CTRLB_PRESCALER_DIV32_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 32 Position */ +#define ADC_CTRLB_PRESCALER_DIV64 (ADC_CTRLB_PRESCALER_DIV64_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 64 Position */ +#define ADC_CTRLB_PRESCALER_DIV128 (ADC_CTRLB_PRESCALER_DIV128_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 128 Position */ +#define ADC_CTRLB_PRESCALER_DIV256 (ADC_CTRLB_PRESCALER_DIV256_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 256 Position */ +#define ADC_CTRLB_PRESCALER_DIV512 (ADC_CTRLB_PRESCALER_DIV512_Val << ADC_CTRLB_PRESCALER_Pos) /**< (ADC_CTRLB) Peripheral clock divided by 512 Position */ +#define ADC_CTRLB_Msk _U_(0x073F) /**< (ADC_CTRLB) Register Mask */ + + +/* -------- ADC_WINCTRL : (ADC Offset: 0x08) (R/W 8) Window Monitor Control -------- */ +#define ADC_WINCTRL_RESETVALUE _U_(0x00) /**< (ADC_WINCTRL) Window Monitor Control Reset Value */ + +#define ADC_WINCTRL_WINMODE_Pos _U_(0) /**< (ADC_WINCTRL) Window Monitor Mode Position */ +#define ADC_WINCTRL_WINMODE_Msk (_U_(0x7) << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) Window Monitor Mode Mask */ +#define ADC_WINCTRL_WINMODE(value) (ADC_WINCTRL_WINMODE_Msk & ((value) << ADC_WINCTRL_WINMODE_Pos)) +#define ADC_WINCTRL_WINMODE_DISABLE_Val _U_(0x0) /**< (ADC_WINCTRL) No window mode (default) */ +#define ADC_WINCTRL_WINMODE_MODE1_Val _U_(0x1) /**< (ADC_WINCTRL) Mode 1: RESULT > WINLT */ +#define ADC_WINCTRL_WINMODE_MODE2_Val _U_(0x2) /**< (ADC_WINCTRL) Mode 2: RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE3_Val _U_(0x3) /**< (ADC_WINCTRL) Mode 3: WINLT < RESULT < WINUT */ +#define ADC_WINCTRL_WINMODE_MODE4_Val _U_(0x4) /**< (ADC_WINCTRL) Mode 4: !(WINLT < RESULT < WINUT) */ +#define ADC_WINCTRL_WINMODE_DISABLE (ADC_WINCTRL_WINMODE_DISABLE_Val << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) No window mode (default) Position */ +#define ADC_WINCTRL_WINMODE_MODE1 (ADC_WINCTRL_WINMODE_MODE1_Val << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) Mode 1: RESULT > WINLT Position */ +#define ADC_WINCTRL_WINMODE_MODE2 (ADC_WINCTRL_WINMODE_MODE2_Val << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) Mode 2: RESULT < WINUT Position */ +#define ADC_WINCTRL_WINMODE_MODE3 (ADC_WINCTRL_WINMODE_MODE3_Val << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) Mode 3: WINLT < RESULT < WINUT Position */ +#define ADC_WINCTRL_WINMODE_MODE4 (ADC_WINCTRL_WINMODE_MODE4_Val << ADC_WINCTRL_WINMODE_Pos) /**< (ADC_WINCTRL) Mode 4: !(WINLT < RESULT < WINUT) Position */ +#define ADC_WINCTRL_Msk _U_(0x07) /**< (ADC_WINCTRL) Register Mask */ + + +/* -------- ADC_SWTRIG : (ADC Offset: 0x0C) (R/W 8) Software Trigger -------- */ +#define ADC_SWTRIG_RESETVALUE _U_(0x00) /**< (ADC_SWTRIG) Software Trigger Reset Value */ + +#define ADC_SWTRIG_FLUSH_Pos _U_(0) /**< (ADC_SWTRIG) ADC Conversion Flush Position */ +#define ADC_SWTRIG_FLUSH_Msk (_U_(0x1) << ADC_SWTRIG_FLUSH_Pos) /**< (ADC_SWTRIG) ADC Conversion Flush Mask */ +#define ADC_SWTRIG_FLUSH(value) (ADC_SWTRIG_FLUSH_Msk & ((value) << ADC_SWTRIG_FLUSH_Pos)) +#define ADC_SWTRIG_START_Pos _U_(1) /**< (ADC_SWTRIG) ADC Start Conversion Position */ +#define ADC_SWTRIG_START_Msk (_U_(0x1) << ADC_SWTRIG_START_Pos) /**< (ADC_SWTRIG) ADC Start Conversion Mask */ +#define ADC_SWTRIG_START(value) (ADC_SWTRIG_START_Msk & ((value) << ADC_SWTRIG_START_Pos)) +#define ADC_SWTRIG_Msk _U_(0x03) /**< (ADC_SWTRIG) Register Mask */ + + +/* -------- ADC_INPUTCTRL : (ADC Offset: 0x10) (R/W 32) Input Control -------- */ +#define ADC_INPUTCTRL_RESETVALUE _U_(0x00) /**< (ADC_INPUTCTRL) Input Control Reset Value */ + +#define ADC_INPUTCTRL_MUXPOS_Pos _U_(0) /**< (ADC_INPUTCTRL) Positive Mux Input Selection Position */ +#define ADC_INPUTCTRL_MUXPOS_Msk (_U_(0x1F) << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) Positive Mux Input Selection Mask */ +#define ADC_INPUTCTRL_MUXPOS(value) (ADC_INPUTCTRL_MUXPOS_Msk & ((value) << ADC_INPUTCTRL_MUXPOS_Pos)) +#define ADC_INPUTCTRL_MUXPOS_PIN0_Val _U_(0x0) /**< (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN1_Val _U_(0x1) /**< (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN2_Val _U_(0x2) /**< (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN3_Val _U_(0x3) /**< (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN4_Val _U_(0x4) /**< (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN5_Val _U_(0x5) /**< (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN6_Val _U_(0x6) /**< (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN7_Val _U_(0x7) /**< (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN8_Val _U_(0x8) /**< (ADC_INPUTCTRL) ADC AIN8 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN9_Val _U_(0x9) /**< (ADC_INPUTCTRL) ADC AIN9 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN10_Val _U_(0xA) /**< (ADC_INPUTCTRL) ADC AIN10 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN11_Val _U_(0xB) /**< (ADC_INPUTCTRL) ADC AIN11 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN12_Val _U_(0xC) /**< (ADC_INPUTCTRL) ADC AIN12 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN13_Val _U_(0xD) /**< (ADC_INPUTCTRL) ADC AIN13 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN14_Val _U_(0xE) /**< (ADC_INPUTCTRL) ADC AIN14 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN15_Val _U_(0xF) /**< (ADC_INPUTCTRL) ADC AIN15 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN16_Val _U_(0x10) /**< (ADC_INPUTCTRL) ADC AIN16 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN17_Val _U_(0x11) /**< (ADC_INPUTCTRL) ADC AIN17 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN18_Val _U_(0x12) /**< (ADC_INPUTCTRL) ADC AIN18 Pin */ +#define ADC_INPUTCTRL_MUXPOS_PIN19_Val _U_(0x13) /**< (ADC_INPUTCTRL) ADC AIN19 Pin */ +#define ADC_INPUTCTRL_MUXPOS_TEMP_Val _U_(0x18) /**< (ADC_INPUTCTRL) Temperature Reference */ +#define ADC_INPUTCTRL_MUXPOS_BANDGAP_Val _U_(0x19) /**< (ADC_INPUTCTRL) Bandgap Voltage */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val _U_(0x1A) /**< (ADC_INPUTCTRL) 1/4 Scaled Core Supply */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val _U_(0x1B) /**< (ADC_INPUTCTRL) 1/4 Scaled I/O Supply */ +#define ADC_INPUTCTRL_MUXPOS_DAC_Val _U_(0x1C) /**< (ADC_INPUTCTRL) DAC Output */ +#define ADC_INPUTCTRL_MUXPOS_PIN0 (ADC_INPUTCTRL_MUXPOS_PIN0_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN0 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN1 (ADC_INPUTCTRL_MUXPOS_PIN1_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN1 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN2 (ADC_INPUTCTRL_MUXPOS_PIN2_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN2 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN3 (ADC_INPUTCTRL_MUXPOS_PIN3_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN3 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN4 (ADC_INPUTCTRL_MUXPOS_PIN4_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN4 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN5 (ADC_INPUTCTRL_MUXPOS_PIN5_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN5 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN6 (ADC_INPUTCTRL_MUXPOS_PIN6_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN6 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN7 (ADC_INPUTCTRL_MUXPOS_PIN7_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN7 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN8 (ADC_INPUTCTRL_MUXPOS_PIN8_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN8 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN9 (ADC_INPUTCTRL_MUXPOS_PIN9_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN9 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN10 (ADC_INPUTCTRL_MUXPOS_PIN10_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN10 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN11 (ADC_INPUTCTRL_MUXPOS_PIN11_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN11 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN12 (ADC_INPUTCTRL_MUXPOS_PIN12_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN12 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN13 (ADC_INPUTCTRL_MUXPOS_PIN13_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN13 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN14 (ADC_INPUTCTRL_MUXPOS_PIN14_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN14 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN15 (ADC_INPUTCTRL_MUXPOS_PIN15_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN15 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN16 (ADC_INPUTCTRL_MUXPOS_PIN16_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN16 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN17 (ADC_INPUTCTRL_MUXPOS_PIN17_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN17 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN18 (ADC_INPUTCTRL_MUXPOS_PIN18_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN18 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_PIN19 (ADC_INPUTCTRL_MUXPOS_PIN19_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) ADC AIN19 Pin Position */ +#define ADC_INPUTCTRL_MUXPOS_TEMP (ADC_INPUTCTRL_MUXPOS_TEMP_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) Temperature Reference Position */ +#define ADC_INPUTCTRL_MUXPOS_BANDGAP (ADC_INPUTCTRL_MUXPOS_BANDGAP_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) Bandgap Voltage Position */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC (ADC_INPUTCTRL_MUXPOS_SCALEDCOREVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) 1/4 Scaled Core Supply Position */ +#define ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC (ADC_INPUTCTRL_MUXPOS_SCALEDIOVCC_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) 1/4 Scaled I/O Supply Position */ +#define ADC_INPUTCTRL_MUXPOS_DAC (ADC_INPUTCTRL_MUXPOS_DAC_Val << ADC_INPUTCTRL_MUXPOS_Pos) /**< (ADC_INPUTCTRL) DAC Output Position */ +#define ADC_INPUTCTRL_MUXNEG_Pos _U_(8) /**< (ADC_INPUTCTRL) Negative Mux Input Selection Position */ +#define ADC_INPUTCTRL_MUXNEG_Msk (_U_(0x1F) << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) Negative Mux Input Selection Mask */ +#define ADC_INPUTCTRL_MUXNEG(value) (ADC_INPUTCTRL_MUXNEG_Msk & ((value) << ADC_INPUTCTRL_MUXNEG_Pos)) +#define ADC_INPUTCTRL_MUXNEG_PIN0_Val _U_(0x0) /**< (ADC_INPUTCTRL) ADC AIN0 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN1_Val _U_(0x1) /**< (ADC_INPUTCTRL) ADC AIN1 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN2_Val _U_(0x2) /**< (ADC_INPUTCTRL) ADC AIN2 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN3_Val _U_(0x3) /**< (ADC_INPUTCTRL) ADC AIN3 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN4_Val _U_(0x4) /**< (ADC_INPUTCTRL) ADC AIN4 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN5_Val _U_(0x5) /**< (ADC_INPUTCTRL) ADC AIN5 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN6_Val _U_(0x6) /**< (ADC_INPUTCTRL) ADC AIN6 Pin */ +#define ADC_INPUTCTRL_MUXNEG_PIN7_Val _U_(0x7) /**< (ADC_INPUTCTRL) ADC AIN7 Pin */ +#define ADC_INPUTCTRL_MUXNEG_GND_Val _U_(0x18) /**< (ADC_INPUTCTRL) Internal Ground */ +#define ADC_INPUTCTRL_MUXNEG_IOGND_Val _U_(0x19) /**< (ADC_INPUTCTRL) I/O Ground */ +#define ADC_INPUTCTRL_MUXNEG_PIN0 (ADC_INPUTCTRL_MUXNEG_PIN0_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN0 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN1 (ADC_INPUTCTRL_MUXNEG_PIN1_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN1 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN2 (ADC_INPUTCTRL_MUXNEG_PIN2_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN2 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN3 (ADC_INPUTCTRL_MUXNEG_PIN3_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN3 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN4 (ADC_INPUTCTRL_MUXNEG_PIN4_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN4 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN5 (ADC_INPUTCTRL_MUXNEG_PIN5_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN5 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN6 (ADC_INPUTCTRL_MUXNEG_PIN6_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN6 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_PIN7 (ADC_INPUTCTRL_MUXNEG_PIN7_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) ADC AIN7 Pin Position */ +#define ADC_INPUTCTRL_MUXNEG_GND (ADC_INPUTCTRL_MUXNEG_GND_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) Internal Ground Position */ +#define ADC_INPUTCTRL_MUXNEG_IOGND (ADC_INPUTCTRL_MUXNEG_IOGND_Val << ADC_INPUTCTRL_MUXNEG_Pos) /**< (ADC_INPUTCTRL) I/O Ground Position */ +#define ADC_INPUTCTRL_INPUTSCAN_Pos _U_(16) /**< (ADC_INPUTCTRL) Number of Input Channels Included in Scan Position */ +#define ADC_INPUTCTRL_INPUTSCAN_Msk (_U_(0xF) << ADC_INPUTCTRL_INPUTSCAN_Pos) /**< (ADC_INPUTCTRL) Number of Input Channels Included in Scan Mask */ +#define ADC_INPUTCTRL_INPUTSCAN(value) (ADC_INPUTCTRL_INPUTSCAN_Msk & ((value) << ADC_INPUTCTRL_INPUTSCAN_Pos)) +#define ADC_INPUTCTRL_INPUTOFFSET_Pos _U_(20) /**< (ADC_INPUTCTRL) Positive Mux Setting Offset Position */ +#define ADC_INPUTCTRL_INPUTOFFSET_Msk (_U_(0xF) << ADC_INPUTCTRL_INPUTOFFSET_Pos) /**< (ADC_INPUTCTRL) Positive Mux Setting Offset Mask */ +#define ADC_INPUTCTRL_INPUTOFFSET(value) (ADC_INPUTCTRL_INPUTOFFSET_Msk & ((value) << ADC_INPUTCTRL_INPUTOFFSET_Pos)) +#define ADC_INPUTCTRL_GAIN_Pos _U_(24) /**< (ADC_INPUTCTRL) Gain Factor Selection Position */ +#define ADC_INPUTCTRL_GAIN_Msk (_U_(0xF) << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) Gain Factor Selection Mask */ +#define ADC_INPUTCTRL_GAIN(value) (ADC_INPUTCTRL_GAIN_Msk & ((value) << ADC_INPUTCTRL_GAIN_Pos)) +#define ADC_INPUTCTRL_GAIN_1X_Val _U_(0x0) /**< (ADC_INPUTCTRL) 1x */ +#define ADC_INPUTCTRL_GAIN_2X_Val _U_(0x1) /**< (ADC_INPUTCTRL) 2x */ +#define ADC_INPUTCTRL_GAIN_4X_Val _U_(0x2) /**< (ADC_INPUTCTRL) 4x */ +#define ADC_INPUTCTRL_GAIN_8X_Val _U_(0x3) /**< (ADC_INPUTCTRL) 8x */ +#define ADC_INPUTCTRL_GAIN_16X_Val _U_(0x4) /**< (ADC_INPUTCTRL) 16x */ +#define ADC_INPUTCTRL_GAIN_DIV2_Val _U_(0xF) /**< (ADC_INPUTCTRL) 1/2x */ +#define ADC_INPUTCTRL_GAIN_1X (ADC_INPUTCTRL_GAIN_1X_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 1x Position */ +#define ADC_INPUTCTRL_GAIN_2X (ADC_INPUTCTRL_GAIN_2X_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 2x Position */ +#define ADC_INPUTCTRL_GAIN_4X (ADC_INPUTCTRL_GAIN_4X_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 4x Position */ +#define ADC_INPUTCTRL_GAIN_8X (ADC_INPUTCTRL_GAIN_8X_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 8x Position */ +#define ADC_INPUTCTRL_GAIN_16X (ADC_INPUTCTRL_GAIN_16X_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 16x Position */ +#define ADC_INPUTCTRL_GAIN_DIV2 (ADC_INPUTCTRL_GAIN_DIV2_Val << ADC_INPUTCTRL_GAIN_Pos) /**< (ADC_INPUTCTRL) 1/2x Position */ +#define ADC_INPUTCTRL_Msk _U_(0x0FFF1F1F) /**< (ADC_INPUTCTRL) Register Mask */ + + +/* -------- ADC_EVCTRL : (ADC Offset: 0x14) (R/W 8) Event Control -------- */ +#define ADC_EVCTRL_RESETVALUE _U_(0x00) /**< (ADC_EVCTRL) Event Control Reset Value */ + +#define ADC_EVCTRL_STARTEI_Pos _U_(0) /**< (ADC_EVCTRL) Start Conversion Event In Position */ +#define ADC_EVCTRL_STARTEI_Msk (_U_(0x1) << ADC_EVCTRL_STARTEI_Pos) /**< (ADC_EVCTRL) Start Conversion Event In Mask */ +#define ADC_EVCTRL_STARTEI(value) (ADC_EVCTRL_STARTEI_Msk & ((value) << ADC_EVCTRL_STARTEI_Pos)) +#define ADC_EVCTRL_SYNCEI_Pos _U_(1) /**< (ADC_EVCTRL) Synchronization Event In Position */ +#define ADC_EVCTRL_SYNCEI_Msk (_U_(0x1) << ADC_EVCTRL_SYNCEI_Pos) /**< (ADC_EVCTRL) Synchronization Event In Mask */ +#define ADC_EVCTRL_SYNCEI(value) (ADC_EVCTRL_SYNCEI_Msk & ((value) << ADC_EVCTRL_SYNCEI_Pos)) +#define ADC_EVCTRL_RESRDYEO_Pos _U_(4) /**< (ADC_EVCTRL) Result Ready Event Out Position */ +#define ADC_EVCTRL_RESRDYEO_Msk (_U_(0x1) << ADC_EVCTRL_RESRDYEO_Pos) /**< (ADC_EVCTRL) Result Ready Event Out Mask */ +#define ADC_EVCTRL_RESRDYEO(value) (ADC_EVCTRL_RESRDYEO_Msk & ((value) << ADC_EVCTRL_RESRDYEO_Pos)) +#define ADC_EVCTRL_WINMONEO_Pos _U_(5) /**< (ADC_EVCTRL) Window Monitor Event Out Position */ +#define ADC_EVCTRL_WINMONEO_Msk (_U_(0x1) << ADC_EVCTRL_WINMONEO_Pos) /**< (ADC_EVCTRL) Window Monitor Event Out Mask */ +#define ADC_EVCTRL_WINMONEO(value) (ADC_EVCTRL_WINMONEO_Msk & ((value) << ADC_EVCTRL_WINMONEO_Pos)) +#define ADC_EVCTRL_Msk _U_(0x33) /**< (ADC_EVCTRL) Register Mask */ + + +/* -------- ADC_INTENCLR : (ADC Offset: 0x16) (R/W 8) Interrupt Enable Clear -------- */ +#define ADC_INTENCLR_RESETVALUE _U_(0x00) /**< (ADC_INTENCLR) Interrupt Enable Clear Reset Value */ + +#define ADC_INTENCLR_RESRDY_Pos _U_(0) /**< (ADC_INTENCLR) Result Ready Interrupt Enable Position */ +#define ADC_INTENCLR_RESRDY_Msk (_U_(0x1) << ADC_INTENCLR_RESRDY_Pos) /**< (ADC_INTENCLR) Result Ready Interrupt Enable Mask */ +#define ADC_INTENCLR_RESRDY(value) (ADC_INTENCLR_RESRDY_Msk & ((value) << ADC_INTENCLR_RESRDY_Pos)) +#define ADC_INTENCLR_OVERRUN_Pos _U_(1) /**< (ADC_INTENCLR) Overrun Interrupt Enable Position */ +#define ADC_INTENCLR_OVERRUN_Msk (_U_(0x1) << ADC_INTENCLR_OVERRUN_Pos) /**< (ADC_INTENCLR) Overrun Interrupt Enable Mask */ +#define ADC_INTENCLR_OVERRUN(value) (ADC_INTENCLR_OVERRUN_Msk & ((value) << ADC_INTENCLR_OVERRUN_Pos)) +#define ADC_INTENCLR_WINMON_Pos _U_(2) /**< (ADC_INTENCLR) Window Monitor Interrupt Enable Position */ +#define ADC_INTENCLR_WINMON_Msk (_U_(0x1) << ADC_INTENCLR_WINMON_Pos) /**< (ADC_INTENCLR) Window Monitor Interrupt Enable Mask */ +#define ADC_INTENCLR_WINMON(value) (ADC_INTENCLR_WINMON_Msk & ((value) << ADC_INTENCLR_WINMON_Pos)) +#define ADC_INTENCLR_SYNCRDY_Pos _U_(3) /**< (ADC_INTENCLR) Synchronization Ready Interrupt Enable Position */ +#define ADC_INTENCLR_SYNCRDY_Msk (_U_(0x1) << ADC_INTENCLR_SYNCRDY_Pos) /**< (ADC_INTENCLR) Synchronization Ready Interrupt Enable Mask */ +#define ADC_INTENCLR_SYNCRDY(value) (ADC_INTENCLR_SYNCRDY_Msk & ((value) << ADC_INTENCLR_SYNCRDY_Pos)) +#define ADC_INTENCLR_Msk _U_(0x0F) /**< (ADC_INTENCLR) Register Mask */ + + +/* -------- ADC_INTENSET : (ADC Offset: 0x17) (R/W 8) Interrupt Enable Set -------- */ +#define ADC_INTENSET_RESETVALUE _U_(0x00) /**< (ADC_INTENSET) Interrupt Enable Set Reset Value */ + +#define ADC_INTENSET_RESRDY_Pos _U_(0) /**< (ADC_INTENSET) Result Ready Interrupt Enable Position */ +#define ADC_INTENSET_RESRDY_Msk (_U_(0x1) << ADC_INTENSET_RESRDY_Pos) /**< (ADC_INTENSET) Result Ready Interrupt Enable Mask */ +#define ADC_INTENSET_RESRDY(value) (ADC_INTENSET_RESRDY_Msk & ((value) << ADC_INTENSET_RESRDY_Pos)) +#define ADC_INTENSET_OVERRUN_Pos _U_(1) /**< (ADC_INTENSET) Overrun Interrupt Enable Position */ +#define ADC_INTENSET_OVERRUN_Msk (_U_(0x1) << ADC_INTENSET_OVERRUN_Pos) /**< (ADC_INTENSET) Overrun Interrupt Enable Mask */ +#define ADC_INTENSET_OVERRUN(value) (ADC_INTENSET_OVERRUN_Msk & ((value) << ADC_INTENSET_OVERRUN_Pos)) +#define ADC_INTENSET_WINMON_Pos _U_(2) /**< (ADC_INTENSET) Window Monitor Interrupt Enable Position */ +#define ADC_INTENSET_WINMON_Msk (_U_(0x1) << ADC_INTENSET_WINMON_Pos) /**< (ADC_INTENSET) Window Monitor Interrupt Enable Mask */ +#define ADC_INTENSET_WINMON(value) (ADC_INTENSET_WINMON_Msk & ((value) << ADC_INTENSET_WINMON_Pos)) +#define ADC_INTENSET_SYNCRDY_Pos _U_(3) /**< (ADC_INTENSET) Synchronization Ready Interrupt Enable Position */ +#define ADC_INTENSET_SYNCRDY_Msk (_U_(0x1) << ADC_INTENSET_SYNCRDY_Pos) /**< (ADC_INTENSET) Synchronization Ready Interrupt Enable Mask */ +#define ADC_INTENSET_SYNCRDY(value) (ADC_INTENSET_SYNCRDY_Msk & ((value) << ADC_INTENSET_SYNCRDY_Pos)) +#define ADC_INTENSET_Msk _U_(0x0F) /**< (ADC_INTENSET) Register Mask */ + + +/* -------- ADC_INTFLAG : (ADC Offset: 0x18) (R/W 8) Interrupt Flag Status and Clear -------- */ +#define ADC_INTFLAG_RESETVALUE _U_(0x00) /**< (ADC_INTFLAG) Interrupt Flag Status and Clear Reset Value */ + +#define ADC_INTFLAG_RESRDY_Pos _U_(0) /**< (ADC_INTFLAG) Result Ready Position */ +#define ADC_INTFLAG_RESRDY_Msk (_U_(0x1) << ADC_INTFLAG_RESRDY_Pos) /**< (ADC_INTFLAG) Result Ready Mask */ +#define ADC_INTFLAG_RESRDY(value) (ADC_INTFLAG_RESRDY_Msk & ((value) << ADC_INTFLAG_RESRDY_Pos)) +#define ADC_INTFLAG_OVERRUN_Pos _U_(1) /**< (ADC_INTFLAG) Overrun Position */ +#define ADC_INTFLAG_OVERRUN_Msk (_U_(0x1) << ADC_INTFLAG_OVERRUN_Pos) /**< (ADC_INTFLAG) Overrun Mask */ +#define ADC_INTFLAG_OVERRUN(value) (ADC_INTFLAG_OVERRUN_Msk & ((value) << ADC_INTFLAG_OVERRUN_Pos)) +#define ADC_INTFLAG_WINMON_Pos _U_(2) /**< (ADC_INTFLAG) Window Monitor Position */ +#define ADC_INTFLAG_WINMON_Msk (_U_(0x1) << ADC_INTFLAG_WINMON_Pos) /**< (ADC_INTFLAG) Window Monitor Mask */ +#define ADC_INTFLAG_WINMON(value) (ADC_INTFLAG_WINMON_Msk & ((value) << ADC_INTFLAG_WINMON_Pos)) +#define ADC_INTFLAG_SYNCRDY_Pos _U_(3) /**< (ADC_INTFLAG) Synchronization Ready Position */ +#define ADC_INTFLAG_SYNCRDY_Msk (_U_(0x1) << ADC_INTFLAG_SYNCRDY_Pos) /**< (ADC_INTFLAG) Synchronization Ready Mask */ +#define ADC_INTFLAG_SYNCRDY(value) (ADC_INTFLAG_SYNCRDY_Msk & ((value) << ADC_INTFLAG_SYNCRDY_Pos)) +#define ADC_INTFLAG_Msk _U_(0x0F) /**< (ADC_INTFLAG) Register Mask */ + + +/* -------- ADC_STATUS : (ADC Offset: 0x19) ( R/ 8) Status -------- */ +#define ADC_STATUS_RESETVALUE _U_(0x00) /**< (ADC_STATUS) Status Reset Value */ + +#define ADC_STATUS_SYNCBUSY_Pos _U_(7) /**< (ADC_STATUS) Synchronization Busy Position */ +#define ADC_STATUS_SYNCBUSY_Msk (_U_(0x1) << ADC_STATUS_SYNCBUSY_Pos) /**< (ADC_STATUS) Synchronization Busy Mask */ +#define ADC_STATUS_SYNCBUSY(value) (ADC_STATUS_SYNCBUSY_Msk & ((value) << ADC_STATUS_SYNCBUSY_Pos)) +#define ADC_STATUS_Msk _U_(0x80) /**< (ADC_STATUS) Register Mask */ + + +/* -------- ADC_RESULT : (ADC Offset: 0x1A) ( R/ 16) Result -------- */ +#define ADC_RESULT_RESETVALUE _U_(0x00) /**< (ADC_RESULT) Result Reset Value */ + +#define ADC_RESULT_RESULT_Pos _U_(0) /**< (ADC_RESULT) Result Conversion Value Position */ +#define ADC_RESULT_RESULT_Msk (_U_(0xFFFF) << ADC_RESULT_RESULT_Pos) /**< (ADC_RESULT) Result Conversion Value Mask */ +#define ADC_RESULT_RESULT(value) (ADC_RESULT_RESULT_Msk & ((value) << ADC_RESULT_RESULT_Pos)) +#define ADC_RESULT_Msk _U_(0xFFFF) /**< (ADC_RESULT) Register Mask */ + + +/* -------- ADC_WINLT : (ADC Offset: 0x1C) (R/W 16) Window Monitor Lower Threshold -------- */ +#define ADC_WINLT_RESETVALUE _U_(0x00) /**< (ADC_WINLT) Window Monitor Lower Threshold Reset Value */ + +#define ADC_WINLT_WINLT_Pos _U_(0) /**< (ADC_WINLT) Window Lower Threshold Position */ +#define ADC_WINLT_WINLT_Msk (_U_(0xFFFF) << ADC_WINLT_WINLT_Pos) /**< (ADC_WINLT) Window Lower Threshold Mask */ +#define ADC_WINLT_WINLT(value) (ADC_WINLT_WINLT_Msk & ((value) << ADC_WINLT_WINLT_Pos)) +#define ADC_WINLT_Msk _U_(0xFFFF) /**< (ADC_WINLT) Register Mask */ + + +/* -------- ADC_WINUT : (ADC Offset: 0x20) (R/W 16) Window Monitor Upper Threshold -------- */ +#define ADC_WINUT_RESETVALUE _U_(0x00) /**< (ADC_WINUT) Window Monitor Upper Threshold Reset Value */ + +#define ADC_WINUT_WINUT_Pos _U_(0) /**< (ADC_WINUT) Window Upper Threshold Position */ +#define ADC_WINUT_WINUT_Msk (_U_(0xFFFF) << ADC_WINUT_WINUT_Pos) /**< (ADC_WINUT) Window Upper Threshold Mask */ +#define ADC_WINUT_WINUT(value) (ADC_WINUT_WINUT_Msk & ((value) << ADC_WINUT_WINUT_Pos)) +#define ADC_WINUT_Msk _U_(0xFFFF) /**< (ADC_WINUT) Register Mask */ + + +/* -------- ADC_GAINCORR : (ADC Offset: 0x24) (R/W 16) Gain Correction -------- */ +#define ADC_GAINCORR_RESETVALUE _U_(0x00) /**< (ADC_GAINCORR) Gain Correction Reset Value */ + +#define ADC_GAINCORR_GAINCORR_Pos _U_(0) /**< (ADC_GAINCORR) Gain Correction Value Position */ +#define ADC_GAINCORR_GAINCORR_Msk (_U_(0xFFF) << ADC_GAINCORR_GAINCORR_Pos) /**< (ADC_GAINCORR) Gain Correction Value Mask */ +#define ADC_GAINCORR_GAINCORR(value) (ADC_GAINCORR_GAINCORR_Msk & ((value) << ADC_GAINCORR_GAINCORR_Pos)) +#define ADC_GAINCORR_Msk _U_(0x0FFF) /**< (ADC_GAINCORR) Register Mask */ + + +/* -------- ADC_OFFSETCORR : (ADC Offset: 0x26) (R/W 16) Offset Correction -------- */ +#define ADC_OFFSETCORR_RESETVALUE _U_(0x00) /**< (ADC_OFFSETCORR) Offset Correction Reset Value */ + +#define ADC_OFFSETCORR_OFFSETCORR_Pos _U_(0) /**< (ADC_OFFSETCORR) Offset Correction Value Position */ +#define ADC_OFFSETCORR_OFFSETCORR_Msk (_U_(0xFFF) << ADC_OFFSETCORR_OFFSETCORR_Pos) /**< (ADC_OFFSETCORR) Offset Correction Value Mask */ +#define ADC_OFFSETCORR_OFFSETCORR(value) (ADC_OFFSETCORR_OFFSETCORR_Msk & ((value) << ADC_OFFSETCORR_OFFSETCORR_Pos)) +#define ADC_OFFSETCORR_Msk _U_(0x0FFF) /**< (ADC_OFFSETCORR) Register Mask */ + + +/* -------- ADC_CALIB : (ADC Offset: 0x28) (R/W 16) Calibration -------- */ +#define ADC_CALIB_RESETVALUE _U_(0x00) /**< (ADC_CALIB) Calibration Reset Value */ + +#define ADC_CALIB_LINEARITY_CAL_Pos _U_(0) /**< (ADC_CALIB) Linearity Calibration Value Position */ +#define ADC_CALIB_LINEARITY_CAL_Msk (_U_(0xFF) << ADC_CALIB_LINEARITY_CAL_Pos) /**< (ADC_CALIB) Linearity Calibration Value Mask */ +#define ADC_CALIB_LINEARITY_CAL(value) (ADC_CALIB_LINEARITY_CAL_Msk & ((value) << ADC_CALIB_LINEARITY_CAL_Pos)) +#define ADC_CALIB_BIAS_CAL_Pos _U_(8) /**< (ADC_CALIB) Bias Calibration Value Position */ +#define ADC_CALIB_BIAS_CAL_Msk (_U_(0x7) << ADC_CALIB_BIAS_CAL_Pos) /**< (ADC_CALIB) Bias Calibration Value Mask */ +#define ADC_CALIB_BIAS_CAL(value) (ADC_CALIB_BIAS_CAL_Msk & ((value) << ADC_CALIB_BIAS_CAL_Pos)) +#define ADC_CALIB_Msk _U_(0x07FF) /**< (ADC_CALIB) Register Mask */ + + +/* -------- ADC_DBGCTRL : (ADC Offset: 0x2A) (R/W 8) Debug Control -------- */ +#define ADC_DBGCTRL_RESETVALUE _U_(0x00) /**< (ADC_DBGCTRL) Debug Control Reset Value */ + +#define ADC_DBGCTRL_DBGRUN_Pos _U_(0) /**< (ADC_DBGCTRL) Debug Run Position */ +#define ADC_DBGCTRL_DBGRUN_Msk (_U_(0x1) << ADC_DBGCTRL_DBGRUN_Pos) /**< (ADC_DBGCTRL) Debug Run Mask */ +#define ADC_DBGCTRL_DBGRUN(value) (ADC_DBGCTRL_DBGRUN_Msk & ((value) << ADC_DBGCTRL_DBGRUN_Pos)) +#define ADC_DBGCTRL_Msk _U_(0x01) /**< (ADC_DBGCTRL) Register Mask */ + + +/** \brief ADC register offsets definitions */ +#define ADC_CTRLA_REG_OFST (0x00) /**< (ADC_CTRLA) Control A Offset */ +#define ADC_REFCTRL_REG_OFST (0x01) /**< (ADC_REFCTRL) Reference Control Offset */ +#define ADC_AVGCTRL_REG_OFST (0x02) /**< (ADC_AVGCTRL) Average Control Offset */ +#define ADC_SAMPCTRL_REG_OFST (0x03) /**< (ADC_SAMPCTRL) Sampling Time Control Offset */ +#define ADC_CTRLB_REG_OFST (0x04) /**< (ADC_CTRLB) Control B Offset */ +#define ADC_WINCTRL_REG_OFST (0x08) /**< (ADC_WINCTRL) Window Monitor Control Offset */ +#define ADC_SWTRIG_REG_OFST (0x0C) /**< (ADC_SWTRIG) Software Trigger Offset */ +#define ADC_INPUTCTRL_REG_OFST (0x10) /**< (ADC_INPUTCTRL) Input Control Offset */ +#define ADC_EVCTRL_REG_OFST (0x14) /**< (ADC_EVCTRL) Event Control Offset */ +#define ADC_INTENCLR_REG_OFST (0x16) /**< (ADC_INTENCLR) Interrupt Enable Clear Offset */ +#define ADC_INTENSET_REG_OFST (0x17) /**< (ADC_INTENSET) Interrupt Enable Set Offset */ +#define ADC_INTFLAG_REG_OFST (0x18) /**< (ADC_INTFLAG) Interrupt Flag Status and Clear Offset */ +#define ADC_STATUS_REG_OFST (0x19) /**< (ADC_STATUS) Status Offset */ +#define ADC_RESULT_REG_OFST (0x1A) /**< (ADC_RESULT) Result Offset */ +#define ADC_WINLT_REG_OFST (0x1C) /**< (ADC_WINLT) Window Monitor Lower Threshold Offset */ +#define ADC_WINUT_REG_OFST (0x20) /**< (ADC_WINUT) Window Monitor Upper Threshold Offset */ +#define ADC_GAINCORR_REG_OFST (0x24) /**< (ADC_GAINCORR) Gain Correction Offset */ +#define ADC_OFFSETCORR_REG_OFST (0x26) /**< (ADC_OFFSETCORR) Offset Correction Offset */ +#define ADC_CALIB_REG_OFST (0x28) /**< (ADC_CALIB) Calibration Offset */ +#define ADC_DBGCTRL_REG_OFST (0x2A) /**< (ADC_DBGCTRL) Debug Control Offset */ + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief ADC register API structure */ +typedef struct +{ /* Analog Digital Converter */ + __IO uint8_t ADC_CTRLA; /**< Offset: 0x00 (R/W 8) Control A */ + __IO uint8_t ADC_REFCTRL; /**< Offset: 0x01 (R/W 8) Reference Control */ + __IO uint8_t ADC_AVGCTRL; /**< Offset: 0x02 (R/W 8) Average Control */ + __IO uint8_t ADC_SAMPCTRL; /**< Offset: 0x03 (R/W 8) Sampling Time Control */ + __IO uint16_t ADC_CTRLB; /**< Offset: 0x04 (R/W 16) Control B */ + __I uint8_t Reserved1[0x02]; + __IO uint8_t ADC_WINCTRL; /**< Offset: 0x08 (R/W 8) Window Monitor Control */ + __I uint8_t Reserved2[0x03]; + __IO uint8_t ADC_SWTRIG; /**< Offset: 0x0C (R/W 8) Software Trigger */ + __I uint8_t Reserved3[0x03]; + __IO uint32_t ADC_INPUTCTRL; /**< Offset: 0x10 (R/W 32) Input Control */ + __IO uint8_t ADC_EVCTRL; /**< Offset: 0x14 (R/W 8) Event Control */ + __I uint8_t Reserved4[0x01]; + __IO uint8_t ADC_INTENCLR; /**< Offset: 0x16 (R/W 8) Interrupt Enable Clear */ + __IO uint8_t ADC_INTENSET; /**< Offset: 0x17 (R/W 8) Interrupt Enable Set */ + __IO uint8_t ADC_INTFLAG; /**< Offset: 0x18 (R/W 8) Interrupt Flag Status and Clear */ + __I uint8_t ADC_STATUS; /**< Offset: 0x19 (R/ 8) Status */ + __I uint16_t ADC_RESULT; /**< Offset: 0x1A (R/ 16) Result */ + __IO uint16_t ADC_WINLT; /**< Offset: 0x1C (R/W 16) Window Monitor Lower Threshold */ + __I uint8_t Reserved5[0x02]; + __IO uint16_t ADC_WINUT; /**< Offset: 0x20 (R/W 16) Window Monitor Upper Threshold */ + __I uint8_t Reserved6[0x02]; + __IO uint16_t ADC_GAINCORR; /**< Offset: 0x24 (R/W 16) Gain Correction */ + __IO uint16_t ADC_OFFSETCORR; /**< Offset: 0x26 (R/W 16) Offset Correction */ + __IO uint16_t ADC_CALIB; /**< Offset: 0x28 (R/W 16) Calibration */ + __IO uint8_t ADC_DBGCTRL; /**< Offset: 0x2A (R/W 8) Debug Control */ +} adc_registers_t; + + +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ +#endif /* _SAMD21_ADC_COMPONENT_H_ */ diff --git a/core/arm/samd21a/include_mcc/component/dac.h b/core/arm/samd21a/include_mcc/component/dac.h new file mode 100644 index 000000000..0f612385f --- /dev/null +++ b/core/arm/samd21a/include_mcc/component/dac.h @@ -0,0 +1,190 @@ +/** + * \brief Component description for DAC + * + * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries. + * + * Subject to your compliance with these terms, you may use Microchip software and any derivatives + * exclusively with Microchip products. It is your responsibility to comply with third party license + * terms applicable to your use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, + * APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND + * FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT + * EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + */ + +/* file generated from device description version 2019-05-20T21:16:53Z */ +#ifndef _SAMD21_DAC_COMPONENT_H_ +#define _SAMD21_DAC_COMPONENT_H_ + +/* ************************************************************************** */ +/* SOFTWARE API DEFINITION FOR DAC */ +/* ************************************************************************** */ + +/* -------- DAC_CTRLA : (DAC Offset: 0x00) (R/W 8) Control A -------- */ +#define DAC_CTRLA_RESETVALUE _U_(0x00) /**< (DAC_CTRLA) Control A Reset Value */ + +#define DAC_CTRLA_SWRST_Pos _U_(0) /**< (DAC_CTRLA) Software Reset Position */ +#define DAC_CTRLA_SWRST_Msk (_U_(0x1) << DAC_CTRLA_SWRST_Pos) /**< (DAC_CTRLA) Software Reset Mask */ +#define DAC_CTRLA_SWRST(value) (DAC_CTRLA_SWRST_Msk & ((value) << DAC_CTRLA_SWRST_Pos)) +#define DAC_CTRLA_ENABLE_Pos _U_(1) /**< (DAC_CTRLA) Enable Position */ +#define DAC_CTRLA_ENABLE_Msk (_U_(0x1) << DAC_CTRLA_ENABLE_Pos) /**< (DAC_CTRLA) Enable Mask */ +#define DAC_CTRLA_ENABLE(value) (DAC_CTRLA_ENABLE_Msk & ((value) << DAC_CTRLA_ENABLE_Pos)) +#define DAC_CTRLA_RUNSTDBY_Pos _U_(2) /**< (DAC_CTRLA) Run in Standby Position */ +#define DAC_CTRLA_RUNSTDBY_Msk (_U_(0x1) << DAC_CTRLA_RUNSTDBY_Pos) /**< (DAC_CTRLA) Run in Standby Mask */ +#define DAC_CTRLA_RUNSTDBY(value) (DAC_CTRLA_RUNSTDBY_Msk & ((value) << DAC_CTRLA_RUNSTDBY_Pos)) +#define DAC_CTRLA_Msk _U_(0x07) /**< (DAC_CTRLA) Register Mask */ + + +/* -------- DAC_CTRLB : (DAC Offset: 0x01) (R/W 8) Control B -------- */ +#define DAC_CTRLB_RESETVALUE _U_(0x00) /**< (DAC_CTRLB) Control B Reset Value */ + +#define DAC_CTRLB_EOEN_Pos _U_(0) /**< (DAC_CTRLB) External Output Enable Position */ +#define DAC_CTRLB_EOEN_Msk (_U_(0x1) << DAC_CTRLB_EOEN_Pos) /**< (DAC_CTRLB) External Output Enable Mask */ +#define DAC_CTRLB_EOEN(value) (DAC_CTRLB_EOEN_Msk & ((value) << DAC_CTRLB_EOEN_Pos)) +#define DAC_CTRLB_IOEN_Pos _U_(1) /**< (DAC_CTRLB) Internal Output Enable Position */ +#define DAC_CTRLB_IOEN_Msk (_U_(0x1) << DAC_CTRLB_IOEN_Pos) /**< (DAC_CTRLB) Internal Output Enable Mask */ +#define DAC_CTRLB_IOEN(value) (DAC_CTRLB_IOEN_Msk & ((value) << DAC_CTRLB_IOEN_Pos)) +#define DAC_CTRLB_LEFTADJ_Pos _U_(2) /**< (DAC_CTRLB) Left Adjusted Data Position */ +#define DAC_CTRLB_LEFTADJ_Msk (_U_(0x1) << DAC_CTRLB_LEFTADJ_Pos) /**< (DAC_CTRLB) Left Adjusted Data Mask */ +#define DAC_CTRLB_LEFTADJ(value) (DAC_CTRLB_LEFTADJ_Msk & ((value) << DAC_CTRLB_LEFTADJ_Pos)) +#define DAC_CTRLB_VPD_Pos _U_(3) /**< (DAC_CTRLB) Voltage Pump Disable Position */ +#define DAC_CTRLB_VPD_Msk (_U_(0x1) << DAC_CTRLB_VPD_Pos) /**< (DAC_CTRLB) Voltage Pump Disable Mask */ +#define DAC_CTRLB_VPD(value) (DAC_CTRLB_VPD_Msk & ((value) << DAC_CTRLB_VPD_Pos)) +#define DAC_CTRLB_BDWP_Pos _U_(4) /**< (DAC_CTRLB) Bypass DATABUF Write Protection Position */ +#define DAC_CTRLB_BDWP_Msk (_U_(0x1) << DAC_CTRLB_BDWP_Pos) /**< (DAC_CTRLB) Bypass DATABUF Write Protection Mask */ +#define DAC_CTRLB_BDWP(value) (DAC_CTRLB_BDWP_Msk & ((value) << DAC_CTRLB_BDWP_Pos)) +#define DAC_CTRLB_REFSEL_Pos _U_(6) /**< (DAC_CTRLB) Reference Selection Position */ +#define DAC_CTRLB_REFSEL_Msk (_U_(0x3) << DAC_CTRLB_REFSEL_Pos) /**< (DAC_CTRLB) Reference Selection Mask */ +#define DAC_CTRLB_REFSEL(value) (DAC_CTRLB_REFSEL_Msk & ((value) << DAC_CTRLB_REFSEL_Pos)) +#define DAC_CTRLB_REFSEL_INT1V_Val _U_(0x0) /**< (DAC_CTRLB) Internal 1.0V reference */ +#define DAC_CTRLB_REFSEL_AVCC_Val _U_(0x1) /**< (DAC_CTRLB) AVCC */ +#define DAC_CTRLB_REFSEL_VREFP_Val _U_(0x2) /**< (DAC_CTRLB) External reference */ +#define DAC_CTRLB_REFSEL_INT1V (DAC_CTRLB_REFSEL_INT1V_Val << DAC_CTRLB_REFSEL_Pos) /**< (DAC_CTRLB) Internal 1.0V reference Position */ +#define DAC_CTRLB_REFSEL_AVCC (DAC_CTRLB_REFSEL_AVCC_Val << DAC_CTRLB_REFSEL_Pos) /**< (DAC_CTRLB) AVCC Position */ +#define DAC_CTRLB_REFSEL_VREFP (DAC_CTRLB_REFSEL_VREFP_Val << DAC_CTRLB_REFSEL_Pos) /**< (DAC_CTRLB) External reference Position */ +#define DAC_CTRLB_Msk _U_(0xDF) /**< (DAC_CTRLB) Register Mask */ + + +/* -------- DAC_EVCTRL : (DAC Offset: 0x02) (R/W 8) Event Control -------- */ +#define DAC_EVCTRL_RESETVALUE _U_(0x00) /**< (DAC_EVCTRL) Event Control Reset Value */ + +#define DAC_EVCTRL_STARTEI_Pos _U_(0) /**< (DAC_EVCTRL) Start Conversion Event Input Position */ +#define DAC_EVCTRL_STARTEI_Msk (_U_(0x1) << DAC_EVCTRL_STARTEI_Pos) /**< (DAC_EVCTRL) Start Conversion Event Input Mask */ +#define DAC_EVCTRL_STARTEI(value) (DAC_EVCTRL_STARTEI_Msk & ((value) << DAC_EVCTRL_STARTEI_Pos)) +#define DAC_EVCTRL_EMPTYEO_Pos _U_(1) /**< (DAC_EVCTRL) Data Buffer Empty Event Output Position */ +#define DAC_EVCTRL_EMPTYEO_Msk (_U_(0x1) << DAC_EVCTRL_EMPTYEO_Pos) /**< (DAC_EVCTRL) Data Buffer Empty Event Output Mask */ +#define DAC_EVCTRL_EMPTYEO(value) (DAC_EVCTRL_EMPTYEO_Msk & ((value) << DAC_EVCTRL_EMPTYEO_Pos)) +#define DAC_EVCTRL_Msk _U_(0x03) /**< (DAC_EVCTRL) Register Mask */ + + +/* -------- DAC_INTENCLR : (DAC Offset: 0x04) (R/W 8) Interrupt Enable Clear -------- */ +#define DAC_INTENCLR_RESETVALUE _U_(0x00) /**< (DAC_INTENCLR) Interrupt Enable Clear Reset Value */ + +#define DAC_INTENCLR_UNDERRUN_Pos _U_(0) /**< (DAC_INTENCLR) Underrun Interrupt Enable Position */ +#define DAC_INTENCLR_UNDERRUN_Msk (_U_(0x1) << DAC_INTENCLR_UNDERRUN_Pos) /**< (DAC_INTENCLR) Underrun Interrupt Enable Mask */ +#define DAC_INTENCLR_UNDERRUN(value) (DAC_INTENCLR_UNDERRUN_Msk & ((value) << DAC_INTENCLR_UNDERRUN_Pos)) +#define DAC_INTENCLR_EMPTY_Pos _U_(1) /**< (DAC_INTENCLR) Data Buffer Empty Interrupt Enable Position */ +#define DAC_INTENCLR_EMPTY_Msk (_U_(0x1) << DAC_INTENCLR_EMPTY_Pos) /**< (DAC_INTENCLR) Data Buffer Empty Interrupt Enable Mask */ +#define DAC_INTENCLR_EMPTY(value) (DAC_INTENCLR_EMPTY_Msk & ((value) << DAC_INTENCLR_EMPTY_Pos)) +#define DAC_INTENCLR_SYNCRDY_Pos _U_(2) /**< (DAC_INTENCLR) Synchronization Ready Interrupt Enable Position */ +#define DAC_INTENCLR_SYNCRDY_Msk (_U_(0x1) << DAC_INTENCLR_SYNCRDY_Pos) /**< (DAC_INTENCLR) Synchronization Ready Interrupt Enable Mask */ +#define DAC_INTENCLR_SYNCRDY(value) (DAC_INTENCLR_SYNCRDY_Msk & ((value) << DAC_INTENCLR_SYNCRDY_Pos)) +#define DAC_INTENCLR_Msk _U_(0x07) /**< (DAC_INTENCLR) Register Mask */ + + +/* -------- DAC_INTENSET : (DAC Offset: 0x05) (R/W 8) Interrupt Enable Set -------- */ +#define DAC_INTENSET_RESETVALUE _U_(0x00) /**< (DAC_INTENSET) Interrupt Enable Set Reset Value */ + +#define DAC_INTENSET_UNDERRUN_Pos _U_(0) /**< (DAC_INTENSET) Underrun Interrupt Enable Position */ +#define DAC_INTENSET_UNDERRUN_Msk (_U_(0x1) << DAC_INTENSET_UNDERRUN_Pos) /**< (DAC_INTENSET) Underrun Interrupt Enable Mask */ +#define DAC_INTENSET_UNDERRUN(value) (DAC_INTENSET_UNDERRUN_Msk & ((value) << DAC_INTENSET_UNDERRUN_Pos)) +#define DAC_INTENSET_EMPTY_Pos _U_(1) /**< (DAC_INTENSET) Data Buffer Empty Interrupt Enable Position */ +#define DAC_INTENSET_EMPTY_Msk (_U_(0x1) << DAC_INTENSET_EMPTY_Pos) /**< (DAC_INTENSET) Data Buffer Empty Interrupt Enable Mask */ +#define DAC_INTENSET_EMPTY(value) (DAC_INTENSET_EMPTY_Msk & ((value) << DAC_INTENSET_EMPTY_Pos)) +#define DAC_INTENSET_SYNCRDY_Pos _U_(2) /**< (DAC_INTENSET) Synchronization Ready Interrupt Enable Position */ +#define DAC_INTENSET_SYNCRDY_Msk (_U_(0x1) << DAC_INTENSET_SYNCRDY_Pos) /**< (DAC_INTENSET) Synchronization Ready Interrupt Enable Mask */ +#define DAC_INTENSET_SYNCRDY(value) (DAC_INTENSET_SYNCRDY_Msk & ((value) << DAC_INTENSET_SYNCRDY_Pos)) +#define DAC_INTENSET_Msk _U_(0x07) /**< (DAC_INTENSET) Register Mask */ + + +/* -------- DAC_INTFLAG : (DAC Offset: 0x06) (R/W 8) Interrupt Flag Status and Clear -------- */ +#define DAC_INTFLAG_RESETVALUE _U_(0x00) /**< (DAC_INTFLAG) Interrupt Flag Status and Clear Reset Value */ + +#define DAC_INTFLAG_UNDERRUN_Pos _U_(0) /**< (DAC_INTFLAG) Underrun Position */ +#define DAC_INTFLAG_UNDERRUN_Msk (_U_(0x1) << DAC_INTFLAG_UNDERRUN_Pos) /**< (DAC_INTFLAG) Underrun Mask */ +#define DAC_INTFLAG_UNDERRUN(value) (DAC_INTFLAG_UNDERRUN_Msk & ((value) << DAC_INTFLAG_UNDERRUN_Pos)) +#define DAC_INTFLAG_EMPTY_Pos _U_(1) /**< (DAC_INTFLAG) Data Buffer Empty Position */ +#define DAC_INTFLAG_EMPTY_Msk (_U_(0x1) << DAC_INTFLAG_EMPTY_Pos) /**< (DAC_INTFLAG) Data Buffer Empty Mask */ +#define DAC_INTFLAG_EMPTY(value) (DAC_INTFLAG_EMPTY_Msk & ((value) << DAC_INTFLAG_EMPTY_Pos)) +#define DAC_INTFLAG_SYNCRDY_Pos _U_(2) /**< (DAC_INTFLAG) Synchronization Ready Position */ +#define DAC_INTFLAG_SYNCRDY_Msk (_U_(0x1) << DAC_INTFLAG_SYNCRDY_Pos) /**< (DAC_INTFLAG) Synchronization Ready Mask */ +#define DAC_INTFLAG_SYNCRDY(value) (DAC_INTFLAG_SYNCRDY_Msk & ((value) << DAC_INTFLAG_SYNCRDY_Pos)) +#define DAC_INTFLAG_Msk _U_(0x07) /**< (DAC_INTFLAG) Register Mask */ + + +/* -------- DAC_STATUS : (DAC Offset: 0x07) ( R/ 8) Status -------- */ +#define DAC_STATUS_RESETVALUE _U_(0x00) /**< (DAC_STATUS) Status Reset Value */ + +#define DAC_STATUS_SYNCBUSY_Pos _U_(7) /**< (DAC_STATUS) Synchronization Busy Status Position */ +#define DAC_STATUS_SYNCBUSY_Msk (_U_(0x1) << DAC_STATUS_SYNCBUSY_Pos) /**< (DAC_STATUS) Synchronization Busy Status Mask */ +#define DAC_STATUS_SYNCBUSY(value) (DAC_STATUS_SYNCBUSY_Msk & ((value) << DAC_STATUS_SYNCBUSY_Pos)) +#define DAC_STATUS_Msk _U_(0x80) /**< (DAC_STATUS) Register Mask */ + + +/* -------- DAC_DATA : (DAC Offset: 0x08) (R/W 16) Data -------- */ +#define DAC_DATA_RESETVALUE _U_(0x00) /**< (DAC_DATA) Data Reset Value */ + +#define DAC_DATA_DATA_Pos _U_(0) /**< (DAC_DATA) Data value to be converted Position */ +#define DAC_DATA_DATA_Msk (_U_(0xFFFF) << DAC_DATA_DATA_Pos) /**< (DAC_DATA) Data value to be converted Mask */ +#define DAC_DATA_DATA(value) (DAC_DATA_DATA_Msk & ((value) << DAC_DATA_DATA_Pos)) +#define DAC_DATA_Msk _U_(0xFFFF) /**< (DAC_DATA) Register Mask */ + + +/* -------- DAC_DATABUF : (DAC Offset: 0x0C) (R/W 16) Data Buffer -------- */ +#define DAC_DATABUF_RESETVALUE _U_(0x00) /**< (DAC_DATABUF) Data Buffer Reset Value */ + +#define DAC_DATABUF_DATABUF_Pos _U_(0) /**< (DAC_DATABUF) Data Buffer Position */ +#define DAC_DATABUF_DATABUF_Msk (_U_(0xFFFF) << DAC_DATABUF_DATABUF_Pos) /**< (DAC_DATABUF) Data Buffer Mask */ +#define DAC_DATABUF_DATABUF(value) (DAC_DATABUF_DATABUF_Msk & ((value) << DAC_DATABUF_DATABUF_Pos)) +#define DAC_DATABUF_Msk _U_(0xFFFF) /**< (DAC_DATABUF) Register Mask */ + + +/** \brief DAC register offsets definitions */ +#define DAC_CTRLA_REG_OFST (0x00) /**< (DAC_CTRLA) Control A Offset */ +#define DAC_CTRLB_REG_OFST (0x01) /**< (DAC_CTRLB) Control B Offset */ +#define DAC_EVCTRL_REG_OFST (0x02) /**< (DAC_EVCTRL) Event Control Offset */ +#define DAC_INTENCLR_REG_OFST (0x04) /**< (DAC_INTENCLR) Interrupt Enable Clear Offset */ +#define DAC_INTENSET_REG_OFST (0x05) /**< (DAC_INTENSET) Interrupt Enable Set Offset */ +#define DAC_INTFLAG_REG_OFST (0x06) /**< (DAC_INTFLAG) Interrupt Flag Status and Clear Offset */ +#define DAC_STATUS_REG_OFST (0x07) /**< (DAC_STATUS) Status Offset */ +#define DAC_DATA_REG_OFST (0x08) /**< (DAC_DATA) Data Offset */ +#define DAC_DATABUF_REG_OFST (0x0C) /**< (DAC_DATABUF) Data Buffer Offset */ + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +/** \brief DAC register API structure */ +typedef struct +{ /* Digital Analog Converter */ + __IO uint8_t DAC_CTRLA; /**< Offset: 0x00 (R/W 8) Control A */ + __IO uint8_t DAC_CTRLB; /**< Offset: 0x01 (R/W 8) Control B */ + __IO uint8_t DAC_EVCTRL; /**< Offset: 0x02 (R/W 8) Event Control */ + __I uint8_t Reserved1[0x01]; + __IO uint8_t DAC_INTENCLR; /**< Offset: 0x04 (R/W 8) Interrupt Enable Clear */ + __IO uint8_t DAC_INTENSET; /**< Offset: 0x05 (R/W 8) Interrupt Enable Set */ + __IO uint8_t DAC_INTFLAG; /**< Offset: 0x06 (R/W 8) Interrupt Flag Status and Clear */ + __I uint8_t DAC_STATUS; /**< Offset: 0x07 (R/ 8) Status */ + __IO uint16_t DAC_DATA; /**< Offset: 0x08 (R/W 16) Data */ + __I uint8_t Reserved2[0x02]; + __IO uint16_t DAC_DATABUF; /**< Offset: 0x0C (R/W 16) Data Buffer */ +} dac_registers_t; + + +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ +#endif /* _SAMD21_DAC_COMPONENT_H_ */ diff --git a/core/arm/samd21a/include_mcc/component/dmac.h b/core/arm/samd21a/include_mcc/component/dmac.h new file mode 100644 index 000000000..d99917dda --- /dev/null +++ b/core/arm/samd21a/include_mcc/component/dmac.h @@ -0,0 +1,779 @@ +/** + * \brief Component description for DMAC + * + * Copyright (c) 2019 Microchip Technology Inc. and its subsidiaries. + * + * Subject to your compliance with these terms, you may use Microchip software and any derivatives + * exclusively with Microchip products. It is your responsibility to comply with third party license + * terms applicable to your use of third party software (including open source software) that may + * accompany Microchip software. + * + * THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER EXPRESS, IMPLIED OR STATUTORY, + * APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND + * FITNESS FOR A PARTICULAR PURPOSE. + * + * IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE, INCIDENTAL OR CONSEQUENTIAL + * LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF + * MICROCHIP HAS BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE FULLEST EXTENT + * ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN ANY WAY RELATED TO THIS SOFTWARE WILL NOT + * EXCEED THE AMOUNT OF FEES, IF ANY, THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE. + * + */ + +/* file generated from device description version 2019-05-20T21:16:53Z */ +#ifndef _SAMD21_DMAC_COMPONENT_H_ +#define _SAMD21_DMAC_COMPONENT_H_ + +/* ************************************************************************** */ +/* SOFTWARE API DEFINITION FOR DMAC */ +/* ************************************************************************** */ + +/* -------- DMAC_BTCTRL : (DMAC Offset: 0x00) (R/W 16) Block Transfer Control -------- */ +#define DMAC_BTCTRL_RESETVALUE _U_(0x00) /**< (DMAC_BTCTRL) Block Transfer Control Reset Value */ + +#define DMAC_BTCTRL_VALID_Pos _U_(0) /**< (DMAC_BTCTRL) Descriptor Valid Position */ +#define DMAC_BTCTRL_VALID_Msk (_U_(0x1) << DMAC_BTCTRL_VALID_Pos) /**< (DMAC_BTCTRL) Descriptor Valid Mask */ +#define DMAC_BTCTRL_VALID(value) (DMAC_BTCTRL_VALID_Msk & ((value) << DMAC_BTCTRL_VALID_Pos)) +#define DMAC_BTCTRL_EVOSEL_Pos _U_(1) /**< (DMAC_BTCTRL) Event Output Selection Position */ +#define DMAC_BTCTRL_EVOSEL_Msk (_U_(0x3) << DMAC_BTCTRL_EVOSEL_Pos) /**< (DMAC_BTCTRL) Event Output Selection Mask */ +#define DMAC_BTCTRL_EVOSEL(value) (DMAC_BTCTRL_EVOSEL_Msk & ((value) << DMAC_BTCTRL_EVOSEL_Pos)) +#define DMAC_BTCTRL_EVOSEL_DISABLE_Val _U_(0x0) /**< (DMAC_BTCTRL) Event generation disabled */ +#define DMAC_BTCTRL_EVOSEL_BLOCK_Val _U_(0x1) /**< (DMAC_BTCTRL) Event strobe when block transfer complete */ +#define DMAC_BTCTRL_EVOSEL_BEAT_Val _U_(0x3) /**< (DMAC_BTCTRL) Event strobe when beat transfer complete */ +#define DMAC_BTCTRL_EVOSEL_DISABLE (DMAC_BTCTRL_EVOSEL_DISABLE_Val << DMAC_BTCTRL_EVOSEL_Pos) /**< (DMAC_BTCTRL) Event generation disabled Position */ +#define DMAC_BTCTRL_EVOSEL_BLOCK (DMAC_BTCTRL_EVOSEL_BLOCK_Val << DMAC_BTCTRL_EVOSEL_Pos) /**< (DMAC_BTCTRL) Event strobe when block transfer complete Position */ +#define DMAC_BTCTRL_EVOSEL_BEAT (DMAC_BTCTRL_EVOSEL_BEAT_Val << DMAC_BTCTRL_EVOSEL_Pos) /**< (DMAC_BTCTRL) Event strobe when beat transfer complete Position */ +#define DMAC_BTCTRL_BLOCKACT_Pos _U_(3) /**< (DMAC_BTCTRL) Block Action Position */ +#define DMAC_BTCTRL_BLOCKACT_Msk (_U_(0x3) << DMAC_BTCTRL_BLOCKACT_Pos) /**< (DMAC_BTCTRL) Block Action Mask */ +#define DMAC_BTCTRL_BLOCKACT(value) (DMAC_BTCTRL_BLOCKACT_Msk & ((value) << DMAC_BTCTRL_BLOCKACT_Pos)) +#define DMAC_BTCTRL_BLOCKACT_NOACT_Val _U_(0x0) /**< (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction */ +#define DMAC_BTCTRL_BLOCKACT_INT_Val _U_(0x1) /**< (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction and block interrupt */ +#define DMAC_BTCTRL_BLOCKACT_SUSPEND_Val _U_(0x2) /**< (DMAC_BTCTRL) Channel suspend operation is completed */ +#define DMAC_BTCTRL_BLOCKACT_BOTH_Val _U_(0x3) /**< (DMAC_BTCTRL) Both channel suspend operation and block interrupt */ +#define DMAC_BTCTRL_BLOCKACT_NOACT (DMAC_BTCTRL_BLOCKACT_NOACT_Val << DMAC_BTCTRL_BLOCKACT_Pos) /**< (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction Position */ +#define DMAC_BTCTRL_BLOCKACT_INT (DMAC_BTCTRL_BLOCKACT_INT_Val << DMAC_BTCTRL_BLOCKACT_Pos) /**< (DMAC_BTCTRL) Channel will be disabled if it is the last block transfer in the transaction and block interrupt Position */ +#define DMAC_BTCTRL_BLOCKACT_SUSPEND (DMAC_BTCTRL_BLOCKACT_SUSPEND_Val << DMAC_BTCTRL_BLOCKACT_Pos) /**< (DMAC_BTCTRL) Channel suspend operation is completed Position */ +#define DMAC_BTCTRL_BLOCKACT_BOTH (DMAC_BTCTRL_BLOCKACT_BOTH_Val << DMAC_BTCTRL_BLOCKACT_Pos) /**< (DMAC_BTCTRL) Both channel suspend operation and block interrupt Position */ +#define DMAC_BTCTRL_BEATSIZE_Pos _U_(8) /**< (DMAC_BTCTRL) Beat Size Position */ +#define DMAC_BTCTRL_BEATSIZE_Msk (_U_(0x3) << DMAC_BTCTRL_BEATSIZE_Pos) /**< (DMAC_BTCTRL) Beat Size Mask */ +#define DMAC_BTCTRL_BEATSIZE(value) (DMAC_BTCTRL_BEATSIZE_Msk & ((value) << DMAC_BTCTRL_BEATSIZE_Pos)) +#define DMAC_BTCTRL_BEATSIZE_BYTE_Val _U_(0x0) /**< (DMAC_BTCTRL) 8-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_HWORD_Val _U_(0x1) /**< (DMAC_BTCTRL) 16-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_WORD_Val _U_(0x2) /**< (DMAC_BTCTRL) 32-bit bus transfer */ +#define DMAC_BTCTRL_BEATSIZE_BYTE (DMAC_BTCTRL_BEATSIZE_BYTE_Val << DMAC_BTCTRL_BEATSIZE_Pos) /**< (DMAC_BTCTRL) 8-bit bus transfer Position */ +#define DMAC_BTCTRL_BEATSIZE_HWORD (DMAC_BTCTRL_BEATSIZE_HWORD_Val << DMAC_BTCTRL_BEATSIZE_Pos) /**< (DMAC_BTCTRL) 16-bit bus transfer Position */ +#define DMAC_BTCTRL_BEATSIZE_WORD (DMAC_BTCTRL_BEATSIZE_WORD_Val << DMAC_BTCTRL_BEATSIZE_Pos) /**< (DMAC_BTCTRL) 32-bit bus transfer Position */ +#define DMAC_BTCTRL_SRCINC_Pos _U_(10) /**< (DMAC_BTCTRL) Source Address Increment Enable Position */ +#define DMAC_BTCTRL_SRCINC_Msk (_U_(0x1) << DMAC_BTCTRL_SRCINC_Pos) /**< (DMAC_BTCTRL) Source Address Increment Enable Mask */ +#define DMAC_BTCTRL_SRCINC(value) (DMAC_BTCTRL_SRCINC_Msk & ((value) << DMAC_BTCTRL_SRCINC_Pos)) +#define DMAC_BTCTRL_DSTINC_Pos _U_(11) /**< (DMAC_BTCTRL) Destination Address Increment Enable Position */ +#define DMAC_BTCTRL_DSTINC_Msk (_U_(0x1) << DMAC_BTCTRL_DSTINC_Pos) /**< (DMAC_BTCTRL) Destination Address Increment Enable Mask */ +#define DMAC_BTCTRL_DSTINC(value) (DMAC_BTCTRL_DSTINC_Msk & ((value) << DMAC_BTCTRL_DSTINC_Pos)) +#define DMAC_BTCTRL_STEPSEL_Pos _U_(12) /**< (DMAC_BTCTRL) Step Selection Position */ +#define DMAC_BTCTRL_STEPSEL_Msk (_U_(0x1) << DMAC_BTCTRL_STEPSEL_Pos) /**< (DMAC_BTCTRL) Step Selection Mask */ +#define DMAC_BTCTRL_STEPSEL(value) (DMAC_BTCTRL_STEPSEL_Msk & ((value) << DMAC_BTCTRL_STEPSEL_Pos)) +#define DMAC_BTCTRL_STEPSEL_DST_Val _U_(0x0) /**< (DMAC_BTCTRL) Step size settings apply to the destination address */ +#define DMAC_BTCTRL_STEPSEL_SRC_Val _U_(0x1) /**< (DMAC_BTCTRL) Step size settings apply to the source address */ +#define DMAC_BTCTRL_STEPSEL_DST (DMAC_BTCTRL_STEPSEL_DST_Val << DMAC_BTCTRL_STEPSEL_Pos) /**< (DMAC_BTCTRL) Step size settings apply to the destination address Position */ +#define DMAC_BTCTRL_STEPSEL_SRC (DMAC_BTCTRL_STEPSEL_SRC_Val << DMAC_BTCTRL_STEPSEL_Pos) /**< (DMAC_BTCTRL) Step size settings apply to the source address Position */ +#define DMAC_BTCTRL_STEPSIZE_Pos _U_(13) /**< (DMAC_BTCTRL) Address Increment Step Size Position */ +#define DMAC_BTCTRL_STEPSIZE_Msk (_U_(0x7) << DMAC_BTCTRL_STEPSIZE_Pos) /**< (DMAC_BTCTRL) Address Increment Step Size Mask */ +#define DMAC_BTCTRL_STEPSIZE(value) (DMAC_BTCTRL_STEPSIZE_Msk & ((value) << DMAC_BTCTRL_STEPSIZE_Pos)) +#define DMAC_BTCTRL_STEPSIZE_X1_Val _U_(0x0) /**< (DMAC_BTCTRL) Next ADDR = ADDR + (1< +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !defined(SKIP_INTEGER_LITERALS) +# if defined(_U_) || defined(_L_) || defined(_UL_) +# error "Integer Literals macros already defined elsewhere" +# endif + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +/* Macros that deal with adding suffixes to integer literal constants for C/C++ */ +# define _U_(x) (x ## U) /**< C code: Unsigned integer literal constant value */ +# define _L_(x) (x ## L) /**< C code: Long integer literal constant value */ +# define _UL_(x) (x ## UL) /**< C code: Unsigned Long integer literal constant value */ + +#else /* Assembler */ + +# define _U_(x) x /**< Assembler: Unsigned integer literal constant value */ +# define _L_(x) x /**< Assembler: Long integer literal constant value */ +# define _UL_(x) x /**< Assembler: Unsigned Long integer literal constant value */ +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ +#endif /* SKIP_INTEGER_LITERALS */ +/** @} end of Atmel Global Defines */ + +/* ************************************************************************** */ +/* CMSIS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +/** Interrupt Number Definition */ +typedef enum IRQn +{ +/****** CORTEX-M0PLUS Processor Exceptions Numbers ******************************/ + Reset_IRQn = -15, /**< -15 Reset Vector, invoked on Power up and warm reset */ + NonMaskableInt_IRQn = -14, /**< -14 Non maskable Interrupt, cannot be stopped or preempted */ + HardFault_IRQn = -13, /**< -13 Hard Fault, all classes of Fault */ + SVCall_IRQn = -5, /**< -5 System Service Call via SVC instruction */ + PendSV_IRQn = -2, /**< -2 Pendable request for system service */ + SysTick_IRQn = -1, /**< -1 System Tick Timer */ +/****** SAMD21E18A specific Interrupt Numbers ***********************************/ + PM_IRQn = 0, /**< 0 Power Manager (PM) */ + SYSCTRL_IRQn = 1, /**< 1 System Control (SYSCTRL) */ + WDT_IRQn = 2, /**< 2 Watchdog Timer (WDT) */ + RTC_IRQn = 3, /**< 3 Real-Time Counter (RTC) */ + EIC_IRQn = 4, /**< 4 External Interrupt Controller (EIC) */ + NVMCTRL_IRQn = 5, /**< 5 Non-Volatile Memory Controller (NVMCTRL) */ + DMAC_IRQn = 6, /**< 6 Direct Memory Access Controller (DMAC) */ + USB_IRQn = 7, /**< 7 Universal Serial Bus (USB) */ + EVSYS_IRQn = 8, /**< 8 Event System Interface (EVSYS) */ + SERCOM0_IRQn = 9, /**< 9 Serial Communication Interface (SERCOM0) */ + SERCOM1_IRQn = 10, /**< 10 Serial Communication Interface (SERCOM1) */ + SERCOM2_IRQn = 11, /**< 11 Serial Communication Interface (SERCOM2) */ + SERCOM3_IRQn = 12, /**< 12 Serial Communication Interface (SERCOM3) */ + TCC0_IRQn = 15, /**< 15 Timer Counter Control (TCC0) */ + TCC1_IRQn = 16, /**< 16 Timer Counter Control (TCC1) */ + TCC2_IRQn = 17, /**< 17 Timer Counter Control (TCC2) */ + TC3_IRQn = 18, /**< 18 Basic Timer Counter (TC3) */ + TC4_IRQn = 19, /**< 19 Basic Timer Counter (TC4) */ + TC5_IRQn = 20, /**< 20 Basic Timer Counter (TC5) */ + ADC_IRQn = 23, /**< 23 Analog Digital Converter (ADC) */ + AC_IRQn = 24, /**< 24 Analog Comparators (AC) */ + DAC_IRQn = 25, /**< 25 Digital Analog Converter (DAC) */ + PTC_IRQn = 26, /**< 26 Peripheral Touch Controller (PTC) */ + I2S_IRQn = 27, /**< 27 Inter-IC Sound Interface (I2S) */ + + PERIPH_MAX_IRQn = 27 /**< Max peripheral ID */ +} IRQn_Type; +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +typedef struct _DeviceVectors +{ + /* Stack pointer */ + void* pvStack; + /* Cortex-M handlers */ + void* pfnReset_Handler; /* -15 Reset Vector, invoked on Power up and warm reset */ + void* pfnNonMaskableInt_Handler; /* -14 Non maskable Interrupt, cannot be stopped or preempted */ + void* pfnHardFault_Handler; /* -13 Hard Fault, all classes of Fault */ + void* pvReservedC12; + void* pvReservedC11; + void* pvReservedC10; + void* pvReservedC9; + void* pvReservedC8; + void* pvReservedC7; + void* pvReservedC6; + void* pfnSVCall_Handler; /* -5 System Service Call via SVC instruction */ + void* pvReservedC4; + void* pvReservedC3; + void* pfnPendSV_Handler; /* -2 Pendable request for system service */ + void* pfnSysTick_Handler; /* -1 System Tick Timer */ + + /* Peripheral handlers */ + void* pfnPM_Handler; /* 0 Power Manager (PM) */ + void* pfnSYSCTRL_Handler; /* 1 System Control (SYSCTRL) */ + void* pfnWDT_Handler; /* 2 Watchdog Timer (WDT) */ + void* pfnRTC_Handler; /* 3 Real-Time Counter (RTC) */ + void* pfnEIC_Handler; /* 4 External Interrupt Controller (EIC) */ + void* pfnNVMCTRL_Handler; /* 5 Non-Volatile Memory Controller (NVMCTRL) */ + void* pfnDMAC_Handler; /* 6 Direct Memory Access Controller (DMAC) */ + void* pfnUSB_Handler; /* 7 Universal Serial Bus (USB) */ + void* pfnEVSYS_Handler; /* 8 Event System Interface (EVSYS) */ + void* pfnSERCOM0_Handler; /* 9 Serial Communication Interface (SERCOM0) */ + void* pfnSERCOM1_Handler; /* 10 Serial Communication Interface (SERCOM1) */ + void* pfnSERCOM2_Handler; /* 11 Serial Communication Interface (SERCOM2) */ + void* pfnSERCOM3_Handler; /* 12 Serial Communication Interface (SERCOM3) */ + void* pvReserved13; + void* pvReserved14; + void* pfnTCC0_Handler; /* 15 Timer Counter Control (TCC0) */ + void* pfnTCC1_Handler; /* 16 Timer Counter Control (TCC1) */ + void* pfnTCC2_Handler; /* 17 Timer Counter Control (TCC2) */ + void* pfnTC3_Handler; /* 18 Basic Timer Counter (TC3) */ + void* pfnTC4_Handler; /* 19 Basic Timer Counter (TC4) */ + void* pfnTC5_Handler; /* 20 Basic Timer Counter (TC5) */ + void* pvReserved21; + void* pvReserved22; + void* pfnADC_Handler; /* 23 Analog Digital Converter (ADC) */ + void* pfnAC_Handler; /* 24 Analog Comparators (AC) */ + void* pfnDAC_Handler; /* 25 Digital Analog Converter (DAC) */ + void* pfnPTC_Handler; /* 26 Peripheral Touch Controller (PTC) */ + void* pfnI2S_Handler; /* 27 Inter-IC Sound Interface (I2S) */ +} DeviceVectors; + +/* Defines for Deprecated Interrupt and Exceptions handler names */ +#define pfnMemManage_Handler pfnMemoryManagement_Handler /**< \deprecated Backward compatibility for ASF*/ +#define pfnDebugMon_Handler pfnDebugMonitor_Handler /**< \deprecated Backward compatibility for ASF*/ +#define pfnNMI_Handler pfnNonMaskableInt_Handler /**< \deprecated Backward compatibility for ASF*/ +#define pfnSVC_Handler pfnSVCall_Handler /**< \deprecated Backward compatibility for ASF*/ + +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ + +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +#if !defined DONT_USE_PREDEFINED_CORE_HANDLERS +/* CORTEX-M0PLUS exception handlers */ +void Reset_Handler ( void ); +void NonMaskableInt_Handler ( void ); +void HardFault_Handler ( void ); +void SVCall_Handler ( void ); +void PendSV_Handler ( void ); +void SysTick_Handler ( void ); +#endif /* DONT_USE_PREDEFINED_CORE_HANDLERS */ + +#if !defined DONT_USE_PREDEFINED_PERIPHERALS_HANDLERS +/* Peripherals interrupt handlers */ +void PM_Handler ( void ); +void SYSCTRL_Handler ( void ); +void WDT_Handler ( void ); +void RTC_Handler ( void ); +void EIC_Handler ( void ); +void NVMCTRL_Handler ( void ); +void DMAC_Handler ( void ); +void USB_Handler ( void ); +void EVSYS_Handler ( void ); +void SERCOM0_Handler ( void ); +void SERCOM1_Handler ( void ); +void SERCOM2_Handler ( void ); +void SERCOM3_Handler ( void ); +void TCC0_Handler ( void ); +void TCC1_Handler ( void ); +void TCC2_Handler ( void ); +void TC3_Handler ( void ); +void TC4_Handler ( void ); +void TC5_Handler ( void ); +void ADC_Handler ( void ); +void AC_Handler ( void ); +void DAC_Handler ( void ); +void PTC_Handler ( void ); +void I2S_Handler ( void ); +#endif /* DONT_USE_PREDEFINED_PERIPHERALS_HANDLERS */ +/* Defines for Deprecated Interrupt and Exceptions handler names */ +#define MemManage_Handler MemoryManagement_Handler /**< \deprecated Backward compatibility*/ +#define DebugMon_Handler DebugMonitor_Handler /**< \deprecated Backward compatibility*/ +#define NMI_Handler NonMaskableInt_Handler /**< \deprecated Backward compatibility*/ +#define SVC_Handler SVCall_Handler /**< \deprecated Backward compatibility*/ + +#endif /* !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ + +/* + * \brief Configuration of the CORTEX-M0PLUS Processor and Core Peripherals + */ +#define __MPU_PRESENT 0 /**< MPU present or not */ +#define __NVIC_PRIO_BITS 2 /**< Number of Bits used for Priority Levels */ +#define __VTOR_PRESENT 1 /**< Vector Table Offset Register present or not */ +#define __Vendor_SysTickConfig 0 /**< Set to 1 if different SysTick Config is used feature implemented */ +#define __ARCH_ARM 1 +#define __ARCH_ARM_CORTEX_M 1 +#define __DEVICE_IS_SAM 1 + +/* + * \brief CMSIS includes + */ +#include "core_cm0plus.h" +#if defined USE_CMSIS_INIT +#include "system_samd21.h" +#endif /* USE_CMSIS_INIT */ + +/** \defgroup SAMD21E18A_api Peripheral Software API + * @{ + */ + +/* ************************************************************************** */ +/** SOFTWARE PERIPHERAL API DEFINITION FOR SAMD21E18A */ +/* ************************************************************************** */ +#include "component/ac.h" +#include "component/adc.h" +#include "component/dac.h" +#include "component/dmac.h" +#include "component/dsu.h" +#include "component/eic.h" +#include "component/evsys.h" +#include "component/gclk.h" +#include "component/hmatrixb.h" +#include "component/i2s.h" +#include "component/mtb.h" +#include "component/nvmctrl.h" +#include "component/pac.h" +#include "component/pm.h" +#include "component/port.h" +#include "component/ptc.h" +#include "component/rtc.h" +#include "component/sercom.h" +#include "component/sysctrl.h" +#include "component/tc.h" +#include "component/tcc.h" +#include "component/usb.h" +#include "component/wdt.h" +/** @} end of Peripheral Software API */ + +/** \addtogroup SAMD21E18A_id Peripheral Ids Definitions + * @{ + */ + +/* ************************************************************************** */ +/* PERIPHERAL ID DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +#define ID_PAC0 ( 0) /**< \brief Peripheral Access Controller (PAC0) */ +#define ID_PM ( 1) /**< \brief Power Manager (PM) */ +#define ID_SYSCTRL ( 2) /**< \brief System Control (SYSCTRL) */ +#define ID_GCLK ( 3) /**< \brief Generic Clock Generator (GCLK) */ +#define ID_WDT ( 4) /**< \brief Watchdog Timer (WDT) */ +#define ID_RTC ( 5) /**< \brief Real-Time Counter (RTC) */ +#define ID_EIC ( 6) /**< \brief External Interrupt Controller (EIC) */ +#define ID_PAC1 ( 32) /**< \brief Peripheral Access Controller (PAC1) */ +#define ID_DSU ( 33) /**< \brief Device Service Unit (DSU) */ +#define ID_NVMCTRL ( 34) /**< \brief Non-Volatile Memory Controller (NVMCTRL) */ +#define ID_PORT ( 35) /**< \brief Port Module (PORT) */ +#define ID_DMAC ( 36) /**< \brief Direct Memory Access Controller (DMAC) */ +#define ID_USB ( 37) /**< \brief Universal Serial Bus (USB) */ +#define ID_MTB ( 38) /**< \brief Cortex-M0+ Micro-Trace Buffer (MTB) */ +#define ID_SBMATRIX ( 39) /**< \brief HSB Matrix (SBMATRIX) */ +#define ID_PAC2 ( 64) /**< \brief Peripheral Access Controller (PAC2) */ +#define ID_EVSYS ( 65) /**< \brief Event System Interface (EVSYS) */ +#define ID_SERCOM0 ( 66) /**< \brief Serial Communication Interface (SERCOM0) */ +#define ID_SERCOM1 ( 67) /**< \brief Serial Communication Interface (SERCOM1) */ +#define ID_SERCOM2 ( 68) /**< \brief Serial Communication Interface (SERCOM2) */ +#define ID_SERCOM3 ( 69) /**< \brief Serial Communication Interface (SERCOM3) */ +#define ID_TCC0 ( 72) /**< \brief Timer Counter Control (TCC0) */ +#define ID_TCC1 ( 73) /**< \brief Timer Counter Control (TCC1) */ +#define ID_TCC2 ( 74) /**< \brief Timer Counter Control (TCC2) */ +#define ID_TC3 ( 75) /**< \brief Basic Timer Counter (TC3) */ +#define ID_TC4 ( 76) /**< \brief Basic Timer Counter (TC4) */ +#define ID_TC5 ( 77) /**< \brief Basic Timer Counter (TC5) */ +#define ID_ADC ( 80) /**< \brief Analog Digital Converter (ADC) */ +#define ID_AC ( 81) /**< \brief Analog Comparators (AC) */ +#define ID_DAC ( 82) /**< \brief Digital Analog Converter (DAC) */ +#define ID_PTC ( 83) /**< \brief Peripheral Touch Controller (PTC) */ +#define ID_I2S ( 84) /**< \brief Inter-IC Sound Interface (I2S) */ + +#define ID_PERIPH_MAX ( 84) /**< \brief Number of peripheral IDs */ +/** @} end of Peripheral Ids Definitions */ + +/** \addtogroup SAMD21E18A_base Peripheral Base Address Definitions + * @{ + */ + +/* ************************************************************************** */ +/* REGISTER STRUCTURE ADDRESS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +#if !(defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) +#define AC_REGS ((ac_registers_t*)0x42004400) /**< \brief AC Registers Address */ +#define ADC_REGS ((adc_registers_t*)0x42004000) /**< \brief ADC Registers Address */ +#define DAC_REGS ((dac_registers_t*)0x42004800) /**< \brief DAC Registers Address */ +#define DMAC_REGS ((dmac_registers_t*)0x41004800) /**< \brief DMAC Registers Address */ +#define DSU_REGS ((dsu_registers_t*)0x41002000) /**< \brief DSU Registers Address */ +#define EIC_REGS ((eic_registers_t*)0x40001800) /**< \brief EIC Registers Address */ +#define EVSYS_REGS ((evsys_registers_t*)0x42000400) /**< \brief EVSYS Registers Address */ +#define GCLK_REGS ((gclk_registers_t*)0x40000c00) /**< \brief GCLK Registers Address */ +#define SBMATRIX_REGS ((hmatrixb_registers_t*)0x41007000) /**< \brief SBMATRIX Registers Address */ +#define I2S_REGS ((i2s_registers_t*)0x42005000) /**< \brief I2S Registers Address */ +#define MTB_REGS ((mtb_registers_t*)0x41006000) /**< \brief MTB Registers Address */ +#define NVMCTRL_REGS ((nvmctrl_registers_t*)0x41004000) /**< \brief NVMCTRL Registers Address */ +#define PAC0_REGS ((pac_registers_t*)0x40000000) /**< \brief PAC0 Registers Address */ +#define PAC1_REGS ((pac_registers_t*)0x41000000) /**< \brief PAC1 Registers Address */ +#define PAC2_REGS ((pac_registers_t*)0x42000000) /**< \brief PAC2 Registers Address */ +#define PM_REGS ((pm_registers_t*)0x40000400) /**< \brief PM Registers Address */ +#define PORT_REGS ((port_registers_t*)0x41004400) /**< \brief PORT Registers Address */ +#define PORT_IOBUS_REGS ((port_registers_t*)0x60000000) /**< \brief PORT Registers Address */ +#define PTC_REGS ((ptc_registers_t*)0x42004c00) /**< \brief PTC Registers Address */ +#define RTC_REGS ((rtc_registers_t*)0x40001400) /**< \brief RTC Registers Address */ +#define SERCOM0_REGS ((sercom_registers_t*)0x42000800) /**< \brief SERCOM0 Registers Address */ +#define SERCOM1_REGS ((sercom_registers_t*)0x42000c00) /**< \brief SERCOM1 Registers Address */ +#define SERCOM2_REGS ((sercom_registers_t*)0x42001000) /**< \brief SERCOM2 Registers Address */ +#define SERCOM3_REGS ((sercom_registers_t*)0x42001400) /**< \brief SERCOM3 Registers Address */ +#define SYSCTRL_REGS ((sysctrl_registers_t*)0x40000800) /**< \brief SYSCTRL Registers Address */ +#define TC3_REGS ((tc_registers_t*)0x42002c00) /**< \brief TC3 Registers Address */ +#define TC4_REGS ((tc_registers_t*)0x42003000) /**< \brief TC4 Registers Address */ +#define TC5_REGS ((tc_registers_t*)0x42003400) /**< \brief TC5 Registers Address */ +#define TCC0_REGS ((tcc_registers_t*)0x42002000) /**< \brief TCC0 Registers Address */ +#define TCC1_REGS ((tcc_registers_t*)0x42002400) /**< \brief TCC1 Registers Address */ +#define TCC2_REGS ((tcc_registers_t*)0x42002800) /**< \brief TCC2 Registers Address */ +#define USB_REGS ((usb_registers_t*)0x41005000) /**< \brief USB Registers Address */ +#define WDT_REGS ((wdt_registers_t*)0x40001000) /**< \brief WDT Registers Address */ +#endif /* (defined(__ASSEMBLER__) || defined(__IAR_SYSTEMS_ASM__)) */ +/** @} end of Peripheral Base Address Definitions */ + +/** \addtogroup SAMD21E18A_base Peripheral Base Address Definitions + * @{ + */ + +/* ************************************************************************** */ +/* BASE ADDRESS DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +#define AC_BASE_ADDRESS _UL_(0x42004400) /**< \brief AC Base Address */ +#define ADC_BASE_ADDRESS _UL_(0x42004000) /**< \brief ADC Base Address */ +#define DAC_BASE_ADDRESS _UL_(0x42004800) /**< \brief DAC Base Address */ +#define DMAC_BASE_ADDRESS _UL_(0x41004800) /**< \brief DMAC Base Address */ +#define DSU_BASE_ADDRESS _UL_(0x41002000) /**< \brief DSU Base Address */ +#define EIC_BASE_ADDRESS _UL_(0x40001800) /**< \brief EIC Base Address */ +#define EVSYS_BASE_ADDRESS _UL_(0x42000400) /**< \brief EVSYS Base Address */ +#define GCLK_BASE_ADDRESS _UL_(0x40000c00) /**< \brief GCLK Base Address */ +#define SBMATRIX_BASE_ADDRESS _UL_(0x41007000) /**< \brief SBMATRIX Base Address */ +#define I2S_BASE_ADDRESS _UL_(0x42005000) /**< \brief I2S Base Address */ +#define MTB_BASE_ADDRESS _UL_(0x41006000) /**< \brief MTB Base Address */ +#define NVMCTRL_BASE_ADDRESS _UL_(0x41004000) /**< \brief NVMCTRL Base Address */ +#define PAC0_BASE_ADDRESS _UL_(0x40000000) /**< \brief PAC0 Base Address */ +#define PAC1_BASE_ADDRESS _UL_(0x41000000) /**< \brief PAC1 Base Address */ +#define PAC2_BASE_ADDRESS _UL_(0x42000000) /**< \brief PAC2 Base Address */ +#define PM_BASE_ADDRESS _UL_(0x40000400) /**< \brief PM Base Address */ +#define PORT_BASE_ADDRESS _UL_(0x41004400) /**< \brief PORT Base Address */ +#define PORT_IOBUS_BASE_ADDRESS _UL_(0x60000000) /**< \brief PORT Base Address */ +#define PTC_BASE_ADDRESS _UL_(0x42004c00) /**< \brief PTC Base Address */ +#define RTC_BASE_ADDRESS _UL_(0x40001400) /**< \brief RTC Base Address */ +#define SERCOM0_BASE_ADDRESS _UL_(0x42000800) /**< \brief SERCOM0 Base Address */ +#define SERCOM1_BASE_ADDRESS _UL_(0x42000c00) /**< \brief SERCOM1 Base Address */ +#define SERCOM2_BASE_ADDRESS _UL_(0x42001000) /**< \brief SERCOM2 Base Address */ +#define SERCOM3_BASE_ADDRESS _UL_(0x42001400) /**< \brief SERCOM3 Base Address */ +#define SYSCTRL_BASE_ADDRESS _UL_(0x40000800) /**< \brief SYSCTRL Base Address */ +#define TC3_BASE_ADDRESS _UL_(0x42002c00) /**< \brief TC3 Base Address */ +#define TC4_BASE_ADDRESS _UL_(0x42003000) /**< \brief TC4 Base Address */ +#define TC5_BASE_ADDRESS _UL_(0x42003400) /**< \brief TC5 Base Address */ +#define TCC0_BASE_ADDRESS _UL_(0x42002000) /**< \brief TCC0 Base Address */ +#define TCC1_BASE_ADDRESS _UL_(0x42002400) /**< \brief TCC1 Base Address */ +#define TCC2_BASE_ADDRESS _UL_(0x42002800) /**< \brief TCC2 Base Address */ +#define USB_BASE_ADDRESS _UL_(0x41005000) /**< \brief USB Base Address */ +#define WDT_BASE_ADDRESS _UL_(0x40001000) /**< \brief WDT Base Address */ +/** @} end of Peripheral Base Address Definitions */ + +/** \addtogroup SAMD21E18A_pio Peripheral Pio Definitions + * @{ + */ + +/* ************************************************************************** */ +/* PIO DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ +#include "pio/samd21e18a.h" +/** @} end of Peripheral Pio Definitions */ + +/* ************************************************************************** */ +/* MEMORY MAPPING DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ + +#define FLASH_SIZE _UL_(0x00040000) /* 256kB Memory segment type: flash */ +#define FLASH_PAGE_SIZE _UL_( 64) +#define FLASH_NB_OF_PAGES _UL_( 4096) + +#define CAL_SIZE _UL_(0x00000008) /* 0kB Memory segment type: fuses */ +#define AUX3_SIZE _UL_(0x00000100) /* 0kB Memory segment type: fuses */ +#define AUX3_PAGE_SIZE _UL_( 64) +#define AUX3_NB_OF_PAGES _UL_( 4) + +#define LOCKBIT_SIZE _UL_(0x00000004) /* 0kB Memory segment type: fuses */ +#define OTP1_SIZE _UL_(0x00000008) /* 0kB Memory segment type: fuses */ +#define OTP2_SIZE _UL_(0x00000008) /* 0kB Memory segment type: fuses */ +#define OTP4_SIZE _UL_(0x000000e0) /* 0kB Memory segment type: fuses */ +#define OTP4_PAGE_SIZE _UL_( 64) +#define OTP4_NB_OF_PAGES _UL_( 3) + +#define TEMP_LOG_SIZE _UL_(0x00000008) /* 0kB Memory segment type: fuses */ +#define USER_PAGE_SIZE _UL_(0x00000100) /* 0kB Memory segment type: user_page */ +#define USER_PAGE_PAGE_SIZE _UL_( 64) +#define USER_PAGE_NB_OF_PAGES _UL_( 4) + +#define HMCRAMC0_SIZE _UL_(0x00008000) /* 32kB Memory segment type: ram */ +#define HPB0_SIZE _UL_(0x00010000) /* 64kB Memory segment type: io */ +#define HPB1_SIZE _UL_(0x00010000) /* 64kB Memory segment type: io */ +#define HPB2_SIZE _UL_(0x00010000) /* 64kB Memory segment type: io */ +#define PPB_SIZE _UL_(0x00100000) /* 1024kB Memory segment type: io */ +#define SCS_SIZE _UL_(0x00001000) /* 4kB Memory segment type: io */ +#define PERIPHERALS_SIZE _UL_(0x20000000) /* 524288kB Memory segment type: io */ + +#define FLASH_ADDR _UL_(0x00000000) /**< FLASH base address (type: flash)*/ +#define CAL_ADDR _UL_(0x00800000) /**< CAL base address (type: fuses)*/ +#define AUX3_ADDR _UL_(0x0080a000) /**< AUX3 base address (type: fuses)*/ +#define LOCKBIT_ADDR _UL_(0x00802000) /**< LOCKBIT base address (type: fuses)*/ +#define OTP1_ADDR _UL_(0x00806000) /**< OTP1 base address (type: fuses)*/ +#define OTP2_ADDR _UL_(0x00806008) /**< OTP2 base address (type: fuses)*/ +#define OTP4_ADDR _UL_(0x00806020) /**< OTP4 base address (type: fuses)*/ +#define TEMP_LOG_ADDR _UL_(0x00806030) /**< TEMP_LOG base address (type: fuses)*/ +#define USER_PAGE_ADDR _UL_(0x00804000) /**< USER_PAGE base address (type: user_page)*/ +#define HMCRAMC0_ADDR _UL_(0x20000000) /**< HMCRAMC0 base address (type: ram)*/ +#define HPB0_ADDR _UL_(0x40000000) /**< HPB0 base address (type: io)*/ +#define HPB1_ADDR _UL_(0x41000000) /**< HPB1 base address (type: io)*/ +#define HPB2_ADDR _UL_(0x42000000) /**< HPB2 base address (type: io)*/ +#define PPB_ADDR _UL_(0xe0000000) /**< PPB base address (type: io)*/ +#define SCS_ADDR _UL_(0xe000e000) /**< SCS base address (type: io)*/ +#define PERIPHERALS_ADDR _UL_(0x40000000) /**< PERIPHERALS base address (type: io)*/ + +/* ************************************************************************** */ +/** DEVICE SIGNATURES FOR SAMD21E18A */ +/* ************************************************************************** */ +#define DSU_DID _UL_(0X1001030A) + +/* ************************************************************************** */ +/** ELECTRICAL DEFINITIONS FOR SAMD21E18A */ +/* ************************************************************************** */ + +/* ************************************************************************** */ +/** Event Generator IDs for SAMD21E18A */ +/* ************************************************************************** */ +#define EVENT_ID_GEN_RTC_CMP_0 1 /**< ID for RTC event generator CMP_0 */ +#define EVENT_ID_GEN_RTC_CMP_1 2 /**< ID for RTC event generator CMP_1 */ +#define EVENT_ID_GEN_RTC_OVF 3 /**< ID for RTC event generator OVF */ +#define EVENT_ID_GEN_RTC_PER_0 4 /**< ID for RTC event generator PER_0 */ +#define EVENT_ID_GEN_RTC_PER_1 5 /**< ID for RTC event generator PER_1 */ +#define EVENT_ID_GEN_RTC_PER_2 6 /**< ID for RTC event generator PER_2 */ +#define EVENT_ID_GEN_RTC_PER_3 7 /**< ID for RTC event generator PER_3 */ +#define EVENT_ID_GEN_RTC_PER_4 8 /**< ID for RTC event generator PER_4 */ +#define EVENT_ID_GEN_RTC_PER_5 9 /**< ID for RTC event generator PER_5 */ +#define EVENT_ID_GEN_RTC_PER_6 10 /**< ID for RTC event generator PER_6 */ +#define EVENT_ID_GEN_RTC_PER_7 11 /**< ID for RTC event generator PER_7 */ +#define EVENT_ID_GEN_EIC_EXTINT_0 12 /**< ID for EIC event generator EXTINT_0 */ +#define EVENT_ID_GEN_EIC_EXTINT_1 13 /**< ID for EIC event generator EXTINT_1 */ +#define EVENT_ID_GEN_EIC_EXTINT_2 14 /**< ID for EIC event generator EXTINT_2 */ +#define EVENT_ID_GEN_EIC_EXTINT_3 15 /**< ID for EIC event generator EXTINT_3 */ +#define EVENT_ID_GEN_EIC_EXTINT_4 16 /**< ID for EIC event generator EXTINT_4 */ +#define EVENT_ID_GEN_EIC_EXTINT_5 17 /**< ID for EIC event generator EXTINT_5 */ +#define EVENT_ID_GEN_EIC_EXTINT_6 18 /**< ID for EIC event generator EXTINT_6 */ +#define EVENT_ID_GEN_EIC_EXTINT_7 19 /**< ID for EIC event generator EXTINT_7 */ +#define EVENT_ID_GEN_EIC_EXTINT_8 20 /**< ID for EIC event generator EXTINT_8 */ +#define EVENT_ID_GEN_EIC_EXTINT_9 21 /**< ID for EIC event generator EXTINT_9 */ +#define EVENT_ID_GEN_EIC_EXTINT_10 22 /**< ID for EIC event generator EXTINT_10 */ +#define EVENT_ID_GEN_EIC_EXTINT_11 23 /**< ID for EIC event generator EXTINT_11 */ +#define EVENT_ID_GEN_EIC_EXTINT_12 24 /**< ID for EIC event generator EXTINT_12 */ +#define EVENT_ID_GEN_EIC_EXTINT_13 25 /**< ID for EIC event generator EXTINT_13 */ +#define EVENT_ID_GEN_EIC_EXTINT_14 26 /**< ID for EIC event generator EXTINT_14 */ +#define EVENT_ID_GEN_EIC_EXTINT_15 27 /**< ID for EIC event generator EXTINT_15 */ +#define EVENT_ID_GEN_EIC_EXTINT_16 28 /**< ID for EIC event generator EXTINT_16 */ +#define EVENT_ID_GEN_EIC_EXTINT_17 29 /**< ID for EIC event generator EXTINT_17 */ +#define EVENT_ID_GEN_DMAC_CH_0 30 /**< ID for DMAC event generator CH_0 */ +#define EVENT_ID_GEN_DMAC_CH_1 31 /**< ID for DMAC event generator CH_1 */ +#define EVENT_ID_GEN_DMAC_CH_2 32 /**< ID for DMAC event generator CH_2 */ +#define EVENT_ID_GEN_DMAC_CH_3 33 /**< ID for DMAC event generator CH_3 */ +#define EVENT_ID_GEN_TCC0_OVF 34 /**< ID for TCC0 event generator OVF */ +#define EVENT_ID_GEN_TCC0_TRG 35 /**< ID for TCC0 event generator TRG */ +#define EVENT_ID_GEN_TCC0_CNT 36 /**< ID for TCC0 event generator CNT */ +#define EVENT_ID_GEN_TCC0_MC_0 37 /**< ID for TCC0 event generator MC_0 */ +#define EVENT_ID_GEN_TCC0_MC_1 38 /**< ID for TCC0 event generator MC_1 */ +#define EVENT_ID_GEN_TCC0_MC_2 39 /**< ID for TCC0 event generator MC_2 */ +#define EVENT_ID_GEN_TCC0_MC_3 40 /**< ID for TCC0 event generator MC_3 */ +#define EVENT_ID_GEN_TCC1_OVF 41 /**< ID for TCC1 event generator OVF */ +#define EVENT_ID_GEN_TCC1_TRG 42 /**< ID for TCC1 event generator TRG */ +#define EVENT_ID_GEN_TCC1_CNT 43 /**< ID for TCC1 event generator CNT */ +#define EVENT_ID_GEN_TCC1_MC_0 44 /**< ID for TCC1 event generator MC_0 */ +#define EVENT_ID_GEN_TCC1_MC_1 45 /**< ID for TCC1 event generator MC_1 */ +#define EVENT_ID_GEN_TCC2_OVF 46 /**< ID for TCC2 event generator OVF */ +#define EVENT_ID_GEN_TCC2_TRG 47 /**< ID for TCC2 event generator TRG */ +#define EVENT_ID_GEN_TCC2_CNT 48 /**< ID for TCC2 event generator CNT */ +#define EVENT_ID_GEN_TCC2_MC_0 49 /**< ID for TCC2 event generator MC_0 */ +#define EVENT_ID_GEN_TCC2_MC_1 50 /**< ID for TCC2 event generator MC_1 */ +#define EVENT_ID_GEN_TC3_OVF 51 /**< ID for TC3 event generator OVF */ +#define EVENT_ID_GEN_TC3_MC_0 52 /**< ID for TC3 event generator MC_0 */ +#define EVENT_ID_GEN_TC3_MC_1 53 /**< ID for TC3 event generator MC_1 */ +#define EVENT_ID_GEN_TC4_OVF 54 /**< ID for TC4 event generator OVF */ +#define EVENT_ID_GEN_TC4_MC_0 55 /**< ID for TC4 event generator MC_0 */ +#define EVENT_ID_GEN_TC4_MC_1 56 /**< ID for TC4 event generator MC_1 */ +#define EVENT_ID_GEN_TC5_OVF 57 /**< ID for TC5 event generator OVF */ +#define EVENT_ID_GEN_TC5_MC_0 58 /**< ID for TC5 event generator MC_0 */ +#define EVENT_ID_GEN_TC5_MC_1 59 /**< ID for TC5 event generator MC_1 */ +#define EVENT_ID_GEN_ADC_RESRDY 66 /**< ID for ADC event generator RESRDY */ +#define EVENT_ID_GEN_ADC_WINMON 67 /**< ID for ADC event generator WINMON */ +#define EVENT_ID_GEN_AC_COMP_0 68 /**< ID for AC event generator COMP_0 */ +#define EVENT_ID_GEN_AC_COMP_1 69 /**< ID for AC event generator COMP_1 */ +#define EVENT_ID_GEN_AC_WIN_0 70 /**< ID for AC event generator WIN_0 */ +#define EVENT_ID_GEN_DAC_EMPTY 71 /**< ID for DAC event generator EMPTY */ + +/* ************************************************************************** */ +/** Event User IDs for SAMD21E18A */ +/* ************************************************************************** */ +#define EVENT_ID_USER_DMAC_CH_0 0 /**< ID for DMAC event user CH_0 */ +#define EVENT_ID_USER_DMAC_CH_1 1 /**< ID for DMAC event user CH_1 */ +#define EVENT_ID_USER_DMAC_CH_2 2 /**< ID for DMAC event user CH_2 */ +#define EVENT_ID_USER_DMAC_CH_3 3 /**< ID for DMAC event user CH_3 */ +#define EVENT_ID_USER_TCC0_EV_0 4 /**< ID for TCC0 event user EV_0 */ +#define EVENT_ID_USER_TCC0_EV_1 5 /**< ID for TCC0 event user EV_1 */ +#define EVENT_ID_USER_TCC0_MC_0 6 /**< ID for TCC0 event user MC_0 */ +#define EVENT_ID_USER_TCC0_MC_1 7 /**< ID for TCC0 event user MC_1 */ +#define EVENT_ID_USER_TCC0_MC_2 8 /**< ID for TCC0 event user MC_2 */ +#define EVENT_ID_USER_TCC0_MC_3 9 /**< ID for TCC0 event user MC_3 */ +#define EVENT_ID_USER_TCC1_EV_0 10 /**< ID for TCC1 event user EV_0 */ +#define EVENT_ID_USER_TCC1_EV_1 11 /**< ID for TCC1 event user EV_1 */ +#define EVENT_ID_USER_TCC1_MC_0 12 /**< ID for TCC1 event user MC_0 */ +#define EVENT_ID_USER_TCC1_MC_1 13 /**< ID for TCC1 event user MC_1 */ +#define EVENT_ID_USER_TCC2_EV_0 14 /**< ID for TCC2 event user EV_0 */ +#define EVENT_ID_USER_TCC2_EV_1 15 /**< ID for TCC2 event user EV_1 */ +#define EVENT_ID_USER_TCC2_MC_0 16 /**< ID for TCC2 event user MC_0 */ +#define EVENT_ID_USER_TCC2_MC_1 17 /**< ID for TCC2 event user MC_1 */ +#define EVENT_ID_USER_TC3_EVU 18 /**< ID for TC3 event user EVU */ +#define EVENT_ID_USER_TC4_EVU 19 /**< ID for TC4 event user EVU */ +#define EVENT_ID_USER_TC5_EVU 20 /**< ID for TC5 event user EVU */ +#define EVENT_ID_USER_ADC_START 23 /**< ID for ADC event user START */ +#define EVENT_ID_USER_ADC_SYNC 24 /**< ID for ADC event user SYNC */ +#define EVENT_ID_USER_AC_SOC_0 25 /**< ID for AC event user SOC_0 */ +#define EVENT_ID_USER_AC_SOC_1 26 /**< ID for AC event user SOC_1 */ +#define EVENT_ID_USER_DAC_START 27 /**< ID for DAC event user START */ + +#ifdef __cplusplus +} +#endif + +/** @} end of SAMD21E18A definitions */ + + +#endif /* _SAMD21E18A_H_ */ + diff --git a/core/arm/samd21a/include_mcc/system_samd21.h b/core/arm/samd21a/include_mcc/system_samd21.h new file mode 100644 index 000000000..c9e78f40d --- /dev/null +++ b/core/arm/samd21a/include_mcc/system_samd21.h @@ -0,0 +1,48 @@ +/** + * \file + * + * \brief Low-level initialization functions called upon device startup + * + * Copyright (c) 2019 Microchip Technology Inc. + * + * \license_start + * + * \page License + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * \license_stop + * + */ + +#ifndef _SYSTEM_SAMD21_H_INCLUDED_ +#define _SYSTEM_SAMD21_H_INCLUDED_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +extern uint32_t SystemCoreClock; /*!< System Clock Frequency (Core Clock) */ + +void SystemInit(void); +void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* _SYSTEM_SAMD21_H_INCLUDED */ diff --git a/core/arm/samd21a/keil/Flash/ATSAMD21_128.FLM b/core/arm/samd21a/keil/Flash/ATSAMD21_128.FLM new file mode 100644 index 0000000000000000000000000000000000000000..6875234349ee377d18efd301665d8e8687137bd8 GIT binary patch literal 13592 zcmeHNeQcY@d4G;CNzsxVNt7+yi6Xz2=tQ<~dvoGuY0_d{u@-63twClO>jvxt-5)EK6>Ga?0k#ZXk!|UgEd%DimIC`@>Cj;q zTFm=BcRccyPAokFq4&27T53OBk-bu5QO8 zt}fvgolYX>S`kr8Q^0xvbrqs5O(ukj%0jDE$W_|3KqK0%0-~*&W$;6qA?na%({^W5 z#Ne*Sh=kOMy-HOCLit9|ybP3X!)P?jK@Jpk3jI6~i@r zT2AEe7VO_hH!+SVzy#5#7d4M|JlS!i!*HE!kM^k8jI9+b;S){a={oLkQ>3b!X!Xci zA&ZVSMW=gM@MKeuv2vG%!KTn+q?Kr5 ztwI`sIMfu^jX)TF6hZT0KJt8uD2C`%Q+lD}sg61H^0X3Z_6!@-^`cFN9Xo4b(Zr-; ziDFC`u4C;149-c6*i=)%?DTf%c`D5?K@{(iGgJ*J(K*HPP$zasOFS=Vkl)9WBw(Ygd%(f|q+(9C9|KcSOm7eSRn-hpZB)L&t53>^UOi4b;qY@^g4bH2 zYscyY0*xDTbw6ulDl6IS0kZx4L+-8ALM@`j<}zG%m&4_BwYb_{4}CP&C0q}TWxFlw z?4l=))CY?BA!MfcT6r7t1>}C@81k9!=U=jYUQlmcUPKv34tD?COO8+5Up8K0Ez!Gp z@HI57w0gbs@^*YC={-ZC(n`5h%oS@#&0u26WHw*ORm@TE@R+$;Ud+^TX22X=Sj`s} z&4Ay(&rFp{1%N9np^*7>U~yz@IPeVo3>}?+u2i{_FD}o+(0n`?nw$^TR&s@TbuXU| zpNgw?=k--RwmqU-?32A^wOGwB7juhdp;TNZyR9jxUM^K?WEZaNsa4={ujRRLT8yvJH@N%jW(Q5-(66)YF-j9J&7kavQU$>t(QCCu876!F+JB zLhjeWz9jmpHy}{lXPAp;mVssE=R{v32lGt-vgo^-DMVJvwd>@58-iCwU#%3cl$MqL zE6heJnQFc6Yr^<~;l3lpJ%jqHxooY(j=my{f!l)i{jKUpvMzU_Sw*uk^rbJjxLC1D zcs|@l*5j(f;LZMwM-@JC>gxOlS(fo9ku^TXE6YD?ANjo+M}DxGw|2(a?T&o0Mm6_q z6u-JU;wSgtk=Q#>bN?>$zAEVIR4l6+FoqHc_|L7Y`JFu}; zA*D-<>@>c=9yvnp?*iGy$WyW4X@Vu&z&7K*)&m3N{&xVk_a#%o)NE3@zti{)`#SeW z$^EF!Ht=v?FdVLjrME9O6Pi>tOo~sRpW?1HBQqt$gwcm} z+r%FT$851-lQ+eF%jvDLvPebV5QWzGoL-vN?DUsAN{;w!sZ?BOFFfx}kpp?Llv= zHz>cbiue0%`YuFk+WrIt;-Z`k)cFAx{I5cAv5eg)jcU@7&om?r-~JFHq(4Gl^A3Cr z=F^7BQ(nOKD1+#J74HM@Y5ILQCjIx}iO4#)VvW;3b`YdrCF~*yh}Ya<7qd?uM|Ht!#s!RX!bt)49vB+ql{7a5#GuVL;+w z!`mF~jC44A@oaHE><~LZ>^5q>0?lWn#eFF1EI0A?B3uAH+pj22$te&ID0f?t#}vYl?ym%q#uzcx0y$p>GV z_+3>$Y`G~*t^qwSq%!G60WvLW$gQ$BApIt?pg6xM+zd!OW%^Y-e+yYqN(qQQ58`zx zO5Q=Cv`MYK3W7~qY_Ml+T2KN{nOO8ZvITVs?1B;%P%y%x9S5tl=axV+LeM!pW!jHt z4A~;$@C-{)qc0p0bFBy*;d2TV8?Ld4-#&{i7WGO|!Ol}t`Zlw}BJ zH=;1W!I%tiz%mLKG*BK>)8OPlokD7Q_S9NXJb6)$(-R8e8^f5-Ye@YxnodN5VL20r zEdhIGJt~q&%&7TONBLmul18ZmYq}mQtD(#~NNgq;mOfd`EUd%C6EmkHR*)ZUW!HiD zyt@W80?^_*5ZE=C05G|A7&Ru^XMPQ@;G<$VJrPVsOw5mAl}HpI_BF&lEnd;~bOmU* z5{Xru_LFDQ$>>Ekl9izYm#m*1V!&GjnS&O=J5_1Q)9w z);wXJk0g?&k3|3M^yKu++_Z^~56n!5&P3xZ_CzkE4o^f=rXQb$pnYS^jF5N?%!r>E zxb`@hWISq);yW-I38iKd>FL=ibJT}g`(?vZ!3*Zt=;+88311x%nGPe?{8n%pvd|<# zs$b#6`LuM97gh|`0cND{ybsvuL-gYJLA{EsPf`3q!f688M!$|*nYfMUFTu&P_HG<( z>c{S?7NC z%jb#Cc@lH+sOR})YBDq#_RJ=;b0;hi%xhFk#mPVaojc>_C$gc(W`znOX@SkIyB1C&&Azy_&@JZ6RO0A}=RL7yZu=?kZy}IC!v%AZ2SHRx)K~udghW3RO^x z`OI>_#dqqBPa$dM7>P;6{ucoeE^dG&Y*SCF}D2d9R?7xLBGaqs-hYOQgRnZ|F9 zy~<>1wN_reuRe2aiJQ!3YPDPi22z>Ia<1lus}SdlOQqx0)s>Y@<$5)LBUc?#&swRL zDO876i>uY#;?UJxF^9{|RshbaRtvmcP`^z4HNIDjoZ2_UB#mRM~=Y3 z#oWT`vUxCT9xQq1(aHH{i&9(86&KN|HJU|e)<-W>&Q_1(`Yc!B+u}oqDy4G%Q02LD zo~>*c1oL3jJD*5J=F|Glm_rRIZks1_`GV!D8F$X1sbn-ckDF_+5B^>qtqY>XY+-dV z_rSIAf?+|FrZFW$Q^WHO3*mHn_IxzSdkHVAD36c&{pP`N8cwEBstQche~zyF4Xd?z zDl&y`mR6S13%EL{=GF%+TUk;+T(5sA${3?3|Hq>$TfFb6vSxEs{k{htRSsBVRKs%R z<_&W>R9eh&8Rpd<@^Cdf93Uk#d^hWkSBoVe~5D8HkcD-4dEPHzCmmzumkw<2@=IGoQT z^H}Kg=Ld*>q8XIhrjvxt-5)EK6>Ga?0k#ZXk!|UgEd%DimIC`@>Cj;q zTFm=BcRccyZA?|?AhXMy&P{5-?#U-UOIU8K;+z|p-3d;xzuNq=v($!&37`BPdZ+OnU zmEL>ScGGs_uUmfdZhuttpFH+O;nL3W}E3gAnDuj!r>2@yyp0@I-ppE)u%er3`; zRY+GaH}(Jfl#V<+W9N|WB4?3*VBj->jC8l26u0@^jKF3DHY2bZfz1ePMqo1nn-SQI zz-9zCBd{5P%?NBp;Qvzu#2z}-f!CNl=#+s+o9&Svyc2k+t?fjc;UaQ$3B$G5)$Mr5 z)g|1b(@Er9D$pleRS!lHixk{TBXhgeJK(tk}41Pc}L>-!J+U{(M z7~J&;agW?~bj@(JwGnkQ$;7rnGF-h-ZkNPXqMkOW*ae~;ZKQ~uEF;>53iP1X`#Omp zQV1q{S_GqT9ZEIUQO!s$4HwPY*g~x${qraC4 zqDQ!}!P=veK(_`vrD9(<8b-G;g8P|d;((G74Rxa*2fN`4k+&P}A7YKaUEzln!!>+b zPBhXj*uT+kVjPj538FDCY98%)yyHlR;X2tK=~1y6Un^F^$C|>^b=={mNL4q{>XEfV z79DMhPWQ0j@uomkBs#WMM0C6860$neEW?RGMXiDAprqs2WnDbBg7mj_;6`cwQu!WFo0#L~}dj zY&yRavuS>(oa-0-(voe<5P(l;hUj9Qgwszdk^u{fBzj6Cxy`3FGt|Lss?Iu@xuh7S zNh^lsi+(h(TFpoj4P}|&W^zmrEjeVd%mpv>%Z|FQMEN?2TAxxR(G{&``vuLYmRB^M zbwxJF>#-yW*eL5BaIl|I%*pm+U@D5~?P0&Fnjxx<$rZf%xQyu4b>CRF+p^9s zdeTUJpqL**W}2Usw;^9Z?njOypXq-7CEMo&_15J@lriK$_s_lL__Y0H;}zBty@wA! zL&Hj|*SjEJ$7d7XGZZYXluN~2v3Ar9#HUSW^Mzc+9P#tNVu9e)LZG&iD=esY`Bdms zOtrh9pXzb!5#3~;>@BOsYJRzx%bJB!ahdG4rl5McRH>0&xH6a16)qc4DcE=0ki7}z zuI4j2y0xe8e6CU@_t(ibK*mj*`%g%`Kz&fpq*rp}{tw7)%qFjw!G4{Lffohyfoz4` zZ-9MC^i`jOKyja8E|y*fmX)6seeoR3GyQqdcQsuIuas-o$^8xluZg}|DOM>hEB#lP z4Oi0DdfnHB@dd+uTZp>`^;L73T8SNfMHmCO1nv7<)sIA7?n1MQW@G3}Um%;USS36k zZXxS&)nV{ve#WB;pEz}O{(~&bwsk(nD$74>A9-C(Am882TRY?Ic1ONgqni75id|hD z9U=GMk=Q#>bN?>$zHxGYNa7Lj-(mhRPdV}EKujWECo$-WvG6-2_IdVy)8^`%j|HP~ za(^HPc|Mj1ClzC-7*UnMDB-#IArX9*Y4>HCgafnx&K8@@egh8ALHM@s4pH) zgyZMKAs@M)7CgxrHd(jT7YoD#(~5ERMP`!W8QJQOVWZvnZG&ytnl{j>+pw`!A*D-< z>@>c=9yv$o;U* zHt=9yAQY;HrME9S8=O)#Op48%pXRPLBQq_;q|uL%_Pd?D+Y$X9a(!L6J}K*>tR3Nf zs2$QYP8<^Y30Nl_%WordJnQp*ounNRap`vOfMBPOfQ3eI+d#As;h+>p|Xhe3OezDP5gmy z%oQ6p`B3afo@AT#y2*`oZK(UUA>J1bxfj>BPGg0-`tQRRk#%mx9;g4rZP*!q0$ zGH3wbjqPt}5$#O?X3!qsZTI%K(H<^7fZ%Hww}n$UyZJvy$atpP(PDH;#@H^UJMjhO z5YBA?w}IetFT;hg&AAKZUL)t+4Ph%=*#<$Y{5lM$bC+YcaiiPeaP}y|fW*Ouw>jDw z>2UVq+v0rCA$EY+ZPa#gD?p){DWjj8F<__L!2i$50@h8g3IDk9R%3Ha5D!7hjopt*Sq4 zxgkrg0X=V|GU-hLGA(Mzt+F>E{U)-Y7%voV1|+^R{VKk{g)Atk1Vo<$@rD#7Zlh4z zgw|dK!6q#>*fTaQD2}g8EP5W?Z-EYY!PvI zhNY;{7mkRzRs@dla|#t3uCa($pT!o7dZnmg%OKoVZFUA?u1i{k^?59>C8^+aD10F` z6@J1T9KIG9n~R#qj+uw|kvOvfmkP%jG(4g}!vIA#g63lqo zH6Kv6#+$aH_drEugQuFH>5ZWH{Cqg9{PzW#$eE8ps!sTVP2}uGWK{OSKimX0?mCUw zrsfpL*94v0XeklHk2!?aZwYODBP^(4qfKjxjj-5cP#UugL2@H1k(iVy%Mi?ML}7pf zQ5j&rWfU%GpuDE0z{!C+h1B%yiM60u;-Va<#}vXhjxk@*kos*j6%PkOawZO20`}B; zR5%`=Rr9Bg^1;?6jZzoZR6SN!L+N#p=xiV)eX^KYT!)FpXHSQ%pb@l{SqI|#?i$c2 zK-qO5uxl`WU~=m)YD~1xybQ14N5ybzGLQ(Hm>t*TbGC%=6)R z!t{~opPQMQnVp|85siV_nc$g7jK!Yth2-JMNYWg^&qC0?ab`wIJOXBPgc-Q@D40Yn zVvgZ=U?Ln$&c;(SbJOOS54HBohNlA;%<-|Y(Qy*KIwCw1!l3c0;51~RNd#5DLh1H<-ib+X=|39UrgY5U>bw@|W=Y}buj%AcX! zjm-9#{~k)dCGttkJimIBkonML{-06m_PcC0`d9F}y)GMW=$;yRviRRy$)yW;aZ9U# zQP)LpEqAR(-liBYQ@HhdGo@m+CZ&`7HW#SXD)<>u%T+y|lCdlX$)@3DT@WhGs?Ud=z3s}8AetyD`Fsza;A z)oLy~bTwDZ;c>GS0Y@YJSi6Fk+v-s~!SkOxm+`KKiTBgSZQYZuV$uI2N8n&Kx461& z9?X~rOWp-^a-rFx)RuF_EIPGDlZ9q|^wQ-_^*El-aut3pK6I#3D(4SXo-OCu%7#HO z4@SHT@nm=*rQeJ>)R5w}c`BDLSe}~k<{X?(L=p>lx%T?t@71xoAX3Z}R%SCbjM0<-<586@-g8u0vpK3GzWW|k4p?JULvrWl19Lf8 z%I3HX@oo=!sG6x@ljlX2N-r)}@UIVbZVB&5InD4kp=oR!4SAu26G7EpNoTC6^6Fv{ z2CC%6W>-ruqO4V9SuE91Kcn^#h%eU_a_{vwc4Bo_@p*-Fc$oKV-kaO;VVOS1`0Rwv zWc~dnw!@i!h;rgKo9DbbUs;ZS0F*eKlu~a;rN+;F$aI@sbsVlP(l7Rr{nAO}c0s`H z>hwFP$afx{wC+&|G|jr$4x)e5Ad8Ouw&I3%;)Z2$Q0pev;qI73KhjEzPW_^Xpq}3A zM?da?n}^;arkV%u4fp8B(mLEQEFry93<&T4~XJ3ADA{H}N!h3o@OwjsFIB C=`h#; literal 0 HcmV?d00001 diff --git a/core/arm/samd21a/keil/Flash/ATSAMD21_32.FLM b/core/arm/samd21a/keil/Flash/ATSAMD21_32.FLM new file mode 100644 index 0000000000000000000000000000000000000000..4477f50809e174ac7e856cff81d670b13ced6901 GIT binary patch literal 13588 zcmeHNZERcDd4A8mBt=VdBvH0(CyIP6(TQx!w5YGxjz2_^v`veWXp*uVM+r?)l+2nU zS(0*WZ%(`{O1eIxpDK?U{hG_U%&4c{@^&JJO^_qscs zkGVU9N3^?$Tx&%{O$`C-0n}B9wltU^Dk=-jb|F`3(E^QVwF`*0YL>x|XojdwlMUPL z4H1Joo*?d#$APYy?v@s!P9~Yy)=#Fp8_MmH*hpAh;}QI$kMWrR-!$cX=&No(hAePZPLxYr)1%EqTuN7 zWrFAlE(}qNuo7DjMClS~{?GNOS_^y6SBTp{vx!u><68EIAcLB((l zzm^jXbqe-xxRV%1G{OYYs1G%dwmsc;q|J1nY>jlO*o>_eE8$ZO;prOga6_c3TWIyj zS|N*$HbkepSnza1pehm_TPq?u-VmHdtWGr8hO6TU*~zsEc9zBC4Y6{Ug@K09W~7;D zVy!|NfjHO@*Ni|IdK^LXV?OeH3M+=_R6}~9?U}YY^zyV4Y4!{o)Ab?^h8;U=W6{K< zVu_+mnC@e(BN&{M7_q5_fZ6Ho(DPK9VS*^uC1#o_atrKY+|MUn_4zzJT0|97R6U`Qj_a=LB`v0dE)C$C>EM{~0Y}p$14USo>rNwkLYmHd_3#+;O zqBSx!w9iTwi+O;{E5V@k?8xHq*x<->@H2RH{)J-sO0KXx4@2{@KyY$CP+iI9=heM@ zDs(EQ+MU-|^?22 zSSHUKU|$hEl^YN!?$gZ0(#ycI^0T5Ro`rd)e?|0MP3OZarRsI^yaT~)(NitP%Ee`+ z|8-`=<#eT1_jO_Zs_D5a#C?-`D%ni6$d0}y%)UE<_Wix;N1`Toqgh3>G4!P;u((*Z zOL#uqLDu7{!{E#Oj7Jqdaq4LQCs~$^bw0+*%Rg%$d0mYoKite)JL4PBF{gN*xOh2{2}xHG4gys;tBBIWd1NuIq_s)Od?+=(eI71@S7y|dG~+KaQDo` zg3&m6-j{aTFtc#L% zg!ifTDprMiE6#p&oqDCy(Z)J)O6bR6op3C_fz0u&&HIf@X8o4j>v@w-{FWhZ3umN| ztCH~CL3Q;KJC8D#=B@U3>6g*%Tqb{o=^IQh6*5dOgML1hDrYOJ`6{8Zh;<7(@xCGc zSU6`3b({QB>_whno3*;hjdcywecKe@6Hd7o*S1i0iYxOQlS}PX00vU_#{UCKaj~3T z&J_zO_PqUN%q$;Z7t6&L8j^NM=)|`j;`4@+-vQdTwJq@HN06ipNLR z=W~}yeRytce?yCCZyYd__5g1@*x!14IQRg9r)l05F5&9rf6kEk$xdgJ*)AD#yOi$4 z6O>c9wgKD%g3G-O7v?tCE|h!CtZO%f&1_{G1kLj4G+nM;&fVtCPN&n=r3e!eCmY`8 zY-Oa=)s1J9>rtoJ0b;jV-Nmf{g=QwrUT(&OolX<~Z^#1HEv^awxbbFlh5dx3?OiDP zC393hn_O(O)qKgdn*lJ(z*gm)tzoqA688(sR0v)uC1eNPq%VAdDPA@P-QOuSar z4_j`^l50TE8>visQ-Dm1>TVyzW{BYaMwV%;?s@#?eLVo|pg)oq!C)2iWMAm+NHMOeR&<*_6coC<|6 zq$b19Sp9?70;980>)0{t@IDe}HsDg>ID-a<6lf5j$VSjyOoB!lptBo6;eaw#YmZG$ zZbZ!ml&!Ibt>^<#QQ6?B254#{C_XnA4lDotfd+E=Bao^S{$K++vk@7UeHa;Rfa+(R zdTdj(3gmBq&TX`mh~Z-np&hY>Hog%S)Ue@(wZukPY$7O)*@hsw5tT?xNR({|W;dcR zz=5a?@Q7^`E@+@Url!EjfjWiM@a&njpjhIf9H*xg!as&FpVyGuX*3lN2SRct4%!0t z+p)=FU`Bw+uEVG?(LVDsyn>I4!PG<`5wVXo|&7r5RJZ>>EM}2jK$vYh2-IhNYWa@XCY|+7&F5po&YmE#0*?} z5=pYcF%OfX?fLcWE*QI`nZz!AM$=MBk!ug;sq zckVhl=m+z$Zuli`PQR|%r8ym{}rWfzr!%--@)tlIt-l9y;brq;=iw)P3Ljr zmR19!j*Gr(_F9#E4KZ$}aO(ACiiJv5N+NwO@flIgR=nQinW!F_D}MPKLa*iE!flQ((_Ty)y}{(6Bc? z1ATZRaM+72a5@x-hoX@QZ#;bNus4R=hQr=)U?OsLNX?Sk46)A+`^>1%fi;tkW7vv} zG>&USMd8Wu{zhSE2S*{!6_$#}E2}Fj>GJhT?nbsUpq|xYHJz^v ztQJ-)*~NjY*+Ldqo6QI}+Tg3&72Mlaj^YBIf9+htts17?Pa3s#7rKf??~fdTgNxaP z)n)5o#yVK^&7+U=jTWW0lr1cxQ)@Jf(5#PLx|FFL$K_eJ%y-3y4wZ|g+@bOdr5sz? zFa*}Yh;Kfg49}g-m{RG5gT9 zu)44tO4FE+!KuOdx`j|GHG4ji;1>z+sVI++4#A&L3O=S#stQchev2;M4XJ&3Dm;Zw z7FU*13%E9@WY>o)Q(jWPTCaU2$_S$)Kjkr%Ek1BeS+hB&{)Zh?4p)6lLvqjN-3_A~ zEG}lb4Dn76O{kJ7V}s`Aha` z;{mui=xt)EdU4nAfPO5k!wur_^O`np)A98M$4;j=f#VBJem6HGbNo1*FCz0;==4_y zh<>aYl-j3PL1WI;)7t~;DnSeMczhNDU59n|fO}6XZMx5cwzvBgTnpZTOebyQe*swQ BFi`*i literal 0 HcmV?d00001 diff --git a/core/arm/samd21a/keil/Flash/ATSAMD21_64.FLM b/core/arm/samd21a/keil/Flash/ATSAMD21_64.FLM new file mode 100644 index 0000000000000000000000000000000000000000..7b468fa573934f268171f33cea5cb556545a36c6 GIT binary patch literal 13588 zcmeHNeQcY@d4G;CNzsxVNt7+yi6Xz2=tQ<~XLI6ZY0_d{u?=pqtwClO>jvxt-5)KM73;^c09%Hx@V0d8mI3o$OM(5dbm%Y) zE$026J0AH;axkNRw85aW@4e^ach5cd+{b(Gi7$tvr-TrslZ^&RbIB2+TgYT1ho4Lo zgVaeK6xg%H*?KwNBEDT?==`eZ z%-iX`XKgoaH~zNe$9MaqqW|PExA99m+wYxqy`8q#<+dBY2Ajg{{Q7;L@cqW*hkr+) zKm6*uy`OPypZW~Br{C{AaPz>8_hF-J=J*NP*K^l6HL*|pzyHR2b7ELw58U`-%lBdT!>)Kdp1?zGZ713c7m=e&7_PmpZpUM; zF5woPP9o=85m8H1zd<7 z;I1c#d*rsGYlf?>ji{SRCbkWd;p&BQyCk*}^|V37E)eZ#BSq|F8PP6Ophvadhg*}! z6oScKmNW5q8*$OM6_z7Chqn;zRwR+BW&U=eJ(_82+uGI+)BPRN&4H(6;c=kg=*MBx+zcMkfAPhZ@p!qN#c|L^|Lv*Ssz0mPY$2@v@T8T7!hK=cZktV~AowcxNVoI?@ zQ6>!6v35TO=OjjKx+!3GW;^sem1dbBiuK4Ds)m&4oML&X<2$4!o)-xwnMf)b(cBI> zo6hgVY?|LG=lTV|v}D^d1mH88A-Y&6;qDOAc8qbHNM!vZL-RQNB*1)+ZE6bVaM#enB&;+>opLStDIp$z%?Y?dKnHZ>1J$5iK^C;j+6NE~l%-)$V%aqp>dGdT1=$ZCPg* zJ!zyqP|Ob@GtJk^+mJ6H_ajG<&vd`^s_k=vdh7Bc${2E>`{!PDe9Hcs@j7dX-ot~h zp<$)f>s^r7@BOsYJRzx%bJB!ahdG4rl5McRH>0&xH6a16)qc4DcE<%ki7}z zuI4j2y1l3Ge6CU@_m{~wK*mj*`_D+cOnp$#q*rp}{x8UF%qFjw!G4*Hfma0cfoz4` zZ-RYQ^i^MkKyjaDE|y*fmX)6seeoR3GyN-~?`pabUMbhEllxr=Zi&8HDOM>hEB&uC z8?L0Q^}25e<5vy$9U<-;)K|@AY9)5`bzuzL7PRm0RX-ASxeLuInvJ0^eSvJYVwLcG zxQ(pGRfoZw`5BKYeB#vA`A@Pe+t&FQt1SPledKjDf&6eYZ|#h;+a390jcV>UD0X#q zbcEdhKw|Ge&HabW`^L%r0f{HTf0OycJmtib12KtwgT$aG#=>us*yq{*HJht%J{F9| z$^E_@R?s4pH) zgyZMKAs@M)7d*)sHd(jT7YoD#(~5ERMP`!W8QJQOV58mmeS>Y-nl{j>JFu};A*D-< z>@>c+9yv$o;s@ zHt=X)AQY;HrME9S8=O)#Op48%pXRPLBQq_;q|uL%_Pd?D+Y$W{a(!L6J}&E`tR3Nf zs2$QYP8<^YF<2)Y%WoiaJnQp*{OfMBPOfQ3eK9#EEs;h+>p|Xhe3Oez=P5iNN z%oQ6p`K8#8Jjpieb(0(G+EDi$Lwrv-w7sPhAC_+NzJVi|9v6sk!_KHZQseESoKkp2{T%^LU^%%=^L zr@V;QqYR?^7S;p5)AV{cCjIx}iO4#)Vvo~5b`YeO65b<7YfdyQa5{nhKkKV_d}Mt- zcNsK*=f?Iow21a505fP0@U{p0+h`95A3*Rlj61?9oZbA-5i&m6?PxJNC1Y%t(w%sM zatP-(fZITDxtHO>*yh}Ya<7qd?uM|Ht!#s!RX!bt)49vB+qlu~a5#GuVL;+w!`mF~ zjC44A@oaHE>JU3X>^5qR3^PCK&C|vxmETSq+df86yt@$&49#Hrr*T#_mBl8m4N7TAl{Us#2pk$ zo6y>;AlRhE27AV)1;z1{iA66VTTqw4E-Fz01tTol39w3gZV4nK1f9cEru}$Eku4$) z&#)9V`oa-0*NVUqKBrKz;Tns0^;vAOs8@;_whY2))n;cP=DMUsSig_uu_P6o4uvnI zrozvdgTvPXV{=jS*fI0)J`!g(;8Ni@gN8>GXc(Z#M$mjrg8WU;*^QuZK$)ty$EKz> zqUHn2)_Bua^Z}@-Z17YQG`$fNpPvthmH)m#6FKt{NYx2nu!)@Ah>XfU_=lUI##yHk z+ti!_`I?|}8!aVb_?Saz{g%+iH^PD%Hrlk7*a(YF2Bk5}5F|IE5{XHPvJAo8Mid4( z5S0P;TSno62Fhb<3Y;9MQ%FtEo>>cuB`(TwdP*UD;~4V=4XK|-Q}J*hBxmBVC1B63 zM}_0@Sv7y^C?9NH(kOLcP1R#%HI!ZliOvQ>(kF|V#dVlieD-wM3K~IMnROsO@2&xj z0+d|`0=ov|2PU@;qsB!0%**f!J}QP&lYvCo#QYdmi9`WnUqkHE;uURASAd2qk+_c2 ze&S3j5xK~QWCaqxAlSM&IA~fvUCjOam{pC!gI5^jdoW130MIXrddrN{PSn4J*q|1% zUx0r~D0gCk(_!V)xSzypb!j|&Ix;(> z#}lTHME~5()XePsjEQIr%+3VQL}D!VgfAoyPezjF2tErz`^K3WCGiB9(Gh0g+LK@s zv4}Z_@4!Sjn4FELX6B~NF&}E}mkmz`E|}wEW256Fe04;4CWKh?s^Bzap-BW)ze4fz zDd`|@tQeI8%t+t)Jz%2`(TlHux`nJyQT#!|X%g8+zl~d&n2qSK!O64sZX9gt$L?oA zT2ImMfVUoY*~(+m$`4zJz6I(_$c-}|=#2>`EJ?_>&^HOlknEwt+J|*&-n0dbSC?WGpllgx|soU?e+34TF>-M^AIH7xL&JOF$Xv~2%la6E9j*K*c zYePlh$?^V4uO@MQTgVr$$jiyG?8tM3yUHjF4j!x`NSPXlm2{ce>nn?;LKRdtpI%N? zSIcF5bXJcaIWp=SijI#Ck3p3wuO1KL3Nm-?;Pf!~LcUr%?p>H&tu-z(Q{#TGvRGQJ zl~*66PG4K%1~cheEmuMHWV*7Pt9jul#QEY<>3DT@WhGs?Ud_Lls}8AWtyD`Fsza;A z)oLy~bTwDZ;cBxL;YJ&LRl9 z4`$4RCGP_IxX^4-YRkD|7M)t7$wIR}cIk4adK{N$xeDJEA39VimGg%xFO>6aWy27d z2P58vcrv_@(l^EkG=#Wnp33D5mV0JgI0vT_k;DS7t-U_Ddv&ZXh!iu0)okveYhiU^ zH_u* zvXolHwLvwvK3ti~lKRzp{VP#M7#;a3kEv|&fn&;=%`x>o?3i-68eo|jlEy|`GxUmoh*67G<4n&C}C)7Ul|@)^))T*{IO82W%zHKO%k6k*IlnVGLua!7 zVH4Zo%pakgxXrtgQV(qlfBcg;yd|aHj!KPBeaJMftB%95Mf%1*vR^uB+%5>XU7h{_ z75TiQlh!>6fu>m(+d=ft8f4M2-&WkvPMoeR4r<-RI@~>z=!aTq(W$R_2 + + Microchip Technology Inc. + MICROCHIP + ATSAMD21E18A + SAMD21 + D + Microchip ATSAMD21E18A device: Cortex-M0+ Microcontroller with 256KB Flash, 32KB SRAM, 32-pin package + + Copyright (c) 2018 Microchip Technology Inc.\n +\n + SPDX-License-Identifier: Apache-2.0\n +\n + Licensed under the Apache License, Version 2.0 (the "License");\n + you may not use this file except in compliance with the License.\n + You may obtain a copy of the License at\n +\n + http://www.apache.org/licenses/LICENSE-2.0\n +\n + Unless required by applicable law or agreed to in writing, software\n + distributed under the License is distributed on an "AS IS" BASIS,\n + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n + See the License for the specific language governing permissions and\n + limitations under the License. + + + CM0+ + r0p1 + little + false + false + true + 2 + false + 28 + + system_samd21 + 8 + 32 + 32 + read-write + 0x00000000 + 0xFFFFFFFF + + + AC + 1.1.1 + Analog Comparators + AC + AC_ + 0x42004400 + + 0 + 0x40 + registers + + + AC + 24 + + + + CTRLA + Control A + 0x00 + 8 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + RUNSTDBY + Run in Standby + 2 + 1 + + + LPMUX + Low-Power Mux + 7 + 1 + + + + + CTRLB + Control B + 0x01 + 8 + write-only + + + START0 + Comparator 0 Start Comparison + 0 + 1 + + + START1 + Comparator 1 Start Comparison + 1 + 1 + + + + + EVCTRL + Event Control + 0x02 + 16 + + + COMPEO0 + Comparator 0 Event Output Enable + 0 + 1 + + + COMPEO1 + Comparator 1 Event Output Enable + 1 + 1 + + + WINEO0 + Window 0 Event Output Enable + 4 + 1 + + + COMPEI0 + Comparator 0 Event Input + 8 + 1 + + + COMPEI1 + Comparator 1 Event Input + 9 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x04 + 8 + + + COMP0 + Comparator 0 Interrupt Enable + 0 + 1 + + + COMP1 + Comparator 1 Interrupt Enable + 1 + 1 + + + WIN0 + Window 0 Interrupt Enable + 4 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x05 + 8 + + + COMP0 + Comparator 0 Interrupt Enable + 0 + 1 + + + COMP1 + Comparator 1 Interrupt Enable + 1 + 1 + + + WIN0 + Window 0 Interrupt Enable + 4 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x06 + 8 + + + COMP0 + Comparator 0 + 0 + 1 + + + COMP1 + Comparator 1 + 1 + 1 + + + WIN0 + Window 0 + 4 + 1 + + + + + STATUSA + Status A + 0x08 + 8 + read-only + + + STATE0 + Comparator 0 Current State + 0 + 1 + + + STATE1 + Comparator 1 Current State + 1 + 1 + + + WSTATE0 + Window 0 Current State + 4 + 2 + + WSTATE0Select + + ABOVE + Signal is above window + 0x0 + + + INSIDE + Signal is inside window + 0x1 + + + BELOW + Signal is below window + 0x2 + + + + + + + STATUSB + Status B + 0x09 + 8 + read-only + + + READY0 + Comparator 0 Ready + 0 + 1 + read-only + + + READY1 + Comparator 1 Ready + 1 + 1 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + + + + + STATUSC + Status C + 0x0A + 8 + read-only + + + STATE0 + Comparator 0 Current State + 0 + 1 + + + STATE1 + Comparator 1 Current State + 1 + 1 + + + WSTATE0 + Window 0 Current State + 4 + 2 + + WSTATE0Select + + ABOVE + Signal is above window + 0x0 + + + INSIDE + Signal is inside window + 0x1 + + + BELOW + Signal is below window + 0x2 + + + + + + + WINCTRL + Window Control + 0x0C + 8 + + + WEN0 + Window 0 Mode Enable + 0 + 1 + + + WINTSEL0 + Window 0 Interrupt Selection + 1 + 2 + + WINTSEL0Select + + ABOVE + Interrupt on signal above window + 0x0 + + + INSIDE + Interrupt on signal inside window + 0x1 + + + BELOW + Interrupt on signal below window + 0x2 + + + OUTSIDE + Interrupt on signal outside window + 0x3 + + + + + + + 2 + 0x4 + COMPCTRL%s + Comparator Control n + 0x10 + 32 + + + ENABLE + Enable + 0 + 1 + + + SINGLE + Single-Shot Mode + 1 + 1 + + + SPEED + Speed Selection + 2 + 2 + + SPEEDSelect + + LOW + Low speed + 0x0 + + + HIGH + High speed + 0x1 + + + + + INTSEL + Interrupt Selection + 5 + 2 + + INTSELSelect + + TOGGLE + Interrupt on comparator output toggle + 0x0 + + + RISING + Interrupt on comparator output rising + 0x1 + + + FALLING + Interrupt on comparator output falling + 0x2 + + + EOC + Interrupt on end of comparison (single-shot mode only) + 0x3 + + + + + MUXNEG + Negative Input Mux Selection + 8 + 3 + + MUXNEGSelect + + PIN0 + I/O pin 0 + 0x0 + + + PIN1 + I/O pin 1 + 0x1 + + + PIN2 + I/O pin 2 + 0x2 + + + PIN3 + I/O pin 3 + 0x3 + + + GND + Ground + 0x4 + + + VSCALE + VDD scaler + 0x5 + + + BANDGAP + Internal bandgap voltage + 0x6 + + + DAC + DAC output + 0x7 + + + + + MUXPOS + Positive Input Mux Selection + 12 + 2 + + MUXPOSSelect + + PIN0 + I/O pin 0 + 0x0 + + + PIN1 + I/O pin 1 + 0x1 + + + PIN2 + I/O pin 2 + 0x2 + + + PIN3 + I/O pin 3 + 0x3 + + + + + SWAP + Swap Inputs and Invert + 15 + 1 + + + OUT + Output + 16 + 2 + + OUTSelect + + OFF + The output of COMPn is not routed to the COMPn I/O port + 0x0 + + + ASYNC + The asynchronous output of COMPn is routed to the COMPn I/O port + 0x1 + + + SYNC + The synchronous output (including filtering) of COMPn is routed to the COMPn I/O port + 0x2 + + + + + HYST + Hysteresis Enable + 19 + 1 + + + FLEN + Filter Length + 24 + 3 + + FLENSelect + + OFF + No filtering + 0x0 + + + MAJ3 + 3-bit majority function (2 of 3) + 0x1 + + + MAJ5 + 5-bit majority function (3 of 5) + 0x2 + + + + + + + 2 + 0x1 + SCALER%s + Scaler n + 0x20 + 8 + + + VALUE + Scaler Value + 0 + 6 + + + + + + + ADC + 1.2.0 + Analog Digital Converter + ADC + ADC_ + 0x42004000 + + 0 + 0x80 + registers + + + ADC + 23 + + + + CTRLA + Control A + 0x00 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + RUNSTDBY + Run in Standby + 2 + 1 + + + + + REFCTRL + Reference Control + 0x01 + 8 + + + REFSEL + Reference Selection + 0 + 4 + + REFSELSelect + + INT1V + 1.0V voltage reference + 0x0 + + + INTVCC0 + 1/1.48 VDDANA + 0x1 + + + INTVCC1 + 1/2 VDDANA (only for VDDANA > 2.0V) + 0x2 + + + AREFA + External reference + 0x3 + + + AREFB + External reference + 0x4 + + + + + REFCOMP + Reference Buffer Offset Compensation Enable + 7 + 1 + + + + + AVGCTRL + Average Control + 0x02 + 8 + + + SAMPLENUM + Number of Samples to be Collected + 0 + 4 + + SAMPLENUMSelect + + 1 + 1 sample + 0x0 + + + 2 + 2 samples + 0x1 + + + 4 + 4 samples + 0x2 + + + 8 + 8 samples + 0x3 + + + 16 + 16 samples + 0x4 + + + 32 + 32 samples + 0x5 + + + 64 + 64 samples + 0x6 + + + 128 + 128 samples + 0x7 + + + 256 + 256 samples + 0x8 + + + 512 + 512 samples + 0x9 + + + 1024 + 1024 samples + 0xa + + + + + ADJRES + Adjusting Result / Division Coefficient + 4 + 3 + + + + + SAMPCTRL + Sampling Time Control + 0x03 + 8 + + + SAMPLEN + Sampling Time Length + 0 + 6 + + + + + CTRLB + Control B + 0x04 + 16 + + + DIFFMODE + Differential Mode + 0 + 1 + + + LEFTADJ + Left-Adjusted Result + 1 + 1 + + + FREERUN + Free Running Mode + 2 + 1 + + + CORREN + Digital Correction Logic Enabled + 3 + 1 + + + RESSEL + Conversion Result Resolution + 4 + 2 + + RESSELSelect + + 12BIT + 12-bit result + 0x0 + + + 16BIT + For averaging mode output + 0x1 + + + 10BIT + 10-bit result + 0x2 + + + 8BIT + 8-bit result + 0x3 + + + + + PRESCALER + Prescaler Configuration + 8 + 3 + + PRESCALERSelect + + DIV4 + Peripheral clock divided by 4 + 0x0 + + + DIV8 + Peripheral clock divided by 8 + 0x1 + + + DIV16 + Peripheral clock divided by 16 + 0x2 + + + DIV32 + Peripheral clock divided by 32 + 0x3 + + + DIV64 + Peripheral clock divided by 64 + 0x4 + + + DIV128 + Peripheral clock divided by 128 + 0x5 + + + DIV256 + Peripheral clock divided by 256 + 0x6 + + + DIV512 + Peripheral clock divided by 512 + 0x7 + + + + + + + WINCTRL + Window Monitor Control + 0x08 + 8 + + + WINMODE + Window Monitor Mode + 0 + 3 + + WINMODESelect + + DISABLE + No window mode (default) + 0x0 + + + MODE1 + Mode 1: RESULT > WINLT + 0x1 + + + MODE2 + Mode 2: RESULT < WINUT + 0x2 + + + MODE3 + Mode 3: WINLT < RESULT < WINUT + 0x3 + + + MODE4 + Mode 4: !(WINLT < RESULT < WINUT) + 0x4 + + + + + + + SWTRIG + Software Trigger + 0x0C + 8 + + + FLUSH + ADC Conversion Flush + 0 + 1 + + + START + ADC Start Conversion + 1 + 1 + + + + + INPUTCTRL + Input Control + 0x10 + 32 + + + MUXPOS + Positive Mux Input Selection + 0 + 5 + + MUXPOSSelect + + PIN0 + ADC AIN0 Pin + 0x0 + + + PIN1 + ADC AIN1 Pin + 0x1 + + + PIN2 + ADC AIN2 Pin + 0x2 + + + PIN3 + ADC AIN3 Pin + 0x3 + + + PIN4 + ADC AIN4 Pin + 0x4 + + + PIN5 + ADC AIN5 Pin + 0x5 + + + PIN6 + ADC AIN6 Pin + 0x6 + + + PIN7 + ADC AIN7 Pin + 0x7 + + + PIN8 + ADC AIN8 Pin + 0x8 + + + PIN9 + ADC AIN9 Pin + 0x9 + + + PIN10 + ADC AIN10 Pin + 0xa + + + PIN11 + ADC AIN11 Pin + 0xb + + + PIN12 + ADC AIN12 Pin + 0xc + + + PIN13 + ADC AIN13 Pin + 0xd + + + PIN14 + ADC AIN14 Pin + 0xe + + + PIN15 + ADC AIN15 Pin + 0xf + + + PIN16 + ADC AIN16 Pin + 0x10 + + + PIN17 + ADC AIN17 Pin + 0x11 + + + PIN18 + ADC AIN18 Pin + 0x12 + + + PIN19 + ADC AIN19 Pin + 0x13 + + + TEMP + Temperature Reference + 0x18 + + + BANDGAP + Bandgap Voltage + 0x19 + + + SCALEDCOREVCC + 1/4 Scaled Core Supply + 0x1a + + + SCALEDIOVCC + 1/4 Scaled I/O Supply + 0x1b + + + DAC + DAC Output + 0x1c + + + + + MUXNEG + Negative Mux Input Selection + 8 + 5 + + MUXNEGSelect + + PIN0 + ADC AIN0 Pin + 0x0 + + + PIN1 + ADC AIN1 Pin + 0x1 + + + PIN2 + ADC AIN2 Pin + 0x2 + + + PIN3 + ADC AIN3 Pin + 0x3 + + + PIN4 + ADC AIN4 Pin + 0x4 + + + PIN5 + ADC AIN5 Pin + 0x5 + + + PIN6 + ADC AIN6 Pin + 0x6 + + + PIN7 + ADC AIN7 Pin + 0x7 + + + GND + Internal Ground + 0x18 + + + IOGND + I/O Ground + 0x19 + + + + + INPUTSCAN + Number of Input Channels Included in Scan + 16 + 4 + + + INPUTOFFSET + Positive Mux Setting Offset + 20 + 4 + + + GAIN + Gain Factor Selection + 24 + 4 + + GAINSelect + + 1X + 1x + 0x0 + + + 2X + 2x + 0x1 + + + 4X + 4x + 0x2 + + + 8X + 8x + 0x3 + + + 16X + 16x + 0x4 + + + DIV2 + 1/2x + 0xf + + + + + + + EVCTRL + Event Control + 0x14 + 8 + + + STARTEI + Start Conversion Event In + 0 + 1 + + + SYNCEI + Synchronization Event In + 1 + 1 + + + RESRDYEO + Result Ready Event Out + 4 + 1 + + + WINMONEO + Window Monitor Event Out + 5 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x16 + 8 + + + RESRDY + Result Ready Interrupt Enable + 0 + 1 + + + OVERRUN + Overrun Interrupt Enable + 1 + 1 + + + WINMON + Window Monitor Interrupt Enable + 2 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x17 + 8 + + + RESRDY + Result Ready Interrupt Enable + 0 + 1 + + + OVERRUN + Overrun Interrupt Enable + 1 + 1 + + + WINMON + Window Monitor Interrupt Enable + 2 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x18 + 8 + + + RESRDY + Result Ready + 0 + 1 + + + OVERRUN + Overrun + 1 + 1 + + + WINMON + Window Monitor + 2 + 1 + + + SYNCRDY + Synchronization Ready + 3 + 1 + + + + + STATUS + Status + 0x19 + 8 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + RESULT + Result + 0x1A + 16 + read-only + + + RESULT + Result Conversion Value + 0 + 16 + read-only + + + + + WINLT + Window Monitor Lower Threshold + 0x1C + 16 + + + WINLT + Window Lower Threshold + 0 + 16 + + + + + WINUT + Window Monitor Upper Threshold + 0x20 + 16 + + + WINUT + Window Upper Threshold + 0 + 16 + + + + + GAINCORR + Gain Correction + 0x24 + 16 + + + GAINCORR + Gain Correction Value + 0 + 12 + + + + + OFFSETCORR + Offset Correction + 0x26 + 16 + + + OFFSETCORR + Offset Correction Value + 0 + 12 + + + + + CALIB + Calibration + 0x28 + 16 + + + LINEARITY_CAL + Linearity Calibration Value + 0 + 8 + + + BIAS_CAL + Bias Calibration Value + 8 + 3 + + + + + DBGCTRL + Debug Control + 0x2A + 8 + + + DBGRUN + Debug Run + 0 + 1 + + + + + + + DAC + 1.1.0 + Digital Analog Converter + DAC + DAC_ + 0x42004800 + + 0 + 0x10 + registers + + + DAC + 25 + + + + CTRLA + Control A + 0x0 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + RUNSTDBY + Run in Standby + 2 + 1 + + + + + CTRLB + Control B + 0x1 + 8 + + + EOEN + External Output Enable + 0 + 1 + + + IOEN + Internal Output Enable + 1 + 1 + + + LEFTADJ + Left Adjusted Data + 2 + 1 + + + VPD + Voltage Pump Disable + 3 + 1 + + + BDWP + Bypass DATABUF Write Protection + 4 + 1 + + + REFSEL + Reference Selection + 6 + 2 + + REFSELSelect + + INT1V + Internal 1.0V reference + 0x0 + + + AVCC + AVCC + 0x1 + + + VREFP + External reference + 0x2 + + + + + + + EVCTRL + Event Control + 0x2 + 8 + + + STARTEI + Start Conversion Event Input + 0 + 1 + + + EMPTYEO + Data Buffer Empty Event Output + 1 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x4 + 8 + + + UNDERRUN + Underrun Interrupt Enable + 0 + 1 + + + EMPTY + Data Buffer Empty Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 2 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x5 + 8 + + + UNDERRUN + Underrun Interrupt Enable + 0 + 1 + + + EMPTY + Data Buffer Empty Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 2 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x6 + 8 + + + UNDERRUN + Underrun + 0 + 1 + + + EMPTY + Data Buffer Empty + 1 + 1 + + + SYNCRDY + Synchronization Ready + 2 + 1 + + + + + STATUS + Status + 0x7 + 8 + read-only + + + SYNCBUSY + Synchronization Busy Status + 7 + 1 + read-only + + + + + DATA + Data + 0x8 + 16 + + + DATA + Data value to be converted + 0 + 16 + + + + + DATABUF + Data Buffer + 0xC + 16 + + + DATABUF + Data Buffer + 0 + 16 + + + + + + + DMAC + 1.0.0 + Direct Memory Access Controller + DMAC + DMAC_ + 0x41004800 + + 0 + 0x80 + registers + + + DMAC + 6 + + + + CTRL + Control + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + + + DMAENABLE + DMA Enable + 1 + 1 + + + CRCENABLE + CRC Enable + 2 + 1 + + + LVLEN0 + Priority Level 0 Enable + 8 + 1 + + + LVLEN1 + Priority Level 1 Enable + 9 + 1 + + + LVLEN2 + Priority Level 2 Enable + 10 + 1 + + + LVLEN3 + Priority Level 3 Enable + 11 + 1 + + + + + CRCCTRL + CRC Control + 0x02 + 16 + + + CRCBEATSIZE + CRC Beat Size + 0 + 2 + + CRCBEATSIZESelect + + BYTE + 8-bit bus transfer + 0x0 + + + HWORD + 16-bit bus transfer + 0x1 + + + WORD + 32-bit bus transfer + 0x2 + + + + + CRCPOLY + CRC Polynomial Type + 2 + 2 + + CRCPOLYSelect + + CRC16 + CRC-16 (CRC-CCITT) + 0x0 + + + CRC32 + CRC32 (IEEE 802.3) + 0x1 + + + + + CRCSRC + CRC Input Source + 8 + 6 + + CRCSRCSelect + + NOACT + No action + 0x0 + + + IO + I/O interface + 0x1 + + + + + + + CRCDATAIN + CRC Data Input + 0x04 + 32 + + + CRCDATAIN + CRC Data Input + 0 + 32 + + + + + CRCCHKSUM + CRC Checksum + 0x08 + 32 + + + CRCCHKSUM + CRC Checksum + 0 + 32 + + + + + CRCSTATUS + CRC Status + 0x0C + 8 + + + CRCBUSY + CRC Module Busy + 0 + 1 + + + CRCZERO + CRC Zero + 1 + 1 + read-only + + + + + DBGCTRL + Debug Control + 0x0D + 8 + + + DBGRUN + Debug Run + 0 + 1 + + + + + QOSCTRL + QOS Control + 0x0E + 8 + 0x15 + + + WRBQOS + Write-Back Quality of Service + 0 + 2 + + WRBQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + FQOS + Fetch Quality of Service + 2 + 2 + + FQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + DQOS + Data Transfer Quality of Service + 4 + 2 + + DQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + + + SWTRIGCTRL + Software Trigger Control + 0x10 + 32 + + + SWTRIG0 + Channel 0 Software Trigger + 0 + 1 + + + SWTRIG1 + Channel 1 Software Trigger + 1 + 1 + + + SWTRIG2 + Channel 2 Software Trigger + 2 + 1 + + + SWTRIG3 + Channel 3 Software Trigger + 3 + 1 + + + SWTRIG4 + Channel 4 Software Trigger + 4 + 1 + + + SWTRIG5 + Channel 5 Software Trigger + 5 + 1 + + + SWTRIG6 + Channel 6 Software Trigger + 6 + 1 + + + SWTRIG7 + Channel 7 Software Trigger + 7 + 1 + + + SWTRIG8 + Channel 8 Software Trigger + 8 + 1 + + + SWTRIG9 + Channel 9 Software Trigger + 9 + 1 + + + SWTRIG10 + Channel 10 Software Trigger + 10 + 1 + + + SWTRIG11 + Channel 11 Software Trigger + 11 + 1 + + + + + PRICTRL0 + Priority Control 0 + 0x14 + 32 + + + LVLPRI0 + Level 0 Channel Priority Number + 0 + 4 + + + RRLVLEN0 + Level 0 Round-Robin Scheduling Enable + 7 + 1 + + + LVLPRI1 + Level 1 Channel Priority Number + 8 + 4 + + + RRLVLEN1 + Level 1 Round-Robin Scheduling Enable + 15 + 1 + + + LVLPRI2 + Level 2 Channel Priority Number + 16 + 4 + + + RRLVLEN2 + Level 2 Round-Robin Scheduling Enable + 23 + 1 + + + LVLPRI3 + Level 3 Channel Priority Number + 24 + 4 + + + RRLVLEN3 + Level 3 Round-Robin Scheduling Enable + 31 + 1 + + + + + INTPEND + Interrupt Pending + 0x20 + 16 + + + ID + Channel ID + 0 + 4 + + + TERR + Transfer Error + 8 + 1 + + + TCMPL + Transfer Complete + 9 + 1 + + + SUSP + Channel Suspend + 10 + 1 + + + FERR + Fetch Error + 13 + 1 + read-only + + + BUSY + Busy + 14 + 1 + read-only + + + PEND + Pending + 15 + 1 + read-only + + + + + INTSTATUS + Interrupt Status + 0x24 + 32 + read-only + + + CHINT0 + Channel 0 Pending Interrupt + 0 + 1 + read-only + + + CHINT1 + Channel 1 Pending Interrupt + 1 + 1 + read-only + + + CHINT2 + Channel 2 Pending Interrupt + 2 + 1 + read-only + + + CHINT3 + Channel 3 Pending Interrupt + 3 + 1 + read-only + + + CHINT4 + Channel 4 Pending Interrupt + 4 + 1 + read-only + + + CHINT5 + Channel 5 Pending Interrupt + 5 + 1 + read-only + + + CHINT6 + Channel 6 Pending Interrupt + 6 + 1 + read-only + + + CHINT7 + Channel 7 Pending Interrupt + 7 + 1 + read-only + + + CHINT8 + Channel 8 Pending Interrupt + 8 + 1 + read-only + + + CHINT9 + Channel 9 Pending Interrupt + 9 + 1 + read-only + + + CHINT10 + Channel 10 Pending Interrupt + 10 + 1 + read-only + + + CHINT11 + Channel 11 Pending Interrupt + 11 + 1 + read-only + + + + + BUSYCH + Busy Channels + 0x28 + 32 + read-only + + + BUSYCH0 + Busy Channel 0 + 0 + 1 + read-only + + + BUSYCH1 + Busy Channel 1 + 1 + 1 + read-only + + + BUSYCH2 + Busy Channel 2 + 2 + 1 + read-only + + + BUSYCH3 + Busy Channel 3 + 3 + 1 + read-only + + + BUSYCH4 + Busy Channel 4 + 4 + 1 + read-only + + + BUSYCH5 + Busy Channel 5 + 5 + 1 + read-only + + + BUSYCH6 + Busy Channel 6 + 6 + 1 + read-only + + + BUSYCH7 + Busy Channel 7 + 7 + 1 + read-only + + + BUSYCH8 + Busy Channel 8 + 8 + 1 + read-only + + + BUSYCH9 + Busy Channel 9 + 9 + 1 + read-only + + + BUSYCH10 + Busy Channel 10 + 10 + 1 + read-only + + + BUSYCH11 + Busy Channel 11 + 11 + 1 + read-only + + + + + PENDCH + Pending Channels + 0x2C + 32 + read-only + + + PENDCH0 + Pending Channel 0 + 0 + 1 + read-only + + + PENDCH1 + Pending Channel 1 + 1 + 1 + read-only + + + PENDCH2 + Pending Channel 2 + 2 + 1 + read-only + + + PENDCH3 + Pending Channel 3 + 3 + 1 + read-only + + + PENDCH4 + Pending Channel 4 + 4 + 1 + read-only + + + PENDCH5 + Pending Channel 5 + 5 + 1 + read-only + + + PENDCH6 + Pending Channel 6 + 6 + 1 + read-only + + + PENDCH7 + Pending Channel 7 + 7 + 1 + read-only + + + PENDCH8 + Pending Channel 8 + 8 + 1 + read-only + + + PENDCH9 + Pending Channel 9 + 9 + 1 + read-only + + + PENDCH10 + Pending Channel 10 + 10 + 1 + read-only + + + PENDCH11 + Pending Channel 11 + 11 + 1 + read-only + + + + + ACTIVE + Active Channel and Levels + 0x30 + 32 + read-only + + + LVLEX0 + Level 0 Channel Trigger Request Executing + 0 + 1 + read-only + + + LVLEX1 + Level 1 Channel Trigger Request Executing + 1 + 1 + read-only + + + LVLEX2 + Level 2 Channel Trigger Request Executing + 2 + 1 + read-only + + + LVLEX3 + Level 3 Channel Trigger Request Executing + 3 + 1 + read-only + + + ID + Active Channel ID + 8 + 5 + read-only + + + ABUSY + Active Channel Busy + 15 + 1 + read-only + + + BTCNT + Active Channel Block Transfer Count + 16 + 16 + read-only + + + + + BASEADDR + Descriptor Memory Section Base Address + 0x34 + 32 + + + BASEADDR + Descriptor Memory Base Address + 0 + 32 + + + + + WRBADDR + Write-Back Memory Section Base Address + 0x38 + 32 + + + WRBADDR + Write-Back Memory Base Address + 0 + 32 + + + + + CHID + Channel ID + 0x3F + 8 + + + ID + Channel ID + 0 + 4 + + + + + CHCTRLA + Channel Control A + 0x40 + 8 + + + SWRST + Channel Software Reset + 0 + 1 + + + ENABLE + Channel Enable + 1 + 1 + + + + + CHCTRLB + Channel Control B + 0x44 + 32 + + + EVACT + Event Input Action + 0 + 3 + + EVACTSelect + + NOACT + No action + 0x0 + + + TRIG + Transfer and periodic transfer trigger + 0x1 + + + CTRIG + Conditional transfer trigger + 0x2 + + + CBLOCK + Conditional block transfer + 0x3 + + + SUSPEND + Channel suspend operation + 0x4 + + + RESUME + Channel resume operation + 0x5 + + + SSKIP + Skip next block suspend action + 0x6 + + + + + EVIE + Channel Event Input Enable + 3 + 1 + + + EVOE + Channel Event Output Enable + 4 + 1 + + + LVL + Channel Arbitration Level + 5 + 2 + + LVLSelect + + LVL0 + Channel Priority Level 0 + 0x0 + + + LVL1 + Channel Priority Level 1 + 0x1 + + + LVL2 + Channel Priority Level 2 + 0x2 + + + LVL3 + Channel Priority Level 3 + 0x3 + + + + + TRIGSRC + Trigger Source + 8 + 6 + + TRIGSRCSelect + + DISABLE + Only software/event triggers + 0x0 + + + + + TRIGACT + Trigger Action + 22 + 2 + + TRIGACTSelect + + BLOCK + One trigger required for each block transfer + 0x0 + + + BEAT + One trigger required for each beat transfer + 0x2 + + + TRANSACTION + One trigger required for each transaction + 0x3 + + + + + CMD + Software Command + 24 + 2 + + CMDSelect + + NOACT + No action + 0x0 + + + SUSPEND + Channel suspend operation + 0x1 + + + RESUME + Channel resume operation + 0x2 + + + + + + + CHINTENCLR + Channel Interrupt Enable Clear + 0x4C + 8 + + + TERR + Channel Transfer Error Interrupt Enable + 0 + 1 + + + TCMPL + Channel Transfer Complete Interrupt Enable + 1 + 1 + + + SUSP + Channel Suspend Interrupt Enable + 2 + 1 + + + + + CHINTENSET + Channel Interrupt Enable Set + 0x4D + 8 + + + TERR + Channel Transfer Error Interrupt Enable + 0 + 1 + + + TCMPL + Channel Transfer Complete Interrupt Enable + 1 + 1 + + + SUSP + Channel Suspend Interrupt Enable + 2 + 1 + + + + + CHINTFLAG + Channel Interrupt Flag Status and Clear + 0x4E + 8 + + + TERR + Channel Transfer Error + 0 + 1 + + + TCMPL + Channel Transfer Complete + 1 + 1 + + + SUSP + Channel Suspend + 2 + 1 + + + + + CHSTATUS + Channel Status + 0x4F + 8 + read-only + + + PEND + Channel Pending + 0 + 1 + read-only + + + BUSY + Channel Busy + 1 + 1 + read-only + + + FERR + Channel Fetch Error + 2 + 1 + read-only + + + + + + + DSU + 2.0.0 + Device Service Unit + DSU + DSU_ + 0x41002000 + + 0 + 0x2000 + registers + + + + CTRL + Control + 0x0000 + 8 + write-only + + + SWRST + Software Reset + 0 + 1 + write-only + + + CRC + 32-bit Cyclic Redundancy Check + 2 + 1 + write-only + + + MBIST + Memory Built-In Self-Test + 3 + 1 + write-only + + + CE + Chip Erase + 4 + 1 + write-only + + + + + STATUSA + Status A + 0x0001 + 8 + + + DONE + Done + 0 + 1 + + + CRSTEXT + CPU Reset Phase Extension + 1 + 1 + + + BERR + Bus Error + 2 + 1 + + + FAIL + Failure + 3 + 1 + + + PERR + Protection Error + 4 + 1 + + + + + STATUSB + Status B + 0x0002 + 8 + read-only + 0x10 + + + PROT + Protected + 0 + 1 + + + DBGPRES + Debugger Present + 1 + 1 + + + DCCD0 + Debug Communication Channel 0 Dirty + 2 + 1 + + + DCCD1 + Debug Communication Channel 1 Dirty + 3 + 1 + + + HPE + Hot-Plugging Enable + 4 + 1 + + + + + ADDR + Address + 0x0004 + 32 + + + ADDR + Address + 2 + 30 + + + + + LENGTH + Length + 0x0008 + 32 + + + LENGTH + Length + 2 + 30 + + + + + DATA + Data + 0x000C + 32 + + + DATA + Data + 0 + 32 + + + + + 2 + 0x4 + DCC%s + Debug Communication Channel n + 0x0010 + 32 + + + DATA + Data + 0 + 32 + + + + + DID + Device Identification + 0x0018 + 32 + read-only + 0x1001030A + + + DEVSEL + Device Select + 0 + 8 + read-only + + + REVISION + Revision + 8 + 4 + read-only + + + DIE + Die Identification + 12 + 4 + read-only + + + SERIES + Product Series + 16 + 6 + read-only + + + FAMILY + Product Family + 23 + 5 + read-only + + + PROCESSOR + Processor + 28 + 4 + read-only + + + + + ENTRY + CoreSight ROM Table Entry 0 + 0x1000 + 32 + read-only + 0x9F9FC002 + + + EPRES + Entry Present + 0 + 1 + + + FMT + Format + 1 + 1 + read-only + + + ADDOFF + Address Offset + 12 + 20 + read-only + + + + + ENTRY1 + CoreSight ROM Table Entry 1 + 0x1004 + 32 + read-only + 0x00003002 + + + END + CoreSight ROM Table End + 0x1008 + 32 + read-only + + + END + End Marker + 0 + 32 + + + + + MEMTYPE + CoreSight ROM Table Memory Type + 0x1FCC + 32 + read-only + + + SMEMP + System Memory Present + 0 + 1 + + + + + PID4 + Peripheral Identification 4 + 0x1FD0 + 32 + read-only + + + JEPCC + JEP-106 Continuation Code + 0 + 4 + + + FKBC + 4KB Count + 4 + 4 + read-only + + + + + PID0 + Peripheral Identification 0 + 0x1FE0 + 32 + read-only + 0x000000D0 + + + PARTNBL + Part Number Low + 0 + 8 + + + + + PID1 + Peripheral Identification 1 + 0x1FE4 + 32 + read-only + 0x000000FC + + + PARTNBH + Part Number High + 0 + 4 + + + JEPIDCL + Low part of the JEP-106 Identity Code + 4 + 4 + read-only + + + + + PID2 + Peripheral Identification 2 + 0x1FE8 + 32 + read-only + 0x00000009 + + + JEPIDCH + JEP-106 Identity Code High + 0 + 3 + + + JEPU + JEP-106 Identity Code is used + 3 + 1 + read-only + + + REVISION + Revision Number + 4 + 4 + read-only + + + + + PID3 + Peripheral Identification 3 + 0x1FEC + 32 + read-only + + + CUSMOD + ARM CUSMOD + 0 + 4 + + + REVAND + Revision Number + 4 + 4 + read-only + + + + + CID0 + Component Identification 0 + 0x1FF0 + 32 + read-only + 0x0000000D + + + PREAMBLEB0 + Preamble Byte 0 + 0 + 8 + read-only + + + + + CID1 + Component Identification 1 + 0x1FF4 + 32 + read-only + 0x00000010 + + + PREAMBLE + Preamble + 0 + 4 + read-only + + + CCLASS + Component Class + 4 + 4 + read-only + + + + + CID2 + Component Identification 2 + 0x1FF8 + 32 + read-only + 0x00000005 + + + PREAMBLEB2 + Preamble Byte 2 + 0 + 8 + read-only + + + + + CID3 + Component Identification 3 + 0x1FFC + 32 + read-only + 0x000000B1 + + + PREAMBLEB3 + Preamble Byte 3 + 0 + 8 + + + + + + + EIC + 1.0.1 + External Interrupt Controller + EIC + EIC_ + 0x40001800 + + 0 + 0x40 + registers + + + EIC + 4 + + + + CTRL + Control + 0x00 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + + + STATUS + Status + 0x01 + 8 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + NMICTRL + Non-Maskable Interrupt Control + 0x02 + 8 + + + NMISENSE + Non-Maskable Interrupt Sense + 0 + 3 + + NMISENSESelect + + NONE + No detection + 0x0 + + + RISE + Rising-edge detection + 0x1 + + + FALL + Falling-edge detection + 0x2 + + + BOTH + Both-edges detection + 0x3 + + + HIGH + High-level detection + 0x4 + + + LOW + Low-level detection + 0x5 + + + + + NMIFILTEN + Non-Maskable Interrupt Filter Enable + 3 + 1 + + + + + NMIFLAG + Non-Maskable Interrupt Flag Status and Clear + 0x03 + 8 + + + NMI + Non-Maskable Interrupt + 0 + 1 + + + + + EVCTRL + Event Control + 0x04 + 32 + + + EXTINTEO0 + External Interrupt 0 Event Output Enable + 0 + 1 + + + EXTINTEO1 + External Interrupt 1 Event Output Enable + 1 + 1 + + + EXTINTEO2 + External Interrupt 2 Event Output Enable + 2 + 1 + + + EXTINTEO3 + External Interrupt 3 Event Output Enable + 3 + 1 + + + EXTINTEO4 + External Interrupt 4 Event Output Enable + 4 + 1 + + + EXTINTEO5 + External Interrupt 5 Event Output Enable + 5 + 1 + + + EXTINTEO6 + External Interrupt 6 Event Output Enable + 6 + 1 + + + EXTINTEO7 + External Interrupt 7 Event Output Enable + 7 + 1 + + + EXTINTEO8 + External Interrupt 8 Event Output Enable + 8 + 1 + + + EXTINTEO9 + External Interrupt 9 Event Output Enable + 9 + 1 + + + EXTINTEO10 + External Interrupt 10 Event Output Enable + 10 + 1 + + + EXTINTEO11 + External Interrupt 11 Event Output Enable + 11 + 1 + + + EXTINTEO12 + External Interrupt 12 Event Output Enable + 12 + 1 + + + EXTINTEO13 + External Interrupt 13 Event Output Enable + 13 + 1 + + + EXTINTEO14 + External Interrupt 14 Event Output Enable + 14 + 1 + + + EXTINTEO15 + External Interrupt 15 Event Output Enable + 15 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x08 + 32 + + + EXTINT0 + External Interrupt 0 Enable + 0 + 1 + + + EXTINT1 + External Interrupt 1 Enable + 1 + 1 + + + EXTINT2 + External Interrupt 2 Enable + 2 + 1 + + + EXTINT3 + External Interrupt 3 Enable + 3 + 1 + + + EXTINT4 + External Interrupt 4 Enable + 4 + 1 + + + EXTINT5 + External Interrupt 5 Enable + 5 + 1 + + + EXTINT6 + External Interrupt 6 Enable + 6 + 1 + + + EXTINT7 + External Interrupt 7 Enable + 7 + 1 + + + EXTINT8 + External Interrupt 8 Enable + 8 + 1 + + + EXTINT9 + External Interrupt 9 Enable + 9 + 1 + + + EXTINT10 + External Interrupt 10 Enable + 10 + 1 + + + EXTINT11 + External Interrupt 11 Enable + 11 + 1 + + + EXTINT12 + External Interrupt 12 Enable + 12 + 1 + + + EXTINT13 + External Interrupt 13 Enable + 13 + 1 + + + EXTINT14 + External Interrupt 14 Enable + 14 + 1 + + + EXTINT15 + External Interrupt 15 Enable + 15 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x0C + 32 + + + EXTINT0 + External Interrupt 0 Enable + 0 + 1 + + + EXTINT1 + External Interrupt 1 Enable + 1 + 1 + + + EXTINT2 + External Interrupt 2 Enable + 2 + 1 + + + EXTINT3 + External Interrupt 3 Enable + 3 + 1 + + + EXTINT4 + External Interrupt 4 Enable + 4 + 1 + + + EXTINT5 + External Interrupt 5 Enable + 5 + 1 + + + EXTINT6 + External Interrupt 6 Enable + 6 + 1 + + + EXTINT7 + External Interrupt 7 Enable + 7 + 1 + + + EXTINT8 + External Interrupt 8 Enable + 8 + 1 + + + EXTINT9 + External Interrupt 9 Enable + 9 + 1 + + + EXTINT10 + External Interrupt 10 Enable + 10 + 1 + + + EXTINT11 + External Interrupt 11 Enable + 11 + 1 + + + EXTINT12 + External Interrupt 12 Enable + 12 + 1 + + + EXTINT13 + External Interrupt 13 Enable + 13 + 1 + + + EXTINT14 + External Interrupt 14 Enable + 14 + 1 + + + EXTINT15 + External Interrupt 15 Enable + 15 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x10 + 32 + + + EXTINT0 + External Interrupt 0 + 0 + 1 + + + EXTINT1 + External Interrupt 1 + 1 + 1 + + + EXTINT2 + External Interrupt 2 + 2 + 1 + + + EXTINT3 + External Interrupt 3 + 3 + 1 + + + EXTINT4 + External Interrupt 4 + 4 + 1 + + + EXTINT5 + External Interrupt 5 + 5 + 1 + + + EXTINT6 + External Interrupt 6 + 6 + 1 + + + EXTINT7 + External Interrupt 7 + 7 + 1 + + + EXTINT8 + External Interrupt 8 + 8 + 1 + + + EXTINT9 + External Interrupt 9 + 9 + 1 + + + EXTINT10 + External Interrupt 10 + 10 + 1 + + + EXTINT11 + External Interrupt 11 + 11 + 1 + + + EXTINT12 + External Interrupt 12 + 12 + 1 + + + EXTINT13 + External Interrupt 13 + 13 + 1 + + + EXTINT14 + External Interrupt 14 + 14 + 1 + + + EXTINT15 + External Interrupt 15 + 15 + 1 + + + + + WAKEUP + Wake-Up Enable + 0x14 + 32 + + + WAKEUPEN0 + External Interrupt 0 Wake-up Enable + 0 + 1 + + + WAKEUPEN1 + External Interrupt 1 Wake-up Enable + 1 + 1 + + + WAKEUPEN2 + External Interrupt 2 Wake-up Enable + 2 + 1 + + + WAKEUPEN3 + External Interrupt 3 Wake-up Enable + 3 + 1 + + + WAKEUPEN4 + External Interrupt 4 Wake-up Enable + 4 + 1 + + + WAKEUPEN5 + External Interrupt 5 Wake-up Enable + 5 + 1 + + + WAKEUPEN6 + External Interrupt 6 Wake-up Enable + 6 + 1 + + + WAKEUPEN7 + External Interrupt 7 Wake-up Enable + 7 + 1 + + + WAKEUPEN8 + External Interrupt 8 Wake-up Enable + 8 + 1 + + + WAKEUPEN9 + External Interrupt 9 Wake-up Enable + 9 + 1 + + + WAKEUPEN10 + External Interrupt 10 Wake-up Enable + 10 + 1 + + + WAKEUPEN11 + External Interrupt 11 Wake-up Enable + 11 + 1 + + + WAKEUPEN12 + External Interrupt 12 Wake-up Enable + 12 + 1 + + + WAKEUPEN13 + External Interrupt 13 Wake-up Enable + 13 + 1 + + + WAKEUPEN14 + External Interrupt 14 Wake-up Enable + 14 + 1 + + + WAKEUPEN15 + External Interrupt 15 Wake-up Enable + 15 + 1 + + + + + 2 + 0x4 + CONFIG%s + Configuration n + 0x18 + 32 + + + SENSE0 + Input Sense 0 Configuration + 0 + 3 + + SENSE0Select + + NONE + No detection + 0x0 + + + RISE + Rising-edge detection + 0x1 + + + FALL + Falling-edge detection + 0x2 + + + BOTH + Both-edges detection + 0x3 + + + HIGH + High-level detection + 0x4 + + + LOW + Low-level detection + 0x5 + + + + + FILTEN0 + Filter 0 Enable + 3 + 1 + + + SENSE1 + Input Sense 1 Configuration + 4 + 3 + + SENSE1Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN1 + Filter 1 Enable + 7 + 1 + + + SENSE2 + Input Sense 2 Configuration + 8 + 3 + + SENSE2Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN2 + Filter 2 Enable + 11 + 1 + + + SENSE3 + Input Sense 3 Configuration + 12 + 3 + + SENSE3Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN3 + Filter 3 Enable + 15 + 1 + + + SENSE4 + Input Sense 4 Configuration + 16 + 3 + + SENSE4Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN4 + Filter 4 Enable + 19 + 1 + + + SENSE5 + Input Sense 5 Configuration + 20 + 3 + + SENSE5Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN5 + Filter 5 Enable + 23 + 1 + + + SENSE6 + Input Sense 6 Configuration + 24 + 3 + + SENSE6Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN6 + Filter 6 Enable + 27 + 1 + + + SENSE7 + Input Sense 7 Configuration + 28 + 3 + + SENSE7Select + + NONE + No detection + 0x0 + + + RISE + Rising edge detection + 0x1 + + + FALL + Falling edge detection + 0x2 + + + BOTH + Both edges detection + 0x3 + + + HIGH + High level detection + 0x4 + + + LOW + Low level detection + 0x5 + + + + + FILTEN7 + Filter 7 Enable + 31 + 1 + + + + + + + EVSYS + 1.0.1 + Event System Interface + EVSYS + EVSYS_ + 0x42000400 + + 0 + 0x80 + registers + + + EVSYS + 8 + + + + CTRL + Control + 0x00 + 8 + write-only + + + SWRST + Software Reset + 0 + 1 + write-only + + + GCLKREQ + Generic Clock Requests + 4 + 1 + + + + + CHANNEL + Channel + 0x04 + 32 + + + CHANNEL + Channel Selection + 0 + 4 + + + SWEVT + Software Event + 8 + 1 + + + EVGEN + Event Generator Selection + 16 + 7 + + + PATH + Path Selection + 24 + 2 + + PATHSelect + + SYNCHRONOUS + Synchronous path + 0x0 + + + RESYNCHRONIZED + Resynchronized path + 0x1 + + + ASYNCHRONOUS + Asynchronous path + 0x2 + + + + + EDGSEL + Edge Detection Selection + 26 + 2 + + EDGSELSelect + + NO_EVT_OUTPUT + No event output when using the resynchronized or synchronous path + 0x0 + + + RISING_EDGE + Event detection only on the rising edge of the signal from the event generator when using the resynchronized or synchronous path + 0x1 + + + FALLING_EDGE + Event detection only on the falling edge of the signal from the event generator when using the resynchronized or synchronous path + 0x2 + + + BOTH_EDGES + Event detection on rising and falling edges of the signal from the event generator when using the resynchronized or synchronous path + 0x3 + + + + + + + USER + User Multiplexer + 0x08 + 16 + + + USER + User Multiplexer Selection + 0 + 5 + + + CHANNEL + Channel Event Selection + 8 + 5 + + CHANNELSelect + + 0 + No Channel Output Selected + 0x0 + + + + + + + CHSTATUS + Channel Status + 0x0C + 32 + read-only + 0x000F00FF + + + USRRDY0 + Channel 0 User Ready + 0 + 1 + read-only + + + USRRDY1 + Channel 1 User Ready + 1 + 1 + read-only + + + USRRDY2 + Channel 2 User Ready + 2 + 1 + read-only + + + USRRDY3 + Channel 3 User Ready + 3 + 1 + read-only + + + USRRDY4 + Channel 4 User Ready + 4 + 1 + read-only + + + USRRDY5 + Channel 5 User Ready + 5 + 1 + read-only + + + USRRDY6 + Channel 6 User Ready + 6 + 1 + read-only + + + USRRDY7 + Channel 7 User Ready + 7 + 1 + read-only + + + CHBUSY0 + Channel 0 Busy + 8 + 1 + read-only + + + CHBUSY1 + Channel 1 Busy + 9 + 1 + read-only + + + CHBUSY2 + Channel 2 Busy + 10 + 1 + read-only + + + CHBUSY3 + Channel 3 Busy + 11 + 1 + read-only + + + CHBUSY4 + Channel 4 Busy + 12 + 1 + read-only + + + CHBUSY5 + Channel 5 Busy + 13 + 1 + read-only + + + CHBUSY6 + Channel 6 Busy + 14 + 1 + read-only + + + CHBUSY7 + Channel 7 Busy + 15 + 1 + read-only + + + USRRDY8 + Channel 8 User Ready + 16 + 1 + read-only + + + USRRDY9 + Channel 9 User Ready + 17 + 1 + read-only + + + USRRDY10 + Channel 10 User Ready + 18 + 1 + read-only + + + USRRDY11 + Channel 11 User Ready + 19 + 1 + read-only + + + CHBUSY8 + Channel 8 Busy + 24 + 1 + read-only + + + CHBUSY9 + Channel 9 Busy + 25 + 1 + read-only + + + CHBUSY10 + Channel 10 Busy + 26 + 1 + read-only + + + CHBUSY11 + Channel 11 Busy + 27 + 1 + read-only + + + + + INTENCLR + Interrupt Enable Clear + 0x10 + 32 + + + OVR0 + Channel 0 Overrun Interrupt Enable + 0 + 1 + + + OVR1 + Channel 1 Overrun Interrupt Enable + 1 + 1 + + + OVR2 + Channel 2 Overrun Interrupt Enable + 2 + 1 + + + OVR3 + Channel 3 Overrun Interrupt Enable + 3 + 1 + + + OVR4 + Channel 4 Overrun Interrupt Enable + 4 + 1 + + + OVR5 + Channel 5 Overrun Interrupt Enable + 5 + 1 + + + OVR6 + Channel 6 Overrun Interrupt Enable + 6 + 1 + + + OVR7 + Channel 7 Overrun Interrupt Enable + 7 + 1 + + + EVD0 + Channel 0 Event Detection Interrupt Enable + 8 + 1 + + + EVD1 + Channel 1 Event Detection Interrupt Enable + 9 + 1 + + + EVD2 + Channel 2 Event Detection Interrupt Enable + 10 + 1 + + + EVD3 + Channel 3 Event Detection Interrupt Enable + 11 + 1 + + + EVD4 + Channel 4 Event Detection Interrupt Enable + 12 + 1 + + + EVD5 + Channel 5 Event Detection Interrupt Enable + 13 + 1 + + + EVD6 + Channel 6 Event Detection Interrupt Enable + 14 + 1 + + + EVD7 + Channel 7 Event Detection Interrupt Enable + 15 + 1 + + + OVR8 + Channel 8 Overrun Interrupt Enable + 16 + 1 + + + OVR9 + Channel 9 Overrun Interrupt Enable + 17 + 1 + + + OVR10 + Channel 10 Overrun Interrupt Enable + 18 + 1 + + + OVR11 + Channel 11 Overrun Interrupt Enable + 19 + 1 + + + EVD8 + Channel 8 Event Detection Interrupt Enable + 24 + 1 + + + EVD9 + Channel 9 Event Detection Interrupt Enable + 25 + 1 + + + EVD10 + Channel 10 Event Detection Interrupt Enable + 26 + 1 + + + EVD11 + Channel 11 Event Detection Interrupt Enable + 27 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x14 + 32 + + + OVR0 + Channel 0 Overrun Interrupt Enable + 0 + 1 + + + OVR1 + Channel 1 Overrun Interrupt Enable + 1 + 1 + + + OVR2 + Channel 2 Overrun Interrupt Enable + 2 + 1 + + + OVR3 + Channel 3 Overrun Interrupt Enable + 3 + 1 + + + OVR4 + Channel 4 Overrun Interrupt Enable + 4 + 1 + + + OVR5 + Channel 5 Overrun Interrupt Enable + 5 + 1 + + + OVR6 + Channel 6 Overrun Interrupt Enable + 6 + 1 + + + OVR7 + Channel 7 Overrun Interrupt Enable + 7 + 1 + + + EVD0 + Channel 0 Event Detection Interrupt Enable + 8 + 1 + + + EVD1 + Channel 1 Event Detection Interrupt Enable + 9 + 1 + + + EVD2 + Channel 2 Event Detection Interrupt Enable + 10 + 1 + + + EVD3 + Channel 3 Event Detection Interrupt Enable + 11 + 1 + + + EVD4 + Channel 4 Event Detection Interrupt Enable + 12 + 1 + + + EVD5 + Channel 5 Event Detection Interrupt Enable + 13 + 1 + + + EVD6 + Channel 6 Event Detection Interrupt Enable + 14 + 1 + + + EVD7 + Channel 7 Event Detection Interrupt Enable + 15 + 1 + + + OVR8 + Channel 8 Overrun Interrupt Enable + 16 + 1 + + + OVR9 + Channel 9 Overrun Interrupt Enable + 17 + 1 + + + OVR10 + Channel 10 Overrun Interrupt Enable + 18 + 1 + + + OVR11 + Channel 11 Overrun Interrupt Enable + 19 + 1 + + + EVD8 + Channel 8 Event Detection Interrupt Enable + 24 + 1 + + + EVD9 + Channel 9 Event Detection Interrupt Enable + 25 + 1 + + + EVD10 + Channel 10 Event Detection Interrupt Enable + 26 + 1 + + + EVD11 + Channel 11 Event Detection Interrupt Enable + 27 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x18 + 32 + + + OVR0 + Channel 0 Overrun + 0 + 1 + + + OVR1 + Channel 1 Overrun + 1 + 1 + + + OVR2 + Channel 2 Overrun + 2 + 1 + + + OVR3 + Channel 3 Overrun + 3 + 1 + + + OVR4 + Channel 4 Overrun + 4 + 1 + + + OVR5 + Channel 5 Overrun + 5 + 1 + + + OVR6 + Channel 6 Overrun + 6 + 1 + + + OVR7 + Channel 7 Overrun + 7 + 1 + + + EVD0 + Channel 0 Event Detection + 8 + 1 + + + EVD1 + Channel 1 Event Detection + 9 + 1 + + + EVD2 + Channel 2 Event Detection + 10 + 1 + + + EVD3 + Channel 3 Event Detection + 11 + 1 + + + EVD4 + Channel 4 Event Detection + 12 + 1 + + + EVD5 + Channel 5 Event Detection + 13 + 1 + + + EVD6 + Channel 6 Event Detection + 14 + 1 + + + EVD7 + Channel 7 Event Detection + 15 + 1 + + + OVR8 + Channel 8 Overrun + 16 + 1 + + + OVR9 + Channel 9 Overrun + 17 + 1 + + + OVR10 + Channel 10 Overrun + 18 + 1 + + + OVR11 + Channel 11 Overrun + 19 + 1 + + + EVD8 + Channel 8 Event Detection + 24 + 1 + + + EVD9 + Channel 9 Event Detection + 25 + 1 + + + EVD10 + Channel 10 Event Detection + 26 + 1 + + + EVD11 + Channel 11 Event Detection + 27 + 1 + + + + + + + GCLK + 2.1.0 + Generic Clock Generator + GCLK + GCLK_ + 0x40000C00 + + 0 + 0x10 + registers + + + + CTRL + Control + 0x0 + 8 + + + SWRST + Software Reset + 0 + 1 + + + + + STATUS + Status + 0x1 + 8 + read-only + + + SYNCBUSY + Synchronization Busy Status + 7 + 1 + read-only + + + + + CLKCTRL + Generic Clock Control + 0x2 + 16 + + + ID + Generic Clock Selection ID + 0 + 6 + + IDSelect + + DFLL48 + DFLL48 + 0x0 + + + FDPLL + FDPLL + 0x1 + + + FDPLL32K + FDPLL32K + 0x2 + + + WDT + WDT + 0x3 + + + RTC + RTC + 0x4 + + + EIC + EIC + 0x5 + + + USB + USB + 0x6 + + + EVSYS_0 + EVSYS_0 + 0x7 + + + EVSYS_1 + EVSYS_1 + 0x8 + + + EVSYS_2 + EVSYS_2 + 0x9 + + + EVSYS_3 + EVSYS_3 + 0xa + + + EVSYS_4 + EVSYS_4 + 0xb + + + EVSYS_5 + EVSYS_5 + 0xc + + + EVSYS_6 + EVSYS_6 + 0xd + + + EVSYS_7 + EVSYS_7 + 0xe + + + EVSYS_8 + EVSYS_8 + 0xf + + + EVSYS_9 + EVSYS_9 + 0x10 + + + EVSYS_10 + EVSYS_10 + 0x11 + + + EVSYS_11 + EVSYS_11 + 0x12 + + + SERCOMX_SLOW + SERCOMX_SLOW + 0x13 + + + SERCOM0_CORE + SERCOM0_CORE + 0x14 + + + SERCOM1_CORE + SERCOM1_CORE + 0x15 + + + SERCOM2_CORE + SERCOM2_CORE + 0x16 + + + SERCOM3_CORE + SERCOM3_CORE + 0x17 + + + SERCOM4_CORE + SERCOM4_CORE + 0x18 + + + SERCOM5_CORE + SERCOM5_CORE + 0x19 + + + TCC0_TCC1 + TCC0_TCC1 + 0x1a + + + TCC2_TC3 + TCC2_TC3 + 0x1b + + + TC4_TC5 + TC4_TC5 + 0x1c + + + TC6_TC7 + TC6_TC7 + 0x1d + + + ADC + ADC + 0x1e + + + AC_DIG + AC_DIG + 0x1f + + + AC_ANA + AC_ANA + 0x20 + + + DAC + DAC + 0x21 + + + I2S_0 + I2S_0 + 0x23 + + + I2S_1 + I2S_1 + 0x24 + + + + + GEN + Generic Clock Generator + 8 + 4 + + GENSelect + + GCLK0 + Generic clock generator 0 + 0x0 + + + GCLK1 + Generic clock generator 1 + 0x1 + + + GCLK2 + Generic clock generator 2 + 0x2 + + + GCLK3 + Generic clock generator 3 + 0x3 + + + GCLK4 + Generic clock generator 4 + 0x4 + + + GCLK5 + Generic clock generator 5 + 0x5 + + + GCLK6 + Generic clock generator 6 + 0x6 + + + GCLK7 + Generic clock generator 7 + 0x7 + + + GCLK8 + Generic clock generator 8 + 0x8 + + + + + CLKEN + Clock Enable + 14 + 1 + + + WRTLOCK + Write Lock + 15 + 1 + + + + + GENCTRL + Generic Clock Generator Control + 0x4 + 32 + + + ID + Generic Clock Generator Selection + 0 + 4 + + + SRC + Source Select + 8 + 5 + + SRCSelect + + XOSC + XOSC oscillator output + 0x0 + + + GCLKIN + Generator input pad + 0x1 + + + GCLKGEN1 + Generic clock generator 1 output + 0x2 + + + OSCULP32K + OSCULP32K oscillator output + 0x3 + + + OSC32K + OSC32K oscillator output + 0x4 + + + XOSC32K + XOSC32K oscillator output + 0x5 + + + OSC8M + OSC8M oscillator output + 0x6 + + + DFLL48M + DFLL48M output + 0x7 + + + DPLL96M + DPLL96M output + 0x8 + + + + + GENEN + Generic Clock Generator Enable + 16 + 1 + + + IDC + Improve Duty Cycle + 17 + 1 + + + OOV + Output Off Value + 18 + 1 + + + OE + Output Enable + 19 + 1 + + + DIVSEL + Divide Selection + 20 + 1 + + + RUNSTDBY + Run in Standby + 21 + 1 + + + + + GENDIV + Generic Clock Generator Division + 0x8 + 32 + + + ID + Generic Clock Generator Selection + 0 + 4 + + + DIV + Division Factor + 8 + 16 + + + + + + + HMATRIX + 2.1.2 + HSB Matrix + HMATRIXB + HMATRIXB_ + 0x41007000 + + 0 + 0x400 + registers + + + + 16 + 0x8 + PRAS%s + Priority A for Slave + 0x080 + 32 + + + 16 + 0x8 + PRBS%s + Priority B for Slave + 0x084 + 32 + + + 16 + 0x4 + SFR%s + Special Function + 0x110 + 32 + + + SFR + Special Function Register + 0 + 32 + + + + + + + I2S + 1.0.2 + Inter-IC Sound Interface + I2S + I2S_ + 0x42005000 + + 0 + 0x40 + registers + + + I2S + 27 + + + + CTRLA + Control A + 0x00 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + CKEN0 + Clock Unit 0 Enable + 2 + 1 + + + CKEN1 + Clock Unit 1 Enable + 3 + 1 + + + SEREN0 + Serializer 0 Enable + 4 + 1 + + + SEREN1 + Serializer 1 Enable + 5 + 1 + + + + + 2 + 0x4 + CLKCTRL%s + Clock Unit n Control + 0x04 + 32 + + + SLOTSIZE + Slot Size + 0 + 2 + + SLOTSIZESelect + + 8 + 8-bit Slot for Clock Unit n + 0x0 + + + 16 + 16-bit Slot for Clock Unit n + 0x1 + + + 24 + 24-bit Slot for Clock Unit n + 0x2 + + + 32 + 32-bit Slot for Clock Unit n + 0x3 + + + + + NBSLOTS + Number of Slots in Frame + 2 + 3 + + + FSWIDTH + Frame Sync Width + 5 + 2 + + FSWIDTHSelect + + SLOT + Frame Sync Pulse is 1 Slot wide (default for I2S protocol) + 0x0 + + + HALF + Frame Sync Pulse is half a Frame wide + 0x1 + + + BIT + Frame Sync Pulse is 1 Bit wide + 0x2 + + + BURST + Clock Unit n operates in Burst mode, with a 1-bit wide Frame Sync pulse per Data sample, only when Data transfer is requested + 0x3 + + + + + BITDELAY + Data Delay from Frame Sync + 7 + 1 + + BITDELAYSelect + + LJ + Left Justified (0 Bit Delay) + 0x0 + + + I2S + I2S (1 Bit Delay) + 0x1 + + + + + FSSEL + Frame Sync Select + 8 + 1 + + FSSELSelect + + SCKDIV + Divided Serial Clock n is used as Frame Sync n source + 0x0 + + + FSPIN + FSn input pin is used as Frame Sync n source + 0x1 + + + + + FSINV + Frame Sync Invert + 11 + 1 + + + SCKSEL + Serial Clock Select + 12 + 1 + + SCKSELSelect + + MCKDIV + Divided Master Clock n is used as Serial Clock n source + 0x0 + + + SCKPIN + SCKn input pin is used as Serial Clock n source + 0x1 + + + + + MCKSEL + Master Clock Select + 16 + 1 + + MCKSELSelect + + GCLK + GCLK_I2S_n is used as Master Clock n source + 0x0 + + + MCKPIN + MCKn input pin is used as Master Clock n source + 0x1 + + + + + MCKEN + Master Clock Enable + 18 + 1 + + + MCKDIV + Master Clock Division Factor + 19 + 5 + + + MCKOUTDIV + Master Clock Output Division Factor + 24 + 5 + + + FSOUTINV + Frame Sync Output Invert + 29 + 1 + + + SCKOUTINV + Serial Clock Output Invert + 30 + 1 + + + MCKOUTINV + Master Clock Output Invert + 31 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x0C + 16 + + + RXRDY0 + Receive Ready 0 Interrupt Enable + 0 + 1 + + + RXRDY1 + Receive Ready 1 Interrupt Enable + 1 + 1 + + + RXOR0 + Receive Overrun 0 Interrupt Enable + 4 + 1 + + + RXOR1 + Receive Overrun 1 Interrupt Enable + 5 + 1 + + + TXRDY0 + Transmit Ready 0 Interrupt Enable + 8 + 1 + + + TXRDY1 + Transmit Ready 1 Interrupt Enable + 9 + 1 + + + TXUR0 + Transmit Underrun 0 Interrupt Enable + 12 + 1 + + + TXUR1 + Transmit Underrun 1 Interrupt Enable + 13 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x10 + 16 + + + RXRDY0 + Receive Ready 0 Interrupt Enable + 0 + 1 + + + RXRDY1 + Receive Ready 1 Interrupt Enable + 1 + 1 + + + RXOR0 + Receive Overrun 0 Interrupt Enable + 4 + 1 + + + RXOR1 + Receive Overrun 1 Interrupt Enable + 5 + 1 + + + TXRDY0 + Transmit Ready 0 Interrupt Enable + 8 + 1 + + + TXRDY1 + Transmit Ready 1 Interrupt Enable + 9 + 1 + + + TXUR0 + Transmit Underrun 0 Interrupt Enable + 12 + 1 + + + TXUR1 + Transmit Underrun 1 Interrupt Enable + 13 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x14 + 16 + + + RXRDY0 + Receive Ready 0 + 0 + 1 + + + RXRDY1 + Receive Ready 1 + 1 + 1 + + + RXOR0 + Receive Overrun 0 + 4 + 1 + + + RXOR1 + Receive Overrun 1 + 5 + 1 + + + TXRDY0 + Transmit Ready 0 + 8 + 1 + + + TXRDY1 + Transmit Ready 1 + 9 + 1 + + + TXUR0 + Transmit Underrun 0 + 12 + 1 + + + TXUR1 + Transmit Underrun 1 + 13 + 1 + + + + + SYNCBUSY + Synchronization Status + 0x18 + 16 + read-only + + + SWRST + Software Reset Synchronization Status + 0 + 1 + + + ENABLE + Enable Synchronization Status + 1 + 1 + + + CKEN0 + Clock Unit 0 Enable Synchronization Status + 2 + 1 + + + CKEN1 + Clock Unit 1 Enable Synchronization Status + 3 + 1 + + + SEREN0 + Serializer 0 Enable Synchronization Status + 4 + 1 + + + SEREN1 + Serializer 1 Enable Synchronization Status + 5 + 1 + + + DATA0 + Data 0 Synchronization Status + 8 + 1 + + + DATA1 + Data 1 Synchronization Status + 9 + 1 + + + + + 2 + 0x4 + SERCTRL%s + Serializer n Control + 0x20 + 32 + + + SERMODE + Serializer Mode + 0 + 2 + + SERMODESelect + + RX + Receive + 0x0 + + + TX + Transmit + 0x1 + + + PDM2 + Receive one PDM data on each serial clock edge + 0x2 + + + + + TXDEFAULT + Line Default Line when Slot Disabled + 2 + 2 + + TXDEFAULTSelect + + ZERO + Output Default Value is 0 + 0x0 + + + ONE + Output Default Value is 1 + 0x1 + + + HIZ + Output Default Value is high impedance + 0x3 + + + + + TXSAME + Transmit Data when Underrun + 4 + 1 + + TXSAMESelect + + ZERO + Zero data transmitted in case of underrun + 0x0 + + + SAME + Last data transmitted in case of underrun + 0x1 + + + + + CLKSEL + Clock Unit Selection + 5 + 1 + + CLKSELSelect + + CLK0 + Use Clock Unit 0 + 0x0 + + + CLK1 + Use Clock Unit 1 + 0x1 + + + + + SLOTADJ + Data Slot Formatting Adjust + 7 + 1 + + SLOTADJSelect + + RIGHT + Data is right adjusted in slot + 0x0 + + + LEFT + Data is left adjusted in slot + 0x1 + + + + + DATASIZE + Data Word Size + 8 + 3 + + DATASIZESelect + + 32 + 32 bits + 0x0 + + + 24 + 24 bits + 0x1 + + + 20 + 20 bits + 0x2 + + + 18 + 18 bits + 0x3 + + + 16 + 16 bits + 0x4 + + + 16C + 16 bits compact stereo + 0x5 + + + 8 + 8 bits + 0x6 + + + 8C + 8 bits compact stereo + 0x7 + + + + + WORDADJ + Data Word Formatting Adjust + 12 + 1 + + WORDADJSelect + + RIGHT + Data is right adjusted in word + 0x0 + + + LEFT + Data is left adjusted in word + 0x1 + + + + + EXTEND + Data Formatting Bit Extension + 13 + 2 + + EXTENDSelect + + ZERO + Extend with zeroes + 0x0 + + + ONE + Extend with ones + 0x1 + + + MSBIT + Extend with Most Significant Bit + 0x2 + + + LSBIT + Extend with Least Significant Bit + 0x3 + + + + + BITREV + Data Formatting Bit Reverse + 15 + 1 + + BITREVSelect + + MSBIT + Transfer Data Most Significant Bit (MSB) first (default for I2S protocol) + 0x0 + + + LSBIT + Transfer Data Least Significant Bit (LSB) first + 0x1 + + + + + SLOTDIS0 + Slot 0 Disabled for this Serializer + 16 + 1 + + + SLOTDIS1 + Slot 1 Disabled for this Serializer + 17 + 1 + + + SLOTDIS2 + Slot 2 Disabled for this Serializer + 18 + 1 + + + SLOTDIS3 + Slot 3 Disabled for this Serializer + 19 + 1 + + + SLOTDIS4 + Slot 4 Disabled for this Serializer + 20 + 1 + + + SLOTDIS5 + Slot 5 Disabled for this Serializer + 21 + 1 + + + SLOTDIS6 + Slot 6 Disabled for this Serializer + 22 + 1 + + + SLOTDIS7 + Slot 7 Disabled for this Serializer + 23 + 1 + + + MONO + Mono Mode + 24 + 1 + + MONOSelect + + STEREO + Normal mode + 0x0 + + + MONO + Left channel data is duplicated to right channel + 0x1 + + + + + DMA + Single or Multiple DMA Channels + 25 + 1 + + DMASelect + + SINGLE + Single DMA channel + 0x0 + + + MULTIPLE + One DMA channel per data channel + 0x1 + + + + + RXLOOP + Loop-back Test Mode + 26 + 1 + + + + + 2 + 0x4 + DATA%s + Data n + 0x30 + 32 + + + DATA + Sample Data + 0 + 32 + + + + + + + MTB + 1.0.0 + Cortex-M0+ Micro-Trace Buffer + MTB + MTB_ + 0x41006000 + + 0 + 0x1000 + registers + + + + POSITION + MTB Position + 0x000 + 32 + + + WRAP + Pointer Value Wraps + 2 + 1 + + + POINTER + Trace Packet Location Pointer + 3 + 29 + + + + + MASTER + MTB Master + 0x004 + 32 + + + MASK + Maximum Value of the Trace Buffer in SRAM + 0 + 5 + + + TSTARTEN + Trace Start Input Enable + 5 + 1 + + + TSTOPEN + Trace Stop Input Enable + 6 + 1 + + + SFRWPRIV + Special Function Register Write Privilege + 7 + 1 + + + RAMPRIV + SRAM Privilege + 8 + 1 + + + HALTREQ + Halt Request + 9 + 1 + + + EN + Main Trace Enable + 31 + 1 + + + + + FLOW + MTB Flow + 0x008 + 32 + + + AUTOSTOP + Auto Stop Tracing + 0 + 1 + + + AUTOHALT + Auto Halt Request + 1 + 1 + + + WATERMARK + Watermark value + 3 + 29 + + + + + BASE + MTB Base + 0x00C + 32 + read-only + + + ITCTRL + MTB Integration Mode Control + 0xF00 + 32 + + + CLAIMSET + MTB Claim Set + 0xFA0 + 32 + + + CLAIMCLR + MTB Claim Clear + 0xFA4 + 32 + + + LOCKACCESS + MTB Lock Access + 0xFB0 + 32 + + + LOCKSTATUS + MTB Lock Status + 0xFB4 + 32 + read-only + + + AUTHSTATUS + MTB Authentication Status + 0xFB8 + 32 + read-only + + + DEVARCH + MTB Device Architecture + 0xFBC + 32 + read-only + + + DEVID + MTB Device Configuration + 0xFC8 + 32 + read-only + + + DEVTYPE + MTB Device Type + 0xFCC + 32 + read-only + + + PID4 + CoreSight + 0xFD0 + 32 + read-only + + + PID5 + CoreSight + 0xFD4 + 32 + read-only + + + PID6 + CoreSight + 0xFD8 + 32 + read-only + + + PID7 + CoreSight + 0xFDC + 32 + read-only + + + PID0 + CoreSight + 0xFE0 + 32 + read-only + + + PID1 + CoreSight + 0xFE4 + 32 + read-only + + + PID2 + CoreSight + 0xFE8 + 32 + read-only + + + PID3 + CoreSight + 0xFEC + 32 + read-only + + + CID0 + CoreSight + 0xFF0 + 32 + read-only + + + CID1 + CoreSight + 0xFF4 + 32 + read-only + + + CID2 + CoreSight + 0xFF8 + 32 + read-only + + + CID3 + CoreSight + 0xFFC + 32 + read-only + + + + + NVMCTRL + 1.0.6 + Non-Volatile Memory Controller + NVMCTRL + NVMCTRL_ + 0x41004000 + + 0 + 0x80 + registers + + + NVMCTRL + 5 + + + + CTRLA + Control A + 0x00 + 16 + + + CMD + Command + 0 + 7 + + CMDSelect + + ER + Erase Row - Erases the row addressed by the ADDR register. + 0x2 + + + WP + Write Page - Writes the contents of the page buffer to the page addressed by the ADDR register. + 0x4 + + + EAR + Erase Auxiliary Row - Erases the auxiliary row addressed by the ADDR register. This command can be given only when the security bit is not set and only to the user configuration row. + 0x5 + + + WAP + Write Auxiliary Page - Writes the contents of the page buffer to the page addressed by the ADDR register. This command can be given only when the security bit is not set and only to the user configuration row. + 0x6 + + + SF + Security Flow Command + 0xa + + + WL + Write lockbits + 0xf + + + LR + Lock Region - Locks the region containing the address location in the ADDR register. + 0x40 + + + UR + Unlock Region - Unlocks the region containing the address location in the ADDR register. + 0x41 + + + SPRM + Sets the power reduction mode. + 0x42 + + + CPRM + Clears the power reduction mode. + 0x43 + + + PBC + Page Buffer Clear - Clears the page buffer. + 0x44 + + + SSB + Set Security Bit - Sets the security bit by writing 0x00 to the first byte in the lockbit row. + 0x45 + + + INVALL + Invalidates all cache lines. + 0x46 + + + + + CMDEX + Command Execution + 8 + 8 + + CMDEXSelect + + KEY + Execution Key + 0xa5 + + + + + + + CTRLB + Control B + 0x04 + 32 + + + RWS + NVM Read Wait States + 1 + 4 + + RWSSelect + + SINGLE + Single Auto Wait State + 0x0 + + + HALF + Half Auto Wait State + 0x1 + + + DUAL + Dual Auto Wait State + 0x2 + + + + + MANW + Manual Write + 7 + 1 + + + SLEEPPRM + Power Reduction Mode during Sleep + 8 + 2 + + SLEEPPRMSelect + + WAKEONACCESS + NVM block enters low-power mode when entering sleep.NVM block exits low-power mode upon first access. + 0x0 + + + WAKEUPINSTANT + NVM block enters low-power mode when entering sleep.NVM block exits low-power mode when exiting sleep. + 0x1 + + + DISABLED + Auto power reduction disabled. + 0x3 + + + + + READMODE + NVMCTRL Read Mode + 16 + 2 + + READMODESelect + + NO_MISS_PENALTY + The NVM Controller (cache system) does not insert wait states on a cache miss. Gives the best system performance. + 0x0 + + + LOW_POWER + Reduces power consumption of the cache system, but inserts a wait state each time there is a cache miss. This mode may not be relevant if CPU performance is required, as the application will be stalled and may lead to increase run time. + 0x1 + + + DETERMINISTIC + The cache system ensures that a cache hit or miss takes the same amount of time, determined by the number of programmed flash wait states. This mode can be used for real-time applications that require deterministic execution timings. + 0x2 + + + + + CACHEDIS + Cache Disable + 18 + 1 + + + + + PARAM + NVM Parameter + 0x08 + 32 + + + NVMP + NVM Pages + 0 + 16 + read-only + + + PSZ + Page Size + 16 + 3 + read-only + + PSZSelect + + 8 + 8 bytes + 0x0 + + + 16 + 16 bytes + 0x1 + + + 32 + 32 bytes + 0x2 + + + 64 + 64 bytes + 0x3 + + + 128 + 128 bytes + 0x4 + + + 256 + 256 bytes + 0x5 + + + 512 + 512 bytes + 0x6 + + + 1024 + 1024 bytes + 0x7 + + + + + + + INTENCLR + Interrupt Enable Clear + 0x0C + 8 + + + READY + NVM Ready Interrupt Enable + 0 + 1 + + + ERROR + Error Interrupt Enable + 1 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x10 + 8 + + + READY + NVM Ready Interrupt Enable + 0 + 1 + + + ERROR + Error Interrupt Enable + 1 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x14 + 8 + + + READY + NVM Ready + 0 + 1 + read-only + + + ERROR + Error + 1 + 1 + + + + + STATUS + Status + 0x18 + 16 + + + PRM + Power Reduction Mode + 0 + 1 + read-only + + + LOAD + NVM Page Buffer Active Loading + 1 + 1 + + + PROGE + Programming Error Status + 2 + 1 + + + LOCKE + Lock Error Status + 3 + 1 + + + NVME + NVM Error + 4 + 1 + + + SB + Security Bit Status + 8 + 1 + read-only + + + + + ADDR + Address + 0x1C + 32 + + + ADDR + NVM Address + 0 + 22 + + + + + LOCK + Lock Section + 0x20 + 16 + + + LOCK + Region Lock Bits + 0 + 16 + read-only + + + + + + + PAC0 + 1.0.1 + Peripheral Access Controller 0 + PAC + PAC_ + 0x40000000 + + 0 + 0x08 + registers + + + + WPCLR + Write Protection Clear + 0x0 + 32 + + + WP + Write Protection Clear + 1 + 31 + + + + + WPSET + Write Protection Set + 0x4 + 32 + + + WP + Write Protection Set + 1 + 31 + + + + + + + PAC1 + Peripheral Access Controller 1 + 0x41000000 + + + PAC2 + Peripheral Access Controller 2 + 0x42000000 + + + PM + 2.0.1 + Power Manager + PM + PM_ + 0x40000400 + + 0 + 0x80 + registers + + + PM + 0 + + + + CTRL + Control + 0x00 + 8 + + + SLEEP + Sleep Mode + 0x01 + 8 + + + IDLE + Idle Mode Configuration + 0 + 2 + + IDLESelect + + CPU + The CPU clock domain is stopped + 0x0 + + + AHB + The CPU and AHB clock domains are stopped + 0x1 + + + APB + The CPU, AHB and APB clock domains are stopped + 0x2 + + + + + + + CPUSEL + CPU Clock Select + 0x08 + 8 + + + CPUDIV + CPU Prescaler Selection + 0 + 3 + + CPUDIVSelect + + DIV1 + Divide by 1 + 0x0 + + + DIV2 + Divide by 2 + 0x1 + + + DIV4 + Divide by 4 + 0x2 + + + DIV8 + Divide by 8 + 0x3 + + + DIV16 + Divide by 16 + 0x4 + + + DIV32 + Divide by 32 + 0x5 + + + DIV64 + Divide by 64 + 0x6 + + + DIV128 + Divide by 128 + 0x7 + + + + + + + APBASEL + APBA Clock Select + 0x09 + 8 + + + APBADIV + APBA Prescaler Selection + 0 + 3 + + APBADIVSelect + + DIV1 + Divide by 1 + 0x0 + + + DIV2 + Divide by 2 + 0x1 + + + DIV4 + Divide by 4 + 0x2 + + + DIV8 + Divide by 8 + 0x3 + + + DIV16 + Divide by 16 + 0x4 + + + DIV32 + Divide by 32 + 0x5 + + + DIV64 + Divide by 64 + 0x6 + + + DIV128 + Divide by 128 + 0x7 + + + + + + + APBBSEL + APBB Clock Select + 0x0A + 8 + + + APBBDIV + APBB Prescaler Selection + 0 + 3 + + APBBDIVSelect + + DIV1 + Divide by 1 + 0x0 + + + DIV2 + Divide by 2 + 0x1 + + + DIV4 + Divide by 4 + 0x2 + + + DIV8 + Divide by 8 + 0x3 + + + DIV16 + Divide by 16 + 0x4 + + + DIV32 + Divide by 32 + 0x5 + + + DIV64 + Divide by 64 + 0x6 + + + DIV128 + Divide by 128 + 0x7 + + + + + + + APBCSEL + APBC Clock Select + 0x0B + 8 + + + APBCDIV + APBC Prescaler Selection + 0 + 3 + + APBCDIVSelect + + DIV1 + Divide by 1 + 0x0 + + + DIV2 + Divide by 2 + 0x1 + + + DIV4 + Divide by 4 + 0x2 + + + DIV8 + Divide by 8 + 0x3 + + + DIV16 + Divide by 16 + 0x4 + + + DIV32 + Divide by 32 + 0x5 + + + DIV64 + Divide by 64 + 0x6 + + + DIV128 + Divide by 128 + 0x7 + + + + + + + AHBMASK + AHB Mask + 0x14 + 32 + 0x0000007F + + + HPB0_ + HPB0 AHB Clock Mask + 0 + 1 + + + HPB1_ + HPB1 AHB Clock Mask + 1 + 1 + + + HPB2_ + HPB2 AHB Clock Mask + 2 + 1 + + + DSU_ + DSU AHB Clock Mask + 3 + 1 + + + NVMCTRL_ + NVMCTRL AHB Clock Mask + 4 + 1 + + + DMAC_ + DMAC AHB Clock Mask + 5 + 1 + + + USB_ + USB AHB Clock Mask + 6 + 1 + + + + + APBAMASK + APBA Mask + 0x18 + 32 + 0x0000007F + + + PAC0_ + PAC0 APB Clock Enable + 0 + 1 + + + PM_ + PM APB Clock Enable + 1 + 1 + + + SYSCTRL_ + SYSCTRL APB Clock Enable + 2 + 1 + + + GCLK_ + GCLK APB Clock Enable + 3 + 1 + + + WDT_ + WDT APB Clock Enable + 4 + 1 + + + RTC_ + RTC APB Clock Enable + 5 + 1 + + + EIC_ + EIC APB Clock Enable + 6 + 1 + + + + + APBBMASK + APBB Mask + 0x1C + 32 + 0x0000007F + + + PAC1_ + PAC1 APB Clock Enable + 0 + 1 + + + DSU_ + DSU APB Clock Enable + 1 + 1 + + + NVMCTRL_ + NVMCTRL APB Clock Enable + 2 + 1 + + + PORT_ + PORT APB Clock Enable + 3 + 1 + + + DMAC_ + DMAC APB Clock Enable + 4 + 1 + + + USB_ + USB APB Clock Enable + 5 + 1 + + + HMATRIX_ + HMATRIX APB Clock Enable + 6 + 1 + + + + + APBCMASK + APBC Mask + 0x20 + 32 + 0x00010000 + + + PAC2_ + PAC2 APB Clock Enable + 0 + 1 + + + EVSYS_ + EVSYS APB Clock Enable + 1 + 1 + + + SERCOM0_ + SERCOM0 APB Clock Enable + 2 + 1 + + + SERCOM1_ + SERCOM1 APB Clock Enable + 3 + 1 + + + SERCOM2_ + SERCOM2 APB Clock Enable + 4 + 1 + + + SERCOM3_ + SERCOM3 APB Clock Enable + 5 + 1 + + + TCC0_ + TCC0 APB Clock Enable + 8 + 1 + + + TCC1_ + TCC1 APB Clock Enable + 9 + 1 + + + TCC2_ + TCC2 APB Clock Enable + 10 + 1 + + + TC3_ + TC3 APB Clock Enable + 11 + 1 + + + TC4_ + TC4 APB Clock Enable + 12 + 1 + + + TC5_ + TC5 APB Clock Enable + 13 + 1 + + + ADC_ + ADC APB Clock Enable + 16 + 1 + + + AC_ + AC APB Clock Enable + 17 + 1 + + + DAC_ + DAC APB Clock Enable + 18 + 1 + + + PTC_ + PTC APB Clock Enable + 19 + 1 + + + I2S_ + I2S APB Clock Enable + 20 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x34 + 8 + + + CKRDY + Clock Ready Interrupt Enable + 0 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x35 + 8 + + + CKRDY + Clock Ready Interrupt Enable + 0 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x36 + 8 + + + CKRDY + Clock Ready + 0 + 1 + + + + + RCAUSE + Reset Cause + 0x38 + 8 + read-only + 0x01 + + + POR + Power On Reset + 0 + 1 + + + BOD12 + Brown Out 12 Detector Reset + 1 + 1 + + + BOD33 + Brown Out 33 Detector Reset + 2 + 1 + + + EXT + External Reset + 4 + 1 + + + WDT + Watchdog Reset + 5 + 1 + + + SYST + System Reset Request + 6 + 1 + + + + + + + PORT + 1.0.0 + Port Module + PORT + PORT_ + 0x41004400 + + 0 + 0x200 + registers + + + + 1 + 0x80 + DIR%s + Data Direction + 0x00 + 32 + + + DIR + Port Data Direction + 0 + 32 + + + + + 1 + 0x80 + DIRCLR%s + Data Direction Clear + 0x04 + 32 + + + DIRCLR + Port Data Direction Clear + 0 + 32 + + + + + 1 + 0x80 + DIRSET%s + Data Direction Set + 0x08 + 32 + + + DIRSET + Port Data Direction Set + 0 + 32 + + + + + 1 + 0x80 + DIRTGL%s + Data Direction Toggle + 0x0C + 32 + + + DIRTGL + Port Data Direction Toggle + 0 + 32 + + + + + 1 + 0x80 + OUT%s + Data Output Value + 0x10 + 32 + + + OUT + Port Data Output Value + 0 + 32 + + + + + 1 + 0x80 + OUTCLR%s + Data Output Value Clear + 0x14 + 32 + + + OUTCLR + Port Data Output Value Clear + 0 + 32 + + + + + 1 + 0x80 + OUTSET%s + Data Output Value Set + 0x18 + 32 + + + OUTSET + Port Data Output Value Set + 0 + 32 + + + + + 1 + 0x80 + OUTTGL%s + Data Output Value Toggle + 0x1C + 32 + + + OUTTGL + Port Data Output Value Toggle + 0 + 32 + + + + + 1 + 0x80 + IN%s + Data Input Value + 0x20 + 32 + read-only + + + IN + Port Data Input Value + 0 + 32 + + + + + 1 + 0x80 + CTRL%s + Control + 0x24 + 32 + + + SAMPLING + Input Sampling Mode + 0 + 32 + write-only + + + + + 1 + 0x80 + WRCONFIG%s + Write Configuration + 0x28 + 32 + write-only + + + PINMASK + Pin Mask for Multiple Pin Configuration + 0 + 16 + + + PMUXEN + Peripheral Multiplexer Enable + 16 + 1 + + + INEN + Input Enable + 17 + 1 + + + PULLEN + Pull Enable + 18 + 1 + + + DRVSTR + Output Driver Strength Selection + 22 + 1 + + + PMUX + Peripheral Multiplexing + 24 + 4 + + + WRPMUX + Write PMUX + 28 + 1 + + + WRPINCFG + Write PINCFG + 30 + 1 + + + HWSEL + Half-Word Select + 31 + 1 + + + + + 16 + 0x1 + PMUX0_%s + Peripheral Multiplexing n - Group 0 + 0x30 + 8 + + + PMUXE + Peripheral Multiplexing Even + 0 + 4 + + PMUXESelect + + A + Peripheral function A selected + 0x0 + + + B + Peripheral function B selected + 0x1 + + + C + Peripheral function C selected + 0x2 + + + D + Peripheral function D selected + 0x3 + + + E + Peripheral function E selected + 0x4 + + + F + Peripheral function F selected + 0x5 + + + G + Peripheral function G selected + 0x6 + + + H + Peripheral function H selected + 0x7 + + + + + PMUXO + Peripheral Multiplexing Odd + 4 + 4 + + PMUXOSelect + + A + Peripheral function A selected + 0x0 + + + B + Peripheral function B selected + 0x1 + + + C + Peripheral function C selected + 0x2 + + + D + Peripheral function D selected + 0x3 + + + E + Peripheral function E selected + 0x4 + + + F + Peripheral function F selected + 0x5 + + + G + Peripheral function G selected + 0x6 + + + H + Peripheral function H selected + 0x7 + + + + + + + 32 + 0x1 + PINCFG0_%s + Pin Configuration n - Group 0 + 0x40 + 8 + + + PMUXEN + Peripheral Multiplexer Enable + 0 + 1 + + + INEN + Input Enable + 1 + 1 + + + PULLEN + Pull Enable + 2 + 1 + + + DRVSTR + Output Driver Strength Selection + 6 + 1 + write-only + + + + + + + PORT_IOBUS + Port Module (IOBUS) + PORT_IOBUS + PORT_IOBUS_ + 0x60000000 + + + RTC + 1.0.1 + Real-Time Counter + RTC + RTC_ + 0x40001400 + + 0 + 0x40 + registers + + + RTC + 3 + + + + MODE0 + 32-bit Counter with Single 32-bit Compare + RtcMode0 + 0x0 + + CTRL + MODE0 Control + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 2 + + MODESelect + + COUNT32 + Mode 0: 32-bit Counter + 0x0 + + + COUNT16 + Mode 1: 16-bit Counter + 0x1 + + + CLOCK + Mode 2: Clock/Calendar + 0x2 + + + + + MATCHCLR + Clear on Match + 7 + 1 + + + PRESCALER + Prescaler + 8 + 4 + + PRESCALERSelect + + DIV1 + CLK_RTC_CNT = GCLK_RTC/1 + 0x0 + + + DIV2 + CLK_RTC_CNT = GCLK_RTC/2 + 0x1 + + + DIV4 + CLK_RTC_CNT = GCLK_RTC/4 + 0x2 + + + DIV8 + CLK_RTC_CNT = GCLK_RTC/8 + 0x3 + + + DIV16 + CLK_RTC_CNT = GCLK_RTC/16 + 0x4 + + + DIV32 + CLK_RTC_CNT = GCLK_RTC/32 + 0x5 + + + DIV64 + CLK_RTC_CNT = GCLK_RTC/64 + 0x6 + + + DIV128 + CLK_RTC_CNT = GCLK_RTC/128 + 0x7 + + + DIV256 + CLK_RTC_CNT = GCLK_RTC/256 + 0x8 + + + DIV512 + CLK_RTC_CNT = GCLK_RTC/512 + 0x9 + + + DIV1024 + CLK_RTC_CNT = GCLK_RTC/1024 + 0xa + + + + + + + READREQ + Read Request + 0x02 + 16 + 0x0010 + + + ADDR + Address + 0 + 6 + read-only + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + write-only + + + + + EVCTRL + MODE0 Event Control + 0x04 + 16 + + + PEREO0 + Periodic Interval 0 Event Output Enable + 0 + 1 + + + PEREO1 + Periodic Interval 1 Event Output Enable + 1 + 1 + + + PEREO2 + Periodic Interval 2 Event Output Enable + 2 + 1 + + + PEREO3 + Periodic Interval 3 Event Output Enable + 3 + 1 + + + PEREO4 + Periodic Interval 4 Event Output Enable + 4 + 1 + + + PEREO5 + Periodic Interval 5 Event Output Enable + 5 + 1 + + + PEREO6 + Periodic Interval 6 Event Output Enable + 6 + 1 + + + PEREO7 + Periodic Interval 7 Event Output Enable + 7 + 1 + + + CMPEO0 + Compare 0 Event Output Enable + 8 + 1 + + + OVFEO + Overflow Event Output Enable + 15 + 1 + + + + + INTENCLR + MODE0 Interrupt Enable Clear + 0x06 + 8 + + + CMP0 + Compare 0 Interrupt Enable + 0 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTENSET + MODE0 Interrupt Enable Set + 0x07 + 8 + + + CMP0 + Compare 0 Interrupt Enable + 0 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTFLAG + MODE0 Interrupt Flag Status and Clear + 0x08 + 8 + + + CMP0 + Compare 0 + 0 + 1 + + + SYNCRDY + Synchronization Ready + 6 + 1 + + + OVF + Overflow + 7 + 1 + + + + + STATUS + Status + 0x0A + 8 + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + DBGCTRL + Debug Control + 0x0B + 8 + + + DBGRUN + Run During Debug + 0 + 1 + + + + + FREQCORR + Frequency Correction + 0x0C + 8 + + + VALUE + Correction Value + 0 + 7 + + + SIGN + Correction Sign + 7 + 1 + + + + + COUNT + MODE0 Counter Value + 0x10 + 32 + + + COUNT + Counter Value + 0 + 32 + + + + + 1 + 0x4 + COMP%s + MODE0 Compare n Value + 0x18 + 32 + + + COMP + Compare Value + 0 + 32 + + + + + + MODE1 + 16-bit Counter with Two 16-bit Compares + MODE0 + RtcMode1 + 0x0 + + CTRL + MODE1 Control + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 2 + + MODESelect + + COUNT32 + Mode 0: 32-bit Counter + 0x0 + + + COUNT16 + Mode 1: 16-bit Counter + 0x1 + + + CLOCK + Mode 2: Clock/Calendar + 0x2 + + + + + PRESCALER + Prescaler + 8 + 4 + + PRESCALERSelect + + DIV1 + CLK_RTC_CNT = GCLK_RTC/1 + 0x0 + + + DIV2 + CLK_RTC_CNT = GCLK_RTC/2 + 0x1 + + + DIV4 + CLK_RTC_CNT = GCLK_RTC/4 + 0x2 + + + DIV8 + CLK_RTC_CNT = GCLK_RTC/8 + 0x3 + + + DIV16 + CLK_RTC_CNT = GCLK_RTC/16 + 0x4 + + + DIV32 + CLK_RTC_CNT = GCLK_RTC/32 + 0x5 + + + DIV64 + CLK_RTC_CNT = GCLK_RTC/64 + 0x6 + + + DIV128 + CLK_RTC_CNT = GCLK_RTC/128 + 0x7 + + + DIV256 + CLK_RTC_CNT = GCLK_RTC/256 + 0x8 + + + DIV512 + CLK_RTC_CNT = GCLK_RTC/512 + 0x9 + + + DIV1024 + CLK_RTC_CNT = GCLK_RTC/1024 + 0xa + + + + + + + READREQ + Read Request + 0x02 + 16 + 0x0010 + + + ADDR + Address + 0 + 6 + read-only + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + write-only + + + + + EVCTRL + MODE1 Event Control + 0x04 + 16 + + + PEREO0 + Periodic Interval 0 Event Output Enable + 0 + 1 + + + PEREO1 + Periodic Interval 1 Event Output Enable + 1 + 1 + + + PEREO2 + Periodic Interval 2 Event Output Enable + 2 + 1 + + + PEREO3 + Periodic Interval 3 Event Output Enable + 3 + 1 + + + PEREO4 + Periodic Interval 4 Event Output Enable + 4 + 1 + + + PEREO5 + Periodic Interval 5 Event Output Enable + 5 + 1 + + + PEREO6 + Periodic Interval 6 Event Output Enable + 6 + 1 + + + PEREO7 + Periodic Interval 7 Event Output Enable + 7 + 1 + + + CMPEO0 + Compare 0 Event Output Enable + 8 + 1 + + + CMPEO1 + Compare 1 Event Output Enable + 9 + 1 + + + OVFEO + Overflow Event Output Enable + 15 + 1 + + + + + INTENCLR + MODE1 Interrupt Enable Clear + 0x06 + 8 + + + CMP0 + Compare 0 Interrupt Enable + 0 + 1 + + + CMP1 + Compare 1 Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTENSET + MODE1 Interrupt Enable Set + 0x07 + 8 + + + CMP0 + Compare 0 Interrupt Enable + 0 + 1 + + + CMP1 + Compare 1 Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTFLAG + MODE1 Interrupt Flag Status and Clear + 0x08 + 8 + + + CMP0 + Compare 0 + 0 + 1 + + + CMP1 + Compare 1 + 1 + 1 + + + SYNCRDY + Synchronization Ready + 6 + 1 + + + OVF + Overflow + 7 + 1 + + + + + STATUS + Status + 0x0A + 8 + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + DBGCTRL + Debug Control + 0x0B + 8 + + + DBGRUN + Run During Debug + 0 + 1 + + + + + FREQCORR + Frequency Correction + 0x0C + 8 + + + VALUE + Correction Value + 0 + 7 + + + SIGN + Correction Sign + 7 + 1 + + + + + COUNT + MODE1 Counter Value + 0x10 + 16 + + + COUNT + Counter Value + 0 + 16 + + + + + PER + MODE1 Counter Period + 0x14 + 16 + + + PER + Counter Period + 0 + 16 + + + + + 2 + 0x2 + COMP%s + MODE1 Compare n Value + 0x18 + 16 + + + COMP + Compare Value + 0 + 16 + + + + + + MODE2 + Clock/Calendar with Alarm + MODE0 + RtcMode2 + 0x0 + + CTRL + MODE2 Control + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 2 + + MODESelect + + COUNT32 + Mode 0: 32-bit Counter + 0x0 + + + COUNT16 + Mode 1: 16-bit Counter + 0x1 + + + CLOCK + Mode 2: Clock/Calendar + 0x2 + + + + + CLKREP + Clock Representation + 6 + 1 + + + MATCHCLR + Clear on Match + 7 + 1 + + + PRESCALER + Prescaler + 8 + 4 + + PRESCALERSelect + + DIV1 + CLK_RTC_CNT = GCLK_RTC/1 + 0x0 + + + DIV2 + CLK_RTC_CNT = GCLK_RTC/2 + 0x1 + + + DIV4 + CLK_RTC_CNT = GCLK_RTC/4 + 0x2 + + + DIV8 + CLK_RTC_CNT = GCLK_RTC/8 + 0x3 + + + DIV16 + CLK_RTC_CNT = GCLK_RTC/16 + 0x4 + + + DIV32 + CLK_RTC_CNT = GCLK_RTC/32 + 0x5 + + + DIV64 + CLK_RTC_CNT = GCLK_RTC/64 + 0x6 + + + DIV128 + CLK_RTC_CNT = GCLK_RTC/128 + 0x7 + + + DIV256 + CLK_RTC_CNT = GCLK_RTC/256 + 0x8 + + + DIV512 + CLK_RTC_CNT = GCLK_RTC/512 + 0x9 + + + DIV1024 + CLK_RTC_CNT = GCLK_RTC/1024 + 0xa + + + + + + + READREQ + Read Request + 0x02 + 16 + 0x0010 + + + ADDR + Address + 0 + 6 + read-only + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + write-only + + + + + EVCTRL + MODE2 Event Control + 0x04 + 16 + + + PEREO0 + Periodic Interval 0 Event Output Enable + 0 + 1 + + + PEREO1 + Periodic Interval 1 Event Output Enable + 1 + 1 + + + PEREO2 + Periodic Interval 2 Event Output Enable + 2 + 1 + + + PEREO3 + Periodic Interval 3 Event Output Enable + 3 + 1 + + + PEREO4 + Periodic Interval 4 Event Output Enable + 4 + 1 + + + PEREO5 + Periodic Interval 5 Event Output Enable + 5 + 1 + + + PEREO6 + Periodic Interval 6 Event Output Enable + 6 + 1 + + + PEREO7 + Periodic Interval 7 Event Output Enable + 7 + 1 + + + ALARMEO0 + Alarm 0 Event Output Enable + 8 + 1 + + + OVFEO + Overflow Event Output Enable + 15 + 1 + + + + + INTENCLR + MODE2 Interrupt Enable Clear + 0x06 + 8 + + + ALARM0 + Alarm 0 Interrupt Enable + 0 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTENSET + MODE2 Interrupt Enable Set + 0x07 + 8 + + + ALARM0 + Alarm 0 Interrupt Enable + 0 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 6 + 1 + + + OVF + Overflow Interrupt Enable + 7 + 1 + + + + + INTFLAG + MODE2 Interrupt Flag Status and Clear + 0x08 + 8 + + + ALARM0 + Alarm 0 + 0 + 1 + + + SYNCRDY + Synchronization Ready + 6 + 1 + + + OVF + Overflow + 7 + 1 + + + + + STATUS + Status + 0x0A + 8 + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + DBGCTRL + Debug Control + 0x0B + 8 + + + DBGRUN + Run During Debug + 0 + 1 + + + + + FREQCORR + Frequency Correction + 0x0C + 8 + + + VALUE + Correction Value + 0 + 7 + + + SIGN + Correction Sign + 7 + 1 + + + + + CLOCK + MODE2 Clock Value + 0x10 + 32 + + + SECOND + Second + 0 + 6 + + + MINUTE + Minute + 6 + 6 + + + HOUR + Hour + 12 + 5 + + HOURSelect + + AM + AM when CLKREP in 12-hour + 0x0 + + + PM + PM when CLKREP in 12-hour + 0x10 + + + + + DAY + Day + 17 + 5 + + + MONTH + Month + 22 + 4 + + + YEAR + Year + 26 + 6 + + + + + 1 + 0x8 + ALARM%s + MODE2 Alarm n Value + 0x18 + 32 + + + SECOND + Second + 0 + 6 + + + MINUTE + Minute + 6 + 6 + + + HOUR + Hour + 12 + 5 + + HOURSelect + + AM + Morning hour + 0x0 + + + PM + Afternoon hour + 0x10 + + + + + DAY + Day + 17 + 5 + + + MONTH + Month + 22 + 4 + + + YEAR + Year + 26 + 6 + + + + + 1 + 0x8 + MASK%s + MODE2 Alarm n Mask + 0x1C + 8 + + + SEL + Alarm Mask Selection + 0 + 3 + + SELSelect + + OFF + Alarm Disabled + 0x0 + + + SS + Match seconds only + 0x1 + + + MMSS + Match seconds and minutes only + 0x2 + + + HHMMSS + Match seconds, minutes, and hours only + 0x3 + + + DDHHMMSS + Match seconds, minutes, hours, and days only + 0x4 + + + MMDDHHMMSS + Match seconds, minutes, hours, days, and months only + 0x5 + + + YYMMDDHHMMSS + Match seconds, minutes, hours, days, months, and years + 0x6 + + + + + + + + + + SERCOM0 + 2.0.0 + Serial Communication Interface 0 + SERCOM + SERCOM_ + 0x42000800 + + 0 + 0x40 + registers + + + SERCOM0 + 9 + + + + I2CM + I2C Master Mode + SercomI2cm + 0x0 + + CTRLA + I2CM Control A + 0x00 + 32 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 3 + + MODESelect + + USART_EXT_CLK + USART mode with external clock + 0x0 + + + USART_INT_CLK + USART mode with internal clock + 0x1 + + + SPI_SLAVE + SPI mode with external clock + 0x2 + + + SPI_MASTER + SPI mode with internal clock + 0x3 + + + I2C_SLAVE + I2C mode with external clock + 0x4 + + + I2C_MASTER + I2C mode with internal clock + 0x5 + + + + + RUNSTDBY + Run in Standby + 7 + 1 + + + PINOUT + Pin Usage + 16 + 1 + + + SDAHOLD + SDA Hold Time + 20 + 2 + + + MEXTTOEN + Master SCL Low Extend Timeout + 22 + 1 + + + SEXTTOEN + Slave SCL Low Extend Timeout + 23 + 1 + + + SPEED + Transfer Speed + 24 + 2 + + + SCLSM + SCL Clock Stretch Mode + 27 + 1 + + + INACTOUT + Inactive Time-Out + 28 + 2 + + + LOWTOUTEN + SCL Low Timeout Enable + 30 + 1 + + + + + CTRLB + I2CM Control B + 0x04 + 32 + + + SMEN + Smart Mode Enable + 8 + 1 + + + QCEN + Quick Command Enable + 9 + 1 + + + CMD + Command + 16 + 2 + write-only + + + ACKACT + Acknowledge Action + 18 + 1 + + + + + BAUD + I2CM Baud Rate + 0x0C + 32 + + + BAUD + Baud Rate Value + 0 + 8 + + + BAUDLOW + Baud Rate Value Low + 8 + 8 + + + HSBAUD + High Speed Baud Rate Value + 16 + 8 + + + HSBAUDLOW + High Speed Baud Rate Value Low + 24 + 8 + + + + + INTENCLR + I2CM Interrupt Enable Clear + 0x14 + 8 + + + MB + Master On Bus Interrupt Disable + 0 + 1 + + + SB + Slave On Bus Interrupt Disable + 1 + 1 + + + ERROR + Combined Error Interrupt Disable + 7 + 1 + + + + + INTENSET + I2CM Interrupt Enable Set + 0x16 + 8 + + + MB + Master On Bus Interrupt Enable + 0 + 1 + + + SB + Slave On Bus Interrupt Enable + 1 + 1 + + + ERROR + Combined Error Interrupt Enable + 7 + 1 + + + + + INTFLAG + I2CM Interrupt Flag Status and Clear + 0x18 + 8 + + + MB + Master On Bus Interrupt + 0 + 1 + + + SB + Slave On Bus Interrupt + 1 + 1 + + + ERROR + Combined Error Interrupt + 7 + 1 + + + + + STATUS + I2CM Status + 0x1A + 16 + + + BUSERR + Bus Error + 0 + 1 + + + ARBLOST + Arbitration Lost + 1 + 1 + + + RXNACK + Received Not Acknowledge + 2 + 1 + read-only + + + BUSSTATE + Bus State + 4 + 2 + + + LOWTOUT + SCL Low Timeout + 6 + 1 + + + CLKHOLD + Clock Hold + 7 + 1 + read-only + + + MEXTTOUT + Master SCL Low Extend Timeout + 8 + 1 + + + SEXTTOUT + Slave SCL Low Extend Timeout + 9 + 1 + + + LENERR + Length Error + 10 + 1 + + + + + SYNCBUSY + I2CM Syncbusy + 0x1C + 32 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + SERCOM Enable Synchronization Busy + 1 + 1 + read-only + + + SYSOP + System Operation Synchronization Busy + 2 + 1 + read-only + + + + + ADDR + I2CM Address + 0x24 + 32 + + + ADDR + Address Value + 0 + 11 + + + LENEN + Length Enable + 13 + 1 + + + HS + High Speed Mode + 14 + 1 + + + TENBITEN + Ten Bit Addressing Enable + 15 + 1 + + + LEN + Length + 16 + 8 + + + + + DATA + I2CM Data + 0x28 + 8 + + + DATA + Data Value + 0 + 8 + + + + + DBGCTRL + I2CM Debug Control + 0x30 + 8 + + + DBGSTOP + Debug Mode + 0 + 1 + + + + + + I2CS + I2C Slave Mode + I2CM + SercomI2cs + 0x0 + + CTRLA + I2CS Control A + 0x00 + 32 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 3 + + MODESelect + + USART_EXT_CLK + USART mode with external clock + 0x0 + + + USART_INT_CLK + USART mode with internal clock + 0x1 + + + SPI_SLAVE + SPI mode with external clock + 0x2 + + + SPI_MASTER + SPI mode with internal clock + 0x3 + + + I2C_SLAVE + I2C mode with external clock + 0x4 + + + I2C_MASTER + I2C mode with internal clock + 0x5 + + + + + RUNSTDBY + Run during Standby + 7 + 1 + + + PINOUT + Pin Usage + 16 + 1 + + + SDAHOLD + SDA Hold Time + 20 + 2 + + + SEXTTOEN + Slave SCL Low Extend Timeout + 23 + 1 + + + SPEED + Transfer Speed + 24 + 2 + + + SCLSM + SCL Clock Stretch Mode + 27 + 1 + + + LOWTOUTEN + SCL Low Timeout Enable + 30 + 1 + + + + + CTRLB + I2CS Control B + 0x04 + 32 + + + SMEN + Smart Mode Enable + 8 + 1 + + + GCMD + PMBus Group Command + 9 + 1 + + + AACKEN + Automatic Address Acknowledge + 10 + 1 + + + AMODE + Address Mode + 14 + 2 + + + CMD + Command + 16 + 2 + write-only + + + ACKACT + Acknowledge Action + 18 + 1 + + + + + INTENCLR + I2CS Interrupt Enable Clear + 0x14 + 8 + + + PREC + Stop Received Interrupt Disable + 0 + 1 + + + AMATCH + Address Match Interrupt Disable + 1 + 1 + + + DRDY + Data Interrupt Disable + 2 + 1 + + + ERROR + Combined Error Interrupt Disable + 7 + 1 + + + + + INTENSET + I2CS Interrupt Enable Set + 0x16 + 8 + + + PREC + Stop Received Interrupt Enable + 0 + 1 + + + AMATCH + Address Match Interrupt Enable + 1 + 1 + + + DRDY + Data Interrupt Enable + 2 + 1 + + + ERROR + Combined Error Interrupt Enable + 7 + 1 + + + + + INTFLAG + I2CS Interrupt Flag Status and Clear + 0x18 + 8 + + + PREC + Stop Received Interrupt + 0 + 1 + + + AMATCH + Address Match Interrupt + 1 + 1 + + + DRDY + Data Interrupt + 2 + 1 + + + ERROR + Combined Error Interrupt + 7 + 1 + + + + + STATUS + I2CS Status + 0x1A + 16 + + + BUSERR + Bus Error + 0 + 1 + + + COLL + Transmit Collision + 1 + 1 + + + RXNACK + Received Not Acknowledge + 2 + 1 + read-only + + + DIR + Read/Write Direction + 3 + 1 + read-only + + + SR + Repeated Start + 4 + 1 + read-only + + + LOWTOUT + SCL Low Timeout + 6 + 1 + + + CLKHOLD + Clock Hold + 7 + 1 + read-only + + + SEXTTOUT + Slave SCL Low Extend Timeout + 9 + 1 + + + HS + High Speed + 10 + 1 + + + + + SYNCBUSY + I2CS Syncbusy + 0x1C + 32 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + SERCOM Enable Synchronization Busy + 1 + 1 + read-only + + + + + ADDR + I2CS Address + 0x24 + 32 + + + GENCEN + General Call Address Enable + 0 + 1 + + + ADDR + Address Value + 1 + 10 + + + TENBITEN + Ten Bit Addressing Enable + 15 + 1 + + + ADDRMASK + Address Mask + 17 + 10 + + + + + DATA + I2CS Data + 0x28 + 8 + + + DATA + Data Value + 0 + 8 + + + + + + SPI + SPI Mode + I2CM + SercomSpi + 0x0 + + CTRLA + SPI Control A + 0x00 + 32 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 3 + + MODESelect + + USART_EXT_CLK + USART mode with external clock + 0x0 + + + USART_INT_CLK + USART mode with internal clock + 0x1 + + + SPI_SLAVE + SPI mode with external clock + 0x2 + + + SPI_MASTER + SPI mode with internal clock + 0x3 + + + I2C_SLAVE + I2C mode with external clock + 0x4 + + + I2C_MASTER + I2C mode with internal clock + 0x5 + + + + + RUNSTDBY + Run during Standby + 7 + 1 + + + IBON + Immediate Buffer Overflow Notification + 8 + 1 + + + DOPO + Data Out Pinout + 16 + 2 + + + DIPO + Data In Pinout + 20 + 2 + + + FORM + Frame Format + 24 + 4 + + + CPHA + Clock Phase + 28 + 1 + + + CPOL + Clock Polarity + 29 + 1 + + + DORD + Data Order + 30 + 1 + + + + + CTRLB + SPI Control B + 0x04 + 32 + + + CHSIZE + Character Size + 0 + 3 + + + PLOADEN + Data Preload Enable + 6 + 1 + + + SSDE + Slave Select Low Detect Enable + 9 + 1 + + + MSSEN + Master Slave Select Enable + 13 + 1 + + + AMODE + Address Mode + 14 + 2 + + + RXEN + Receiver Enable + 17 + 1 + + + + + BAUD + SPI Baud Rate + 0x0C + 8 + + + BAUD + Baud Rate Value + 0 + 8 + + + + + INTENCLR + SPI Interrupt Enable Clear + 0x14 + 8 + + + DRE + Data Register Empty Interrupt Disable + 0 + 1 + + + TXC + Transmit Complete Interrupt Disable + 1 + 1 + + + RXC + Receive Complete Interrupt Disable + 2 + 1 + + + SSL + Slave Select Low Interrupt Disable + 3 + 1 + + + ERROR + Combined Error Interrupt Disable + 7 + 1 + + + + + INTENSET + SPI Interrupt Enable Set + 0x16 + 8 + + + DRE + Data Register Empty Interrupt Enable + 0 + 1 + + + TXC + Transmit Complete Interrupt Enable + 1 + 1 + + + RXC + Receive Complete Interrupt Enable + 2 + 1 + + + SSL + Slave Select Low Interrupt Enable + 3 + 1 + + + ERROR + Combined Error Interrupt Enable + 7 + 1 + + + + + INTFLAG + SPI Interrupt Flag Status and Clear + 0x18 + 8 + + + DRE + Data Register Empty Interrupt + 0 + 1 + read-only + + + TXC + Transmit Complete Interrupt + 1 + 1 + + + RXC + Receive Complete Interrupt + 2 + 1 + read-only + + + SSL + Slave Select Low Interrupt Flag + 3 + 1 + + + ERROR + Combined Error Interrupt + 7 + 1 + + + + + STATUS + SPI Status + 0x1A + 16 + + + BUFOVF + Buffer Overflow + 2 + 1 + + + + + SYNCBUSY + SPI Syncbusy + 0x1C + 32 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + SERCOM Enable Synchronization Busy + 1 + 1 + read-only + + + CTRLB + CTRLB Synchronization Busy + 2 + 1 + read-only + + + + + ADDR + SPI Address + 0x24 + 32 + + + ADDR + Address Value + 0 + 8 + + + ADDRMASK + Address Mask + 16 + 8 + + + + + DATA + SPI Data + 0x28 + 32 + + + DATA + Data Value + 0 + 9 + + + + + DBGCTRL + SPI Debug Control + 0x30 + 8 + + + DBGSTOP + Debug Mode + 0 + 1 + + + + + + USART + USART Mode + I2CM + SercomUsart + 0x0 + + CTRLA + USART Control A + 0x00 + 32 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + MODE + Operating Mode + 2 + 3 + + MODESelect + + USART_EXT_CLK + USART mode with external clock + 0x0 + + + USART_INT_CLK + USART mode with internal clock + 0x1 + + + SPI_SLAVE + SPI mode with external clock + 0x2 + + + SPI_MASTER + SPI mode with internal clock + 0x3 + + + I2C_SLAVE + I2C mode with external clock + 0x4 + + + I2C_MASTER + I2C mode with internal clock + 0x5 + + + + + RUNSTDBY + Run during Standby + 7 + 1 + + + IBON + Immediate Buffer Overflow Notification + 8 + 1 + + + SAMPR + Sample + 13 + 3 + + + TXPO + Transmit Data Pinout + 16 + 2 + + + RXPO + Receive Data Pinout + 20 + 2 + + + SAMPA + Sample Adjustment + 22 + 2 + + + FORM + Frame Format + 24 + 4 + + + CMODE + Communication Mode + 28 + 1 + + + CPOL + Clock Polarity + 29 + 1 + + + DORD + Data Order + 30 + 1 + + + + + CTRLB + USART Control B + 0x04 + 32 + + + CHSIZE + Character Size + 0 + 3 + + + SBMODE + Stop Bit Mode + 6 + 1 + + + COLDEN + Collision Detection Enable + 8 + 1 + + + SFDE + Start of Frame Detection Enable + 9 + 1 + + + ENC + Encoding Format + 10 + 1 + + + PMODE + Parity Mode + 13 + 1 + + + TXEN + Transmitter Enable + 16 + 1 + + + RXEN + Receiver Enable + 17 + 1 + + + + + BAUD + USART Baud Rate + 0x0C + 16 + + + BAUD + Baud Rate Value + 0 + 16 + + + + + BAUD_FRAC_MODE + USART Baud Rate + BAUD + 0x0C + 16 + + + BAUD + Baud Rate Value + 0 + 13 + + + FP + Fractional Part + 13 + 3 + + + + + BAUD_FRACFP_MODE + USART Baud Rate + BAUD + 0x0C + 16 + + + BAUD + Baud Rate Value + 0 + 13 + + + FP + Fractional Part + 13 + 3 + + + + + BAUD_USARTFP_MODE + USART Baud Rate + BAUD + 0x0C + 16 + + + BAUD + Baud Rate Value + 0 + 16 + + + + + RXPL + USART Receive Pulse Length + 0x0E + 8 + + + RXPL + Receive Pulse Length + 0 + 8 + + + + + INTENCLR + USART Interrupt Enable Clear + 0x14 + 8 + + + DRE + Data Register Empty Interrupt Disable + 0 + 1 + + + TXC + Transmit Complete Interrupt Disable + 1 + 1 + + + RXC + Receive Complete Interrupt Disable + 2 + 1 + + + RXS + Receive Start Interrupt Disable + 3 + 1 + + + CTSIC + Clear To Send Input Change Interrupt Disable + 4 + 1 + + + RXBRK + Break Received Interrupt Disable + 5 + 1 + + + ERROR + Combined Error Interrupt Disable + 7 + 1 + + + + + INTENSET + USART Interrupt Enable Set + 0x16 + 8 + + + DRE + Data Register Empty Interrupt Enable + 0 + 1 + + + TXC + Transmit Complete Interrupt Enable + 1 + 1 + + + RXC + Receive Complete Interrupt Enable + 2 + 1 + + + RXS + Receive Start Interrupt Enable + 3 + 1 + + + CTSIC + Clear To Send Input Change Interrupt Enable + 4 + 1 + + + RXBRK + Break Received Interrupt Enable + 5 + 1 + + + ERROR + Combined Error Interrupt Enable + 7 + 1 + + + + + INTFLAG + USART Interrupt Flag Status and Clear + 0x18 + 8 + + + DRE + Data Register Empty Interrupt + 0 + 1 + read-only + + + TXC + Transmit Complete Interrupt + 1 + 1 + + + RXC + Receive Complete Interrupt + 2 + 1 + read-only + + + RXS + Receive Start Interrupt + 3 + 1 + write-only + + + CTSIC + Clear To Send Input Change Interrupt + 4 + 1 + + + RXBRK + Break Received Interrupt + 5 + 1 + + + ERROR + Combined Error Interrupt + 7 + 1 + + + + + STATUS + USART Status + 0x1A + 16 + + + PERR + Parity Error + 0 + 1 + + + FERR + Frame Error + 1 + 1 + + + BUFOVF + Buffer Overflow + 2 + 1 + + + CTS + Clear To Send + 3 + 1 + read-only + + + ISF + Inconsistent Sync Field + 4 + 1 + + + COLL + Collision Detected + 5 + 1 + + + + + SYNCBUSY + USART Syncbusy + 0x1C + 32 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + SERCOM Enable Synchronization Busy + 1 + 1 + read-only + + + CTRLB + CTRLB Synchronization Busy + 2 + 1 + read-only + + + + + DATA + USART Data + 0x28 + 16 + + + DATA + Data Value + 0 + 9 + + + + + DBGCTRL + USART Debug Control + 0x30 + 8 + + + DBGSTOP + Debug Mode + 0 + 1 + + + + + + + + SERCOM1 + Serial Communication Interface 1 + 0x42000C00 + + SERCOM1 + 10 + + + + SERCOM2 + Serial Communication Interface 2 + 0x42001000 + + SERCOM2 + 11 + + + + SERCOM3 + Serial Communication Interface 3 + 0x42001400 + + SERCOM3 + 12 + + + + SYSCTRL + 2.0.1 + System Control + SYSCTRL + SYSCTRL_ + 0x40000800 + + 0 + 0x80 + registers + + + SYSCTRL + 1 + + + + INTENCLR + Interrupt Enable Clear + 0x00 + 32 + + + XOSCRDY + XOSC Ready Interrupt Enable + 0 + 1 + + + XOSC32KRDY + XOSC32K Ready Interrupt Enable + 1 + 1 + + + OSC32KRDY + OSC32K Ready Interrupt Enable + 2 + 1 + + + OSC8MRDY + OSC8M Ready Interrupt Enable + 3 + 1 + + + DFLLRDY + DFLL Ready Interrupt Enable + 4 + 1 + + + DFLLOOB + DFLL Out Of Bounds Interrupt Enable + 5 + 1 + + + DFLLLCKF + DFLL Lock Fine Interrupt Enable + 6 + 1 + + + DFLLLCKC + DFLL Lock Coarse Interrupt Enable + 7 + 1 + + + DFLLRCS + DFLL Reference Clock Stopped Interrupt Enable + 8 + 1 + + + BOD33RDY + BOD33 Ready Interrupt Enable + 9 + 1 + + + BOD33DET + BOD33 Detection Interrupt Enable + 10 + 1 + + + B33SRDY + BOD33 Synchronization Ready Interrupt Enable + 11 + 1 + + + DPLLLCKR + DPLL Lock Rise Interrupt Enable + 15 + 1 + + + DPLLLCKF + DPLL Lock Fall Interrupt Enable + 16 + 1 + + + DPLLLTO + DPLL Lock Timeout Interrupt Enable + 17 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x04 + 32 + + + XOSCRDY + XOSC Ready Interrupt Enable + 0 + 1 + + + XOSC32KRDY + XOSC32K Ready Interrupt Enable + 1 + 1 + + + OSC32KRDY + OSC32K Ready Interrupt Enable + 2 + 1 + + + OSC8MRDY + OSC8M Ready Interrupt Enable + 3 + 1 + + + DFLLRDY + DFLL Ready Interrupt Enable + 4 + 1 + + + DFLLOOB + DFLL Out Of Bounds Interrupt Enable + 5 + 1 + + + DFLLLCKF + DFLL Lock Fine Interrupt Enable + 6 + 1 + + + DFLLLCKC + DFLL Lock Coarse Interrupt Enable + 7 + 1 + + + DFLLRCS + DFLL Reference Clock Stopped Interrupt Enable + 8 + 1 + + + BOD33RDY + BOD33 Ready Interrupt Enable + 9 + 1 + + + BOD33DET + BOD33 Detection Interrupt Enable + 10 + 1 + + + B33SRDY + BOD33 Synchronization Ready Interrupt Enable + 11 + 1 + + + DPLLLCKR + DPLL Lock Rise Interrupt Enable + 15 + 1 + + + DPLLLCKF + DPLL Lock Fall Interrupt Enable + 16 + 1 + + + DPLLLTO + DPLL Lock Timeout Interrupt Enable + 17 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x08 + 32 + + + XOSCRDY + XOSC Ready + 0 + 1 + + + XOSC32KRDY + XOSC32K Ready + 1 + 1 + + + OSC32KRDY + OSC32K Ready + 2 + 1 + + + OSC8MRDY + OSC8M Ready + 3 + 1 + + + DFLLRDY + DFLL Ready + 4 + 1 + + + DFLLOOB + DFLL Out Of Bounds + 5 + 1 + + + DFLLLCKF + DFLL Lock Fine + 6 + 1 + + + DFLLLCKC + DFLL Lock Coarse + 7 + 1 + + + DFLLRCS + DFLL Reference Clock Stopped + 8 + 1 + + + BOD33RDY + BOD33 Ready + 9 + 1 + + + BOD33DET + BOD33 Detection + 10 + 1 + + + B33SRDY + BOD33 Synchronization Ready + 11 + 1 + + + DPLLLCKR + DPLL Lock Rise + 15 + 1 + + + DPLLLCKF + DPLL Lock Fall + 16 + 1 + + + DPLLLTO + DPLL Lock Timeout + 17 + 1 + + + + + PCLKSR + Power and Clocks Status + 0x0C + 32 + read-only + + + XOSCRDY + XOSC Ready + 0 + 1 + read-only + + + XOSC32KRDY + XOSC32K Ready + 1 + 1 + read-only + + + OSC32KRDY + OSC32K Ready + 2 + 1 + read-only + + + OSC8MRDY + OSC8M Ready + 3 + 1 + read-only + + + DFLLRDY + DFLL Ready + 4 + 1 + read-only + + + DFLLOOB + DFLL Out Of Bounds + 5 + 1 + read-only + + + DFLLLCKF + DFLL Lock Fine + 6 + 1 + read-only + + + DFLLLCKC + DFLL Lock Coarse + 7 + 1 + read-only + + + DFLLRCS + DFLL Reference Clock Stopped + 8 + 1 + read-only + + + BOD33RDY + BOD33 Ready + 9 + 1 + read-only + + + BOD33DET + BOD33 Detection + 10 + 1 + read-only + + + B33SRDY + BOD33 Synchronization Ready + 11 + 1 + read-only + + + DPLLLCKR + DPLL Lock Rise + 15 + 1 + read-only + + + DPLLLCKF + DPLL Lock Fall + 16 + 1 + read-only + + + DPLLLTO + DPLL Lock Timeout + 17 + 1 + read-only + + + + + XOSC + External Multipurpose Crystal Oscillator (XOSC) Control + 0x10 + 16 + 0x0080 + + + ENABLE + Oscillator Enable + 1 + 1 + + + XTALEN + Crystal Oscillator Enable + 2 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Control + 7 + 1 + + + GAIN + Oscillator Gain + 8 + 3 + + GAINSelect + + 0 + 2MHz + 0x0 + + + 1 + 4MHz + 0x1 + + + 2 + 8MHz + 0x2 + + + 3 + 16MHz + 0x3 + + + 4 + 30MHz + 0x4 + + + + + AMPGC + Automatic Amplitude Gain Control + 11 + 1 + + + STARTUP + Start-Up Time + 12 + 4 + + + + + XOSC32K + 32kHz External Crystal Oscillator (XOSC32K) Control + 0x14 + 16 + 0x0080 + + + ENABLE + Oscillator Enable + 1 + 1 + + + XTALEN + Crystal Oscillator Enable + 2 + 1 + + + EN32K + 32kHz Output Enable + 3 + 1 + + + EN1K + 1kHz Output Enable + 4 + 1 + + + AAMPEN + Automatic Amplitude Control Enable + 5 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Control + 7 + 1 + + + STARTUP + Oscillator Start-Up Time + 8 + 3 + + + WRTLOCK + Write Lock + 12 + 1 + + + + + OSC32K + 32kHz Internal Oscillator (OSC32K) Control + 0x18 + 32 + 0x003F0080 + + + ENABLE + Oscillator Enable + 1 + 1 + + + EN32K + 32kHz Output Enable + 2 + 1 + + + EN1K + 1kHz Output Enable + 3 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Control + 7 + 1 + + + STARTUP + Oscillator Start-Up Time + 8 + 3 + + + WRTLOCK + Write Lock + 12 + 1 + + + CALIB + Oscillator Calibration + 16 + 7 + + + + + OSCULP32K + 32kHz Ultra Low Power Internal Oscillator (OSCULP32K) Control + 0x1C + 8 + 0x1F + + + CALIB + Oscillator Calibration + 0 + 5 + + + WRTLOCK + Write Lock + 7 + 1 + + + + + OSC8M + 8MHz Internal Oscillator (OSC8M) Control + 0x20 + 32 + 0x87070382 + + + ENABLE + Oscillator Enable + 1 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Control + 7 + 1 + + + PRESC + Oscillator Prescaler + 8 + 2 + + PRESCSelect + + 0 + 1 + 0x0 + + + 1 + 2 + 0x1 + + + 2 + 4 + 0x2 + + + 3 + 8 + 0x3 + + + + + CALIB + Oscillator Calibration + 16 + 12 + + + FRANGE + Oscillator Frequency Range + 30 + 2 + + FRANGESelect + + 0 + 4 to 6MHz + 0x0 + + + 1 + 6 to 8MHz + 0x1 + + + 2 + 8 to 11MHz + 0x2 + + + 3 + 11 to 15MHz + 0x3 + + + + + + + DFLLCTRL + DFLL48M Control + 0x24 + 16 + 0x0080 + + + ENABLE + DFLL Enable + 1 + 1 + + + MODE + Operating Mode Selection + 2 + 1 + + + STABLE + Stable DFLL Frequency + 3 + 1 + + + LLAW + Lose Lock After Wake + 4 + 1 + + + USBCRM + USB Clock Recovery Mode + 5 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Control + 7 + 1 + + + CCDIS + Chill Cycle Disable + 8 + 1 + + + QLDIS + Quick Lock Disable + 9 + 1 + + + BPLCKC + Bypass Coarse Lock + 10 + 1 + + + WAITLOCK + Wait Lock + 11 + 1 + + + + + DFLLVAL + DFLL48M Value + 0x28 + 32 + + + FINE + Fine Value + 0 + 10 + + + COARSE + Coarse Value + 10 + 6 + + + DIFF + Multiplication Ratio Difference + 16 + 16 + read-only + + + + + DFLLMUL + DFLL48M Multiplier + 0x2C + 32 + + + MUL + DFLL Multiply Factor + 0 + 16 + + + FSTEP + Fine Maximum Step + 16 + 10 + + + CSTEP + Coarse Maximum Step + 26 + 6 + + + + + DFLLSYNC + DFLL48M Synchronization + 0x30 + 8 + + + READREQ + Read Request + 7 + 1 + write-only + + + + + BOD33 + 3.3V Brown-Out Detector (BOD33) Control + 0x34 + 32 + + + ENABLE + Enable + 1 + 1 + + + HYST + Hysteresis + 2 + 1 + + + ACTION + BOD33 Action + 3 + 2 + + ACTIONSelect + + NONE + No action + 0x0 + + + RESET + The BOD33 generates a reset + 0x1 + + + INTERRUPT + The BOD33 generates an interrupt + 0x2 + + + + + RUNSTDBY + Run in Standby + 6 + 1 + + + MODE + Operation Mode + 8 + 1 + + + CEN + Clock Enable + 9 + 1 + + + PSEL + Prescaler Select + 12 + 4 + + PSELSelect + + DIV2 + Divide clock by 2 + 0x0 + + + DIV4 + Divide clock by 4 + 0x1 + + + DIV8 + Divide clock by 8 + 0x2 + + + DIV16 + Divide clock by 16 + 0x3 + + + DIV32 + Divide clock by 32 + 0x4 + + + DIV64 + Divide clock by 64 + 0x5 + + + DIV128 + Divide clock by 128 + 0x6 + + + DIV256 + Divide clock by 256 + 0x7 + + + DIV512 + Divide clock by 512 + 0x8 + + + DIV1K + Divide clock by 1024 + 0x9 + + + DIV2K + Divide clock by 2048 + 0xa + + + DIV4K + Divide clock by 4096 + 0xb + + + DIV8K + Divide clock by 8192 + 0xc + + + DIV16K + Divide clock by 16384 + 0xd + + + DIV32K + Divide clock by 32768 + 0xe + + + DIV64K + Divide clock by 65536 + 0xf + + + + + LEVEL + BOD33 Threshold Level + 16 + 6 + + + + + VREG + Voltage Regulator System (VREG) Control + 0x3C + 16 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + FORCELDO + Force LDO Voltage Regulator + 13 + 1 + + + + + VREF + Voltage References System (VREF) Control + 0x40 + 32 + + + TSEN + Temperature Sensor Enable + 1 + 1 + + + BGOUTEN + Bandgap Output Enable + 2 + 1 + + + CALIB + Bandgap Voltage Generator Calibration + 16 + 11 + + + + + DPLLCTRLA + DPLL Control A + 0x44 + 8 + 0x80 + + + ENABLE + DPLL Enable + 1 + 1 + + + RUNSTDBY + Run in Standby + 6 + 1 + + + ONDEMAND + On Demand Clock Activation + 7 + 1 + + + + + DPLLRATIO + DPLL Ratio Control + 0x48 + 32 + + + LDR + Loop Divider Ratio + 0 + 12 + + + LDRFRAC + Loop Divider Ratio Fractional Part + 16 + 4 + + + + + DPLLCTRLB + DPLL Control B + 0x4C + 32 + + + FILTER + Proportional Integral Filter Selection + 0 + 2 + + FILTERSelect + + DEFAULT + Default filter mode + 0x0 + + + LBFILT + Low bandwidth filter + 0x1 + + + HBFILT + High bandwidth filter + 0x2 + + + HDFILT + High damping filter + 0x3 + + + + + LPEN + Low-Power Enable + 2 + 1 + + + WUF + Wake Up Fast + 3 + 1 + + + REFCLK + Reference Clock Selection + 4 + 2 + + REFCLKSelect + + REF0 + CLK_DPLL_REF0 clock reference + 0x0 + + + REF1 + CLK_DPLL_REF1 clock reference + 0x1 + + + GCLK + GCLK_DPLL clock reference + 0x2 + + + + + LTIME + Lock Time + 8 + 3 + + LTIMESelect + + DEFAULT + No time-out + 0x0 + + + 8MS + Time-out if no lock within 8 ms + 0x4 + + + 9MS + Time-out if no lock within 9 ms + 0x5 + + + 10MS + Time-out if no lock within 10 ms + 0x6 + + + 11MS + Time-out if no lock within 11 ms + 0x7 + + + + + LBYPASS + Lock Bypass + 12 + 1 + + + DIV + Clock Divider + 16 + 11 + + + + + DPLLSTATUS + DPLL Status + 0x50 + 8 + read-only + + + LOCK + DPLL Lock Status + 0 + 1 + read-only + + + CLKRDY + Output Clock Ready + 1 + 1 + read-only + + + ENABLE + DPLL Enable + 2 + 1 + read-only + + + DIV + Divider Enable + 3 + 1 + read-only + + + + + + + TC3 + 1.2.1 + Basic Timer Counter 3 + TC + TC_ + 0x42002C00 + + 0 + 0x040 + registers + + + TC3 + 18 + + + + COUNT8 + 8-bit Counter Mode + TcCount8 + 0x0 + + CTRLA + Control A + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + TC Mode + 2 + 2 + + MODESelect + + COUNT16 + Counter in 16-bit mode + 0x0 + + + COUNT8 + Counter in 8-bit mode + 0x1 + + + COUNT32 + Counter in 32-bit mode + 0x2 + + + + + WAVEGEN + Waveform Generation Operation + 5 + 2 + + WAVEGENSelect + + NFRQ + 0x0 + + + MFRQ + 0x1 + + + NPWM + 0x2 + + + MPWM + 0x3 + + + + + PRESCALER + Prescaler + 8 + 3 + + PRESCALERSelect + + DIV1 + Prescaler: GCLK_TC + 0x0 + + + DIV2 + Prescaler: GCLK_TC/2 + 0x1 + + + DIV4 + Prescaler: GCLK_TC/4 + 0x2 + + + DIV8 + Prescaler: GCLK_TC/8 + 0x3 + + + DIV16 + Prescaler: GCLK_TC/16 + 0x4 + + + DIV64 + Prescaler: GCLK_TC/64 + 0x5 + + + DIV256 + Prescaler: GCLK_TC/256 + 0x6 + + + DIV1024 + Prescaler: GCLK_TC/1024 + 0x7 + + + + + RUNSTDBY + Run in Standby + 11 + 1 + + + PRESCSYNC + Prescaler and Counter Synchronization + 12 + 2 + + PRESCSYNCSelect + + GCLK + Reload or reset the counter on next generic clock + 0x0 + + + PRESC + Reload or reset the counter on next prescaler clock + 0x1 + + + RESYNC + Reload or reset the counter on next generic clock. Reset the prescaler counter + 0x2 + + + + + + + READREQ + Read Request + 0x02 + 16 + + + ADDR + Address + 0 + 5 + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + + + + + CTRLBCLR + Control B Clear + 0x04 + 8 + 0x02 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLBSET + Control B Set + 0x05 + 8 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLC + Control C + 0x06 + 8 + + + INVEN0 + Output Waveform 0 Invert Enable + 0 + 1 + + + INVEN1 + Output Waveform 1 Invert Enable + 1 + 1 + + + CPTEN0 + Capture Channel 0 Enable + 4 + 1 + + + CPTEN1 + Capture Channel 1 Enable + 5 + 1 + + + + + DBGCTRL + Debug Control + 0x08 + 8 + + + DBGRUN + Debug Run Mode + 0 + 1 + + + + + EVCTRL + Event Control + 0x0A + 16 + + + EVACT + Event Action + 0 + 3 + + EVACTSelect + + OFF + Event action disabled + 0x0 + + + RETRIGGER + Start, restart or retrigger TC on event + 0x1 + + + COUNT + Count on event + 0x2 + + + START + Start TC on event + 0x3 + + + PPW + Period captured in CC0, pulse width in CC1 + 0x5 + + + PWP + Period captured in CC1, pulse width in CC0 + 0x6 + + + + + TCINV + TC Inverted Event Input + 4 + 1 + + + TCEI + TC Event Input + 5 + 1 + + + OVFEO + Overflow/Underflow Event Output Enable + 8 + 1 + + + MCEO0 + Match or Capture Channel 0 Event Output Enable + 12 + 1 + + + MCEO1 + Match or Capture Channel 1 Event Output Enable + 13 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x0C + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x0D + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x0E + 8 + + + OVF + Overflow + 0 + 1 + + + ERR + Error + 1 + 1 + + + SYNCRDY + Synchronization Ready + 3 + 1 + + + MC0 + Match or Capture Channel 0 + 4 + 1 + + + MC1 + Match or Capture Channel 1 + 5 + 1 + + + + + STATUS + Status + 0x0F + 8 + read-only + 0x08 + + + STOP + Stop + 3 + 1 + read-only + + + SLAVE + Slave + 4 + 1 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + COUNT + COUNT8 Counter Value + 0x10 + 8 + + + COUNT + Counter Value + 0 + 8 + + + + + PER + COUNT8 Period Value + 0x14 + 8 + 0xFF + + + PER + Period Value + 0 + 8 + + + + + 2 + 0x1 + CC%s + COUNT8 Compare/Capture + 0x18 + 8 + + + CC + Compare/Capture Value + 0 + 8 + + + + + + COUNT16 + 16-bit Counter Mode + COUNT8 + TcCount16 + 0x0 + + CTRLA + Control A + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + TC Mode + 2 + 2 + + MODESelect + + COUNT16 + Counter in 16-bit mode + 0x0 + + + COUNT8 + Counter in 8-bit mode + 0x1 + + + COUNT32 + Counter in 32-bit mode + 0x2 + + + + + WAVEGEN + Waveform Generation Operation + 5 + 2 + + WAVEGENSelect + + NFRQ + 0x0 + + + MFRQ + 0x1 + + + NPWM + 0x2 + + + MPWM + 0x3 + + + + + PRESCALER + Prescaler + 8 + 3 + + PRESCALERSelect + + DIV1 + Prescaler: GCLK_TC + 0x0 + + + DIV2 + Prescaler: GCLK_TC/2 + 0x1 + + + DIV4 + Prescaler: GCLK_TC/4 + 0x2 + + + DIV8 + Prescaler: GCLK_TC/8 + 0x3 + + + DIV16 + Prescaler: GCLK_TC/16 + 0x4 + + + DIV64 + Prescaler: GCLK_TC/64 + 0x5 + + + DIV256 + Prescaler: GCLK_TC/256 + 0x6 + + + DIV1024 + Prescaler: GCLK_TC/1024 + 0x7 + + + + + RUNSTDBY + Run in Standby + 11 + 1 + + + PRESCSYNC + Prescaler and Counter Synchronization + 12 + 2 + + PRESCSYNCSelect + + GCLK + Reload or reset the counter on next generic clock + 0x0 + + + PRESC + Reload or reset the counter on next prescaler clock + 0x1 + + + RESYNC + Reload or reset the counter on next generic clock. Reset the prescaler counter + 0x2 + + + + + + + READREQ + Read Request + 0x02 + 16 + + + ADDR + Address + 0 + 5 + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + + + + + CTRLBCLR + Control B Clear + 0x04 + 8 + 0x02 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLBSET + Control B Set + 0x05 + 8 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLC + Control C + 0x06 + 8 + + + INVEN0 + Output Waveform 0 Invert Enable + 0 + 1 + + + INVEN1 + Output Waveform 1 Invert Enable + 1 + 1 + + + CPTEN0 + Capture Channel 0 Enable + 4 + 1 + + + CPTEN1 + Capture Channel 1 Enable + 5 + 1 + + + + + DBGCTRL + Debug Control + 0x08 + 8 + + + DBGRUN + Debug Run Mode + 0 + 1 + + + + + EVCTRL + Event Control + 0x0A + 16 + + + EVACT + Event Action + 0 + 3 + + EVACTSelect + + OFF + Event action disabled + 0x0 + + + RETRIGGER + Start, restart or retrigger TC on event + 0x1 + + + COUNT + Count on event + 0x2 + + + START + Start TC on event + 0x3 + + + PPW + Period captured in CC0, pulse width in CC1 + 0x5 + + + PWP + Period captured in CC1, pulse width in CC0 + 0x6 + + + + + TCINV + TC Inverted Event Input + 4 + 1 + + + TCEI + TC Event Input + 5 + 1 + + + OVFEO + Overflow/Underflow Event Output Enable + 8 + 1 + + + MCEO0 + Match or Capture Channel 0 Event Output Enable + 12 + 1 + + + MCEO1 + Match or Capture Channel 1 Event Output Enable + 13 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x0C + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x0D + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x0E + 8 + + + OVF + Overflow + 0 + 1 + + + ERR + Error + 1 + 1 + + + SYNCRDY + Synchronization Ready + 3 + 1 + + + MC0 + Match or Capture Channel 0 + 4 + 1 + + + MC1 + Match or Capture Channel 1 + 5 + 1 + + + + + STATUS + Status + 0x0F + 8 + read-only + 0x08 + + + STOP + Stop + 3 + 1 + read-only + + + SLAVE + Slave + 4 + 1 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + COUNT + COUNT16 Counter Value + 0x10 + 16 + + + COUNT + Count Value + 0 + 16 + + + + + 2 + 0x2 + CC%s + COUNT16 Compare/Capture + 0x18 + 16 + + + CC + Compare/Capture Value + 0 + 16 + + + + + + COUNT32 + 32-bit Counter Mode + COUNT8 + TcCount32 + 0x0 + + CTRLA + Control A + 0x00 + 16 + + + SWRST + Software Reset + 0 + 1 + write-only + + + ENABLE + Enable + 1 + 1 + + + MODE + TC Mode + 2 + 2 + + MODESelect + + COUNT16 + Counter in 16-bit mode + 0x0 + + + COUNT8 + Counter in 8-bit mode + 0x1 + + + COUNT32 + Counter in 32-bit mode + 0x2 + + + + + WAVEGEN + Waveform Generation Operation + 5 + 2 + + WAVEGENSelect + + NFRQ + 0x0 + + + MFRQ + 0x1 + + + NPWM + 0x2 + + + MPWM + 0x3 + + + + + PRESCALER + Prescaler + 8 + 3 + + PRESCALERSelect + + DIV1 + Prescaler: GCLK_TC + 0x0 + + + DIV2 + Prescaler: GCLK_TC/2 + 0x1 + + + DIV4 + Prescaler: GCLK_TC/4 + 0x2 + + + DIV8 + Prescaler: GCLK_TC/8 + 0x3 + + + DIV16 + Prescaler: GCLK_TC/16 + 0x4 + + + DIV64 + Prescaler: GCLK_TC/64 + 0x5 + + + DIV256 + Prescaler: GCLK_TC/256 + 0x6 + + + DIV1024 + Prescaler: GCLK_TC/1024 + 0x7 + + + + + RUNSTDBY + Run in Standby + 11 + 1 + + + PRESCSYNC + Prescaler and Counter Synchronization + 12 + 2 + + PRESCSYNCSelect + + GCLK + Reload or reset the counter on next generic clock + 0x0 + + + PRESC + Reload or reset the counter on next prescaler clock + 0x1 + + + RESYNC + Reload or reset the counter on next generic clock. Reset the prescaler counter + 0x2 + + + + + + + READREQ + Read Request + 0x02 + 16 + + + ADDR + Address + 0 + 5 + + + RCONT + Read Continuously + 14 + 1 + + + RREQ + Read Request + 15 + 1 + + + + + CTRLBCLR + Control B Clear + 0x04 + 8 + 0x02 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLBSET + Control B Set + 0x05 + 8 + + + DIR + Counter Direction + 0 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + CMD + Command + 6 + 2 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Force a start, restart or retrigger + 0x1 + + + STOP + Force a stop + 0x2 + + + + + + + CTRLC + Control C + 0x06 + 8 + + + INVEN0 + Output Waveform 0 Invert Enable + 0 + 1 + + + INVEN1 + Output Waveform 1 Invert Enable + 1 + 1 + + + CPTEN0 + Capture Channel 0 Enable + 4 + 1 + + + CPTEN1 + Capture Channel 1 Enable + 5 + 1 + + + + + DBGCTRL + Debug Control + 0x08 + 8 + + + DBGRUN + Debug Run Mode + 0 + 1 + + + + + EVCTRL + Event Control + 0x0A + 16 + + + EVACT + Event Action + 0 + 3 + + EVACTSelect + + OFF + Event action disabled + 0x0 + + + RETRIGGER + Start, restart or retrigger TC on event + 0x1 + + + COUNT + Count on event + 0x2 + + + START + Start TC on event + 0x3 + + + PPW + Period captured in CC0, pulse width in CC1 + 0x5 + + + PWP + Period captured in CC1, pulse width in CC0 + 0x6 + + + + + TCINV + TC Inverted Event Input + 4 + 1 + + + TCEI + TC Event Input + 5 + 1 + + + OVFEO + Overflow/Underflow Event Output Enable + 8 + 1 + + + MCEO0 + Match or Capture Channel 0 Event Output Enable + 12 + 1 + + + MCEO1 + Match or Capture Channel 1 Event Output Enable + 13 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x0C + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x0D + 8 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + ERR + Error Interrupt Enable + 1 + 1 + + + SYNCRDY + Synchronization Ready Interrupt Enable + 3 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 4 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 5 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x0E + 8 + + + OVF + Overflow + 0 + 1 + + + ERR + Error + 1 + 1 + + + SYNCRDY + Synchronization Ready + 3 + 1 + + + MC0 + Match or Capture Channel 0 + 4 + 1 + + + MC1 + Match or Capture Channel 1 + 5 + 1 + + + + + STATUS + Status + 0x0F + 8 + read-only + 0x08 + + + STOP + Stop + 3 + 1 + read-only + + + SLAVE + Slave + 4 + 1 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + COUNT + COUNT32 Counter Value + 0x10 + 32 + + + COUNT + Count Value + 0 + 32 + + + + + 2 + 0x4 + CC%s + COUNT32 Compare/Capture + 0x18 + 32 + + + CC + Compare/Capture Value + 0 + 32 + + + + + + + + TC4 + Basic Timer Counter 4 + 0x42003000 + + TC4 + 19 + + + + TC5 + Basic Timer Counter 5 + 0x42003400 + + TC5 + 20 + + + + TCC0 + 1.0.1 + Timer Counter Control 0 + TCC + TCC_ + 0x42002000 + + 0 + 0x090 + registers + + + TCC0 + 15 + + + + CTRLA + Control A + 0x00 + 32 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + RESOLUTION + Enhanced Resolution + 5 + 2 + + RESOLUTIONSelect + + NONE + Dithering is disabled + 0x0 + + + DITH4 + Dithering is done every 16 PWM frames + 0x1 + + + DITH5 + Dithering is done every 32 PWM frames + 0x2 + + + DITH6 + Dithering is done every 64 PWM frames + 0x3 + + + + + PRESCALER + Prescaler + 8 + 3 + + PRESCALERSelect + + DIV1 + No division + 0x0 + + + DIV2 + Divide by 2 + 0x1 + + + DIV4 + Divide by 4 + 0x2 + + + DIV8 + Divide by 8 + 0x3 + + + DIV16 + Divide by 16 + 0x4 + + + DIV64 + Divide by 64 + 0x5 + + + DIV256 + Divide by 256 + 0x6 + + + DIV1024 + Divide by 1024 + 0x7 + + + + + RUNSTDBY + Run in Standby + 11 + 1 + + + PRESCSYNC + Prescaler and Counter Synchronization Selection + 12 + 2 + + PRESCSYNCSelect + + GCLK + Reload or reset counter on next GCLK + 0x0 + + + PRESC + Reload or reset counter on next prescaler clock + 0x1 + + + RESYNC + Reload or reset counter on next GCLK and reset prescaler counter + 0x2 + + + + + ALOCK + Auto Lock + 14 + 1 + + + CPTEN0 + Capture Channel 0 Enable + 24 + 1 + + + CPTEN1 + Capture Channel 1 Enable + 25 + 1 + + + CPTEN2 + Capture Channel 2 Enable + 26 + 1 + + + CPTEN3 + Capture Channel 3 Enable + 27 + 1 + + + + + CTRLBCLR + Control B Clear + 0x04 + 8 + + + DIR + Counter Direction + 0 + 1 + + + LUPD + Lock Update + 1 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + IDXCMD + Ramp Index Command + 3 + 2 + + IDXCMDSelect + + DISABLE + Command disabled: Index toggles between cycles A and B + 0x0 + + + SET + Set index: cycle B will be forced in the next cycle + 0x1 + + + CLEAR + Clear index: cycle A will be forced in the next cycle + 0x2 + + + HOLD + Hold index: the next cycle will be the same as the current cycle + 0x3 + + + + + CMD + TCC Command + 5 + 3 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Clear start, restart or retrigger + 0x1 + + + STOP + Force stop + 0x2 + + + UPDATE + Force update of double buffered registers + 0x3 + + + READSYNC + Force COUNT read synchronization + 0x4 + + + + + + + CTRLBSET + Control B Set + 0x05 + 8 + + + DIR + Counter Direction + 0 + 1 + + + LUPD + Lock Update + 1 + 1 + + + ONESHOT + One-Shot + 2 + 1 + + + IDXCMD + Ramp Index Command + 3 + 2 + + IDXCMDSelect + + DISABLE + Command disabled: Index toggles between cycles A and B + 0x0 + + + SET + Set index: cycle B will be forced in the next cycle + 0x1 + + + CLEAR + Clear index: cycle A will be forced in the next cycle + 0x2 + + + HOLD + Hold index: the next cycle will be the same as the current cycle + 0x3 + + + + + CMD + TCC Command + 5 + 3 + + CMDSelect + + NONE + No action + 0x0 + + + RETRIGGER + Clear start, restart or retrigger + 0x1 + + + STOP + Force stop + 0x2 + + + UPDATE + Force update of double buffered registers + 0x3 + + + READSYNC + Force COUNT read synchronization + 0x4 + + + + + + + SYNCBUSY + Synchronization Busy + 0x08 + 32 + read-only + + + SWRST + Swrst Busy + 0 + 1 + + + ENABLE + Enable Busy + 1 + 1 + + + CTRLB + Ctrlb Busy + 2 + 1 + + + STATUS + Status Busy + 3 + 1 + + + COUNT + Count Busy + 4 + 1 + + + PATT + Pattern Busy + 5 + 1 + + + WAVE + Wave Busy + 6 + 1 + + + PER + Period busy + 7 + 1 + + + CC0 + Compare Channel 0 Busy + 8 + 1 + + + CC1 + Compare Channel 1 Busy + 9 + 1 + + + CC2 + Compare Channel 2 Busy + 10 + 1 + + + CC3 + Compare Channel 3 Busy + 11 + 1 + + + PATTB + Pattern Buffer Busy + 16 + 1 + + + WAVEB + Wave Buffer Busy + 17 + 1 + + + PERB + Period Buffer Busy + 18 + 1 + + + CCB0 + Compare Channel Buffer 0 Busy + 19 + 1 + + + CCB1 + Compare Channel Buffer 1 Busy + 20 + 1 + + + CCB2 + Compare Channel Buffer 2 Busy + 21 + 1 + + + CCB3 + Compare Channel Buffer 3 Busy + 22 + 1 + + + + + FCTRLA + Recoverable Fault A Configuration + 0x0C + 32 + + + SRC + Fault A Source + 0 + 2 + + SRCSelect + + DISABLE + Fault input disabled + 0x0 + + + ENABLE + MCEx (x=0,1) event input + 0x1 + + + INVERT + Inverted MCEx (x=0,1) event input + 0x2 + + + ALTFAULT + Alternate fault (A or B) state at the end of the previous period + 0x3 + + + + + KEEP + Fault A Keeper + 3 + 1 + + + QUAL + Fault A Qualification + 4 + 1 + + + BLANK + Fault A Blanking Mode + 5 + 2 + + BLANKSelect + + NONE + No blanking applied + 0x0 + + + RISE + Blanking applied from rising edge of the output waveform + 0x1 + + + FALL + Blanking applied from falling edge of the output waveform + 0x2 + + + BOTH + Blanking applied from each toggle of the output waveform + 0x3 + + + + + RESTART + Fault A Restart + 7 + 1 + + + HALT + Fault A Halt Mode + 8 + 2 + + HALTSelect + + DISABLE + Halt action disabled + 0x0 + + + HW + Hardware halt action + 0x1 + + + SW + Software halt action + 0x2 + + + NR + Non-recoverable fault + 0x3 + + + + + CHSEL + Fault A Capture Channel + 10 + 2 + + CHSELSelect + + CC0 + Capture value stored in channel 0 + 0x0 + + + CC1 + Capture value stored in channel 1 + 0x1 + + + CC2 + Capture value stored in channel 2 + 0x2 + + + CC3 + Capture value stored in channel 3 + 0x3 + + + + + CAPTURE + Fault A Capture Action + 12 + 3 + + CAPTURESelect + + DISABLE + No capture + 0x0 + + + CAPT + Capture on fault + 0x1 + + + CAPTMIN + Minimum capture + 0x2 + + + CAPTMAX + Maximum capture + 0x3 + + + LOCMIN + Minimum local detection + 0x4 + + + LOCMAX + Maximum local detection + 0x5 + + + DERIV0 + Minimum and maximum local detection + 0x6 + + + + + BLANKVAL + Fault A Blanking Time + 16 + 8 + + + FILTERVAL + Fault A Filter Value + 24 + 4 + + + + + FCTRLB + Recoverable Fault B Configuration + 0x10 + 32 + + + SRC + Fault B Source + 0 + 2 + + SRCSelect + + DISABLE + Fault input disabled + 0x0 + + + ENABLE + MCEx (x=0,1) event input + 0x1 + + + INVERT + Inverted MCEx (x=0,1) event input + 0x2 + + + ALTFAULT + Alternate fault (A or B) state at the end of the previous period + 0x3 + + + + + KEEP + Fault B Keeper + 3 + 1 + + + QUAL + Fault B Qualification + 4 + 1 + + + BLANK + Fault B Blanking Mode + 5 + 2 + + BLANKSelect + + NONE + No blanking applied + 0x0 + + + RISE + Blanking applied from rising edge of the output waveform + 0x1 + + + FALL + Blanking applied from falling edge of the output waveform + 0x2 + + + BOTH + Blanking applied from each toggle of the output waveform + 0x3 + + + + + RESTART + Fault B Restart + 7 + 1 + + + HALT + Fault B Halt Mode + 8 + 2 + + HALTSelect + + DISABLE + Halt action disabled + 0x0 + + + HW + Hardware halt action + 0x1 + + + SW + Software halt action + 0x2 + + + NR + Non-recoverable fault + 0x3 + + + + + CHSEL + Fault B Capture Channel + 10 + 2 + + CHSELSelect + + CC0 + Capture value stored in channel 0 + 0x0 + + + CC1 + Capture value stored in channel 1 + 0x1 + + + CC2 + Capture value stored in channel 2 + 0x2 + + + CC3 + Capture value stored in channel 3 + 0x3 + + + + + CAPTURE + Fault B Capture Action + 12 + 3 + + CAPTURESelect + + DISABLE + No capture + 0x0 + + + CAPT + Capture on fault + 0x1 + + + CAPTMIN + Minimum capture + 0x2 + + + CAPTMAX + Maximum capture + 0x3 + + + LOCMIN + Minimum local detection + 0x4 + + + LOCMAX + Maximum local detection + 0x5 + + + DERIV0 + Minimum and maximum local detection + 0x6 + + + + + BLANKVAL + Fault B Blanking Time + 16 + 8 + + + FILTERVAL + Fault B Filter Value + 24 + 4 + + + + + WEXCTRL + Waveform Extension Configuration + 0x14 + 32 + + + OTMX + Output Matrix + 0 + 2 + + + DTIEN0 + Dead-time Insertion Generator 0 Enable + 8 + 1 + + + DTIEN1 + Dead-time Insertion Generator 1 Enable + 9 + 1 + + + DTIEN2 + Dead-time Insertion Generator 2 Enable + 10 + 1 + + + DTIEN3 + Dead-time Insertion Generator 3 Enable + 11 + 1 + + + DTLS + Dead-time Low Side Outputs Value + 16 + 8 + + + DTHS + Dead-time High Side Outputs Value + 24 + 8 + + + + + DRVCTRL + Driver Control + 0x18 + 32 + + + NRE0 + Non-Recoverable State 0 Output Enable + 0 + 1 + + + NRE1 + Non-Recoverable State 1 Output Enable + 1 + 1 + + + NRE2 + Non-Recoverable State 2 Output Enable + 2 + 1 + + + NRE3 + Non-Recoverable State 3 Output Enable + 3 + 1 + + + NRE4 + Non-Recoverable State 4 Output Enable + 4 + 1 + + + NRE5 + Non-Recoverable State 5 Output Enable + 5 + 1 + + + NRE6 + Non-Recoverable State 6 Output Enable + 6 + 1 + + + NRE7 + Non-Recoverable State 7 Output Enable + 7 + 1 + + + NRV0 + Non-Recoverable State 0 Output Value + 8 + 1 + + + NRV1 + Non-Recoverable State 1 Output Value + 9 + 1 + + + NRV2 + Non-Recoverable State 2 Output Value + 10 + 1 + + + NRV3 + Non-Recoverable State 3 Output Value + 11 + 1 + + + NRV4 + Non-Recoverable State 4 Output Value + 12 + 1 + + + NRV5 + Non-Recoverable State 5 Output Value + 13 + 1 + + + NRV6 + Non-Recoverable State 6 Output Value + 14 + 1 + + + NRV7 + Non-Recoverable State 7 Output Value + 15 + 1 + + + INVEN0 + Output Waveform 0 Inversion + 16 + 1 + + + INVEN1 + Output Waveform 1 Inversion + 17 + 1 + + + INVEN2 + Output Waveform 2 Inversion + 18 + 1 + + + INVEN3 + Output Waveform 3 Inversion + 19 + 1 + + + INVEN4 + Output Waveform 4 Inversion + 20 + 1 + + + INVEN5 + Output Waveform 5 Inversion + 21 + 1 + + + INVEN6 + Output Waveform 6 Inversion + 22 + 1 + + + INVEN7 + Output Waveform 7 Inversion + 23 + 1 + + + FILTERVAL0 + Non-Recoverable Fault Input 0 Filter Value + 24 + 4 + + + FILTERVAL1 + Non-Recoverable Fault Input 1 Filter Value + 28 + 4 + + + + + DBGCTRL + Debug Control + 0x1E + 8 + + + DBGRUN + Debug Running Mode + 0 + 1 + + + FDDBD + Fault Detection on Debug Break Detection + 2 + 1 + + + + + EVCTRL + Event Control + 0x20 + 32 + + + EVACT0 + Timer/counter Input Event0 Action + 0 + 3 + + EVACT0Select + + OFF + Event action disabled + 0x0 + + + RETRIGGER + Start, restart or re-trigger counter on event + 0x1 + + + COUNTEV + Count on event + 0x2 + + + START + Start counter on event + 0x3 + + + INC + Increment counter on event + 0x4 + + + COUNT + Count on active state of asynchronous event + 0x5 + + + FAULT + Non-recoverable fault + 0x7 + + + + + EVACT1 + Timer/counter Input Event1 Action + 3 + 3 + + EVACT1Select + + OFF + Event action disabled + 0x0 + + + RETRIGGER + Re-trigger counter on event + 0x1 + + + DIR + Direction control + 0x2 + + + STOP + Stop counter on event + 0x3 + + + DEC + Decrement counter on event + 0x4 + + + PPW + Period capture value in CC0 register, pulse width capture value in CC1 register + 0x5 + + + PWP + Period capture value in CC1 register, pulse width capture value in CC0 register + 0x6 + + + FAULT + Non-recoverable fault + 0x7 + + + + + CNTSEL + Timer/counter Output Event Mode + 6 + 2 + + CNTSELSelect + + START + An interrupt/event is generated when a new counter cycle starts + 0x0 + + + END + An interrupt/event is generated when a counter cycle ends + 0x1 + + + BETWEEN + An interrupt/event is generated when a counter cycle ends, except for the first and last cycles + 0x2 + + + BOUNDARY + An interrupt/event is generated when a new counter cycle starts or a counter cycle ends + 0x3 + + + + + OVFEO + Overflow/Underflow Output Event Enable + 8 + 1 + + + TRGEO + Retrigger Output Event Enable + 9 + 1 + + + CNTEO + Timer/counter Output Event Enable + 10 + 1 + + + TCINV0 + Inverted Event 0 Input Enable + 12 + 1 + + + TCINV1 + Inverted Event 1 Input Enable + 13 + 1 + + + TCEI0 + Timer/counter Event 0 Input Enable + 14 + 1 + + + TCEI1 + Timer/counter Event 1 Input Enable + 15 + 1 + + + MCEI0 + Match or Capture Channel 0 Event Input Enable + 16 + 1 + + + MCEI1 + Match or Capture Channel 1 Event Input Enable + 17 + 1 + + + MCEI2 + Match or Capture Channel 2 Event Input Enable + 18 + 1 + + + MCEI3 + Match or Capture Channel 3 Event Input Enable + 19 + 1 + + + MCEO0 + Match or Capture Channel 0 Event Output Enable + 24 + 1 + + + MCEO1 + Match or Capture Channel 1 Event Output Enable + 25 + 1 + + + MCEO2 + Match or Capture Channel 2 Event Output Enable + 26 + 1 + + + MCEO3 + Match or Capture Channel 3 Event Output Enable + 27 + 1 + + + + + INTENCLR + Interrupt Enable Clear + 0x24 + 32 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + TRG + Retrigger Interrupt Enable + 1 + 1 + + + CNT + Counter Interrupt Enable + 2 + 1 + + + ERR + Error Interrupt Enable + 3 + 1 + + + DFS + Non-Recoverable Debug Fault Interrupt Enable + 11 + 1 + + + FAULTA + Recoverable Fault A Interrupt Enable + 12 + 1 + + + FAULTB + Recoverable Fault B Interrupt Enable + 13 + 1 + + + FAULT0 + Non-Recoverable Fault 0 Interrupt Enable + 14 + 1 + + + FAULT1 + Non-Recoverable Fault 1 Interrupt Enable + 15 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 16 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 17 + 1 + + + MC2 + Match or Capture Channel 2 Interrupt Enable + 18 + 1 + + + MC3 + Match or Capture Channel 3 Interrupt Enable + 19 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x28 + 32 + + + OVF + Overflow Interrupt Enable + 0 + 1 + + + TRG + Retrigger Interrupt Enable + 1 + 1 + + + CNT + Counter Interrupt Enable + 2 + 1 + + + ERR + Error Interrupt Enable + 3 + 1 + + + DFS + Non-Recoverable Debug Fault Interrupt Enable + 11 + 1 + + + FAULTA + Recoverable Fault A Interrupt Enable + 12 + 1 + + + FAULTB + Recoverable Fault B Interrupt Enable + 13 + 1 + + + FAULT0 + Non-Recoverable Fault 0 Interrupt Enable + 14 + 1 + + + FAULT1 + Non-Recoverable Fault 1 Interrupt Enable + 15 + 1 + + + MC0 + Match or Capture Channel 0 Interrupt Enable + 16 + 1 + + + MC1 + Match or Capture Channel 1 Interrupt Enable + 17 + 1 + + + MC2 + Match or Capture Channel 2 Interrupt Enable + 18 + 1 + + + MC3 + Match or Capture Channel 3 Interrupt Enable + 19 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x2C + 32 + + + OVF + Overflow + 0 + 1 + + + TRG + Retrigger + 1 + 1 + + + CNT + Counter + 2 + 1 + + + ERR + Error + 3 + 1 + + + DFS + Non-Recoverable Debug Fault + 11 + 1 + + + FAULTA + Recoverable Fault A + 12 + 1 + + + FAULTB + Recoverable Fault B + 13 + 1 + + + FAULT0 + Non-Recoverable Fault 0 + 14 + 1 + + + FAULT1 + Non-Recoverable Fault 1 + 15 + 1 + + + MC0 + Match or Capture 0 + 16 + 1 + + + MC1 + Match or Capture 1 + 17 + 1 + + + MC2 + Match or Capture 2 + 18 + 1 + + + MC3 + Match or Capture 3 + 19 + 1 + + + + + STATUS + Status + 0x30 + 32 + 0x00000001 + + + STOP + Stop + 0 + 1 + read-only + + + IDX + Ramp + 1 + 1 + read-only + + + DFS + Non-Recoverable Debug Fault State + 3 + 1 + + + SLAVE + Slave + 4 + 1 + read-only + + + PATTBV + Pattern Buffer Valid + 5 + 1 + + + WAVEBV + Wave Buffer Valid + 6 + 1 + + + PERBV + Period Buffer Valid + 7 + 1 + + + FAULTAIN + Recoverable Fault A Input + 8 + 1 + read-only + + + FAULTBIN + Recoverable Fault B Input + 9 + 1 + read-only + + + FAULT0IN + Non-Recoverable Fault0 Input + 10 + 1 + read-only + + + FAULT1IN + Non-Recoverable Fault1 Input + 11 + 1 + read-only + + + FAULTA + Recoverable Fault A State + 12 + 1 + + + FAULTB + Recoverable Fault B State + 13 + 1 + + + FAULT0 + Non-Recoverable Fault 0 State + 14 + 1 + + + FAULT1 + Non-Recoverable Fault 1 State + 15 + 1 + + + CCBV0 + Compare Channel 0 Buffer Valid + 16 + 1 + + + CCBV1 + Compare Channel 1 Buffer Valid + 17 + 1 + + + CCBV2 + Compare Channel 2 Buffer Valid + 18 + 1 + + + CCBV3 + Compare Channel 3 Buffer Valid + 19 + 1 + + + CMP0 + Compare Channel 0 Value + 24 + 1 + read-only + + + CMP1 + Compare Channel 1 Value + 25 + 1 + read-only + + + CMP2 + Compare Channel 2 Value + 26 + 1 + read-only + + + CMP3 + Compare Channel 3 Value + 27 + 1 + read-only + + + + + COUNT + Count + 0x34 + 32 + + + COUNT + Counter Value + 0 + 24 + + + + + COUNT_DITH4 + Count + COUNT + 0x34 + 32 + + + COUNT + Counter Value + 4 + 20 + + + + + COUNT_DITH5 + Count + COUNT + 0x34 + 32 + + + COUNT + Counter Value + 5 + 19 + + + + + COUNT_DITH6 + Count + COUNT + 0x34 + 32 + + + COUNT + Counter Value + 6 + 18 + + + + + PATT + Pattern + 0x38 + 16 + + + PGE0 + Pattern Generator 0 Output Enable + 0 + 1 + + + PGE1 + Pattern Generator 1 Output Enable + 1 + 1 + + + PGE2 + Pattern Generator 2 Output Enable + 2 + 1 + + + PGE3 + Pattern Generator 3 Output Enable + 3 + 1 + + + PGE4 + Pattern Generator 4 Output Enable + 4 + 1 + + + PGE5 + Pattern Generator 5 Output Enable + 5 + 1 + + + PGE6 + Pattern Generator 6 Output Enable + 6 + 1 + + + PGE7 + Pattern Generator 7 Output Enable + 7 + 1 + + + PGV0 + Pattern Generator 0 Output Value + 8 + 1 + + + PGV1 + Pattern Generator 1 Output Value + 9 + 1 + + + PGV2 + Pattern Generator 2 Output Value + 10 + 1 + + + PGV3 + Pattern Generator 3 Output Value + 11 + 1 + + + PGV4 + Pattern Generator 4 Output Value + 12 + 1 + + + PGV5 + Pattern Generator 5 Output Value + 13 + 1 + + + PGV6 + Pattern Generator 6 Output Value + 14 + 1 + + + PGV7 + Pattern Generator 7 Output Value + 15 + 1 + + + + + WAVE + Waveform Control + 0x3C + 32 + + + WAVEGEN + Waveform Generation + 0 + 3 + + WAVEGENSelect + + NFRQ + Normal frequency + 0x0 + + + MFRQ + Match frequency + 0x1 + + + NPWM + Normal PWM + 0x2 + + + DSCRITICAL + Dual-slope critical + 0x4 + + + DSBOTTOM + Dual-slope with interrupt/event condition when COUNT reaches ZERO + 0x5 + + + DSBOTH + Dual-slope with interrupt/event condition when COUNT reaches ZERO or TOP + 0x6 + + + DSTOP + Dual-slope with interrupt/event condition when COUNT reaches TOP + 0x7 + + + + + RAMP + Ramp Mode + 4 + 2 + + RAMPSelect + + RAMP1 + RAMP1 operation + 0x0 + + + RAMP2A + Alternative RAMP2 operation + 0x1 + + + RAMP2 + RAMP2 operation + 0x2 + + + + + CIPEREN + Circular period Enable + 7 + 1 + + + CICCEN0 + Circular Channel 0 Enable + 8 + 1 + + + CICCEN1 + Circular Channel 1 Enable + 9 + 1 + + + CICCEN2 + Circular Channel 2 Enable + 10 + 1 + + + CICCEN3 + Circular Channel 3 Enable + 11 + 1 + + + POL0 + Channel 0 Polarity + 16 + 1 + + + POL1 + Channel 1 Polarity + 17 + 1 + + + POL2 + Channel 2 Polarity + 18 + 1 + + + POL3 + Channel 3 Polarity + 19 + 1 + + + SWAP0 + Swap DTI Output Pair 0 + 24 + 1 + + + SWAP1 + Swap DTI Output Pair 1 + 25 + 1 + + + SWAP2 + Swap DTI Output Pair 2 + 26 + 1 + + + SWAP3 + Swap DTI Output Pair 3 + 27 + 1 + + + + + PER + Period + 0x40 + 32 + 0xFFFFFFFF + + + PER + Period Value + 0 + 24 + + + + + PER_DITH4 + Period + PER + 0x40 + 32 + 0xFFFFFFFF + + + DITHERCY + Dithering Cycle Number + 0 + 4 + + + PER + Period Value + 4 + 20 + + + + + PER_DITH5 + Period + PER + 0x40 + 32 + 0xFFFFFFFF + + + DITHERCY + Dithering Cycle Number + 0 + 5 + + + PER + Period Value + 5 + 19 + + + + + PER_DITH6 + Period + PER + 0x40 + 32 + 0xFFFFFFFF + + + DITHERCY + Dithering Cycle Number + 0 + 6 + + + PER + Period Value + 6 + 18 + + + + + 4 + 0x4 + CC%s + Compare and Capture + 0x44 + 32 + + + CC + Channel Compare/Capture Value + 0 + 24 + + + + + 4 + 0x4 + CC%s_DITH4 + Compare and Capture + CC%s + 0x44 + 32 + + + DITHERCY + Dithering Cycle Number + 0 + 4 + + + CC + Channel Compare/Capture Value + 4 + 20 + + + + + 4 + 0x4 + CC%s_DITH5 + Compare and Capture + CC%s + 0x44 + 32 + + + DITHERCY + Dithering Cycle Number + 0 + 5 + + + CC + Channel Compare/Capture Value + 5 + 19 + + + + + 4 + 0x4 + CC%s_DITH6 + Compare and Capture + CC%s + 0x44 + 32 + + + DITHERCY + Dithering Cycle Number + 0 + 6 + + + CC + Channel Compare/Capture Value + 6 + 18 + + + + + PATTB + Pattern Buffer + 0x64 + 16 + + + PGEB0 + Pattern Generator 0 Output Enable Buffer + 0 + 1 + + + PGEB1 + Pattern Generator 1 Output Enable Buffer + 1 + 1 + + + PGEB2 + Pattern Generator 2 Output Enable Buffer + 2 + 1 + + + PGEB3 + Pattern Generator 3 Output Enable Buffer + 3 + 1 + + + PGEB4 + Pattern Generator 4 Output Enable Buffer + 4 + 1 + + + PGEB5 + Pattern Generator 5 Output Enable Buffer + 5 + 1 + + + PGEB6 + Pattern Generator 6 Output Enable Buffer + 6 + 1 + + + PGEB7 + Pattern Generator 7 Output Enable Buffer + 7 + 1 + + + PGVB0 + Pattern Generator 0 Output Enable + 8 + 1 + + + PGVB1 + Pattern Generator 1 Output Enable + 9 + 1 + + + PGVB2 + Pattern Generator 2 Output Enable + 10 + 1 + + + PGVB3 + Pattern Generator 3 Output Enable + 11 + 1 + + + PGVB4 + Pattern Generator 4 Output Enable + 12 + 1 + + + PGVB5 + Pattern Generator 5 Output Enable + 13 + 1 + + + PGVB6 + Pattern Generator 6 Output Enable + 14 + 1 + + + PGVB7 + Pattern Generator 7 Output Enable + 15 + 1 + + + + + WAVEB + Waveform Control Buffer + 0x68 + 32 + + + WAVEGENB + Waveform Generation Buffer + 0 + 3 + + WAVEGENBSelect + + NFRQ + Normal frequency + 0x0 + + + MFRQ + Match frequency + 0x1 + + + NPWM + Normal PWM + 0x2 + + + DSCRITICAL + Dual-slope critical + 0x4 + + + DSBOTTOM + Dual-slope with interrupt/event condition when COUNT reaches ZERO + 0x5 + + + DSBOTH + Dual-slope with interrupt/event condition when COUNT reaches ZERO or TOP + 0x6 + + + DSTOP + Dual-slope with interrupt/event condition when COUNT reaches TOP + 0x7 + + + + + RAMPB + Ramp Mode Buffer + 4 + 2 + + RAMPBSelect + + RAMP1 + RAMP1 operation + 0x0 + + + RAMP2A + Alternative RAMP2 operation + 0x1 + + + RAMP2 + RAMP2 operation + 0x2 + + + + + CIPERENB + Circular Period Enable Buffer + 7 + 1 + + + CICCENB0 + Circular Channel 0 Enable Buffer + 8 + 1 + + + CICCENB1 + Circular Channel 1 Enable Buffer + 9 + 1 + + + CICCENB2 + Circular Channel 2 Enable Buffer + 10 + 1 + + + CICCENB3 + Circular Channel 3 Enable Buffer + 11 + 1 + + + POLB0 + Channel 0 Polarity Buffer + 16 + 1 + + + POLB1 + Channel 1 Polarity Buffer + 17 + 1 + + + POLB2 + Channel 2 Polarity Buffer + 18 + 1 + + + POLB3 + Channel 3 Polarity Buffer + 19 + 1 + + + SWAPB0 + Swap DTI Output Pair 0 Buffer + 24 + 1 + + + SWAPB1 + Swap DTI Output Pair 1 Buffer + 25 + 1 + + + SWAPB2 + Swap DTI Output Pair 2 Buffer + 26 + 1 + + + SWAPB3 + Swap DTI Output Pair 3 Buffer + 27 + 1 + + + + + PERB + Period Buffer + 0x6C + 32 + 0xFFFFFFFF + + + PERB + Period Buffer Value + 0 + 24 + + + + + PERB_DITH4 + Period Buffer + PERB + 0x6C + 32 + 0xFFFFFFFF + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 4 + + + PERB + Period Buffer Value + 4 + 20 + + + + + PERB_DITH5 + Period Buffer + PERB + 0x6C + 32 + 0xFFFFFFFF + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 5 + + + PERB + Period Buffer Value + 5 + 19 + + + + + PERB_DITH6 + Period Buffer + PERB + 0x6C + 32 + 0xFFFFFFFF + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 6 + + + PERB + Period Buffer Value + 6 + 18 + + + + + 4 + 0x4 + CCB%s + Compare and Capture Buffer + 0x70 + 32 + + + CCB + Channel Compare/Capture Buffer Value + 0 + 24 + + + + + 4 + 0x4 + CCB%s_DITH4 + Compare and Capture Buffer + CCB%s + 0x70 + 32 + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 4 + + + CCB + Channel Compare/Capture Buffer Value + 4 + 20 + + + + + 4 + 0x4 + CCB%s_DITH5 + Compare and Capture Buffer + CCB%s + 0x70 + 32 + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 5 + + + CCB + Channel Compare/Capture Buffer Value + 5 + 19 + + + + + 4 + 0x4 + CCB%s_DITH6 + Compare and Capture Buffer + CCB%s + 0x70 + 32 + + + DITHERCYB + Dithering Buffer Cycle Number + 0 + 6 + + + CCB + Channel Compare/Capture Buffer Value + 6 + 18 + + + + + + + TCC1 + Timer Counter Control 1 + 0x42002400 + + TCC1 + 16 + + + + TCC2 + Timer Counter Control 2 + 0x42002800 + + TCC2 + 17 + + + + USB + 1.0.1 + Universal Serial Bus + USB + USB_ + 0x41005000 + + 0 + 0x1000 + registers + + + USB + 7 + + + + DEVICE + USB is Device + UsbDevice + 0x0 + + CTRLA + Control A + 0x000 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + RUNSTDBY + Run in Standby Mode + 2 + 1 + + + MODE + Operating Mode + 7 + 1 + + MODESelect + + DEVICE + Device Mode + 0x0 + + + HOST + Host Mode + 0x1 + + + + + + + SYNCBUSY + Synchronization Busy + 0x002 + 8 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + Enable Synchronization Busy + 1 + 1 + read-only + + + + + QOSCTRL + USB Quality Of Service + 0x003 + 8 + 0x05 + + + CQOS + Configuration Quality of Service + 0 + 2 + + CQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + DQOS + Data Quality of Service + 2 + 2 + + DQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + + + CTRLB + DEVICE Control B + 0x008 + 16 + 0x0001 + + + DETACH + Detach + 0 + 1 + + + UPRSM + Upstream Resume + 1 + 1 + + + SPDCONF + Speed Configuration + 2 + 2 + + SPDCONFSelect + + FS + FS : Full Speed + 0x0 + + + LS + LS : Low Speed + 0x1 + + + HS + HS : High Speed capable + 0x2 + + + HSTM + HSTM: High Speed Test Mode (force high-speed mode for test mode) + 0x3 + + + + + NREPLY + No Reply + 4 + 1 + + + TSTJ + Test mode J + 5 + 1 + + + TSTK + Test mode K + 6 + 1 + + + TSTPCKT + Test packet mode + 7 + 1 + + + OPMODE2 + Specific Operational Mode + 8 + 1 + + + GNAK + Global NAK + 9 + 1 + + + LPMHDSK + Link Power Management Handshake + 10 + 2 + + LPMHDSKSelect + + NO + No handshake. LPM is not supported + 0x0 + + + ACK + ACK + 0x1 + + + NYET + NYET + 0x2 + + + STALL + STALL + 0x3 + + + + + + + DADD + DEVICE Device Address + 0x00A + 8 + + + DADD + Device Address + 0 + 7 + + + ADDEN + Device Address Enable + 7 + 1 + + + + + STATUS + DEVICE Status + 0x00C + 8 + read-only + 0x40 + + + SPEED + Speed Status + 2 + 2 + read-only + + SPEEDSelect + + FS + Full-speed mode + 0x0 + + + HS + High-speed mode + 0x1 + + + LS + Low-speed mode + 0x2 + + + + + LINESTATE + USB Line State Status + 6 + 2 + read-only + + LINESTATESelect + + 0 + SE0/RESET + 0x0 + + + 1 + FS-J or LS-K State + 0x1 + + + 2 + FS-K or LS-J State + 0x2 + + + + + + + FSMSTATUS + Finite State Machine Status + 0x00D + 8 + read-only + 0x01 + + + FSMSTATE + Fine State Machine Status + 0 + 7 + read-only + + FSMSTATESelect + + OFF + OFF (L3). It corresponds to the powered-off, disconnected, and disabled state + 0x1 + + + ON + ON (L0). It corresponds to the Idle and Active states + 0x2 + + + SUSPEND + SUSPEND (L2) + 0x4 + + + SLEEP + SLEEP (L1) + 0x8 + + + DNRESUME + DNRESUME. Down Stream Resume. + 0x10 + + + UPRESUME + UPRESUME. Up Stream Resume. + 0x20 + + + RESET + RESET. USB lines Reset. + 0x40 + + + + + + + FNUM + DEVICE Device Frame Number + 0x010 + 16 + read-only + + + MFNUM + Micro Frame Number + 0 + 3 + read-only + + + FNUM + Frame Number + 3 + 11 + read-only + + + FNCERR + Frame Number CRC Error + 15 + 1 + read-only + + + + + INTENCLR + DEVICE Device Interrupt Enable Clear + 0x014 + 16 + + + SUSPEND + Suspend Interrupt Enable + 0 + 1 + + + MSOF + Micro Start of Frame Interrupt Enable in High Speed Mode + 1 + 1 + + + SOF + Start Of Frame Interrupt Enable + 2 + 1 + + + EORST + End of Reset Interrupt Enable + 3 + 1 + + + WAKEUP + Wake Up Interrupt Enable + 4 + 1 + + + EORSM + End Of Resume Interrupt Enable + 5 + 1 + + + UPRSM + Upstream Resume Interrupt Enable + 6 + 1 + + + RAMACER + Ram Access Interrupt Enable + 7 + 1 + + + LPMNYET + Link Power Management Not Yet Interrupt Enable + 8 + 1 + + + LPMSUSP + Link Power Management Suspend Interrupt Enable + 9 + 1 + + + + + INTENSET + DEVICE Device Interrupt Enable Set + 0x018 + 16 + + + SUSPEND + Suspend Interrupt Enable + 0 + 1 + + + MSOF + Micro Start of Frame Interrupt Enable in High Speed Mode + 1 + 1 + + + SOF + Start Of Frame Interrupt Enable + 2 + 1 + + + EORST + End of Reset Interrupt Enable + 3 + 1 + + + WAKEUP + Wake Up Interrupt Enable + 4 + 1 + + + EORSM + End Of Resume Interrupt Enable + 5 + 1 + + + UPRSM + Upstream Resume Interrupt Enable + 6 + 1 + + + RAMACER + Ram Access Interrupt Enable + 7 + 1 + + + LPMNYET + Link Power Management Not Yet Interrupt Enable + 8 + 1 + + + LPMSUSP + Link Power Management Suspend Interrupt Enable + 9 + 1 + + + + + INTFLAG + DEVICE Device Interrupt Flag + 0x01C + 16 + + + SUSPEND + Suspend + 0 + 1 + + + MSOF + Micro Start of Frame in High Speed Mode + 1 + 1 + + + SOF + Start Of Frame + 2 + 1 + + + EORST + End of Reset + 3 + 1 + + + WAKEUP + Wake Up + 4 + 1 + + + EORSM + End Of Resume + 5 + 1 + + + UPRSM + Upstream Resume + 6 + 1 + + + RAMACER + Ram Access + 7 + 1 + + + LPMNYET + Link Power Management Not Yet + 8 + 1 + + + LPMSUSP + Link Power Management Suspend + 9 + 1 + + + + + EPINTSMRY + DEVICE End Point Interrupt Summary + 0x020 + 16 + read-only + + + EPINT0 + End Point 0 Interrupt + 0 + 1 + read-only + + + EPINT1 + End Point 1 Interrupt + 1 + 1 + read-only + + + EPINT2 + End Point 2 Interrupt + 2 + 1 + read-only + + + EPINT3 + End Point 3 Interrupt + 3 + 1 + read-only + + + EPINT4 + End Point 4 Interrupt + 4 + 1 + read-only + + + EPINT5 + End Point 5 Interrupt + 5 + 1 + read-only + + + EPINT6 + End Point 6 Interrupt + 6 + 1 + read-only + + + EPINT7 + End Point 7 Interrupt + 7 + 1 + read-only + + + + + DESCADD + Descriptor Address + 0x024 + 32 + + + DESCADD + Descriptor Address Value + 0 + 32 + + + + + PADCAL + USB PAD Calibration + 0x028 + 16 + + + TRANSP + USB Pad Transp calibration + 0 + 5 + + + TRANSN + USB Pad Transn calibration + 6 + 5 + + + TRIM + USB Pad Trim calibration + 12 + 3 + + + + + 8 + 0x20 + EPCFG%s + DEVICE End Point Configuration + 0x100 + 8 + + + EPTYPE0 + End Point Type0 + 0 + 3 + + + EPTYPE1 + End Point Type1 + 4 + 3 + + + NYETDIS + NYET Token Disable + 7 + 1 + + + + + 8 + 0x20 + EPSTATUSCLR%s + DEVICE End Point Pipe Status Clear + 0x104 + 8 + write-only + + + DTGLOUT + Data Toggle OUT Clear + 0 + 1 + write-only + + + DTGLIN + Data Toggle IN Clear + 1 + 1 + write-only + + + CURBK + Curren Bank Clear + 2 + 1 + write-only + + + STALLRQ0 + Stall 0 Request Clear + 4 + 1 + write-only + + + STALLRQ1 + Stall 1 Request Clear + 5 + 1 + write-only + + + BK0RDY + Bank 0 Ready Clear + 6 + 1 + write-only + + + BK1RDY + Bank 1 Ready Clear + 7 + 1 + write-only + + + + + 8 + 0x20 + EPSTATUSSET%s + DEVICE End Point Pipe Status Set + 0x105 + 8 + write-only + + + DTGLOUT + Data Toggle OUT Set + 0 + 1 + write-only + + + DTGLIN + Data Toggle IN Set + 1 + 1 + write-only + + + CURBK + Current Bank Set + 2 + 1 + write-only + + + STALLRQ0 + Stall 0 Request Set + 4 + 1 + write-only + + + STALLRQ1 + Stall 1 Request Set + 5 + 1 + write-only + + + BK0RDY + Bank 0 Ready Set + 6 + 1 + write-only + + + BK1RDY + Bank 1 Ready Set + 7 + 1 + write-only + + + + + 8 + 0x20 + EPSTATUS%s + DEVICE End Point Pipe Status + 0x106 + 8 + read-only + + + DTGLOUT + Data Toggle Out + 0 + 1 + read-only + + + DTGLIN + Data Toggle In + 1 + 1 + read-only + + + CURBK + Current Bank + 2 + 1 + read-only + + + STALLRQ0 + Stall 0 Request + 4 + 1 + read-only + + + STALLRQ1 + Stall 1 Request + 5 + 1 + read-only + + + BK0RDY + Bank 0 ready + 6 + 1 + read-only + + + BK1RDY + Bank 1 ready + 7 + 1 + read-only + + + + + 8 + 0x20 + EPINTFLAG%s + DEVICE End Point Interrupt Flag + 0x107 + 8 + + + TRCPT0 + Transfer Complete 0 + 0 + 1 + + + TRCPT1 + Transfer Complete 1 + 1 + 1 + + + TRFAIL0 + Error Flow 0 + 2 + 1 + + + TRFAIL1 + Error Flow 1 + 3 + 1 + + + RXSTP + Received Setup + 4 + 1 + + + STALL0 + Stall 0 In/out + 5 + 1 + + + STALL1 + Stall 1 In/out + 6 + 1 + + + + + 8 + 0x20 + EPINTENCLR%s + DEVICE End Point Interrupt Clear Flag + 0x108 + 8 + + + TRCPT0 + Transfer Complete 0 Interrupt Disable + 0 + 1 + + + TRCPT1 + Transfer Complete 1 Interrupt Disable + 1 + 1 + + + TRFAIL0 + Error Flow 0 Interrupt Disable + 2 + 1 + + + TRFAIL1 + Error Flow 1 Interrupt Disable + 3 + 1 + + + RXSTP + Received Setup Interrupt Disable + 4 + 1 + + + STALL0 + Stall 0 In/Out Interrupt Disable + 5 + 1 + + + STALL1 + Stall 1 In/Out Interrupt Disable + 6 + 1 + + + + + 8 + 0x20 + EPINTENSET%s + DEVICE End Point Interrupt Set Flag + 0x109 + 8 + + + TRCPT0 + Transfer Complete 0 Interrupt Enable + 0 + 1 + + + TRCPT1 + Transfer Complete 1 Interrupt Enable + 1 + 1 + + + TRFAIL0 + Error Flow 0 Interrupt Enable + 2 + 1 + + + TRFAIL1 + Error Flow 1 Interrupt Enable + 3 + 1 + + + RXSTP + Received Setup Interrupt Enable + 4 + 1 + + + STALL0 + Stall 0 In/out Interrupt enable + 5 + 1 + + + STALL1 + Stall 1 In/out Interrupt enable + 6 + 1 + + + + + + HOST + USB is Host + DEVICE + UsbHost + 0x0 + + CTRLA + Control A + 0x000 + 8 + + + SWRST + Software Reset + 0 + 1 + + + ENABLE + Enable + 1 + 1 + + + RUNSTDBY + Run in Standby Mode + 2 + 1 + + + MODE + Operating Mode + 7 + 1 + + MODESelect + + DEVICE + Device Mode + 0x0 + + + HOST + Host Mode + 0x1 + + + + + + + SYNCBUSY + Synchronization Busy + 0x002 + 8 + read-only + + + SWRST + Software Reset Synchronization Busy + 0 + 1 + read-only + + + ENABLE + Enable Synchronization Busy + 1 + 1 + read-only + + + + + QOSCTRL + USB Quality Of Service + 0x003 + 8 + 0x05 + + + CQOS + Configuration Quality of Service + 0 + 2 + + CQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + DQOS + Data Quality of Service + 2 + 2 + + DQOSSelect + + DISABLE + Background (no sensitive operation) + 0x0 + + + LOW + Sensitive Bandwidth + 0x1 + + + MEDIUM + Sensitive Latency + 0x2 + + + HIGH + Critical Latency + 0x3 + + + + + + + CTRLB + HOST Control B + 0x008 + 16 + + + RESUME + Send USB Resume + 1 + 1 + + + SPDCONF + Speed Configuration for Host + 2 + 2 + + SPDCONFSelect + + NORMAL + Normal mode:the host starts in full-speed mode and performs a high-speed reset to switch to the high speed mode if the downstream peripheral is high-speed capable. + 0x0 + + + FS + Full-speed:the host remains in full-speed mode whatever is the peripheral speed capability. Relevant in UTMI mode only. + 0x3 + + + + + TSTJ + Test mode J + 5 + 1 + + + TSTK + Test mode K + 6 + 1 + + + SOFE + Start of Frame Generation Enable + 8 + 1 + + + BUSRESET + Send USB Reset + 9 + 1 + + + VBUSOK + VBUS is OK + 10 + 1 + + + L1RESUME + Send L1 Resume + 11 + 1 + + + + + HSOFC + HOST Host Start Of Frame Control + 0x00A + 8 + + + FLENC + Frame Length Control + 0 + 4 + + + FLENCE + Frame Length Control Enable + 7 + 1 + + + + + STATUS + HOST Status + 0x00C + 8 + + + SPEED + Speed Status + 2 + 2 + + + LINESTATE + USB Line State Status + 6 + 2 + read-only + + + + + FSMSTATUS + Finite State Machine Status + 0x00D + 8 + read-only + 0x01 + + + FSMSTATE + Fine State Machine Status + 0 + 7 + read-only + + FSMSTATESelect + + OFF + OFF (L3). It corresponds to the powered-off, disconnected, and disabled state + 0x1 + + + ON + ON (L0). It corresponds to the Idle and Active states + 0x2 + + + SUSPEND + SUSPEND (L2) + 0x4 + + + SLEEP + SLEEP (L1) + 0x8 + + + DNRESUME + DNRESUME. Down Stream Resume. + 0x10 + + + UPRESUME + UPRESUME. Up Stream Resume. + 0x20 + + + RESET + RESET. USB lines Reset. + 0x40 + + + + + + + FNUM + HOST Host Frame Number + 0x010 + 16 + + + MFNUM + Micro Frame Number + 0 + 3 + + + FNUM + Frame Number + 3 + 11 + + + + + FLENHIGH + HOST Host Frame Length + 0x012 + 8 + read-only + + + FLENHIGH + Frame Length + 0 + 8 + read-only + + + + + INTENCLR + HOST Host Interrupt Enable Clear + 0x014 + 16 + + + HSOF + Host Start Of Frame Interrupt Disable + 2 + 1 + + + RST + BUS Reset Interrupt Disable + 3 + 1 + + + WAKEUP + Wake Up Interrupt Disable + 4 + 1 + + + DNRSM + DownStream to Device Interrupt Disable + 5 + 1 + + + UPRSM + Upstream Resume from Device Interrupt Disable + 6 + 1 + + + RAMACER + Ram Access Interrupt Disable + 7 + 1 + + + DCONN + Device Connection Interrupt Disable + 8 + 1 + + + DDISC + Device Disconnection Interrupt Disable + 9 + 1 + + + + + INTENSET + HOST Host Interrupt Enable Set + 0x018 + 16 + + + HSOF + Host Start Of Frame Interrupt Enable + 2 + 1 + + + RST + Bus Reset Interrupt Enable + 3 + 1 + + + WAKEUP + Wake Up Interrupt Enable + 4 + 1 + + + DNRSM + DownStream to the Device Interrupt Enable + 5 + 1 + + + UPRSM + Upstream Resume fromthe device Interrupt Enable + 6 + 1 + + + RAMACER + Ram Access Interrupt Enable + 7 + 1 + + + DCONN + Link Power Management Interrupt Enable + 8 + 1 + + + DDISC + Device Disconnection Interrupt Enable + 9 + 1 + + + + + INTFLAG + HOST Host Interrupt Flag + 0x01C + 16 + + + HSOF + Host Start Of Frame + 2 + 1 + + + RST + Bus Reset + 3 + 1 + + + WAKEUP + Wake Up + 4 + 1 + + + DNRSM + Downstream + 5 + 1 + + + UPRSM + Upstream Resume from the Device + 6 + 1 + + + RAMACER + Ram Access + 7 + 1 + + + DCONN + Device Connection + 8 + 1 + + + DDISC + Device Disconnection + 9 + 1 + + + + + PINTSMRY + HOST Pipe Interrupt Summary + 0x020 + 16 + read-only + + + EPINT0 + Pipe 0 Interrupt + 0 + 1 + read-only + + + EPINT1 + Pipe 1 Interrupt + 1 + 1 + read-only + + + EPINT2 + Pipe 2 Interrupt + 2 + 1 + read-only + + + EPINT3 + Pipe 3 Interrupt + 3 + 1 + read-only + + + EPINT4 + Pipe 4 Interrupt + 4 + 1 + read-only + + + EPINT5 + Pipe 5 Interrupt + 5 + 1 + read-only + + + EPINT6 + Pipe 6 Interrupt + 6 + 1 + read-only + + + EPINT7 + Pipe 7 Interrupt + 7 + 1 + read-only + + + + + DESCADD + Descriptor Address + 0x024 + 32 + + + DESCADD + Descriptor Address Value + 0 + 32 + + + + + PADCAL + USB PAD Calibration + 0x028 + 16 + + + TRANSP + USB Pad Transp calibration + 0 + 5 + + + TRANSN + USB Pad Transn calibration + 6 + 5 + + + TRIM + USB Pad Trim calibration + 12 + 3 + + + + + 8 + 0x20 + PCFG%s + HOST End Point Configuration + 0x100 + 8 + + + PTOKEN + Pipe Token + 0 + 2 + + + BK + Pipe Bank + 2 + 1 + + + PTYPE + Pipe Type + 3 + 3 + + + + + 8 + 0x20 + BINTERVAL%s + HOST Bus Access Period of Pipe + 0x103 + 8 + + + BITINTERVAL + Bit Interval + 0 + 8 + + + + + 8 + 0x20 + PSTATUSCLR%s + HOST End Point Pipe Status Clear + 0x104 + 8 + write-only + + + DTGL + Data Toggle clear + 0 + 1 + read-only + + + CURBK + Curren Bank clear + 2 + 1 + write-only + + + PFREEZE + Pipe Freeze Clear + 4 + 1 + write-only + + + BK0RDY + Bank 0 Ready Clear + 6 + 1 + write-only + + + BK1RDY + Bank 1 Ready Clear + 7 + 1 + write-only + + + + + 8 + 0x20 + PSTATUSSET%s + HOST End Point Pipe Status Set + 0x105 + 8 + write-only + + + DTGL + Data Toggle Set + 0 + 1 + write-only + + + CURBK + Current Bank Set + 2 + 1 + write-only + + + PFREEZE + Pipe Freeze Set + 4 + 1 + write-only + + + BK0RDY + Bank 0 Ready Set + 6 + 1 + write-only + + + BK1RDY + Bank 1 Ready Set + 7 + 1 + write-only + + + + + 8 + 0x20 + PSTATUS%s + HOST End Point Pipe Status + 0x106 + 8 + read-only + + + DTGL + Data Toggle + 0 + 1 + read-only + + + CURBK + Current Bank + 2 + 1 + read-only + + + PFREEZE + Pipe Freeze + 4 + 1 + read-only + + + BK0RDY + Bank 0 ready + 6 + 1 + read-only + + + BK1RDY + Bank 1 ready + 7 + 1 + read-only + + + + + 8 + 0x20 + PINTFLAG%s + HOST Pipe Interrupt Flag + 0x107 + 8 + + + TRCPT0 + Transfer Complete 0 Interrupt Flag + 0 + 1 + + + TRCPT1 + Transfer Complete 1 Interrupt Flag + 1 + 1 + + + TRFAIL + Error Flow Interrupt Flag + 2 + 1 + + + PERR + Pipe Error Interrupt Flag + 3 + 1 + + + TXSTP + Transmit Setup Interrupt Flag + 4 + 1 + + + STALL + Stall Interrupt Flag + 5 + 1 + + + + + 8 + 0x20 + PINTENCLR%s + HOST Pipe Interrupt Flag Clear + 0x108 + 8 + + + TRCPT0 + Transfer Complete 0 Disable + 0 + 1 + + + TRCPT1 + Transfer Complete 1 Disable + 1 + 1 + + + TRFAIL + Error Flow Interrupt Disable + 2 + 1 + + + PERR + Pipe Error Interrupt Disable + 3 + 1 + + + TXSTP + Transmit Setup Interrupt Disable + 4 + 1 + + + STALL + Stall Inetrrupt Disable + 5 + 1 + + + + + 8 + 0x20 + PINTENSET%s + HOST Pipe Interrupt Flag Set + 0x109 + 8 + + + TRCPT0 + Transfer Complete 0 Interrupt Enable + 0 + 1 + + + TRCPT1 + Transfer Complete 1 Interrupt Enable + 1 + 1 + + + TRFAIL + Error Flow Interrupt Enable + 2 + 1 + + + PERR + Pipe Error Interrupt Enable + 3 + 1 + + + TXSTP + Transmit Setup Interrupt Enable + 4 + 1 + + + STALL + Stall Interrupt Enable + 5 + 1 + + + + + + + + WDT + 2.0.0 + Watchdog Timer + WDT + WDT_ + 0x40001000 + + 0 + 0x10 + registers + + + WDT + 2 + + + + CTRL + Control + 0x0 + 8 + + + ENABLE + Enable + 1 + 1 + + + WEN + Watchdog Timer Window Mode Enable + 2 + 1 + + + ALWAYSON + Always-On + 7 + 1 + + + + + CONFIG + Configuration + 0x1 + 8 + 0xBB + + + PER + Time-Out Period + 0 + 4 + + PERSelect + + 8 + 8 clock cycles + 0x0 + + + 16 + 16 clock cycles + 0x1 + + + 32 + 32 clock cycles + 0x2 + + + 64 + 64 clock cycles + 0x3 + + + 128 + 128 clock cycles + 0x4 + + + 256 + 256 clock cycles + 0x5 + + + 512 + 512 clock cycles + 0x6 + + + 1K + 1024 clock cycles + 0x7 + + + 2K + 2048 clock cycles + 0x8 + + + 4K + 4096 clock cycles + 0x9 + + + 8K + 8192 clock cycles + 0xa + + + 16K + 16384 clock cycles + 0xb + + + + + WINDOW + Window Mode Time-Out Period + 4 + 4 + + WINDOWSelect + + 8 + 8 clock cycles + 0x0 + + + 16 + 16 clock cycles + 0x1 + + + 32 + 32 clock cycles + 0x2 + + + 64 + 64 clock cycles + 0x3 + + + 128 + 128 clock cycles + 0x4 + + + 256 + 256 clock cycles + 0x5 + + + 512 + 512 clock cycles + 0x6 + + + 1K + 1024 clock cycles + 0x7 + + + 2K + 2048 clock cycles + 0x8 + + + 4K + 4096 clock cycles + 0x9 + + + 8K + 8192 clock cycles + 0xa + + + 16K + 16384 clock cycles + 0xb + + + + + + + EWCTRL + Early Warning Interrupt Control + 0x2 + 8 + 0x0B + + + EWOFFSET + Early Warning Interrupt Time Offset + 0 + 4 + + EWOFFSETSelect + + 8 + 8 clock cycles + 0x0 + + + 16 + 16 clock cycles + 0x1 + + + 32 + 32 clock cycles + 0x2 + + + 64 + 64 clock cycles + 0x3 + + + 128 + 128 clock cycles + 0x4 + + + 256 + 256 clock cycles + 0x5 + + + 512 + 512 clock cycles + 0x6 + + + 1K + 1024 clock cycles + 0x7 + + + 2K + 2048 clock cycles + 0x8 + + + 4K + 4096 clock cycles + 0x9 + + + 8K + 8192 clock cycles + 0xa + + + 16K + 16384 clock cycles + 0xb + + + + + + + INTENCLR + Interrupt Enable Clear + 0x4 + 8 + + + EW + Early Warning Interrupt Enable + 0 + 1 + + + + + INTENSET + Interrupt Enable Set + 0x5 + 8 + + + EW + Early Warning Interrupt Enable + 0 + 1 + + + + + INTFLAG + Interrupt Flag Status and Clear + 0x6 + 8 + + + EW + Early Warning + 0 + 1 + + + + + STATUS + Status + 0x7 + 8 + read-only + + + SYNCBUSY + Synchronization Busy + 7 + 1 + read-only + + + + + CLEAR + Clear + 0x8 + 8 + write-only + + + CLEAR + Watchdog Clear + 0 + 8 + write-only + + CLEARSelect + + KEY + Clear Key + 0xa5 + + + + + + + + + From 6c88c58438ccb99fc23bab60e771d3678cc1baba Mon Sep 17 00:00:00 2001 From: Jacob Young Date: Wed, 15 Jul 2020 15:34:50 -0400 Subject: [PATCH 06/26] Everything is broken. --- core/arm/CMSIS/Core/Include/core_cm0plus.h | 34 +- core/arm/README.md | 2 +- core/arm/arm.c | 161 +++ core/arm/arm.h | 29 + core/arm/armcpu.c | 823 +++++++---- core/arm/armcpu.h | 35 +- core/arm/armmem.c | 1452 +++++++++++++++++++- core/arm/armmem.h | 144 +- core/arm/armstate.c | 21 - core/arm/armstate.h | 30 +- core/arm/samd21a/include/samd21e18a.h | 12 + core/arm/spscqueue.c | 80 ++ core/arm/spscqueue.h | 43 + core/arm/sync.c | 111 +- core/arm/sync.h | 15 +- core/asic.c | 2 + core/coproc.c | 36 +- core/coproc.h | 11 +- core/defines.h | 3 + core/spi.c | 13 +- core/uart.c | 15 +- gui/qt/CEmu.pro | 5 +- gui/qt/CMakeLists.txt | 7 +- gui/qt/mainwindow.cpp | 10 +- gui/qt/mainwindow.h | 3 + gui/qt/mainwindow.ui | 111 +- gui/qt/settings.cpp | 22 +- 27 files changed, 2795 insertions(+), 435 deletions(-) create mode 100644 core/arm/arm.c create mode 100644 core/arm/arm.h delete mode 100644 core/arm/armstate.c create mode 100644 core/arm/spscqueue.c create mode 100644 core/arm/spscqueue.h diff --git a/core/arm/CMSIS/Core/Include/core_cm0plus.h b/core/arm/CMSIS/Core/Include/core_cm0plus.h index b9377e8c7..0ad5f074a 100644 --- a/core/arm/CMSIS/Core/Include/core_cm0plus.h +++ b/core/arm/CMSIS/Core/Include/core_cm0plus.h @@ -112,7 +112,9 @@ #endif +#ifndef NO_VOLATILE_CONST_IO #include "cmsis_compiler.h" /* CMSIS compiler specific defines */ +#endif #ifdef __cplusplus @@ -166,18 +168,27 @@ \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 */ +#ifndef NO_VOLATILE_CONST_IO + #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 */ + + /* following defines should be used for structure members */ + #define __IM volatile const /*! Defines 'read only' structure member permissions */ + #define __OM volatile /*! Defines 'write only' structure member permissions */ + #define __IOM volatile /*! Defines 'read / write' structure member permissions */ #else - #define __I volatile const /*!< Defines 'read only' permissions */ + #define __I /*!< Defines 'read only' permissions */ + #define __O /*!< Defines 'write only' permissions */ + #define __IO /*!< Defines 'read / write' permissions */ + #define __IM /*!< Defines 'read only' structure member permissions */ + #define __OM /*!< Defines 'write only' structure member permissions */ + #define __IOM /*!< Defines 'read / write' structure member permissions */ #endif -#define __O volatile /*!< Defines 'write only' permissions */ -#define __IO volatile /*!< Defines 'read / write' permissions */ - -/* following defines should be used for structure members */ -#define __IM volatile const /*! Defines 'read only' structure member permissions */ -#define __OM volatile /*! Defines 'write only' structure member permissions */ -#define __IOM volatile /*! Defines 'read / write' structure member permissions */ /*@} end of group Cortex-M0+ */ @@ -732,6 +743,7 @@ typedef struct #define __NVIC_SetPriorityGrouping(X) (void)(X) #define __NVIC_GetPriorityGrouping() (0U) +#ifndef NO_VOLATILE_CONST_IO /** \brief Enable Interrupt \details Enables a device specific interrupt in the NVIC interrupt controller. @@ -1070,7 +1082,7 @@ __STATIC_INLINE uint32_t SysTick_Config(uint32_t ticks) #endif /*@} end of CMSIS_Core_SysTickFunctions */ - +#endif diff --git a/core/arm/README.md b/core/arm/README.md index 4731356c7..788741e89 100644 --- a/core/arm/README.md +++ b/core/arm/README.md @@ -1 +1 @@ -[`CMSIS`](arm/CMSIS) and [`samd21a`](arm/samd21a) contain select files unzipped unmodified from [Atmel SAMD21 Series Device Support (1.3.395)](http://packs.download.atmel.com/#ATSAMD21E18A) and [CMSIS (Cortex Microcontroller Software Interface Standard) (5.4.0)](http://packs.download.atmel.com/#ARMCM0P) respectively. +[`CMSIS`](arm/CMSIS) and [`samd21a`](arm/samd21a) contain select files unzipped from [Atmel SAMD21 Series Device Support (1.3.395)](http://packs.download.atmel.com/#ATSAMD21E18A) and [CMSIS (Cortex Microcontroller Software Interface Standard) (5.4.0)](http://packs.download.atmel.com/#ARMCM0P) respectively and slightly modified. diff --git a/core/arm/arm.c b/core/arm/arm.c new file mode 100644 index 000000000..42f624deb --- /dev/null +++ b/core/arm/arm.c @@ -0,0 +1,161 @@ +#include "armstate.h" +#include "../defines.h" +#include "../os/os.h" + +#include +#include +#include +#include +#include + +static void reset(arm_t *arm, uint8_t rcause) { + sync_wake(&arm->sync); + arm_mem_reset(&arm->mem, rcause); + arm_cpu_reset(arm); + spsc_queue_clear(&arm->usart[0]); + spsc_queue_clear(&arm->usart[1]); +} + +static int arm_thrd(void *context) { + arm_t *arm = context; + reset(arm, PM_RCAUSE_POR); + while (sync_loop(&arm->sync)) { + uint8_t i = 0; + spsc_queue_entry_t peek; + uint16_t val; + do { + arm_cpu_execute(arm); + } while (++i); + peek = spsc_queue_peek(&arm->usart[0]); + if (unlikely(peek != SPSC_QUEUE_INVALID_ENTRY && + arm_mem_usart_recv(arm, 3, peek))) { + spsc_queue_entry_t entry = spsc_queue_dequeue(&arm->usart[0]); + (void)entry; + assert(entry == peek && "Already successfully peeked"); + } + if (unlikely(spsc_queue_flush(&arm->usart[1]) && + arm_mem_usart_send(arm, 3, &val))) { + bool success = spsc_queue_enqueue(&arm->usart[0], val); + (void)success; + assert(success && "Already successfully flushed, so can't fail"); + } + } + spsc_queue_destroy(&arm->usart[1]); + spsc_queue_destroy(&arm->usart[0]); + arm_mem_destroy(&arm->mem); + free(arm); + return 0; +} + +arm_t *arm_create(void) { + arm_t *arm = malloc(sizeof(arm_t)); + if (likely(arm)) { + if (likely(sync_init(&arm->sync))) { + if (likely(arm_mem_init(&arm->mem))) { + if (likely(spsc_queue_init(&arm->usart[0]))) { + if (likely(spsc_queue_init(&arm->usart[1]))) { + arm->debug = false; + if (likely(thrd_create(&arm->thrd, &arm_thrd, arm) == thrd_success)) { + return arm; + } + spsc_queue_destroy(&arm->usart[1]); + } + spsc_queue_destroy(&arm->usart[0]); + } + arm_mem_destroy(&arm->mem); + } + sync_destroy(&arm->sync); + } + free(arm); + } + return NULL; +} + +void arm_destroy(arm_t *arm) { + if (arm) { + sync_enter(&arm->sync); + arm->sync.run = false; + thrd_detach(arm->thrd); + sync_leave(&arm->sync); + } +} + +void arm_reset(arm_t *arm) { + sync_enter(&arm->sync); + reset(arm, PM_RCAUSE_EXT); + sync_leave(&arm->sync); +} + +bool arm_load(arm_t *arm, const char *path) { + bool success = false; + FILE *file = fopen_utf8(path, "rb"); + if (likely(file)) { + sync_enter(&arm->sync); + success = arm_mem_load_rom(&arm->mem, file); + fclose(file); + reset(arm, PM_RCAUSE_POR); + //arm->debug = true; + sync_leave(&arm->sync); + } + return success; +} + +void arm_spi_sel(arm_t *arm, bool low) { + sync_enter(&arm->sync); + sync_wake(&arm->sync); + //printf("%c\n", low ? 'L' : 'H'); + arm_mem_spi_sel(arm, 0, low); + sync_run_leave(&arm->sync); +} + +static void debug_byte(bool dir, unsigned char c) { + //printf("\x1b[%dm%02X\x1b[m", 94 + dir, c); + //fflush(stdout); +} + +static void debug_char(bool dir, char c) { + if (c >= ' ' && c <= '~') { + //printf("\x1b[%dm%c\x1b[m", 94 + dir, c); + //fflush(stdout); + } +} + +uint8_t arm_spi_peek(arm_t *arm, uint32_t *res) { + sync_enter(&arm->sync); + sync_wake(&arm->sync); + uint8_t bits = arm_mem_spi_peek(arm, 0, res); + if (bits == 8) { + debug_byte(true, *res); + } + sync_run_leave(&arm->sync); + return bits; +} + +uint8_t arm_spi_xfer(arm_t *arm, uint32_t val, uint32_t *res) { + sync_enter(&arm->sync); + sync_wake(&arm->sync); + debug_byte(false, val); + //printf("%02X ", val); + arm_mem_spi_xfer(arm, 0, val); + uint8_t bits = arm_mem_spi_peek(arm, 0, res); + if (bits == 8) { + debug_byte(true, *res); + } + //printf("<-> %02X\n", *res); + sync_run_leave(&arm->sync); + return bits; +} + +bool arm_usart_send(arm_t *arm, uint8_t val) { + bool success = spsc_queue_enqueue(&arm->usart[0], val); + if (likely(success)) { + (void)spsc_queue_flush(&arm->usart[0]); + } + return success; +} + +bool arm_usart_recv(arm_t *arm, uint8_t *val) { + spsc_queue_entry_t entry = spsc_queue_dequeue(&arm->usart[1]); + *val = entry; + return entry != SPSC_QUEUE_INVALID_ENTRY; +} diff --git a/core/arm/arm.h b/core/arm/arm.h new file mode 100644 index 000000000..98d331dad --- /dev/null +++ b/core/arm/arm.h @@ -0,0 +1,29 @@ +#ifndef ARM_H +#define ARM_H + +#include +#include + +typedef struct arm arm_t; + +#ifdef __cplusplus +extern "C" { +#endif + +arm_t *arm_create(void); +void arm_destroy(arm_t *arm); + +/* Thread-safe */ +void arm_reset(arm_t *arm); +bool arm_load(arm_t *arm, const char *path); +void arm_spi_sel(arm_t *arm, bool low); +uint8_t arm_spi_peek(arm_t *arm, uint32_t *res); +uint8_t arm_spi_xfer(arm_t *arm, uint32_t val, uint32_t *res); +bool arm_usart_send(arm_t *arm, uint8_t val); +bool arm_usart_recv(arm_t *arm, uint8_t *val); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index c93b4ef58..f94a8be9b 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -4,15 +4,18 @@ #include "armstate.h" #include "../defines.h" +#include #include #include -#ifdef __GCC_ASM_FLAG_OUTPUTS__ -# if defined(__i386) || defined(__x86_64__) || defined(_M_IX86) || defined(_M_IX64) -# define FLAGS_FROM_EXTENDED_X86_ASM 1 -# else -# define FLAGS_FROM_EXTENDED_X86_ASM 0 -# endif +#ifndef __has_builtin +# define __has_builtin(builtin) 0 +#endif + +#if defined(__GCC_ASM_FLAG_OUTPUTS__) && \ + (defined(__i386) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_IX64)) +# define FLAGS_FROM_EXTENDED_X86_ASM 1 #else # define FLAGS_FROM_EXTENDED_X86_ASM 0 #endif @@ -29,28 +32,57 @@ # define HAVE_BUILTIN_CONSTANT_P 0 #endif -void arm_cpu_reset(arm_state_t *state) { - memset(&state->cpu, 0, sizeof(state->cpu)); - state->cpu.sp = arm_mem_load_word(state, 0x2000); - state->cpu.pc = arm_mem_load_word(state, 0x2004) + 1; -} - -static uint32_t arm_bitcount_9(uint32_t x) { -#if defined(__POPCNT__) && (__has_builtin(__builtin_popcount) || __GNUC__ >= 4) +static uint8_t bitcount9(uint32_t x) { +#if __has_builtin(__builtin_popcount) || __GNUC__ >= 4 return __builtin_popcount(x & 0777); #else - uint64_t result = x & 0777, mask = UINT64_C(0x1111111111111111); - result *= UINT64_C(0001001001001); -#if defined(__x86_64__) || defined(_M_IX64) - __asm__("andq\t%1, %0\nimulq\t%1, %0" : "+r"(result) : "r"(mask) : "cc"); -#else - result &= mask; - result *= mask; + uint64_t res = x & 0777, mask = UINT64_C(0x1111111111111111); + res *= UINT64_C(0001001001001); +# if defined(__x86_64__) || defined(_M_IX64) + __asm__("andq\t%1, %0\nimulq\t%1, %0" : "+r"(res) : "r"(mask) : "cc"); +# else + res &= mask; + res *= mask; +# endif + return res >> 60; #endif - return result >> 60; +} + +static uint8_t lowestsetbit32(uint32_t x) { + assert(x && "invalid argument"); +#if __has_builtin(__builtin_ctz) || __GNUC__ >= 4 + return __builtin_ctz(x); +#else + uint32_t res; +# if defined(__i386) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_IX64) + __asm__("bsfl\t%1, %0" : "+r"(res) : "r"(x) : "cc"); +# else + res = 0; + while (!(x & 1)) { + x >>= 1; + ++res; + } +# endif + return res; #endif } +void arm_cpu_reset(arm_t *arm) { + arm_cpu_t *cpu = &arm->cpu; + memset(cpu, 0, sizeof(*cpu)); + cpu->sp = arm_mem_load_word(arm, cpu->scb.vtor + 0); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->pc = arm_mem_load_word(arm, cpu->scb.vtor + 4) + 1; + if (cpu->exc) { + cpu->exc = false; + return; + } +} + static uint32_t arm_movs(arm_cpu_t *cpu, uint32_t x) { #if FLAGS_FROM_EXTENDED_X86_ASM if (true @@ -167,16 +199,16 @@ static uint32_t arm_negs(arm_cpu_t *cpu, uint32_t x) { __asm__("negl\t%0" : "+r"(x), "=@cco"(cpu->v), "=@ccnc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) :: "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS - int32_t result; - cpu->v = __builtin_sub_overflow(0, (int32_t)x, &result); + int32_t res; + cpu->v = __builtin_sub_overflow(0, (int32_t)x, &res); cpu->c = x; return arm_movs(cpu, -x); #else - int64_t result = UINT64_C(0) - (int32_t)x; - cpu->v = result != (int32_t)result; - cpu->c = (uint32_t)result <= 0; + int64_t res = UINT64_C(0) - (int32_t)x; + cpu->v = res != (int32_t)res; + cpu->c = (uint32_t)res <= 0; //cpu->c = 0 >= x; - return arm_movs(cpu, result); + return arm_movs(cpu, res); #endif } @@ -185,16 +217,16 @@ static uint32_t arm_adds(arm_cpu_t *cpu, uint32_t x, uint32_t y) { __asm__("addl\t%5, %0" : "+r"(x), "=@cco"(cpu->v), "=@ccc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS - int32_t result; - cpu->v = __builtin_add_overflow((int32_t)x, (int32_t)y, &result); + int32_t res; + cpu->v = __builtin_add_overflow((int32_t)x, (int32_t)y, &res); cpu->c = __builtin_add_overflow(x, y, &x); return arm_movs(cpu, x); #else - int64_t result = (int64_t)(int32_t)x + (int32_t)y; - cpu->v = result != (int32_t)result; - cpu->c = (uint32_t)result < x; + int64_t res = (int64_t)(int32_t)x + (int32_t)y; + cpu->v = res != (int32_t)res; + cpu->c = (uint32_t)res < x; //cpu->c = x > ~y; - return arm_movs(cpu, result); + return arm_movs(cpu, res); #endif } @@ -203,16 +235,16 @@ static uint32_t arm_subs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { __asm__("subl\t%5, %0" : "+r"(x), "=@cco"(cpu->v), "=@ccnc"(cpu->c), "=@ccz"(cpu->z), "=@ccs"(cpu->n) : "ir"(y) : "cc"); return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS - int32_t result; - cpu->v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &result); + int32_t res; + cpu->v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &res); cpu->c = !__builtin_sub_overflow(x, y, &x); return arm_movs(cpu, x); #else - int64_t result = (int64_t)(int32_t)x - (int32_t)y; - cpu->v = result != (int32_t)result; - cpu->c = (uint32_t)result <= x; + int64_t res = (int64_t)(int32_t)x - (int32_t)y; + cpu->v = res != (int32_t)res; + cpu->c = (uint32_t)res <= x; //cpu->c = x >= y; - return arm_movs(cpu, result); + return arm_movs(cpu, res); #endif } @@ -222,17 +254,17 @@ static uint32_t arm_adcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS bool carry = cpu->c; - int32_t result; - cpu->v = __builtin_add_overflow(x, y, &result); - cpu->v |= __builtin_add_overflow(result, carry, &result); + int32_t res; + cpu->v = __builtin_add_overflow(x, y, &res); + cpu->v |= __builtin_add_overflow(res, carry, &res); cpu->c = __builtin_add_overflow(x, y, &x); cpu->c |= __builtin_add_overflow(x, carry, &x); return arm_movs(cpu, x); #else - int64_t result = (uint64_t)(int32_t)x + (int32_t)y + cpu->c; - cpu->v = result != (int32_t)result; + int64_t res = (uint64_t)(int32_t)x + (int32_t)y + cpu->c; + cpu->v = res != (int32_t)res; cpu->c = ((uint64_t)x + y + cpu->c) >> 32; - return arm_movs(cpu, result); + return arm_movs(cpu, res); #endif } @@ -242,17 +274,17 @@ static uint32_t arm_sbcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { return x; #elif FLAGS_FROM_OVERFLOW_BUILTINS bool borrow = !cpu->c; - int32_t result; - cpu->v = __builtin_sub_overflow(x, y, &result); - cpu->v |= __builtin_sub_overflow(result, borrow, &result); + int32_t res; + cpu->v = __builtin_sub_overflow(x, y, &res); + cpu->v |= __builtin_sub_overflow(res, borrow, &res); cpu->c = __builtin_sub_overflow(x, y, &x); cpu->c |= __builtin_sub_overflow(x, borrow, &x); return arm_movs(cpu, x); #else - int64_t result = (uint64_t)(int32_t)x - (int32_t)y - !cpu->c; - cpu->v = result != (int32_t)result; + int64_t res = (uint64_t)(int32_t)x - (int32_t)y - !cpu->c; + cpu->v = res != (int32_t)res; cpu->c = ((uint64_t)x - y - !cpu->c) >> 32; - return arm_movs(cpu, result); + return arm_movs(cpu, res); #endif } @@ -275,45 +307,319 @@ static int16_t arm_revsh(uint32_t x) { (x << 8 & UINT32_C(0x0000FF00)); } -static void arm_exception(arm_exception_number_t type) { - (void)type; - abort(); +static void arm_cpu_tick(arm_t *arm) { + arm_systick_t *systick = &arm->cpu.systick; + if (likely(systick->ctrl & SysTick_CTRL_ENABLE_Msk)) { + if (unlikely(!systick->val)) { + systick->val = systick->load; + } else if (unlikely(!--systick->val)) { + systick->ctrl |= SysTick_CTRL_COUNTFLAG_Msk; + if (likely(systick->ctrl & SysTick_CTRL_TICKINT_Msk)) { + arm->cpu.scb.icsr |= SCB_ICSR_PENDSTSET_Msk; + } + } + } +} + +bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) { + arm_cpu_t *cpu = &arm->cpu; + arm_exception_number_t curexc = + (cpu->scb.icsr & SCB_ICSR_VECTACTIVE_Msk) >> + SCB_ICSR_VECTACTIVE_Pos; + uint32_t sp = cpu->sp; + bool align = sp >> 2 & 1; + assert(exc > ARM_Thread_Mode && + exc < ARM_Invalid_Exception && + "Invalid exception"); + if (cpu->active & 1 << exc) { + return false; + } + if (arm->debug && exc == ARM_Exception_HardFault) { + asm("int3"); + } + if (cpu->exc) { + cpu->exc = false; + cpu->pc = 0; + if (arm->debug) { + asm("int3"); + } + return false; + } + arm_cpu_tick(arm); + cpu->exc = true; + sp -= 0x20; + sp &= ~7; + arm_mem_store_word(arm, cpu->r0, sp + 0x00); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->r1, sp + 0x04); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->r2, sp + 0x08); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->r3, sp + 0x0C); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->ip, sp + 0x10); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->lr, sp + 0x14); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->pc - 2, sp + 0x18); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + arm_mem_store_word(arm, cpu->n << 31 | + cpu->z << 30 | + cpu->c << 29 | + cpu->v << 28 | + (~cpu->pc & 1) << 24 | + align << 9 | + curexc << 0, + sp + 0x1C); + if (!cpu->exc) { + cpu->exc = true; + return false; + } + uint32_t pc = arm_mem_load_word(arm, cpu->scb.vtor + (exc << 2)) + 1; + if (!pc || pc >= UINT32_C(0x80000000)) { + asm("int3"); + } + if (!cpu->exc) { + cpu->exc = true; + return false; + } + if (unlikely(curexc != ARM_Thread_Mode)) { + cpu->lr = -15; + cpu->sp = sp; + } else if (unlikely(cpu->spsel)) { + cpu->lr = -3; + cpu->sp = cpu->altsp; + cpu->altsp = sp; + cpu->spsel = false; + } else { + cpu->lr = -7; + cpu->sp = sp; + } + cpu->scb.icsr = (cpu->scb.icsr & ~SCB_ICSR_VECTACTIVE_Msk) | + (exc & SCB_ICSR_VECTACTIVE_Msk) << SCB_ICSR_VECTACTIVE_Pos; + cpu->active |= 1 << exc; + cpu->pc = pc; + return true; +} + +static void arm_cpu_interwork(arm_t *arm, uint32_t addr) { + arm_cpu_t *cpu = &arm->cpu; + arm_exception_number_t curexc = + (cpu->scb.icsr & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos; + if (likely(curexc == ARM_Thread_Mode || addr >> 28 != 0xF)) { + cpu->pc = addr + 1; + } else { + // Exception Return + uint32_t sp, val; + assert(!~(addr | 0xF) && cpu->active & 1 << curexc && + "Unpredictable exception return"); + cpu->active &= ~(1 << curexc); + switch (addr) { + case -15: + assert(cpu->active && "Unpredictable exception return"); + sp = cpu->sp; + cpu->spsel = false; + break; + case -7: + assert(!cpu->active && "Unpredictable exception return"); + sp = cpu->sp; + cpu->spsel = false; + break; + case -3: + assert(!cpu->active && "Unpredictable exception return"); + sp = cpu->altsp; + cpu->altsp = cpu->sp; + cpu->spsel = true; + break; + default: + assert(false && "Unpredictable exception return"); + } + cpu->r0 = arm_mem_load_word(arm, sp + 0x00); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->r1 = arm_mem_load_word(arm, sp + 0x04); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->r2 = arm_mem_load_word(arm, sp + 0x08); + if (cpu->exc) { + if (unlikely(cpu->pc & 1)) { + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; + } + cpu->exc = false; + return; + } + cpu->r3 = arm_mem_load_word(arm, sp + 0x0C); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->ip = arm_mem_load_word(arm, sp + 0x10); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->lr = arm_mem_load_word(arm, sp + 0x14); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->pc = arm_mem_load_word(arm, sp + 0x18) + 1; + if (!cpu->pc || cpu->pc >= UINT32_C(0x80000000)) { + asm("int3"); + } + assert(cpu->pc & 1 && "Unpredictable exception return"); + if (cpu->exc) { + cpu->exc = false; + return; + } + val = arm_mem_load_word(arm, sp + 0x1C); + if (cpu->exc) { + cpu->exc = false; + return; + } + cpu->n = val >> 31 & 1; + cpu->z = val >> 30 & 1; + cpu->c = val >> 29 & 1; + cpu->v = val >> 28 & 1; + cpu->pc += val >> 24 & 1; + cpu->sp = (sp + 0x20) | (val >> 7 & 4); + curexc = (val & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos; + switch (addr) { + case -15: + assert(curexc != ARM_Thread_Mode && "Unpredictable exception return"); + cpu->scb.icsr = (cpu->scb.icsr & ~SCB_ICSR_VECTACTIVE_Msk) | + curexc << SCB_ICSR_VECTACTIVE_Pos; + break; + case -7: + case -3: + assert(curexc == ARM_Thread_Mode && "Unpredictable exception return"); + cpu->scb.icsr &= ~SCB_ICSR_VECTACTIVE_Msk; + break; + } + } } -void arm_execute(arm_state_t *state) { - arm_cpu_t *cpu = &state->cpu; - uint32_t opcode; +void arm_cpu_execute(arm_t *arm) { + arm_cpu_t *cpu = &arm->cpu; + uint32_t icsr = cpu->scb.icsr, pc = cpu->pc - 2, opc, val; + if (arm->debug && pc >= UINT32_C(0x80000000)) { + asm("int3"); + } + uint8_t i; + arm_exception_number_t curexc = + (icsr & SCB_ICSR_VECTACTIVE_Msk) >> SCB_ICSR_VECTACTIVE_Pos; if (unlikely(cpu->pc & 1)) { - arm_exception(ARM_Exception_HardFault); + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; + } + if (unlikely(!cpu->pm && + (icsr & (SCB_ICSR_NMIPENDSET_Msk | + SCB_ICSR_PENDSVSET_Msk | + SCB_ICSR_PENDSTSET_Msk) || + cpu->nvic.ipr & cpu->nvic.ier))) { + if (icsr & SCB_ICSR_NMIPENDSET_Msk) { + if (likely(arm_cpu_exception(arm, ARM_Exception_NMI))) { + cpu->scb.icsr &= ~SCB_ICSR_NMIPENDSET_Msk; + cpu->exc = false; + return; + } + } else if (icsr & SCB_ICSR_PENDSVSET_Msk) { + if (likely(arm_cpu_exception(arm, ARM_Exception_PendSV))) { + cpu->scb.icsr &= ~SCB_ICSR_PENDSVSET_Msk; + cpu->exc = false; + return; + } + } else if (icsr & SCB_ICSR_PENDSTSET_Msk) { + if (likely(arm_cpu_exception(arm, ARM_Exception_SysTick))) { + cpu->scb.icsr &= ~SCB_ICSR_PENDSTSET_Msk; + cpu->exc = false; + return; + } + } else { + uint8_t src = lowestsetbit32(cpu->nvic.ipr & cpu->nvic.ier); + if (likely(arm_cpu_exception(arm, ARM_Exception_External + src))) { + arm_mem_update_pending(arm); + cpu->exc = false; + return; + } + } + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } + } + arm_cpu_tick(arm); + opc = arm_mem_load_half(arm, pc); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; } - opcode = arm_mem_load_half(state, cpu->pc - 2); cpu->pc += 2; - switch (opcode >> 12 & 0xF) { + //arm->debug |= pc == UINT32_C(0x10E00); + if (arm->debug) { + fprintf(stderr, "PC %08X %04X\n", pc, opc); + if (!arm->sync.slp) { + asm("int3"); + } + //if (pc == UINT32_C(0x000010BC) || + // pc == UINT32_C(0x000010CA) || + // pc == UINT32_C(0x000010F6) || + // pc == UINT32_C(0x00001104)) asm("int3"); + } + switch (opc >> 12 & 0xF) { case 0: case 1: - switch (opcode >> 11 & 3) { + switch (opc >> 11 & 3) { case 0: // Logical Shift Left - cpu->r[opcode >> 0 & 7] = arm_lsls(cpu, cpu->r[opcode >> 3 & 7], opcode >> 5 & 0x1F); + cpu->r[opc >> 0 & 7] = arm_lsls(cpu, cpu->r[opc >> 3 & 7], opc >> 6 & 0x1F); break; case 1: // Logical Shift Right - cpu->r[opcode >> 0 & 7] = arm_lsrs(cpu, cpu->r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + cpu->r[opc >> 0 & 7] = arm_lsrs(cpu, cpu->r[opc >> 3 & 7], (((opc >> 6) - 1) & 0x1F) + 1); break; case 2: // Arithmetic Shift Right - cpu->r[opcode >> 0 & 7] = arm_asrs(cpu, cpu->r[opcode >> 3 & 7], (((opcode >> 5) - 1) & 0x1F) + 1); + cpu->r[opc >> 0 & 7] = arm_asrs(cpu, cpu->r[opc >> 3 & 7], (((opc >> 6) - 1) & 0x1F) + 1); break; case 3: - switch (opcode >> 8 & 3) { + switch (opc >> 9 & 3) { case 0: // Add register - cpu->r[opcode >> 0 & 7] = arm_adds(cpu, cpu->r[opcode >> 3 & 7], cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = arm_adds(cpu, cpu->r[opc >> 3 & 7], cpu->r[opc >> 6 & 7]); break; case 1: // Subtract register - cpu->r[opcode >> 0 & 7] = arm_subs(cpu, cpu->r[opcode >> 3 & 7], cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = arm_subs(cpu, cpu->r[opc >> 3 & 7], cpu->r[opc >> 6 & 7]); break; case 2: // Add 3-bit immediate - cpu->r[opcode >> 0 & 7] = arm_adds(cpu, cpu->r[opcode >> 3 & 7], opcode >> 6 & 7); + cpu->r[opc >> 0 & 7] = arm_adds(cpu, cpu->r[opc >> 3 & 7], opc >> 6 & 7); break; case 3: // Subtract 3-bit immediate - cpu->r[opcode >> 0 & 7] = arm_subs(cpu, cpu->r[opcode >> 3 & 7], opcode >> 6 & 7); + cpu->r[opc >> 0 & 7] = arm_subs(cpu, cpu->r[opc >> 3 & 7], opc >> 6 & 7); break; } break; @@ -321,247 +627,251 @@ void arm_execute(arm_state_t *state) { break; case 2: case 3: - switch (opcode >> 11 & 3) { + switch (opc >> 11 & 3) { case 0: // Move - cpu->r[opcode >> 8 & 7] = arm_movs(cpu, opcode >> 0 & 0xFF); + cpu->r[opc >> 8 & 7] = arm_movs(cpu, opc >> 0 & 0xFF); break; case 1: // Compare - arm_subs(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + arm_subs(cpu, cpu->r[opc >> 8 & 7], opc >> 0 & 0xFF); break; case 2: // Add 8-bit immediate - cpu->r[opcode >> 8 & 7] = arm_adds(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + cpu->r[opc >> 8 & 7] = arm_adds(cpu, cpu->r[opc >> 8 & 7], opc >> 0 & 0xFF); break; case 3: // Subtract 8-bit immediate - cpu->r[opcode >> 8 & 7] = arm_subs(cpu, cpu->r[opcode >> 8 & 7], opcode >> 0 & 0xFF); + cpu->r[opc >> 8 & 7] = arm_subs(cpu, cpu->r[opc >> 8 & 7], opc >> 0 & 0xFF); break; } break; case 4: - switch (opcode >> 10 & 3) { + switch (opc >> 10 & 3) { case 0: // Data processing - switch (opcode >> 6 & 0xF) { + switch (opc >> 6 & 0xF) { case 0: // Bitwise AND - cpu->r[opcode >> 0 & 7] = arm_ands(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_ands(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 1: // Exclusive OR - cpu->r[opcode >> 0 & 7] = arm_eors(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_eors(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 2: // Logical Shift Left - cpu->r[opcode >> 0 & 7] = arm_lsls(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_lsls(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 3: // Logical Shift Right - cpu->r[opcode >> 0 & 7] = arm_lsrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_lsrs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 4: // Arithmetic Shift Right - cpu->r[opcode >> 0 & 7] = arm_asrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_asrs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 5: // Add with Carry - cpu->r[opcode >> 0 & 7] = arm_adcs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_adcs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 6: // Subtract with Carry - cpu->r[opcode >> 0 & 7] = arm_sbcs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_sbcs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 7: // Rotate Right - cpu->r[opcode >> 0 & 7] = arm_rors(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_rors(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 8: // Set flags on bitwise AND - arm_ands(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + arm_ands(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 9: // Reverse Subtract from 0 - cpu->r[opcode >> 0 & 7] = arm_negs(cpu, cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_negs(cpu, cpu->r[opc >> 3 & 7]); break; case 10: // Compare Registers - arm_subs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + arm_subs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 11: // Compare Negative - arm_adds(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + arm_adds(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 12: // Logical OR - cpu->r[opcode >> 0 & 7] = arm_orrs(cpu, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_orrs(cpu, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7]); break; case 13: // Multiply Two Registers - cpu->r[opcode >> 0 & 7] = arm_movs(cpu, cpu->r[opcode >> 0 & 7] * cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_movs(cpu, cpu->r[opc >> 0 & 7] * cpu->r[opc >> 3 & 7]); break; case 14: // Bit Clear - cpu->r[opcode >> 0 & 7] = arm_ands(cpu, cpu->r[opcode >> 0 & 7], ~cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_ands(cpu, cpu->r[opc >> 0 & 7], ~cpu->r[opc >> 3 & 7]); break; case 15: // Bitwise NOT - cpu->r[opcode >> 0 & 7] = arm_mvns(cpu, cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_mvns(cpu, cpu->r[opc >> 3 & 7]); break; } break; case 1: // Special data instructions and branch and exchange - switch (opcode >> 8 & 3) { + switch (opc >> 8 & 3) { case 0: // Add Registers - cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] += cpu->r[opcode >> 1 & 7]; + cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] += cpu->r[opc >> 3 & 0xF]; break; case 1: // Compare Registers - arm_subs(cpu, cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)], cpu->r[opcode >> 1 & 7]); + arm_subs(cpu, cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)], cpu->r[opc >> 3 & 0xF]); break; case 2: // Move Registers - cpu->r[(opcode >> 4 & 8) | (opcode >> 0 & 7)] = cpu->r[opcode >> 1 & 7]; + cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] = cpu->r[opc >> 3 & 0xF]; break; - case 3: { // Branch (with Link) and Exchange - uint32_t address = cpu->r[opcode >> 3 & 0xF]; - if (unlikely(opcode >> 7 & 1)) { // Branch with Link and Exchange + case 3: // Branch (with Link) and Exchange + val = cpu->r[opc >> 3 & 0xF]; + if (unlikely(opc >> 7 & 1)) { // Branch with Link and Exchange cpu->lr = cpu->pc - 1; - } else if (unlikely(cpu->mode && address >> 28 == 0xF)) { - // Exception Return - abort(); + cpu->pc = val + 1; + } else { + arm_cpu_interwork(arm, val); } - cpu->pc = address + 1; break; - } } break; default: // Load from Literal Pool - cpu->r[opcode >> 8 & 7] = arm_mem_load_word(state, ((cpu->pc >> 2) + (opcode & 0xFF)) << 2); + cpu->r[opc >> 8 & 7] = arm_mem_load_word(arm, ((cpu->pc >> 2) + (opc & 0xFF)) << 2); break; } break; case 5: - switch (opcode >> 9 & 7) { + switch (opc >> 9 & 7) { case 0: // Store Register - arm_mem_store_word(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + arm_mem_store_word(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 1: // Store Register Halfword - arm_mem_store_half(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + arm_mem_store_half(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 2: // Store Register Byte - arm_mem_store_byte(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + arm_mem_store_byte(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 3: // Load Register Signed Byte - cpu->r[opcode >> 0 & 7] = (int8_t)arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = (int8_t)arm_mem_load_byte(arm, cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 4: // Load Register - cpu->r[opcode >> 0 & 7] = arm_mem_load_word(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = arm_mem_load_word(arm, cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 5: // Load Register Halfword - cpu->r[opcode >> 0 & 7] = arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = arm_mem_load_half(arm, cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 6: // Load Register Byte - cpu->r[opcode >> 0 & 7] = arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = arm_mem_load_byte(arm, cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; case 7: // Load Register Signed Halfword - cpu->r[opcode >> 0 & 7] = (int16_t)arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + cpu->r[opcode >> 6 & 7]); + cpu->r[opc >> 0 & 7] = (int16_t)arm_mem_load_half(arm, cpu->r[opc >> 3 & 7] + cpu->r[opc >> 6 & 7]); break; } break; case 6: - if (opcode >> 11 & 1) { // Load Register - cpu->r[opcode >> 0 & 7] = arm_mem_load_word(state, cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + if (opc >> 11 & 1) { // Load Register + cpu->r[opc >> 0 & 7] = arm_mem_load_word(arm, cpu->r[opc >> 3 & 7] + ((opc >> 6 & 0x1F) << 2)); } else { // Store Register - arm_mem_store_word(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 2)); + arm_mem_store_word(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + ((opc >> 6 & 0x1F) << 2)); } break; case 7: - if (opcode >> 11 & 1) { // Load Register Byte - cpu->r[opcode >> 0 & 7] = arm_mem_load_byte(state, cpu->r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + if (opc >> 11 & 1) { // Load Register Byte + cpu->r[opc >> 0 & 7] = arm_mem_load_byte(arm, cpu->r[opc >> 3 & 7] + (opc >> 6 & 0x1F)); } else { // Store Register Byte - arm_mem_store_byte(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + (opcode >> 6 & 0x1F)); + arm_mem_store_byte(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + (opc >> 6 & 0x1F)); } break; case 8: - if (opcode >> 11 & 1) { // Load Register Halfword - cpu->r[opcode >> 0 & 7] = arm_mem_load_half(state, cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + if (opc >> 11 & 1) { // Load Register Halfword + cpu->r[opc >> 0 & 7] = arm_mem_load_half(arm, cpu->r[opc >> 3 & 7] + ((opc >> 6 & 0x1F) << 1)); } else { // Store Register Halfword - arm_mem_store_half(state, cpu->r[opcode >> 0 & 7], cpu->r[opcode >> 3 & 7] + ((opcode >> 6 & 0x1F) << 1)); + arm_mem_store_half(arm, cpu->r[opc >> 0 & 7], cpu->r[opc >> 3 & 7] + ((opc >> 6 & 0x1F) << 1)); } break; case 9: - if (opcode >> 11 & 1) { // Load Register SP relative - cpu->r[opcode >> 8 & 7] = arm_mem_load_word(state, cpu->sp + ((opcode >> 0 & 0xFF) << 2)); + if (opc >> 11 & 1) { // Load Register SP relative + cpu->r[opc >> 8 & 7] = arm_mem_load_word(arm, cpu->sp + ((opc >> 0 & 0xFF) << 2)); } else { // Store Register SP relative - arm_mem_store_word(state, cpu->r[opcode >> 8 & 7], cpu->sp + ((opcode >> 0 & 0xFF) << 2)); + arm_mem_store_word(arm, cpu->r[opc >> 8 & 7], cpu->sp + ((opc >> 0 & 0xFF) << 2)); } break; case 10: // Generate SP/PC - cpu->r[opcode >> 8 & 7] = cpu->r[opcode >> 11 & 1 ? 13 : 15] + ((opcode >> 0 & 0xFF) << 2); + cpu->r[opc >> 8 & 7] = cpu->r[opc >> 11 & 1 ? 13 : 15] + ((opc >> 0 & 0xFF) << 2); break; case 11: // Miscellaneous 16-bit instructions - switch (opcode >> 9 & 7) { + switch (opc >> 9 & 7) { case 0: - switch (opcode >> 7 & 3) { + switch (opc >> 7 & 3) { case 0: // Add Immediate to SP - cpu->sp += (opcode & 0x7F) << 2; + cpu->sp += (opc & 0x7F) << 2; break; case 1: // Subtract Immediate from SP - cpu->sp -= (opcode & 0x7F) << 2; + cpu->sp -= (opc & 0x7F) << 2; break; } break; case 1: - switch (opcode >> 6 & 7) { + switch (opc >> 6 & 7) { case 0: // Signed Extend Halfword - cpu->r[opcode >> 0 & 7] = (int16_t)cpu->r[opcode >> 3 & 7]; + cpu->r[opc >> 0 & 7] = (int16_t)cpu->r[opc >> 3 & 7]; break; case 1: // Signed Extend Byte - cpu->r[opcode >> 0 & 7] = (int8_t)cpu->r[opcode >> 3 & 7]; + cpu->r[opc >> 0 & 7] = (int8_t)cpu->r[opc >> 3 & 7]; break; case 2: // Unsigned Extend Halfword - cpu->r[opcode >> 0 & 7] = (uint16_t)cpu->r[opcode >> 3 & 7]; + cpu->r[opc >> 0 & 7] = (uint16_t)cpu->r[opc >> 3 & 7]; break; case 3: // Unsigned Extend Byte - cpu->r[opcode >> 0 & 7] = (uint8_t)cpu->r[opcode >> 3 & 7]; + cpu->r[opc >> 0 & 7] = (uint8_t)cpu->r[opc >> 3 & 7]; break; } break; - case 2: { // Push Multiple Registers - uint32_t address = cpu->sp -= (arm_bitcount_9(opcode) << 2); + case 2: // Push Multiple Registers + val = cpu->sp -= (bitcount9(opc) << 2); int i; for (i = 0; i < 8; i++) { - if (opcode >> i & 1) { - arm_mem_store_word(state, cpu->r[i], address); - address += 4; + if (opc >> i & 1) { + arm_mem_store_word(arm, cpu->r[i], val); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } + val += 4; } } - if (opcode >> i & 1) { - arm_mem_store_word(state, cpu->lr, address); + if (opc >> i & 1) { + arm_mem_store_word(arm, cpu->lr, val); } break; - } case 3: - switch (opcode >> 5 & 0xF) { + switch (opc >> 5 & 0xF) { case 3: // Change Processor State - cpu->pm = opcode >> 4 & 1; + cpu->pm = opc >> 4 & 1; break; } break; case 5: - switch (opcode >> 6 & 7) { + switch (opc >> 6 & 7) { case 0: // Byte-Reverse Word - cpu->r[opcode >> 0 & 7] = arm_rev(cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_rev(cpu->r[opc >> 3 & 7]); break; case 1: // Byte-Reverse Packed Halfword - cpu->r[opcode >> 0 & 7] = arm_rev16(cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_rev16(cpu->r[opc >> 3 & 7]); break; case 3: // Byte-Reverse Signed Halfword - cpu->r[opcode >> 0 & 7] = arm_revsh(cpu->r[opcode >> 3 & 7]); + cpu->r[opc >> 0 & 7] = arm_revsh(cpu->r[opc >> 3 & 7]); break; } break; - case 6: { // Pop Multiple Registers - int i; + case 6: // Pop Multiple Registers for (i = 0; i < 8; i++) { - if (opcode >> i & 1) { - cpu->r[i] = arm_mem_load_word(state, cpu->sp); + if (opc >> i & 1) { + cpu->r[i] = arm_mem_load_word(arm, cpu->sp); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } cpu->sp += 4; } } - if (opcode >> i & 1) { - cpu->pc = arm_mem_load_word(state, cpu->sp) + 1; + if (opc >> i & 1) { + val = arm_mem_load_word(arm, cpu->sp); cpu->sp += 4; + arm_cpu_interwork(arm, val); } break; - } case 7: - switch (opcode >> 8 & 1) { + switch (opc >> 8 & 1) { case 0: // Breakpoint break; case 1: // Hints - switch (opcode >> 0 & 0xF) { + switch (opc >> 0 & 0xF) { case 0: - switch (opcode >> 4 & 0xF) { + switch (opc >> 4 & 0xF) { case 0: // No Operation hint break; case 1: // Yield hint @@ -581,167 +891,184 @@ void arm_execute(arm_state_t *state) { } break; case 12: - switch (opcode >> 11 & 1) { - case 0: { // Store multiple registers - uint32_t address = cpu->r[opcode >> 8 & 7]; - int i; + switch (opc >> 11 & 1) { + case 0: // Store multiple registers + val = cpu->r[opc >> 8 & 7]; for (i = 0; i < 8; i++) { - if (opcode >> i & 1) { - arm_mem_store_word(state, cpu->r[i], address); - address += 4; + if (opc >> i & 1) { + arm_mem_store_word(arm, cpu->r[i], val); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } + val += 4; } } - cpu->r[opcode >> 8 & 7] = address; + cpu->r[opc >> 8 & 7] = val; break; - } - case 1: { // Load multiple registers - uint32_t address = cpu->r[opcode >> 8 & 7]; - int i; + case 1: // Load multiple registers + val = cpu->r[opc >> 8 & 7]; for (i = 0; i < 8; i++) { - if (opcode >> i & 1) { - cpu->r[i] = arm_mem_load_word(state, address); - address += 4; + if (opc >> i & 1) { + cpu->r[i] = arm_mem_load_word(arm, val); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } + val += 4; } } - if (!(opcode >> (opcode >> 8 & 7) & 1)) { - cpu->r[opcode >> 8 & 7] = address; + if (!(opc >> (opc >> 8 & 7) & 1)) { + cpu->r[opc >> 8 & 7] = val; } break; - } } break; case 13: - switch (opcode >> 8 & 0xF) { // Conditional branch, and Supervisor Call + switch (opc >> 8 & 0xF) { // Conditional branch, and Supervisor Call case 0: // Branch Equal if (cpu->z) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 1: // Branch Not equal if (!cpu->z) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 2: // Branch Carry set if (cpu->c) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 3: // Branch Carry clear if (!cpu->c) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 4: // Branch Minus, negative if (cpu->n) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 5: // Branch Plus, positive or zero if (!cpu->n) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 6: // Branch Overflow if (cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 7: // Branch No overflow if (!cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 8: // Branch Unsigned higher if (cpu->c && !cpu->z) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 9: // Branch Unsigned lower or same if (!cpu->c || cpu->z) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 10: // Branch Signed greater than or equal if (cpu->n == cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 11: // Branch Signed less than if (cpu->n != cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 12: // Branch Signed greater than if (!cpu->z && cpu->n == cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; case 13: // Branch Signed less than or equal if (cpu->z || cpu->n != cpu->v) { - cpu->pc += ((int32_t)opcode << 24 >> 23) + 2; + cpu->pc += ((int32_t)opc << 24 >> 23) + 2; } break; default: // Permanently UNDEFINED - arm_exception(ARM_Exception_HardFault); - break; + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; case 15: // Supervisor Call - arm_exception(ARM_Exception_SVCall); - break; + arm_cpu_exception(arm, ARM_Exception_SVCall); + cpu->exc = false; + return; } break; case 14: - switch (opcode >> 11 & 1) { + switch (opc >> 11 & 1) { case 0: // Unconditional Branch - cpu->pc += ((int32_t)opcode << 21 >> 20) + 2; + cpu->pc += ((int32_t)opc << 21 >> 20) + 2; break; default: // UNDEFINED 32-bit Thumb instruction - opcode = opcode << 16 | arm_mem_load_half(state, cpu->pc - 2); + arm_cpu_tick(arm); + opc = opc << 16 | arm_mem_load_half(arm, cpu->pc - 2); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } cpu->pc += 2; - arm_exception(ARM_Exception_HardFault); - break; + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; } break; case 15: // 32-bit Thumb instruction. - opcode = opcode << 16 | arm_mem_load_half(state, cpu->pc - 2); + arm_cpu_tick(arm); + opc = opc << 16 | arm_mem_load_half(arm, cpu->pc - 2); + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } cpu->pc += 2; - if (!(opcode >> 27 & 1) && (opcode >> 15 & 1)) { - switch (opcode >> 12 & 5) { + if (!(opc >> 27 & 1) && (opc >> 15 & 1)) { + switch (opc >> 12 & 5) { case 0: - switch (opcode >> 20 & 0x7F) { + switch (opc >> 20 & 0x7F) { case 0x38: - case 0x39: { // Move to Special Register - uint32_t value = cpu->r[opcode >> 16 & 0xF]; - switch (opcode >> 0 & 0xFF) { + case 0x39: // Move to Special Register + val = cpu->r[opc >> 16 & 0xF]; + switch (opc >> 0 & 0xFF) { case 0x00: case 0x01: case 0x02: case 0x03: - cpu->v = value >> 28 & 1; - cpu->c = value >> 29 & 1; - cpu->z = value >> 30 & 1; - cpu->n = value >> 31 & 1; + cpu->v = val >> 28 & 1; + cpu->c = val >> 29 & 1; + cpu->z = val >> 30 & 1; + cpu->n = val >> 31 & 1; break; case 0x80: case 0x81: - *((opcode >> 0 & 1) == cpu->spsel ? &cpu->sp : &cpu->altsp) = value >> 0 & ~3; + *((opc >> 0 & 1) == cpu->spsel ? &cpu->sp : &cpu->altsp) = val >> 0 & ~3; break; case 0x10: - cpu->pm = value >> 0 & 1; + cpu->pm = val >> 0 & 1; break; case 0x14: - if (cpu->mode && cpu->spsel != (value >> 1 & 1)) { + if (likely(cpu->spsel != (val >> 1 & 1) && + curexc == ARM_Thread_Mode)) { uint32_t sp = cpu->sp; cpu->sp = cpu->altsp; cpu->altsp = sp; - cpu->spsel = value >> 1 & 1; + cpu->spsel = val >> 1 & 1; } break; } break; - } case 0x3B: // Miscellaneous control instructions - switch (opcode >> 4 & 0xF) { + switch (opc >> 4 & 0xF) { case 4: // Data Synchronization Barrier break; case 5: // Data Memory Barrier @@ -751,9 +1078,9 @@ void arm_execute(arm_state_t *state) { } break; case 0x3E: - case 0x3F: { // Move from Special Register - uint32_t value = 0; - switch (opcode >> 0 & 0xFF) { + case 0x3F: // Move from Special Register + val = 0; + switch (opc >> 0 & 0xFF) { case 0x00: case 0x01: case 0x03: @@ -761,47 +1088,57 @@ void arm_execute(arm_state_t *state) { case 0x05: case 0x06: case 0x07: - if (opcode >> 0 & 1) { - value |= cpu->excNum << 0; + if (opc >> 0 & 1) { + val |= curexc << 0; } - if (!(opcode >> 2 & 1)) { - value |= cpu->v << 28; - value |= cpu->c << 29; - value |= cpu->z << 30; - value |= cpu->n << 31; + if (!(opc >> 2 & 1)) { + val |= cpu->v << 28; + val |= cpu->c << 29; + val |= cpu->z << 30; + val |= cpu->n << 31; } break; case 0x08: case 0x09: - value = (opcode >> 0 & 1) == cpu->spsel ? cpu->sp : cpu->altsp; + val = (opc >> 0 & 1) == cpu->spsel ? cpu->sp : cpu->altsp; break; case 0x10: - value |= cpu->pm; + val |= cpu->pm; break; case 0x14: - value |= cpu->spsel << 1; + val |= cpu->spsel << 1; break; } - cpu->r[opcode >> 16 & 0xF] = value; + cpu->r[opc >> 8 & 0xF] = val; break; - } default: - arm_exception(ARM_Exception_HardFault); - break; + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; } break; case 5: // Branch with Link cpu->lr = cpu->pc - 1; - cpu->pc += ((int32_t)opcode << 5 >> 7 & UINT32_C(0xFF000000)) | - (~(opcode >> 3 ^ opcode << 10) & UINT32_C(0x00800000)) | - (~(opcode >> 4 ^ opcode << 11) & UINT32_C(0x00400000)) | - (opcode >> 4 & UINT32_C(0x003FF000)) | - (opcode << 1 & UINT32_C(0x00000FFE)); + cpu->pc += ((int32_t)opc << 5 >> 7 & UINT32_C(0xFF000000)) | + (~(opc >> 3 ^ opc << 10) & UINT32_C(0x00800000)) | + (~(opc >> 4 ^ opc << 11) & UINT32_C(0x00400000)) | + (opc >> 4 & UINT32_C(0x003FF000)) | + (opc << 1 & UINT32_C(0x00000FFE)); break; } } else { // UNDEFINED 32-bit Thumb instruction - arm_exception(ARM_Exception_HardFault); + arm_cpu_exception(arm, ARM_Exception_HardFault); + cpu->exc = false; + return; } break; } + if (!cpu->pc || cpu->pc >= UINT32_C(0x80000000) || + cpu->pc - 2 == UINT32_C(0x00006A0C)) { + asm("int3"); + } + if (unlikely(cpu->exc)) { + cpu->exc = false; + return; + } } diff --git a/core/arm/armcpu.h b/core/arm/armcpu.h index 7d578960a..853bd4581 100644 --- a/core/arm/armcpu.h +++ b/core/arm/armcpu.h @@ -1,35 +1,54 @@ #ifndef ARMCPU_H #define ARMCPU_H +#include "arm.h" + #include #include typedef enum arm_exception_number { + ARM_Thread_Mode = 0, ARM_Exception_Reset = 1, ARM_Exception_NMI = 2, ARM_Exception_HardFault = 3, ARM_Exception_SVCall = 11, ARM_Exception_PendSV = 14, ARM_Exception_SysTick = 15, + ARM_Exception_External = 16, + ARM_Invalid_Exception = 49, } arm_exception_number_t; +typedef struct arm_systick { + uint32_t ctrl, load, val, calib; +} arm_systick_t; + +typedef struct arm_nvic { + uint32_t ier, ipr, ip[8]; +} arm_nvic_t; + +typedef struct arm_scb { + uint32_t icsr, vtor, aircr, scr, shp[2]; +} arm_scb_t; + typedef union arm_cpu { - uint32_t r[32]; + uint32_t r[16]; struct { - uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, sp, lr, pc, altsp; - arm_exception_number_t excNum : 6; - bool v, c, z, n, pm, spsel, mode; + uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, ip, sp, lr, pc, altsp; + uint64_t active; + bool v, c, z, n, pm, spsel, exc; + arm_systick_t systick; + arm_nvic_t nvic; + arm_scb_t scb; }; } arm_cpu_t; -typedef struct arm_state arm_state_t; - #ifdef __cplusplus extern "C" { #endif -void arm_cpu_reset(arm_state_t *state); -void arm_execute(arm_state_t *state); +void arm_cpu_reset(arm_t *arm); +bool arm_cpu_exception(arm_t *arm, arm_exception_number_t type); +void arm_cpu_execute(arm_t *arm); #ifdef __cplusplus } diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 3555bc3f8..f42051a33 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -1,82 +1,1446 @@ #include "armmem.h" #include "armstate.h" +#include "../defines.h" #include #include #include -#define ARM_FLASH_WORDS 0x10000 -#define ARM_RAM_WORDS 0x2000 +#define FLASH_REGION_SIZE (FLASH_SIZE >> 4) +#define FLASH_ROW_SIZE (FLASH_PAGE_SIZE << 2) -bool arm_mem_init(arm_state_t *state) { - state->flash = calloc(ARM_FLASH_WORDS, sizeof(uint32_t)); - if (state->flash) { - state->ram = calloc(ARM_RAM_WORDS, sizeof(uint32_t)); - if (state->ram) { - return true; - free(state->ram); - } - free(state->flash); +#define ARM_SERCOM_SLEEP 4 + +static uint32_t bitreverse(uint32_t x, uint8_t bits) { +#if __has_builtin(__builtin_bitreverse32) + return __builtin_bitreverse32(x) >> (32 - bits); +#else + uint32_t r = 0; + while (bits--) { + r <<= 1; + r |= x & 1; + x >>= 1; + } + return r; +#endif +} + +static void arm_mem_set_pending(arm_t *arm, IRQn_Type irq, bool set) { + if (unlikely(set)) { + arm->cpu.nvic.ipr |= 1 << irq; + } else { + arm->cpu.nvic.ipr &= ~(1 << irq); + } +} + +static void arm_mem_pm_update_pending(arm_t *arm) { + PM_Type *pm = &arm->mem.pm; + arm_mem_set_pending(arm, PM_IRQn, + pm->INTFLAG.reg & + pm->INTEN.reg); +} + +static void arm_mem_nvmctrl_update_pending(arm_t *arm) { + NVMCTRL_Type *nvmctrl = &arm->mem.nvmctrl; + nvmctrl->INTFLAG.bit.ERROR = + nvmctrl->STATUS.reg & ~(NVMCTRL_STATUS_PRM | + NVMCTRL_STATUS_LOAD); + arm_mem_set_pending(arm, NVMCTRL_IRQn, + nvmctrl->INTFLAG.reg & + nvmctrl->INTEN.reg); +} + +static void arm_mem_sercom_update_pending(arm_t *arm, uint8_t idx) { + SERCOM_Type *sercom = &arm->mem.sercom[idx]; + sercom->USART.INTFLAG.bit.ERROR = + sercom->USART.STATUS.reg & ~SERCOM_USART_STATUS_CTS; + arm_mem_set_pending(arm, SERCOM0_IRQn + idx, + sercom->USART.INTFLAG.reg & + sercom->USART.INTEN.reg); +} + +void arm_mem_update_pending(arm_t *arm) { + arm_mem_pm_update_pending(arm); + arm_mem_nvmctrl_update_pending(arm); + for (uint8_t idx = 0; idx != SERCOM_INST_NUM; ++idx) { + arm_mem_sercom_update_pending(arm, idx); + } +} + +static uint16_t arm_nvm_region_lock_mask(NVMCTRL_Type *nvmctrl) { + return 1 << (nvmctrl->ADDR.bit.ADDR << 1) / FLASH_REGION_SIZE; +} + +static bool arm_nvm_region_lock_check(arm_t *arm) { + NVMCTRL_Type *nvmctrl = &arm->mem.nvmctrl; + if (nvmctrl->LOCK.bit.LOCK & arm_nvm_region_lock_mask(nvmctrl)) { + return true; } + nvmctrl->INTFLAG.bit.ERROR = true; + if (likely(nvmctrl->INTEN.bit.ERROR)) { + arm_mem_set_pending(arm, NVMCTRL_IRQn, true); + } + nvmctrl->STATUS.bit.LOCKE = true; return false; } -void arm_mem_destroy(arm_state_t *state) { - free(state->flash); - free(state->ram); +static void arm_nvm_clear_page_buffer(arm_mem_t *mem) { + memset(mem->pb, ~0, FLASH_PAGE_SIZE); +} + +static void arm_nvm_erase_row(arm_t *arm, bool aux) { + assert(!aux && "Not implemented"); + if (likely(arm_nvm_region_lock_check(arm))) { + memset(&arm->mem.nvm[(arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & + (FLASH_SIZE - 1) & -FLASH_ROW_SIZE) >> 2], + ~0, FLASH_ROW_SIZE); + } } -void arm_mem_reset(arm_state_t *state) { - memset(state->ram, 0, ARM_RAM_WORDS * sizeof(uint32_t)); +static void arm_nvm_write_page(arm_t *arm, bool aux) { + uint32_t idx = (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & + (FLASH_SIZE - 1) & -FLASH_PAGE_SIZE) >> 2; + assert(!aux && "Not implemented"); + if (likely(arm_nvm_region_lock_check(arm))) { + for (uint32_t off = 0; off != FLASH_PAGE_SIZE >> 2; ++off) { + arm->mem.nvm[idx + off] &= arm->mem.pb[off]; + } + } + arm_nvm_clear_page_buffer(&arm->mem); } -bool arm_mem_load_rom(arm_state_t *state, FILE *file) { - size_t read = fread(state->flash, 1, ARM_FLASH_WORDS * sizeof(uint32_t), file); - if (!read) { +static void arm_mem_sercom_reset(SERCOM_Type *sercom) { + memset(sercom, 0, sizeof(*sercom)); +} + +void arm_mem_spi_sel(arm_t *arm, uint8_t pin, bool low) { + SERCOM_SPI_Type *spi = &arm->mem.sercom[pin].SPI; + assert(pin < SERCOM_INST_NUM && "pin out of range"); + if (unlikely(!spi->CTRLA.bit.ENABLE || + spi->CTRLA.bit.MODE != + SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val || + !spi->CTRLB.bit.SSDE || + spi->SS == low)) { + return; + } + if ((spi->SS = low)) { + spi->INTFLAG.bit.SSL = true; + } else { + spi->INTFLAG.bit.TXC = true; + } + arm_mem_sercom_update_pending(arm, pin); +} + +uint8_t arm_mem_spi_peek(arm_t *arm, uint8_t pin, uint32_t *res) { + SERCOM_SPI_Type* spi = &arm->mem.sercom[pin].SPI; + assert(pin < SERCOM_INST_NUM && "pin out of range"); + if (likely(!spi->CTRLA.bit.ENABLE || + spi->CTRLA.bit.MODE != + SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val || + !spi->CTRLB.bit.RXEN)) { + *res = 1 << 15; + return 16; + } + uint8_t bits = 8 | (spi->CTRLB.bit.CHSIZE & 1); + *res = spi->BUFFER[1].bit.DATA; + if (unlikely(spi->CTRLA.bit.DORD)) { + *res = bitreverse(*res, bits); + } + return bits; +} + +void arm_mem_spi_xfer(arm_t *arm, uint8_t pin, uint32_t val) { + SERCOM_SPI_Type *spi = &arm->mem.sercom[pin].SPI; + assert(pin < SERCOM_INST_NUM && "pin out of range"); + if (likely(!spi->CTRLA.bit.ENABLE || + spi->CTRLA.bit.MODE != + SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val || + !spi->CTRLB.bit.RXEN)) { + return; + } + if (unlikely(spi->CTRLA.bit.DORD)) { + uint8_t bits = 8 | (spi->CTRLB.bit.CHSIZE & 1); + val = bitreverse(val, bits); + } + spi->BUFFER[1].bit.DATA = val; + if (spi->BUFFER[3].bit.VLD) { + if (spi->CTRLA.bit.IBON) { + spi->INTFLAG.bit.ERROR = true; + if (likely(spi->INTEN.bit.ERROR)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + spi->STATUS.bit.BUFOVF = true; + } else { + spi->BUFFER[2].bit.OVF = true; + } + spi->BUFFER[1].bit.VLD = true; + } else { + spi->INTFLAG.bit.DRE = true; + spi->INTFLAG.bit.RXC = true; + if (likely(spi->INTEN.bit.DRE || spi->INTEN.bit.RXC)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + spi->BUFFER[3].reg = spi->BUFFER[2].reg; + spi->BUFFER[2].reg = spi->BUFFER[1].reg; + if (likely(spi->BUFFER[1].bit.VLD = spi->BUFFER[0].bit.VLD)) { + spi->BUFFER[1].bit.DATA = spi->BUFFER[0].bit.DATA; + spi->BUFFER[0].reg = 0; + } else if (unlikely(spi->CTRLA.bit.MODE == + SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val)) { + spi->INTFLAG.bit.TXC = true; + if (likely(spi->INTEN.bit.TXC)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + } + } +} + +bool arm_mem_usart_send(arm_t *arm, uint8_t pin, uint16_t *val) { + SERCOM_USART_Type *usart = &arm->mem.sercom[pin].USART; + assert(pin < SERCOM_INST_NUM && "pin out of range"); + uint16_t tmp; + if (likely(!usart->CTRLA.bit.ENABLE || + usart->CTRLA.bit.MODE != + SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val || + !usart->CTRLB.bit.TXEN || + !usart->BUFFER[1].bit.VLD)) { return false; } - memset(state->flash + read, ~0, ARM_FLASH_WORDS * sizeof(uint32_t) - read); + usart->INTFLAG.bit.DRE = true; + if (likely(usart->INTEN.bit.DRE)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + tmp = usart->BUFFER[1].bit.DATA; + if (likely(usart->BUFFER[1].bit.VLD = usart->BUFFER[0].bit.VLD)) { + usart->BUFFER[1].bit.DATA = usart->BUFFER[0].bit.DATA; + usart->BUFFER[0].reg = 0; + } else { + usart->INTFLAG.bit.TXC = true; + if (likely(usart->INTEN.bit.TXC)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + } + if (unlikely(!usart->CTRLA.bit.DORD)) { + tmp = bitreverse(tmp, !(usart->CTRLB.bit.CHSIZE >> 1) << 3 | + usart->CTRLB.bit.CHSIZE); + } + *val = tmp; return true; } -uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr) { - return arm_mem_load_word(state, addr & ~UINT32_C(3)) >> ((addr & UINT32_C(3)) << UINT32_C(3)); +bool arm_mem_usart_recv(arm_t *arm, uint8_t pin, uint16_t val) { + SERCOM_USART_Type *usart = &arm->mem.sercom[pin].USART; + assert(pin < SERCOM_INST_NUM && "pin out of range"); + if (likely(!usart->CTRLA.bit.ENABLE || + usart->CTRLA.bit.MODE != + SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val || + !usart->CTRLB.bit.RXEN || + usart->BUFFER[3].bit.VLD)) { + return false; + } + if (unlikely(!usart->CTRLA.bit.DORD)) { + val = bitreverse(val, !(usart->CTRLB.bit.CHSIZE >> 1) << 3 | + usart->CTRLB.bit.CHSIZE); + } + usart->INTFLAG.bit.RXC = true; + if (likely(usart->INTEN.bit.RXC)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + usart->BUFFER[3].reg = usart->BUFFER[2].reg; + usart->BUFFER[2].bit.DATA = val; + usart->BUFFER[2].bit.VLD = true; + return true; +} + +bool arm_mem_init(arm_mem_t *mem) { + memset(mem, 0, sizeof(*mem)); + mem->nvm = malloc(FLASH_SIZE); + if (likely(mem->nvm)) { + memset(mem->nvm, ~0, FLASH_SIZE); + mem->ram = malloc(HMCRAMC0_SIZE); + if (likely(mem->ram)) { + return true; + free(mem->ram); + } + free(mem->nvm); + } + return false; +} + +void arm_mem_destroy(arm_mem_t *mem) { + free(mem->nvm); + free(mem->ram); +} + +void arm_mem_reset(arm_mem_t *mem, uint8_t rcause) { + memset(mem->ram, 0, HMCRAMC0_SIZE); + arm_nvm_clear_page_buffer(mem); + mem->pm.RCAUSE.reg = rcause; + mem->nvmctrl.INTFLAG.bit.READY = true; + mem->nvmctrl.LOCK.reg = NVMCTRL_LOCK_LOCK_Msk; + for (uint8_t idx = 0; idx != SERCOM_INST_NUM; ++idx) { + arm_mem_sercom_reset(&mem->sercom[idx]); + } +} + +bool arm_mem_load_rom(arm_mem_t *mem, FILE *file) { + size_t read = fread(mem->nvm, 1, FLASH_SIZE, file); + memset((uint8_t *)mem->nvm + read, ~0, FLASH_SIZE - read); + return read; +} + +static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { + uint8_t offset = addr >> 2 & 0xFF; + uint32_t val = 0; + assert(!(addr & 3) && + "Address should be aligned"); + if (likely(addr - FLASH_ADDR < FLASH_SIZE)) { // Internal Flash + return arm->mem.nvm[(addr - FLASH_ADDR) >> 2]; + } else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM + return arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2]; + } else if (unlikely(addr < HPB0_ADDR)) { + if (addr - NVMCTRL_OTP1 < 8) { + return 0; + } + if (addr - NVMCTRL_OTP2 < 8) { + return 0; + } + if (addr - NVMCTRL_OTP4 < 8) { + return 0; + } + if (addr == 0x80A00C) { + return 0; + } + if (addr == 0x80A040) { + return 0; + } + if (addr == 0x80A044) { + return 0; + } + if (addr == 0x80A048) { + return 0; + } + } else if (unlikely(addr < HPB1_ADDR)) { // Peripheral Bridge A + uint32_t id = ID_PAC0 + ((addr - HPB0_ADDR) >> 10); + switch (id) { + case ID_PAC0: + break; + case ID_PM: { + PM_Type *pm = &arm->mem.pm; + switch (offset) { + case (PM_CPUSEL_OFFSET | + PM_APBASEL_OFFSET | + PM_APBBSEL_OFFSET | + PM_APBCSEL_OFFSET) >> 2: + return pm->CPUSEL.reg << 0 | + pm->APBASEL.reg << 8 | + pm->APBBSEL.reg << 16 | + pm->APBCSEL.reg << 24; + case PM_AHBMASK_OFFSET >> 2: + return pm->AHBMASK.reg; + case PM_APBAMASK_OFFSET >> 2: + return pm->APBAMASK.reg; + case PM_APBBMASK_OFFSET >> 2: + return pm->APBBMASK.reg; + case PM_APBCMASK_OFFSET >> 2: + return pm->APBCMASK.reg; + case (PM_INTENCLR_OFFSET | + PM_INTENSET_OFFSET | + PM_INTFLAG_OFFSET) >> 2: + return pm->INTEN.reg << 0 | + pm->INTEN.reg << 8 | + pm->INTFLAG.reg << 16; + case PM_RCAUSE_OFFSET >> 2: + return pm->RCAUSE.reg; + } + break; + } + case ID_SYSCTRL: + switch (offset) { + case SYSCTRL_INTENCLR_OFFSET >> 2: + break; + case SYSCTRL_INTENSET_OFFSET >> 2: + break; + case SYSCTRL_INTFLAG_OFFSET >> 2: + break; + case SYSCTRL_PCLKSR_OFFSET >> 2: + return SYSCTRL_PCLKSR_XOSCRDY | + SYSCTRL_PCLKSR_XOSC32KRDY | + SYSCTRL_PCLKSR_OSC32KRDY | + SYSCTRL_PCLKSR_OSC8MRDY | + SYSCTRL_PCLKSR_DFLLRDY | + SYSCTRL_PCLKSR_BOD33RDY | + SYSCTRL_PCLKSR_B33SRDY; + case SYSCTRL_XOSC_OFFSET >> 2: + return SYSCTRL_XOSC_RESETVALUE; + case SYSCTRL_XOSC32K_OFFSET >> 2: + return SYSCTRL_XOSC32K_RESETVALUE; + case SYSCTRL_OSC32K_OFFSET >> 2: + return SYSCTRL_OSC32K_RESETVALUE; + case SYSCTRL_OSCULP32K_OFFSET >> 2: + return SYSCTRL_OSCULP32K_RESETVALUE; + case SYSCTRL_OSC8M_OFFSET >> 2: + return SYSCTRL_OSC8M_RESETVALUE; + case SYSCTRL_DFLLCTRL_OFFSET >> 2: + return SYSCTRL_DFLLCTRL_RESETVALUE; + case SYSCTRL_DFLLVAL_OFFSET >> 2: + return SYSCTRL_DFLLVAL_RESETVALUE; + case SYSCTRL_DFLLMUL_OFFSET >> 2: + return SYSCTRL_DFLLMUL_RESETVALUE; + case SYSCTRL_DFLLSYNC_OFFSET >> 2: + return SYSCTRL_DFLLSYNC_RESETVALUE; + case SYSCTRL_BOD33_OFFSET >> 2: + return SYSCTRL_BOD33_RESETVALUE; + case SYSCTRL_VREG_OFFSET >> 2: + return SYSCTRL_VREG_RESETVALUE; + case SYSCTRL_VREF_OFFSET >> 2: + return SYSCTRL_VREF_RESETVALUE; + case SYSCTRL_DPLLCTRLA_OFFSET >> 2: + return SYSCTRL_DPLLCTRLA_RESETVALUE; + case SYSCTRL_DPLLRATIO_OFFSET >> 2: + return SYSCTRL_DPLLRATIO_RESETVALUE; + case SYSCTRL_DPLLCTRLB_OFFSET >> 2: + return SYSCTRL_DPLLCTRLB_RESETVALUE; + case SYSCTRL_DPLLSTATUS_OFFSET >> 2: + return SYSCTRL_DPLLSTATUS_RESETVALUE; + } + break; + case ID_GCLK: { + GCLK_Type *gclk = &arm->mem.gclk; + switch (offset) { + case (GCLK_CTRL_OFFSET | + GCLK_STATUS_OFFSET | + GCLK_CLKCTRL_OFFSET) >> 2: + return GCLK_CTRL_RESETVALUE << 0 | + GCLK_STATUS_RESETVALUE << 8 | + (gclk->CLKCTRL->bit.ID <= GCLK_CLKCTRL_ID_I2S_1_Val ? + gclk->CLKCTRL[gclk->CLKCTRL->bit.ID].reg : + gclk->CLKCTRL->bit.ID << GCLK_CLKCTRL_ID_Pos) << 16; + case GCLK_GENCTRL_OFFSET >> 2: + return gclk->GENCTRL->bit.ID <= GCLK_CLKCTRL_GEN_GCLK8_Val ? + gclk->GENCTRL[gclk->GENCTRL->bit.ID].reg : + gclk->GENCTRL->bit.ID << GCLK_GENCTRL_ID_Pos; + case GCLK_GENDIV_OFFSET >> 2: + return gclk->GENDIV->bit.ID <= GCLK_CLKCTRL_GEN_GCLK8_Val ? + gclk->GENDIV[gclk->GENDIV->bit.ID].reg : + gclk->GENDIV->bit.ID << GCLK_GENDIV_ID_Pos; + } + break; + } + case ID_WDT: + break; + case ID_RTC: + return 0; + case ID_EIC: + switch (offset) { + case (EIC_CTRL_OFFSET | + EIC_STATUS_OFFSET | + EIC_NMICTRL_OFFSET | + EIC_NMIFLAG_OFFSET) >> 2: + return EIC_CTRL_RESETVALUE << 0 | + EIC_STATUS_RESETVALUE << 8 | + EIC_NMICTRL_RESETVALUE << 16 | + EIC_NMIFLAG_RESETVALUE << 24; + } + break; + } + } else if (unlikely(addr < HPB2_ADDR)) { // Peripheral Bridge B + if (addr < (uint32_t)DSU) { // PAC1 + } else if (addr < (uint32_t)NVMCTRL) { // DSU + } else if (addr < (uint32_t)PORT) { + NVMCTRL_Type *nvmctrl = &arm->mem.nvmctrl; + switch (offset) { + case NVMCTRL_CTRLA_OFFSET >> 2: + return nvmctrl->CTRLA.reg; + case NVMCTRL_CTRLB_OFFSET >> 2: + return nvmctrl->CTRLB.reg; + case NVMCTRL_PARAM_OFFSET >> 2: + return CONCAT(NVMCTRL_PARAM_PSZ_, FLASH_PAGE_SIZE) | + NVMCTRL_PARAM_NVMP(FLASH_NB_OF_PAGES); + case NVMCTRL_INTENCLR_OFFSET >> 2: + case NVMCTRL_INTENSET_OFFSET >> 2: + return nvmctrl->INTEN.reg; + case NVMCTRL_INTFLAG_OFFSET >> 2: + return nvmctrl->INTFLAG.reg; + case NVMCTRL_STATUS_OFFSET >> 2: + return nvmctrl->STATUS.reg; + case NVMCTRL_ADDR_OFFSET >> 2: + return nvmctrl->ADDR.reg; + case NVMCTRL_LOCK_OFFSET >> 2: + return nvmctrl->LOCK.reg; + } + } else if (addr < (uint32_t)DMAC) { // PORT + switch (offset & 0x1F) { + case PORT_DIR_OFFSET >> 2: + return PORT_DIR_RESETVALUE; + case PORT_DIRCLR_OFFSET >> 2: + return PORT_DIRCLR_RESETVALUE; + case PORT_DIRSET_OFFSET >> 2: + return PORT_DIRSET_RESETVALUE; + case PORT_DIRTGL_OFFSET >> 2: + return PORT_DIRTGL_RESETVALUE; + case PORT_OUT_OFFSET >> 2: + return PORT_OUT_RESETVALUE; + case PORT_OUTCLR_OFFSET >> 2: + return PORT_OUTCLR_RESETVALUE; + case PORT_OUTSET_OFFSET >> 2: + return PORT_OUTSET_RESETVALUE; + case PORT_OUTTGL_OFFSET >> 2: + return PORT_OUTTGL_RESETVALUE; + case PORT_IN_OFFSET >> 2: + return PORT_IN_RESETVALUE; + case PORT_CTRL_OFFSET >> 2: + return PORT_CTRL_RESETVALUE; + case PORT_WRCONFIG_OFFSET >> 2: + return PORT_WRCONFIG_RESETVALUE; + default: + if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + return PORT_PMUX_RESETVALUE; + } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + return PORT_PINCFG_RESETVALUE; + } + break; + } + } else if (addr < (uint32_t)USB) { // DMAC + switch (offset) { + case (DMAC_CRCSTATUS_OFFSET | DMAC_DBGCTRL_OFFSET | DMAC_QOSCTRL_OFFSET) >> 2: + return DMAC_CRCSTATUS_RESETVALUE << 0 | + DMAC_DBGCTRL_RESETVALUE << 8 | + DMAC_QOSCTRL_RESETVALUE << 16; + case DMAC_SWTRIGCTRL_OFFSET >> 2: + return DMAC_SWTRIGCTRL_RESETVALUE; + case DMAC_BUSYCH_OFFSET >> 2: + return DMAC_BUSYCH_RESETVALUE; + case DMAC_CHCTRLA_OFFSET >> 2: + return DMAC_CHCTRLA_RESETVALUE; + } + } else if (addr < (uint32_t)MTB) { // USB + switch (offset) { + case (USB_CTRLA_OFFSET | USB_SYNCBUSY_OFFSET | USB_QOSCTRL_OFFSET) >> 2: + return USB_CTRLA_RESETVALUE << 0 | + USB_SYNCBUSY_RESETVALUE << 16 | + USB_QOSCTRL_RESETVALUE << 24; + } + } else if (addr < (uint32_t)SBMATRIX) { // MTB + } else { // SBMATRIX + } + } else if (likely(addr < (uint32_t)PORT_IOBUS)) { // Peripheral Bridge C + uint32_t id = ID_PAC2 + ((addr - HPB2_ADDR) >> 10); + switch (id) { + case ID_PAC2: + break; + case ID_EVSYS: + switch (offset) { + case EVSYS_CTRL_OFFSET >> 2: + return EVSYS_CTRL_RESETVALUE; + } + break; + case ID_SERCOM0: + case ID_SERCOM1: + case ID_SERCOM2: + case ID_SERCOM3: { + SERCOM_Type *sercom = &arm->mem.sercom[id - ID_SERCOM0]; + switch (sercom->USART.CTRLA.bit.MODE) { + case SERCOM_USART_CTRLA_MODE_USART_EXT_CLK_Val: + case SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val: { + SERCOM_USART_Type *usart = &sercom->USART; + switch (offset) { + case SERCOM_USART_CTRLA_OFFSET >> 2: + return usart->CTRLA.reg; + case SERCOM_USART_CTRLB_OFFSET >> 2: + return usart->CTRLB.reg; + case (SERCOM_USART_BAUD_OFFSET | + SERCOM_USART_RXPL_OFFSET) >> 2: + return usart->BAUD.reg << 0 | + usart->RXPL.reg << 16; + case (SERCOM_USART_INTENCLR_OFFSET | + SERCOM_USART_INTENSET_OFFSET) >> 2: + return usart->INTEN.reg | + usart->INTEN.reg << 16; + case (SERCOM_USART_INTFLAG_OFFSET | + SERCOM_USART_STATUS_OFFSET) >> 2: + if (usart->SLEEPFLAG != usart->INTFLAG.reg) { + usart->SLEEPFLAG = usart->INTFLAG.reg; + usart->SLEEPCOUNT = 0; + } else if (++usart->SLEEPCOUNT == ARM_SERCOM_SLEEP) { + usart->SLEEPCOUNT = 0; + sync_sleep(&arm->sync); + } + return usart->INTFLAG.reg | + usart->STATUS.reg << 16; + case SERCOM_USART_SYNCBUSY_OFFSET >> 2: + return SERCOM_USART_SYNCBUSY_RESETVALUE; + case SERCOM_USART_DATA_OFFSET >> 2: { + SERCOM_BUFFER_Type *buffer = &usart->BUFFER[3]; + if (!buffer->bit.VLD) { + usart->INTFLAG.bit.RXC = false; + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + --buffer; + } + if (buffer->bit.OVF) { + usart->INTFLAG.bit.ERROR = true; + if (likely(usart->INTEN.bit.ERROR)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + + id - ID_SERCOM0, true); + } + usart->STATUS.bit.BUFOVF = true; + } + val = buffer->bit.DATA; + buffer->reg = 0; + return val; + } + } + break; + } + case SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val: + case SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val: { + SERCOM_SPI_Type *spi = &sercom->SPI; + switch (offset) { + case SERCOM_SPI_CTRLA_OFFSET >> 2: + return spi->CTRLA.reg; + case SERCOM_SPI_CTRLB_OFFSET >> 2: + return spi->CTRLB.reg; + case SERCOM_SPI_BAUD_OFFSET >> 2: + return spi->BAUD.reg; + case (SERCOM_SPI_INTENCLR_OFFSET | + SERCOM_SPI_INTENSET_OFFSET) >> 2: + return spi->INTEN.reg | + spi->INTEN.reg << 16; + case (SERCOM_SPI_INTFLAG_OFFSET | + SERCOM_SPI_STATUS_OFFSET) >> 2: + if (spi->SLEEPFLAG != spi->INTFLAG.reg) { + spi->SLEEPFLAG = spi->INTFLAG.reg; + spi->SLEEPCOUNT = 0; + } else if (++spi->SLEEPCOUNT == ARM_SERCOM_SLEEP) { + spi->SLEEPCOUNT = 0; + sync_sleep(&arm->sync); + } + return spi->INTFLAG.reg | + spi->STATUS.reg << 16; + case SERCOM_SPI_SYNCBUSY_OFFSET >> 2: + return SERCOM_SPI_SYNCBUSY_RESETVALUE; + case SERCOM_SPI_ADDR_OFFSET >> 2: + return spi->ADDR.reg; + case SERCOM_SPI_DATA_OFFSET >> 2: { + SERCOM_BUFFER_Type *buffer = &spi->BUFFER[3]; + if (!buffer->bit.VLD) { + spi->INTFLAG.bit.RXC = false; + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + --buffer; + } + if (buffer->bit.OVF) { + spi->INTFLAG.bit.ERROR = true; + if (likely(spi->INTEN.bit.ERROR)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + + id - ID_SERCOM0, true); + } + spi->STATUS.bit.BUFOVF = true; + } + val = buffer->bit.DATA; + buffer->reg = 0; + return val; + } + } + break; + } + } + break; + } + case ID_TCC0: + case ID_TCC1: + case ID_TCC2: + break; + case ID_TC3: + case ID_TC4: + case ID_TC5: + break; + case ID_ADC: + break; + case ID_DAC: + break; + case ID_PTC: + break; + case ID_I2S: + break; + } + } else if (unlikely(addr - (uint32_t)PORT_IOBUS <= 1u << 10)) { // IOBUS + switch (offset & 0x1F) { + case PORT_DIR_OFFSET >> 2: + return PORT_DIR_RESETVALUE; + case PORT_DIRCLR_OFFSET >> 2: + return PORT_DIRCLR_RESETVALUE; + case PORT_DIRSET_OFFSET >> 2: + return PORT_DIRSET_RESETVALUE; + case PORT_DIRTGL_OFFSET >> 2: + return PORT_DIRTGL_RESETVALUE; + case PORT_OUT_OFFSET >> 2: + return PORT_OUT_RESETVALUE; + case PORT_OUTCLR_OFFSET >> 2: + return PORT_OUTCLR_RESETVALUE; + case PORT_OUTSET_OFFSET >> 2: + return PORT_OUTSET_RESETVALUE; + case PORT_OUTTGL_OFFSET >> 2: + return PORT_OUTTGL_RESETVALUE; + case PORT_IN_OFFSET >> 2: + return PORT_IN_RESETVALUE; + case PORT_CTRL_OFFSET >> 2: + return PORT_CTRL_RESETVALUE; + case PORT_WRCONFIG_OFFSET >> 2: + return PORT_WRCONFIG_RESETVALUE; + default: + if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + return PORT_PMUX_RESETVALUE; + } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + return PORT_PINCFG_RESETVALUE; + } + break; + } + } + if (arm->debug) { + printf("%08X: load %08X %08X\n", arm->cpu.pc - 4, val, addr); + } + arm_cpu_exception(arm, ARM_Exception_HardFault); + return val; } -uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr) { - return arm_mem_load_word(state, addr & ~UINT32_C(2)) >> ((addr & UINT32_C(2)) << UINT32_C(3)); +uint8_t arm_mem_load_byte(arm_t *arm, uint32_t addr) { + return arm_mem_load_any(arm, addr & ~3) >> ((addr & 3) << 3); } -uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr) { - assert(!(addr & UINT32_C(3))); - if (addr - UINT32_C(0) < UINT32_C(0x40000)) { - return state->flash[(addr - UINT32_C(0)) >> 2]; +uint16_t arm_mem_load_half(arm_t *arm, uint32_t addr) { + uint16_t val = 0; + if (unlikely(addr & 1)) { + arm_cpu_exception(arm, ARM_Exception_HardFault); + } else { + val = arm_mem_load_any(arm, addr & ~2) >> ((addr & 2) << 3); } - if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { - return state->ram[(addr - UINT32_C(0x20000000)) >> 2]; + return val; +} + +uint32_t arm_mem_load_word(arm_t *arm, uint32_t addr) { + uint32_t val = 0; + if (unlikely(addr & 3)) { + arm_cpu_exception(arm, ARM_Exception_HardFault); + return val; } - return 0; + if (likely(addr < PPB_ADDR)) { + return arm_mem_load_any(arm, addr); + } else if (unlikely(addr < SCS_BASE)) { + } else if (unlikely(addr < SysTick_BASE)) { + } else if (unlikely(addr < NVIC_BASE)) { + arm_systick_t *systick = &arm->cpu.systick; + if (addr == (uint32_t)&SysTick->CTRL) { + val = systick->ctrl; + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; + return val; + } else if (addr == (uint32_t)&SysTick->LOAD) { + return systick->load; + } else if (addr == (uint32_t)&SysTick->VAL) { + return systick->val; + } else if (addr == (uint32_t)&SysTick->CALIB) { + } + } else if (unlikely(addr < SCB_BASE)) { + arm_nvic_t *nvic = &arm->cpu.nvic; + if (addr == (uint32_t)&NVIC->ISER[0] || + addr == (uint32_t)&NVIC->ICER[0]) { + return nvic->ier; + } else if (addr == (uint32_t)&NVIC->ISPR[0] || + addr == (uint32_t)&NVIC->ICPR[0]) { + return nvic->ipr; + } else if (addr >= (uint32_t)&NVIC->IP[0] && + addr <= (uint32_t)&NVIC->IP[7]) { + return nvic->ip[addr >> 2 & 7]; + } + } else { + arm_scb_t *scb = &arm->cpu.scb; + if (addr == (uint32_t)&SCB->CPUID) { + return 'A' << SCB_CPUID_IMPLEMENTER_Pos | + 0 << SCB_CPUID_VARIANT_Pos | + 12 << SCB_CPUID_ARCHITECTURE_Pos | + 28 << SCB_CPUID_PARTNO_Pos | + 6 << SCB_CPUID_REVISION_Pos; + } else if (addr == (uint32_t)&SCB->ICSR) { + return scb->icsr; + } else if (addr == (uint32_t)&SCB->VTOR) { + return scb->vtor; + } else if (addr == (uint32_t)&SCB->AIRCR) { + return 0; + } else if (addr == (uint32_t)&SCB->CCR) { + return SCB_CCR_STKALIGN_Msk | + SCB_CCR_UNALIGN_TRP_Msk; + } else if (addr == (uint32_t)&SCB->SHP[0]) { + return scb->shp[0]; + } else if (addr == (uint32_t)&SCB->SHP[1]) { + return scb->shp[1]; + } else if (addr == (uint32_t)&SCB->SHCSR) { + return (scb->icsr & SCB_ICSR_PENDSVSET_Msk) >> + SCB_ICSR_PENDSVSET_Pos << SCB_SHCSR_SVCALLPENDED_Pos; + } + } + if (arm->debug) { + printf("%08X: load %08X %08X\n", arm->cpu.pc - 4, val, addr); + } + arm_cpu_exception(arm, ARM_Exception_HardFault); + return val; } -static void arm_mem_store(arm_state_t *state, uint32_t val, uint32_t mask, uint32_t addr) { - assert(!(addr & UINT32_C(3)) && !(val & ~mask)); - if (addr - UINT32_C(0x20000000) < UINT32_C(0x8000)) { - uint32_t *ptr = &state->ram[(addr - UINT32_C(0x20000000)) >> UINT32_C(2)]; - *ptr = (*ptr & ~mask) | val; +static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t addr) { + uint8_t offset = addr >> 2 & 0xFF; + assert(!((addr & 3) | (val & mask)) && + "Address should be aligned and mask should be valid"); + if (unlikely(addr - FLASH_ADDR < FLASH_SIZE)) { // Page Buffer + if (likely(!(mask & mask >> 16))) { // no 8-bit writes + uint32_t *ptr = &arm->mem.pb[((addr - FLASH_ADDR) & (FLASH_PAGE_SIZE - 1)) >> 2]; + *ptr = (*ptr & mask) | val; + arm->mem.nvmctrl.ADDR.bit.ADDR = (addr - FLASH_ADDR) >> 1 | (mask & 1); + if (unlikely(!(mask >> 16) && !~(addr | -FLASH_PAGE_SIZE | 3) && + !arm->mem.nvmctrl.CTRLB.bit.MANW)) { + arm_nvm_write_page(arm, false); + } + return; + } + } else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM + uint32_t *ptr = &arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2]; + *ptr = (*ptr & mask) | val; + return; + } else if (unlikely(addr < HPB0_ADDR)) { + } else if (unlikely(addr < HPB1_ADDR)) { // Peripheral Bridge A + uint32_t id = ID_PAC0 + ((addr - HPB0_ADDR) >> 10); + switch (id) { + case ID_PAC0: + break; + case ID_PM: { + PM_Type *pm = &arm->mem.pm; + switch (offset) { + case (PM_CPUSEL_OFFSET | + PM_APBASEL_OFFSET | + PM_APBBSEL_OFFSET | + PM_APBCSEL_OFFSET) >> 2: + pm->CPUSEL.reg = + ((pm->CPUSEL.reg & mask >> 0) | val >> 0) & PM_CPUSEL_MASK; + pm->APBASEL.reg = + ((pm->APBASEL.reg & mask >> 8) | val >> 8) & PM_APBASEL_MASK; + pm->APBBSEL.reg = + ((pm->APBBSEL.reg & mask >> 16) | val >> 16) & PM_APBBSEL_MASK; + pm->APBCSEL.reg = + ((pm->APBCSEL.reg & mask >> 24) | val >> 24) & PM_APBCSEL_MASK; + return; + case PM_AHBMASK_OFFSET >> 2: + pm->AHBMASK.reg = ((pm->AHBMASK.reg & mask) | val) & PM_AHBMASK_MASK; + return; + case PM_APBAMASK_OFFSET >> 2: + pm->APBAMASK.reg = ((pm->APBAMASK.reg & mask) | val) & PM_APBAMASK_MASK; + return; + case PM_APBBMASK_OFFSET >> 2: + pm->APBBMASK.reg = ((pm->APBBMASK.reg & mask) | val) & PM_APBBMASK_MASK; + return; + case PM_APBCMASK_OFFSET >> 2: + pm->APBCMASK.reg = ((pm->APBCMASK.reg & mask) | val) & PM_APBCMASK_MASK; + return; + case (PM_INTENCLR_OFFSET | PM_INTENSET_OFFSET | PM_INTFLAG_OFFSET) >> 2: + pm->INTEN.reg = (pm->INTEN.reg & ~(val >> 0 & PM_INTENCLR_MASK)) | + (val >> 8 & PM_INTENSET_MASK); + pm->INTFLAG.reg &= ~(val >> 16 & PM_INTFLAG_MASK); + arm_mem_pm_update_pending(arm); + return; + } + break; + } + case ID_SYSCTRL: + switch (offset) { + case SYSCTRL_INTENCLR_OFFSET >> 2: + break; + case SYSCTRL_INTENSET_OFFSET >> 2: + break; + case SYSCTRL_INTFLAG_OFFSET >> 2: + break; + case SYSCTRL_PCLKSR_OFFSET >> 2: + return; + case SYSCTRL_XOSC_OFFSET >> 2: + break; + case SYSCTRL_XOSC32K_OFFSET >> 2: + break; + case SYSCTRL_OSC32K_OFFSET >> 2: + return; + case SYSCTRL_OSCULP32K_OFFSET >> 2: + break; + case SYSCTRL_OSC8M_OFFSET >> 2: + return; + case SYSCTRL_DFLLCTRL_OFFSET >> 2: + return; + case SYSCTRL_DFLLVAL_OFFSET >> 2: + return; + case SYSCTRL_DFLLMUL_OFFSET >> 2: + return; + case SYSCTRL_DFLLSYNC_OFFSET >> 2: + break; + case SYSCTRL_BOD33_OFFSET >> 2: + return; + case SYSCTRL_VREG_OFFSET >> 2: + break; + case SYSCTRL_VREF_OFFSET >> 2: + break; + case SYSCTRL_DPLLCTRLA_OFFSET >> 2: + break; + case SYSCTRL_DPLLRATIO_OFFSET >> 2: + break; + case SYSCTRL_DPLLCTRLB_OFFSET >> 2: + break; + case SYSCTRL_DPLLSTATUS_OFFSET >> 2: + break; + } + break; + case ID_GCLK: { + GCLK_Type *gclk = &arm->mem.gclk; + switch (offset) { + case (GCLK_CTRL_OFFSET | GCLK_STATUS_OFFSET | GCLK_CLKCTRL_OFFSET) >> 2: + if (val >> 0 & GCLK_STATUS_SYNCBUSY) { + memset(gclk, 0, sizeof(*gclk)); + } else { + gclk->CLKCTRL->bit.ID = + (gclk->CLKCTRL->bit.ID & mask >> (16 + GCLK_CLKCTRL_ID_Pos)) | + val >> (16 + GCLK_CLKCTRL_ID_Pos); + if (gclk->CLKCTRL->bit.ID <= GCLK_CLKCTRL_ID_I2S_1_Val) { + gclk->CLKCTRL[gclk->CLKCTRL->bit.ID].reg = + ((gclk->CLKCTRL[gclk->CLKCTRL->bit.ID].reg & mask >> 16) | + val >> 16) & GCLK_CLKCTRL_MASK; + } + } + return; + case GCLK_GENCTRL_OFFSET >> 2: + gclk->GENCTRL->bit.ID = + (gclk->GENCTRL->bit.ID & mask >> GCLK_GENCTRL_ID_Pos) | + val >> GCLK_GENCTRL_ID_Pos; + if (gclk->GENCTRL->bit.ID <= GCLK_CLKCTRL_GEN_GCLK8_Val) { + gclk->GENCTRL[gclk->GENCTRL->bit.ID].reg = + ((gclk->GENCTRL[gclk->GENCTRL->bit.ID].reg & mask) | val) & + GCLK_GENCTRL_MASK; + } + return; + case GCLK_GENDIV_OFFSET >> 2: + gclk->GENDIV->bit.ID = + (gclk->GENDIV->bit.ID & mask >> GCLK_GENDIV_ID_Pos) | + val >> GCLK_GENDIV_ID_Pos; + if (gclk->GENDIV->bit.ID <= GCLK_CLKCTRL_GEN_GCLK8_Val) { + gclk->GENDIV[gclk->GENDIV->bit.ID].reg = + ((gclk->GENDIV[gclk->GENDIV->bit.ID].reg & mask) | val) & + GCLK_GENDIV_MASK; + } + return; + } + break; + } + case ID_WDT: + break; + case ID_RTC: + return; + case ID_EIC: + switch (offset) { + case (EIC_CTRL_OFFSET | + EIC_STATUS_OFFSET | + EIC_NMICTRL_OFFSET | + EIC_NMIFLAG_OFFSET) >> 2: + return; + } + break; + } + } else if (unlikely(addr < HPB2_ADDR)) { // Peripheral Bridge B + if (addr < (uint32_t)DSU) { // PAC1 + } else if (addr < (uint32_t)NVMCTRL) { // DSU + } else if (addr < (uint32_t)PORT) { + NVMCTRL_Type *nvmctrl = &arm->mem.nvmctrl; + switch (offset) { + case NVMCTRL_CTRLA_OFFSET >> 2: { + nvmctrl->CTRLA.reg = ((nvmctrl->CTRLA.reg & mask) | val) & NVMCTRL_CTRLA_MASK & + ~NVMCTRL_CTRLA_CMDEX(1); + if ((val & NVMCTRL_CTRLA_CMDEX_Msk) == NVMCTRL_CTRLA_CMDEX_KEY) { + switch (val & NVMCTRL_CTRLA_CMD_Msk) { + case NVMCTRL_CTRLA_CMD_ER: + arm_nvm_erase_row(arm, false); + return; + case NVMCTRL_CTRLA_CMD_WP: + arm_nvm_write_page(arm, false); + return; + case NVMCTRL_CTRLA_CMD_EAR: + arm_nvm_erase_row(arm, true); + return; + case NVMCTRL_CTRLA_CMD_WAP: + arm_nvm_write_page(arm, true); + return; + case NVMCTRL_CTRLA_CMD_SF: + break; + case NVMCTRL_CTRLA_CMD_WL: + break; + case NVMCTRL_CTRLA_CMD_LR: + nvmctrl->LOCK.bit.LOCK &= ~arm_nvm_region_lock_mask(nvmctrl); + return; + case NVMCTRL_CTRLA_CMD_UR: + nvmctrl->LOCK.bit.LOCK |= arm_nvm_region_lock_mask(nvmctrl); + return; + case NVMCTRL_CTRLA_CMD_SPRM: + break; + case NVMCTRL_CTRLA_CMD_CPRM: + break; + case NVMCTRL_CTRLA_CMD_PBC: + arm_nvm_clear_page_buffer(&arm->mem); + return; + case NVMCTRL_CTRLA_CMD_SSB: + break; + case NVMCTRL_CTRLA_CMD_INVALL: + return; + } + } + nvmctrl->INTFLAG.bit.ERROR = true; + if (likely(nvmctrl->INTEN.bit.ERROR)) { + arm_mem_set_pending(arm, NVMCTRL_IRQn, true); + } + nvmctrl->STATUS.bit.PROGE = true; + return; + } + case NVMCTRL_CTRLB_OFFSET >> 2: + nvmctrl->CTRLB.reg = ((nvmctrl->CTRLB.reg & mask) | val) & NVMCTRL_CTRLB_MASK; + return; + case NVMCTRL_PARAM_OFFSET >> 2: + return; + case NVMCTRL_INTENCLR_OFFSET >> 2: + nvmctrl->INTEN.reg &= ~(val & NVMCTRL_INTENCLR_MASK); + arm_mem_nvmctrl_update_pending(arm); + return; + case NVMCTRL_INTENSET_OFFSET >> 2: + nvmctrl->INTEN.reg |= val & NVMCTRL_INTENCLR_MASK; + arm_mem_nvmctrl_update_pending(arm); + return; + case NVMCTRL_INTFLAG_OFFSET >> 2: + nvmctrl->INTFLAG.reg &= ~(val & NVMCTRL_INTFLAG_ERROR); + arm_mem_nvmctrl_update_pending(arm); + return; + case NVMCTRL_STATUS_OFFSET >> 2: + nvmctrl->STATUS.reg &= ~(val & (NVMCTRL_STATUS_NVME | + NVMCTRL_STATUS_LOCKE | + NVMCTRL_STATUS_PROGE | + NVMCTRL_STATUS_LOAD)); + arm_mem_nvmctrl_update_pending(arm); + return; + case NVMCTRL_ADDR_OFFSET >> 2: + nvmctrl->ADDR.reg = ((nvmctrl->ADDR.reg & mask) | val) & NVMCTRL_ADDR_MASK; + return; + case NVMCTRL_LOCK_OFFSET >> 2: + return; + } + } else if (addr < (uint32_t)DMAC) { // PORT + switch (offset & 0x1F) { + case PORT_DIR_OFFSET >> 2: + return; + case PORT_DIRCLR_OFFSET >> 2: + return; + case PORT_DIRSET_OFFSET >> 2: + return; + case PORT_DIRTGL_OFFSET >> 2: + return; + case PORT_OUT_OFFSET >> 2: + return; + case PORT_OUTCLR_OFFSET >> 2: + return; + case PORT_OUTSET_OFFSET >> 2: + return; + case PORT_OUTTGL_OFFSET >> 2: + return; + case PORT_IN_OFFSET >> 2: + return; + case PORT_CTRL_OFFSET >> 2: + return; + case PORT_WRCONFIG_OFFSET >> 2: + return; + default: + if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + return; + } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + return; + } + break; + } + } else if (addr < (uint32_t)USB) { // DMAC + switch (offset) { + case (DMAC_CTRL_OFFSET | DMAC_CRCCTRL_OFFSET) >> 2: + return; + case (DMAC_CRCSTATUS_OFFSET | DMAC_DBGCTRL_OFFSET | DMAC_QOSCTRL_OFFSET) >> 2: + return; + case DMAC_SWTRIGCTRL_OFFSET >> 2: + return; + case DMAC_BASEADDR_OFFSET >> 2: + return; + case DMAC_WRBADDR_OFFSET >> 2: + return; + case DMAC_CHID_OFFSET >> 2: + return; + case DMAC_CHCTRLA_OFFSET >> 2: + return; + case DMAC_CHCTRLB_OFFSET >> 2: + return; + } + } else if (addr < (uint32_t)MTB) { // USB + switch (offset) { + case (USB_CTRLA_OFFSET | USB_SYNCBUSY_OFFSET | USB_QOSCTRL_OFFSET) >> 2: + return; + } + } else if (addr < (uint32_t)SBMATRIX) { // MTB + switch (offset) { + case MTB_MASTER_OFFSET >> 2: + return; + } + } else { // SBMATRIX + switch (addr) { + case (uint32_t)®_SBMATRIX_SFR4: + return; + } + } + } else if (likely(addr < (uint32_t)PORT_IOBUS)) { // Peripheral Bridge C + uint32_t id = ID_PAC2 + ((addr - HPB2_ADDR) >> 10); + switch (id) { + case ID_PAC2: + break; + case ID_EVSYS: + switch (offset) { + case EVSYS_CTRL_OFFSET >> 2: + return; + } + break; + case ID_SERCOM0: + case ID_SERCOM1: + case ID_SERCOM2: + case ID_SERCOM3: { + SERCOM_Type *sercom = &arm->mem.sercom[id - ID_SERCOM0]; + if (unlikely(offset == (SERCOM_USART_CTRLA_OFFSET | + SERCOM_SPI_CTRLA_OFFSET) >> 2)) { + val = (sercom->USART.CTRLA.reg & mask) | val; + if (unlikely(val & (SERCOM_USART_CTRLA_SWRST | + SERCOM_SPI_CTRLA_SWRST))) { + memset(sercom, 0, sizeof(*sercom)); + return; + } else if (unlikely(val & (SERCOM_USART_CTRLA_ENABLE | + SERCOM_SPI_CTRLA_ENABLE))) { + sercom->USART.CTRLA.bit.ENABLE = true; + sercom->USART.INTFLAG.bit.DRE = + !sercom->USART.BUFFER[0].bit.VLD; + sercom->USART.INTFLAG.bit.RXC = + sercom->USART.BUFFER[2].bit.VLD; + if (likely((sercom->USART.INTFLAG.bit.DRE && + sercom->USART.INTEN.bit.DRE) || + (sercom->USART.INTFLAG.bit.RXC && + sercom->USART.INTEN.bit.RXC))) { + arm_mem_set_pending(arm, SERCOM0_IRQn + + id - ID_SERCOM0, true); + } + return; + } else { + switch ((val & (SERCOM_USART_CTRLA_MODE_Msk | + SERCOM_SPI_CTRLA_MODE_Msk)) >> + (SERCOM_USART_CTRLA_MODE_Pos | + SERCOM_SPI_CTRLA_MODE_Pos)) { + case SERCOM_USART_CTRLA_MODE_USART_EXT_CLK_Val: + case SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val: + sercom->USART.CTRLA.reg = val & SERCOM_USART_CTRLA_MASK; + return; + case SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val: + case SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val: + sercom->SPI.CTRLA.reg = val & SERCOM_SPI_CTRLA_MASK; + return; + } + } + } else { + switch (sercom->USART.CTRLA.bit.MODE) { + case SERCOM_USART_CTRLA_MODE_USART_EXT_CLK_Val: + case SERCOM_USART_CTRLA_MODE_USART_INT_CLK_Val: { + SERCOM_USART_Type *usart = &sercom->USART; + switch (offset) { + case SERCOM_USART_CTRLB_OFFSET >> 2: + if (unlikely((usart->CTRLB.reg ^ val) & + ~mask & SERCOM_USART_CTRLB_RXEN && + !(usart->CTRLB.bit.RXEN ^= true))) { + usart->INTFLAG.bit.RXC = false; + usart->STATUS.bit.COLL = false; + usart->STATUS.bit.ISF = false; + usart->STATUS.bit.BUFOVF = false; + usart->STATUS.bit.FERR = false; + usart->STATUS.bit.PERR = false; + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + usart->BUFFER[2].reg = 0; + usart->BUFFER[3].reg = 0; + } + if (unlikely((usart->CTRLB.reg ^ val) & + ~mask & SERCOM_USART_CTRLB_TXEN)) { + usart->CTRLB.bit.TXEN ^= true; + } + if (likely(!usart->CTRLA.bit.ENABLE)) { + usart->CTRLB.reg = ((usart->CTRLB.reg & mask) | val) & + SERCOM_USART_CTRLB_MASK; + } + return; + case (SERCOM_USART_BAUD_OFFSET | + SERCOM_USART_RXPL_OFFSET) >> 2: + if (likely(!usart->CTRLA.bit.ENABLE)) { + usart->BAUD.reg = ((usart->BAUD.reg & mask >> 0) | + val >> 0) & SERCOM_USART_BAUD_MASK; + } + usart->RXPL.reg = ((usart->RXPL.reg & mask >> 16) | + val >> 16) & SERCOM_USART_RXPL_MASK; + return; + case (SERCOM_USART_INTENCLR_OFFSET | + SERCOM_USART_INTENSET_OFFSET) >> 2: + usart->INTEN.reg = (usart->INTEN.reg & + ~(val >> 0 & SERCOM_USART_INTENCLR_MASK)) | + (val >> 16 & SERCOM_USART_INTENSET_MASK); + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + return; + case (SERCOM_USART_INTFLAG_OFFSET | + SERCOM_USART_STATUS_OFFSET) >> 2: + usart->INTFLAG.reg &= ~(val >> 0 & SERCOM_USART_INTFLAG_MASK & + ~(SERCOM_USART_INTFLAG_RXC | + SERCOM_USART_INTFLAG_DRE)); + usart->STATUS.reg &= ~(val >> 16 & SERCOM_USART_STATUS_MASK & + ~SERCOM_USART_STATUS_CTS); + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + return; + case SERCOM_USART_DATA_OFFSET >> 2: { + SERCOM_BUFFER_Type *buffer = &usart->BUFFER[1]; + if (likely(buffer->bit.VLD)) { + usart->INTFLAG.bit.DRE = false; + --buffer; + } else { + usart->INTFLAG.bit.TXC = false; + } + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + buffer->bit.DATA = val; + buffer->bit.VLD = true; + return; + } + case SERCOM_USART_DBGCTRL_OFFSET >> 2: + return; + } + break; + } + case SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val: + case SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val: { + SERCOM_SPI_Type *spi = &sercom->SPI; + switch (offset) { + case SERCOM_SPI_CTRLB_OFFSET >> 2: + if (unlikely((spi->CTRLB.reg ^ val) & + ~mask & SERCOM_SPI_CTRLB_RXEN && + !(spi->CTRLB.bit.RXEN ^= true))) { + spi->INTFLAG.bit.RXC = false; + spi->STATUS.bit.BUFOVF = false; + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + spi->BUFFER[2].reg = 0; + spi->BUFFER[3].reg = 0; + spi->SS = false; + } + if (likely(!spi->CTRLA.bit.ENABLE)) { + spi->CTRLB.reg = ((spi->CTRLB.reg & mask) | + val) & SERCOM_SPI_CTRLB_MASK; + } + return; + case SERCOM_SPI_BAUD_OFFSET >> 2: + if (likely(!spi->CTRLA.bit.ENABLE)) { + spi->BAUD.reg = ((spi->BAUD.reg & mask) | + val) & SERCOM_SPI_BAUD_MASK; + } + return; + case (SERCOM_SPI_INTENCLR_OFFSET | + SERCOM_SPI_INTENSET_OFFSET) >> 2: + spi->INTEN.reg = (spi->INTEN.reg & + ~(val >> 0 & SERCOM_SPI_INTENCLR_MASK)) | + (val >> 16 & SERCOM_SPI_INTENSET_MASK); + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + return; + case (SERCOM_SPI_INTFLAG_OFFSET | + SERCOM_SPI_STATUS_OFFSET) >> 2: + spi->INTFLAG.reg &= ~(val & SERCOM_SPI_INTFLAG_MASK & + ~(SERCOM_SPI_INTFLAG_RXC | + SERCOM_SPI_INTFLAG_DRE)); + spi->STATUS.reg &= ~(val >> 16 & SERCOM_SPI_STATUS_MASK); + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + return; + case SERCOM_SPI_ADDR_OFFSET >> 2: + if (likely(!spi->CTRLA.bit.ENABLE)) { + spi->ADDR.reg = ((spi->ADDR.reg & mask) | + val) & SERCOM_SPI_ADDR_MASK; + } + return; + case SERCOM_SPI_DATA_OFFSET >> 2: { + SERCOM_BUFFER_Type *buffer = &spi->BUFFER[1]; + if (likely(!spi->CTRLB.bit.PLOADEN || //spi->SS || + buffer->bit.VLD)) { + spi->INTFLAG.bit.DRE = false; + --buffer; + } else { + spi->INTFLAG.bit.TXC = false; + } + arm_mem_sercom_update_pending(arm, id - ID_SERCOM0); + buffer->bit.DATA = val; + buffer->bit.VLD = true; + return; + } + case SERCOM_SPI_DBGCTRL_OFFSET >> 2: + return; + } + break; + } + } + } + break; + } + case ID_TCC0: + case ID_TCC1: + case ID_TCC2: + break; + case ID_TC3: + case ID_TC4: + case ID_TC5: + break; + case ID_ADC: + break; + case ID_DAC: + break; + case ID_PTC: + break; + case ID_I2S: + break; + } + } else if (unlikely(addr - (uint32_t)PORT_IOBUS <= 1u << 10)) { // IOBUS + switch (offset & 0x1F) { + case PORT_DIR_OFFSET >> 2: + return; + case PORT_DIRCLR_OFFSET >> 2: + return; + case PORT_DIRSET_OFFSET >> 2: + return; + case PORT_DIRTGL_OFFSET >> 2: + return; + case PORT_OUT_OFFSET >> 2: + return; + case PORT_OUTCLR_OFFSET >> 2: + return; + case PORT_OUTSET_OFFSET >> 2: + return; + case PORT_OUTTGL_OFFSET >> 2: + return; + case PORT_IN_OFFSET >> 2: + return; + case PORT_CTRL_OFFSET >> 2: + return; + case PORT_WRCONFIG_OFFSET >> 2: + return; + default: + if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + return; + } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + return; + } + break; + } + } + if (arm->debug) { + printf("%08X: store %08X %08X\n", arm->cpu.pc - 4, val, addr); } + arm_cpu_exception(arm, ARM_Exception_HardFault); } -void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr) { - uint32_t shift = (addr & UINT32_C(3)) << UINT32_C(3); - arm_mem_store(state, val << shift, UINT32_C(0xFF) << shift, addr & ~UINT32_C(3)); +void arm_mem_store_byte(arm_t *arm, uint8_t val, uint32_t addr) { + uint32_t shift = (addr & 3) << 3; + arm_mem_store_any(arm, val << shift, ~(UINT32_C(0xFF) << shift), addr & ~3); } -void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr) { - uint32_t shift = (addr & UINT32_C(2)) << UINT32_C(3); - arm_mem_store(state, val << shift, UINT32_C(0xFFFF) << shift, addr & ~UINT32_C(2)); +void arm_mem_store_half(arm_t *arm, uint16_t val, uint32_t addr) { + uint32_t shift = (addr & 2) << 3; + if (unlikely(addr & 1)) { + arm_cpu_exception(arm, ARM_Exception_HardFault); + return; + } + arm_mem_store_any(arm, val << shift, ~(UINT32_C(0xFFFF) << shift), addr & ~2); } -void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr) { - arm_mem_store(state, val, UINT32_C(0xFFFFFFFF), addr); +void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr) { + if (unlikely(addr & 3)) { + arm_cpu_exception(arm, ARM_Exception_HardFault); + return; + } + if (likely(addr < PPB_ADDR)) { + arm_mem_store_any(arm, val, 0, addr); + return; + } else if (unlikely(addr < SCS_BASE)) { + } else if (unlikely(addr < SysTick_BASE)) { + } else if (unlikely(addr < NVIC_BASE)) { + arm_systick_t *systick = &arm->cpu.systick; + if (addr == (uint32_t)&SysTick->CTRL) { + systick->ctrl = (systick->ctrl & SysTick_CTRL_COUNTFLAG_Msk) | + (val & (SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk)); + return; + } else if (addr == (uint32_t)&SysTick->LOAD) { + systick->load = val & SysTick_LOAD_RELOAD_Msk; + return; + } else if (addr == (uint32_t)&SysTick->VAL) { + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; + systick->val = 0; + return; + } else if (addr == (uint32_t)&SysTick->CALIB) { + } + } else if (unlikely(addr < SCB_BASE)) { + arm_nvic_t *nvic = &arm->cpu.nvic; + if (addr == (uint32_t)&NVIC->ISER[0]) { + nvic->ier |= val; + return; + } else if (addr == (uint32_t)&NVIC->ICER[0]) { + nvic->ier &= ~val; + return; + } else if (addr == (uint32_t)&NVIC->ISPR[0]) { + nvic->ipr |= val; + return; + } else if (addr == (uint32_t)&NVIC->ICPR[0]) { + nvic->ipr &= ~val; + return; + } else if (addr >= (uint32_t)&NVIC->IP[0] && addr <= (uint32_t)&NVIC->IP[7]) { + nvic->ip[addr >> 2 & 7] = val & UINT32_C(0xC0C0C0C0); + return; + } + } else { + arm_scb_t *scb = &arm->cpu.scb; + if (addr == (uint32_t)&SCB->ICSR) { + if (val & SCB_ICSR_NMIPENDSET_Msk) { + scb->icsr |= SCB_ICSR_NMIPENDSET_Msk; + } + if (val & SCB_ICSR_PENDSVSET_Msk) { + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; + } else if (val & SCB_ICSR_PENDSVCLR_Msk) { + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; + } + if (val & SCB_ICSR_PENDSTSET_Msk) { + scb->icsr |= SCB_ICSR_PENDSTSET_Msk; + } else if (val & SCB_ICSR_PENDSTCLR_Msk) { + scb->icsr &= ~SCB_ICSR_PENDSTSET_Msk; + } + return; + } else if (addr == (uint32_t)&SCB->VTOR) { + scb->vtor = val & SCB_VTOR_TBLOFF_Msk; + return; + } else if (addr == (uint32_t)&SCB->SHP[0]) { + scb->shp[0] = val & UINT32_C(0xC0000000); + return; + } else if (addr == (uint32_t)&SCB->SHP[1]) { + scb->shp[1] = val & UINT32_C(0xC0C00000); + return; + } else if (addr == (uint32_t)&SCB->SHCSR) { + if (val & SCB_SHCSR_SVCALLPENDED_Msk) { + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; + } else { + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; + } + } + } + if (arm->debug) { + printf("%08X: store %08X %08X\n", arm->cpu.pc - 4, val, addr); + } + arm_cpu_exception(arm, ARM_Exception_HardFault); } diff --git a/core/arm/armmem.h b/core/arm/armmem.h index 28c1a747f..509fbb4b5 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -1,26 +1,148 @@ #ifndef ARMMEM_H #define ARMMEM_H +#include "arm.h" + +#define NO_VOLATILE_CONST_IO +#include "samd21a/include/samd21e18a.h" + +#include +#include #include +#include #include #include +#include + +typedef struct { + __IO PM_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 8) Control */ + __IO PM_SLEEP_Type SLEEP; /**< \brief Offset: 0x01 (R/W 8) Sleep Mode */ + __IO PM_CPUSEL_Type CPUSEL; /**< \brief Offset: 0x08 (R/W 8) CPU Clock Select */ + __IO PM_APBASEL_Type APBASEL; /**< \brief Offset: 0x09 (R/W 8) APBA Clock Select */ + __IO PM_APBBSEL_Type APBBSEL; /**< \brief Offset: 0x0A (R/W 8) APBB Clock Select */ + __IO PM_APBCSEL_Type APBCSEL; /**< \brief Offset: 0x0B (R/W 8) APBC Clock Select */ + __IO PM_AHBMASK_Type AHBMASK; /**< \brief Offset: 0x14 (R/W 32) AHB Mask */ + __IO PM_APBAMASK_Type APBAMASK; /**< \brief Offset: 0x18 (R/W 32) APBA Mask */ + __IO PM_APBBMASK_Type APBBMASK; /**< \brief Offset: 0x1C (R/W 32) APBB Mask */ + __IO PM_APBCMASK_Type APBCMASK; /**< \brief Offset: 0x20 (R/W 32) APBC Mask */ + __IO PM_INTENCLR_Type INTEN; /**< \brief Offset: 0x34 (R/W 8) Interrupt Enable Clear */ + /**< \brief Offset: 0x35 (R/W 8) Interrupt Enable Set */ + __IO PM_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x36 (R/W 8) Interrupt Flag Status and Clear */ + __I PM_RCAUSE_Type RCAUSE; /**< \brief Offset: 0x38 (R/ 8) Reset Cause */ +} PM_Type; + +typedef struct { + /**< \brief Offset: 0x0 (R/W 8) Control */ + /**< \brief Offset: 0x1 (R/ 8) Status */ + __IO GCLK_CLKCTRL_Type CLKCTRL /**< \brief Offset: 0x2 (R/W 16) Generic Clock Control */ + [GCLK_CLKCTRL_ID_I2S_1_Val + 1]; + __IO GCLK_GENCTRL_Type GENCTRL /**< \brief Offset: 0x4 (R/W 32) Generic Clock Generator Control */ + [GCLK_CLKCTRL_GEN_GCLK8_Val + 1]; + __IO GCLK_GENDIV_Type GENDIV /**< \brief Offset: 0x8 (R/W 32) Generic Clock Generator Division */ + [GCLK_CLKCTRL_GEN_GCLK8_Val + 1]; +} GCLK_Type; + +typedef struct { + __IO NVMCTRL_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 16) Control A */ + __IO NVMCTRL_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) Control B */ + /**< \brief Offset: 0x08 (R/W 32) NVM Parameter */ + __IO NVMCTRL_INTENCLR_Type INTEN; /**< \brief Offset: 0x0C (R/W 8) Interrupt Enable Clear */ + /**< \brief Offset: 0x10 (R/W 8) Interrupt Enable Set */ + __IO NVMCTRL_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x14 (R/W 8) Interrupt Flag Status and Clear */ + __IO NVMCTRL_STATUS_Type STATUS; /**< \brief Offset: 0x18 (R/W 16) Status */ + __IO NVMCTRL_ADDR_Type ADDR; /**< \brief Offset: 0x1C (R/W 32) Address */ + __IO NVMCTRL_LOCK_Type LOCK; /**< \brief Offset: 0x20 (R/W 16) Lock Section */ +} NVMCTRL_Type; + +typedef union { + struct { + uint16_t DATA:9; /*!< bit: 0.. 8 Data Value */ + bool VLD:1; /*!< bit: 9 Valid Flag */ + bool OVF:1; /*!< bit: 10 Overflow Flag */ + } bit; /*!< Structure used for bit access */ + uint16_t reg; /*!< Type used for register access */ +} SERCOM_BUFFER_Type; -typedef struct arm_state arm_state_t; +typedef struct { /* SPI Mode */ + __IO SERCOM_SPI_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) SPI Control A */ + __IO SERCOM_SPI_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) SPI Control B */ + __IO SERCOM_SPI_BAUD_Type BAUD; /**< \brief Offset: 0x0C (R/W 8) SPI Baud Rate */ + RoReg8 Reserved[2]; + __IO SERCOM_SPI_INTENCLR_Type INTEN; /**< \brief Offset: 0x14 (R/W 8) SPI Interrupt Enable Clear */ + /**< \brief Offset: 0x16 (R/W 8) SPI Interrupt Enable Set */ + __IO SERCOM_SPI_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x18 (R/W 8) SPI Interrupt Flag Status and Clear */ + __IO SERCOM_SPI_STATUS_Type STATUS; /**< \brief Offset: 0x1A (R/W 16) SPI Status */ + /**< \brief Offset: 0x1C (R/ 32) SPI Syncbusy */ + __IO SERCOM_SPI_ADDR_Type ADDR; /**< \brief Offset: 0x24 (R/W 32) SPI Address */ + /**< \brief Offset: 0x28 (R/W 32) SPI Data */ + /**< \brief Offset: 0x30 (R/W 8) SPI Debug Control */ + SERCOM_BUFFER_Type BUFFER[0x4]; + uint8_t SLEEPFLAG, SLEEPCOUNT; + bool SS; +} SERCOM_SPI_Type; + +typedef struct { /* USART Mode */ + __IO SERCOM_USART_CTRLA_Type CTRLA; /**< \brief Offset: 0x00 (R/W 32) USART Control A */ + __IO SERCOM_USART_CTRLB_Type CTRLB; /**< \brief Offset: 0x04 (R/W 32) USART Control B */ + __IO SERCOM_USART_BAUD_Type BAUD; /**< \brief Offset: 0x0C (R/W 16) USART Baud Rate */ + __IO SERCOM_USART_RXPL_Type RXPL; /**< \brief Offset: 0x0E (R/W 8) USART Receive Pulse Length */ + __IO SERCOM_USART_INTENCLR_Type INTEN; /**< \brief Offset: 0x14 (R/W 8) USART Interrupt Enable Clear */ + /**< \brief Offset: 0x16 (R/W 8) USART Interrupt Enable Set */ + __IO SERCOM_USART_INTFLAG_Type INTFLAG; /**< \brief Offset: 0x18 (R/W 8) USART Interrupt Flag Status and Clear */ + __IO SERCOM_USART_STATUS_Type STATUS; /**< \brief Offset: 0x1A (R/W 16) USART Status */ + /**< \brief Offset: 0x1C (R/ 32) USART Syncbusy */ + RoReg Reserved[1]; + /**< \brief Offset: 0x28 (R/W 16) USART Data */ + /**< \brief Offset: 0x30 (R/W 8) USART Debug Control */ + SERCOM_BUFFER_Type BUFFER[0x4]; + uint8_t SLEEPFLAG, SLEEPCOUNT; +} SERCOM_USART_Type; + +static_assert(offsetof(SERCOM_SPI_Type, CTRLA) == offsetof(SERCOM_USART_Type, CTRLA) && + offsetof(SERCOM_SPI_Type, CTRLB) == offsetof(SERCOM_USART_Type, CTRLB) && + offsetof(SERCOM_SPI_Type, BAUD) == offsetof(SERCOM_USART_Type, BAUD) && + offsetof(SERCOM_SPI_Type, INTEN) == offsetof(SERCOM_USART_Type, INTEN) && + offsetof(SERCOM_SPI_Type, INTFLAG) == offsetof(SERCOM_USART_Type, INTFLAG) && + offsetof(SERCOM_SPI_Type, STATUS) == offsetof(SERCOM_USART_Type, STATUS) && + offsetof(SERCOM_SPI_Type, BUFFER) == offsetof(SERCOM_USART_Type, BUFFER) && + offsetof(SERCOM_SPI_Type, SLEEPFLAG) == offsetof(SERCOM_USART_Type, SLEEPFLAG) && + offsetof(SERCOM_SPI_Type, SLEEPCOUNT) == offsetof(SERCOM_USART_Type, SLEEPCOUNT), + "SERCOM_SPI_Type and SERCOM_USART_Type are not compatible!"); + +typedef union { + SERCOM_SPI_Type SPI; /**< \brief Offset: 0x00 SPI Mode */ + SERCOM_USART_Type USART; /**< \brief Offset: 0x00 USART Mode */ +} SERCOM_Type; + +typedef struct arm_mem { + uint32_t *ram, *nvm, pb[FLASH_PAGE_SIZE >> 2]; + PM_Type pm; + GCLK_Type gclk; + NVMCTRL_Type nvmctrl; + SERCOM_Type sercom[SERCOM_INST_NUM]; +} arm_mem_t; #ifdef __cplusplus extern "C" { #endif -bool arm_mem_init(arm_state_t *state); -void arm_mem_destroy(arm_state_t *state); -void arm_mem_reset(arm_state_t *state); -bool arm_mem_load_rom(arm_state_t *state, FILE *file); -uint8_t arm_mem_load_byte(arm_state_t *state, uint32_t addr); -uint16_t arm_mem_load_half(arm_state_t *state, uint32_t addr); -uint32_t arm_mem_load_word(arm_state_t *state, uint32_t addr); -void arm_mem_store_byte(arm_state_t *state, uint8_t val, uint32_t addr); -void arm_mem_store_half(arm_state_t *state, uint16_t val, uint32_t addr); -void arm_mem_store_word(arm_state_t *state, uint32_t val, uint32_t addr); +bool arm_mem_init(arm_mem_t *mem); +void arm_mem_destroy(arm_mem_t *mem); +void arm_mem_reset(arm_mem_t *mem, uint8_t rcause); +bool arm_mem_load_rom(arm_mem_t *mem, FILE *file); +void arm_mem_update_pending(arm_t *arm); +uint8_t arm_mem_load_byte(arm_t *arm, uint32_t addr); +uint16_t arm_mem_load_half(arm_t *arm, uint32_t addr); +uint32_t arm_mem_load_word(arm_t *arm, uint32_t addr); +void arm_mem_store_byte(arm_t *arm, uint8_t val, uint32_t addr); +void arm_mem_store_half(arm_t *arm, uint16_t val, uint32_t addr); +void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr); + +void arm_mem_spi_sel(arm_t *arm, uint8_t pin, bool low); +uint8_t arm_mem_spi_peek(arm_t *arm, uint8_t pin, uint32_t *res); +void arm_mem_spi_xfer(arm_t *arm, uint8_t pin, uint32_t val); +bool arm_mem_usart_send(arm_t *arm, uint8_t pin, uint16_t *val); +bool arm_mem_usart_recv(arm_t *arm, uint8_t pin, uint16_t val); #ifdef __cplusplus } diff --git a/core/arm/armstate.c b/core/arm/armstate.c deleted file mode 100644 index b9f84b869..000000000 --- a/core/arm/armstate.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "armstate.h" - -#include "armcpu.h" -#include "armmem.h" - -bool arm_state_init(arm_state_t *state) { - return arm_mem_init(state); -} - -void arm_state_destroy(arm_state_t *state) { - arm_mem_destroy(state); -} - -void arm_state_reset(arm_state_t *state) { - arm_mem_reset(state); - arm_cpu_reset(state); -} - -void arm_state_load(arm_state_t *state, FILE *file) { - arm_mem_load_rom(state, file); -} diff --git a/core/arm/armstate.h b/core/arm/armstate.h index 5e79db314..0358198b1 100644 --- a/core/arm/armstate.h +++ b/core/arm/armstate.h @@ -1,28 +1,22 @@ #ifndef ARMSTATE_H #define ARMSTATE_H +#include "arm.h" #include "armcpu.h" +#include "armmem.h" +#include "spscqueue.h" +#include "sync.h" #include -#include -#include +#include -typedef struct arm_state { +struct arm { + sync_t sync; arm_cpu_t cpu; - uint32_t *flash, *ram; -} arm_state_t; - -#ifdef __cplusplus -extern "C" { -#endif - -bool arm_state_init(arm_state_t *state); -void arm_state_destroy(arm_state_t *state); -void arm_state_reset(arm_state_t *state); -void arm_state_load(arm_state_t *state, FILE *file); - -#ifdef __cplusplus -} -#endif + arm_mem_t mem; + spsc_queue_t usart[2]; + thrd_t thrd; + bool debug; +}; #endif diff --git a/core/arm/samd21a/include/samd21e18a.h b/core/arm/samd21a/include/samd21e18a.h index afc982eff..716d7c9fe 100644 --- a/core/arm/samd21a/include/samd21e18a.h +++ b/core/arm/samd21a/include/samd21e18a.h @@ -47,6 +47,7 @@ #if !(defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) #include +#ifndef NO_VOLATILE_CONST_IO #ifndef __cplusplus typedef volatile const uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ typedef volatile const uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ @@ -62,6 +63,17 @@ typedef volatile uint8_t WoReg8; /**< Write only 8-bit register (volati typedef volatile uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ typedef volatile uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ typedef volatile uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#else /* NO_VOLATILE_CONST_IO */ +typedef uint32_t RoReg; /**< Read only 32-bit register (volatile const unsigned int) */ +typedef uint16_t RoReg16; /**< Read only 16-bit register (volatile const unsigned int) */ +typedef uint8_t RoReg8; /**< Read only 8-bit register (volatile const unsigned int) */ +typedef uint32_t WoReg; /**< Write only 32-bit register (volatile unsigned int) */ +typedef uint16_t WoReg16; /**< Write only 16-bit register (volatile unsigned int) */ +typedef uint8_t WoReg8; /**< Write only 8-bit register (volatile unsigned int) */ +typedef uint32_t RwReg; /**< Read-Write 32-bit register (volatile unsigned int) */ +typedef uint16_t RwReg16; /**< Read-Write 16-bit register (volatile unsigned int) */ +typedef uint8_t RwReg8; /**< Read-Write 8-bit register (volatile unsigned int) */ +#endif /* NO_VOLATILE_CONST_IO */ #endif #if !defined(SKIP_INTEGER_LITERALS) diff --git a/core/arm/spscqueue.c b/core/arm/spscqueue.c new file mode 100644 index 000000000..0f441438f --- /dev/null +++ b/core/arm/spscqueue.c @@ -0,0 +1,80 @@ +#include "spscqueue.h" + +#include "../defines.h" + +#include +#include +#include + +static_assert(SPSC_QUEUE_SIZE && !(SPSC_QUEUE_SIZE & (SPSC_QUEUE_SIZE - 1)), + "Expected a non-zero power-of-two queue size."); + +bool spsc_queue_init(spsc_queue_t *queue) { + spsc_queue_clear(queue); + return true; +} + +void spsc_queue_clear(spsc_queue_t *queue) { + spsc_queue_index_t index = 0; + queue->enqueue = 0; + queue->dequeue = 0; + queue->poke = SPSC_QUEUE_INVALID_ENTRY; + queue->peek = SPSC_QUEUE_INVALID_ENTRY; + do { + atomic_init(&queue->queue[index], SPSC_QUEUE_INVALID_ENTRY); + index = SPSC_QUEUE_NEXT_INDEX(index); + } while (index); +} + +void spsc_queue_destroy(spsc_queue_t *queue) { + (void)queue; +} + +bool spsc_queue_flush(spsc_queue_t *queue) { + spsc_queue_entry_t poke = queue->poke; + bool success = true; + if (unlikely(poke != SPSC_QUEUE_INVALID_ENTRY)) { + spsc_queue_index_t index = SPSC_QUEUE_MASK_INDEX(queue->enqueue); + spsc_queue_entry_t invalid = SPSC_QUEUE_INVALID_ENTRY; + success = atomic_compare_exchange_weak_explicit( + &queue->queue[index], &invalid, poke, + memory_order_relaxed, memory_order_relaxed); + if (likely(success)) { + queue->enqueue = SPSC_QUEUE_NEXT_INDEX(index); + queue->poke = SPSC_QUEUE_INVALID_ENTRY; + } + } + return success; +} + +bool spsc_queue_enqueue(spsc_queue_t *queue, spsc_queue_entry_t entry) { + bool success; + assert(entry != SPSC_QUEUE_INVALID_ENTRY && + "Cannot queue invalid entry."); + success = spsc_queue_flush(queue); + if (likely(success)) { + queue->poke = entry; + } + return success; +} + +spsc_queue_entry_t spsc_queue_peek(spsc_queue_t *queue) { + spsc_queue_entry_t peek = queue->peek; + if (likely(peek == SPSC_QUEUE_INVALID_ENTRY)) { + spsc_queue_index_t index = SPSC_QUEUE_MASK_INDEX(queue->dequeue); + peek = atomic_exchange_explicit( + &queue->queue[index], SPSC_QUEUE_INVALID_ENTRY, + memory_order_relaxed); + if (likely(peek != SPSC_QUEUE_INVALID_ENTRY)) { + queue->dequeue = SPSC_QUEUE_NEXT_INDEX(index); + queue->peek = peek; + } + } + return peek; +} + +spsc_queue_entry_t spsc_queue_dequeue(spsc_queue_t *queue) { + spsc_queue_entry_t entry = spsc_queue_peek(queue); + queue->peek = SPSC_QUEUE_INVALID_ENTRY; + return entry; +} diff --git a/core/arm/spscqueue.h b/core/arm/spscqueue.h new file mode 100644 index 000000000..1fcc9e26c --- /dev/null +++ b/core/arm/spscqueue.h @@ -0,0 +1,43 @@ +#ifndef SPSCQUEUE_H +#define SPSCQUEUE_H + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint8_t spsc_queue_index_t; +typedef uint32_t spsc_queue_entry_t; + +#define SPSC_QUEUE_SIZE 0x10 +#define SPSC_QUEUE_MASK_INDEX(x) ((spsc_queue_index_t)(x & (SPSC_QUEUE_SIZE - 1))) +#define SPSC_QUEUE_NEXT_INDEX(x) SPSC_QUEUE_MASK_INDEX(x + 1) +#define SPSC_QUEUE_INVALID_ENTRY ((spsc_queue_entry_t)~0) + +typedef struct spsc_queue { + spsc_queue_index_t enqueue, dequeue; + spsc_queue_entry_t poke, peek; + _Atomic(spsc_queue_entry_t) queue[SPSC_QUEUE_SIZE]; +} spsc_queue_t; + +bool spsc_queue_init(spsc_queue_t *queue); +void spsc_queue_clear(spsc_queue_t *queue); +void spsc_queue_destroy(spsc_queue_t *queue); + +/* Producer thread only */ +bool spsc_queue_flush(spsc_queue_t *queue); +bool spsc_queue_enqueue(spsc_queue_t *queue, spsc_queue_entry_t entry); + +/* Consumer thread only */ +spsc_queue_entry_t spsc_queue_peek(spsc_queue_t *queue); +spsc_queue_entry_t spsc_queue_dequeue(spsc_queue_t *queue); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/core/arm/sync.c b/core/arm/sync.c index 282a1a7be..c83098951 100644 --- a/core/arm/sync.c +++ b/core/arm/sync.c @@ -6,15 +6,19 @@ bool sync_init(sync_t *sync) { if (likely(mtx_init(&sync->mtx, mtx_plain) == thrd_success)) { - if (likely(cnd_init(&sync->cnd[0]) == thrd_success)) { - if (likely(cnd_init(&sync->cnd[1]) == thrd_success)) { - atomic_init(&sync->cnt, 0u); - sync->run = true; - sync->rdy = false; - return true; - cnd_destroy(&sync->cnd[1]); + if (likely(cnd_init(&sync->cnd[false]) == thrd_success)) { + if (likely(cnd_init(&sync->cnd[true]) == thrd_success)) { + if (likely(cnd_init(&sync->cnd[2]) == thrd_success)) { + atomic_init(&sync->cnt, 0u); + sync->run = true; + sync->slp = false; + sync->rdy = false; + return true; + cnd_destroy(&sync->cnd[2]); + } + cnd_destroy(&sync->cnd[true]); } - cnd_destroy(&sync->cnd[0]); + cnd_destroy(&sync->cnd[false]); } mtx_destroy(&sync->mtx); } @@ -22,53 +26,108 @@ bool sync_init(sync_t *sync) { } void sync_destroy(sync_t *sync) { - cnd_destroy(&sync->cnd[1]); - cnd_destroy(&sync->cnd[0]); + cnd_destroy(&sync->cnd[2]); + cnd_destroy(&sync->cnd[true]); + cnd_destroy(&sync->cnd[false]); mtx_destroy(&sync->mtx); } -bool sync_check(sync_t *sync) { - if (likely(!atomic_load_explicit(&sync->cnt, memory_order_relaxed))) { - return true; - } +void sync_lock(sync_t *sync) { if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) { abort(); } +} + +void sync_unlock(sync_t *sync) { + if (unlikely(mtx_unlock(&sync->mtx) != thrd_success)) { + abort(); + } +} + +bool sync_check(sync_t *sync) { + return unlikely(atomic_load_explicit(&sync->cnt, memory_order_relaxed)); +} + +bool sync_loop(sync_t *sync) { + if (likely(!sync_check(sync))) { + return true; + } + sync_lock(sync); sync->rdy = true; do { - if (cnd_signal(&sync->cnd[0]) != thrd_success || - cnd_wait(&sync->cnd[1], &sync->mtx) != thrd_success) { + if (unlikely(cnd_signal(&sync->cnd[false]) != thrd_success || + cnd_wait(&sync->cnd[true], &sync->mtx) != thrd_success)) { abort(); } } while (unlikely(atomic_load_explicit(&sync->cnt, memory_order_relaxed))); bool run = sync->run; sync->rdy = false; - if (unlikely(mtx_unlock(&sync->mtx) != thrd_success)) { - abort(); - } + sync_unlock(sync); if (likely(run)) { + if (unlikely(cnd_broadcast(&sync->cnd[2]) != thrd_success)) { + abort(); + } return true; } sync_destroy(sync); return false; } -void sync_enter(sync_t *sync) { - if (unlikely(mtx_lock(&sync->mtx) != thrd_success)) { - abort(); +void sync_sleep(sync_t *sync) { + if (likely(!sync->slp)) { + (void)atomic_fetch_add_explicit(&sync->cnt, 1, memory_order_relaxed); + sync->slp = true; + } +} + +void sync_wake(sync_t *sync) { + if (likely(sync->slp)) { + (void)atomic_fetch_sub_explicit(&sync->cnt, 1, memory_order_relaxed); + sync->slp = false; } +} + +static void sync_reenter(sync_t *sync) { (void)atomic_fetch_add_explicit(&sync->cnt, 1, memory_order_relaxed); while (unlikely(!sync->rdy)) { - if (unlikely(cnd_wait(&sync->cnd[0], &sync->mtx) != thrd_success)) { + if (unlikely(cnd_wait(&sync->cnd[false], &sync->mtx) != thrd_success)) { abort(); } } } -void sync_leave(sync_t *sync) { +static void sync_maybe_leave(sync_t *sync, bool unlock) { bool done = atomic_fetch_sub_explicit(&sync->cnt, 1, memory_order_relaxed) == 1; - if (unlikely(mtx_unlock(&sync->mtx) != thrd_success || - cnd_signal(&sync->cnd[done]) != thrd_success)) { + if (unlock) { + sync_unlock(sync); + } + if (unlikely(cnd_signal(&sync->cnd[done]) != thrd_success)) { + abort(); + } +} + +static void sync_wait_run(sync_t *sync) { + sync_maybe_leave(sync, false); + if (unlikely(cnd_wait(&sync->cnd[2], &sync->mtx) != thrd_success)) { abort(); } } + +void sync_enter(sync_t *sync) { + sync_lock(sync); + sync_reenter(sync); +} + +void sync_run(sync_t *sync) { + sync_wait_run(sync); + sync_reenter(sync); +} + +void sync_leave(sync_t *sync) { + sync_maybe_leave(sync, true); +} + +void sync_run_leave(sync_t *sync) { + sync_wait_run(sync); + sync_unlock(sync); +} diff --git a/core/arm/sync.h b/core/arm/sync.h index a9fa01fae..d92da622c 100644 --- a/core/arm/sync.h +++ b/core/arm/sync.h @@ -11,20 +11,29 @@ extern "C" { typedef struct sync { mtx_t mtx; - cnd_t cnd[2]; - bool run, rdy; + cnd_t cnd[3]; atomic_uint cnt; + bool run, slp, rdy; } sync_t; bool sync_init(sync_t *sync); void sync_destroy(sync_t *sync); -/* Target thread only */ +/* Thread-safe, any thread */ +void sync_lock(sync_t *sync); +void sync_unlock(sync_t *sync); + +/* Target thread or while synced only */ bool sync_check(sync_t *sync); +bool sync_loop(sync_t *sync); +void sync_sleep(sync_t *sync); +void sync_wake(sync_t *sync); /* Thread-safe, not target thread */ void sync_enter(sync_t *sync); +void sync_run(sync_t *sync); void sync_leave(sync_t *sync); +void sync_run_leave(sync_t *sync); #ifdef __cplusplus } diff --git a/core/asic.c b/core/asic.c index eeec771f6..d28d5e3ba 100644 --- a/core/asic.c +++ b/core/asic.c @@ -21,6 +21,8 @@ #include "realclock.h" #include "defines.h" #include "cert.h" +#include "arm/armcpu.h" +#include "arm/armmem.h" #include #include diff --git a/core/coproc.c b/core/coproc.c index 24b9f523f..748a640da 100644 --- a/core/coproc.c +++ b/core/coproc.c @@ -1,15 +1,45 @@ #include "coproc.h" +#include "debug/debug.h" +#include "defines.h" +#include "emu.h" +#include "interrupt.h" +#include "schedule.h" -coproc_state_t coproc; +#include -void coproc_init(void) { -} +coproc_state_t coproc; void coproc_reset(void) { + gui_console_printf("[CEmu] Reset Coprocessor Interface...\n"); arm_destroy(coproc.arm); + memset(&coproc, 0, sizeof(coproc)); coproc.arm = arm_create(); } bool coproc_load(const char *path) { return arm_load(coproc.arm, path); } + +void coproc_uart_transmit(const uart_transfer_t *transfer) { + /* TODO: Send line control & divisor as well */ + arm_usart_send(coproc.arm, transfer->ch); +} + +bool coproc_uart_receive(uart_transfer_t *transfer) { + /* TODO: Populate line control & divisor based on ARM config */ + transfer->lcr = 3; + transfer->divisor = 13; + return arm_usart_recv(coproc.arm, &transfer->ch); +} + +void coproc_spi_select(bool low) { + arm_spi_sel(coproc.arm, low); +} + +uint8_t coproc_spi_peek(uint32_t *rxData) { + return arm_spi_peek(coproc.arm, rxData); +} + +uint8_t coproc_spi_transfer(uint32_t txData, uint32_t *rxData) { + return arm_spi_xfer(coproc.arm, txData, rxData); +} diff --git a/core/coproc.h b/core/coproc.h index 45a772ba5..71501b99d 100644 --- a/core/coproc.h +++ b/core/coproc.h @@ -2,6 +2,11 @@ #define COPROC_H #include "arm/arm.h" +#include "port.h" +#include "uart.h" + +#include +#include typedef struct coproc_state { arm_t *arm; @@ -13,9 +18,13 @@ extern "C" { extern coproc_state_t state; -void coproc_init(void); void coproc_reset(void); bool coproc_load(const char *path); +void coproc_uart_transmit(const uart_transfer_t *transfer); +bool coproc_uart_receive(uart_transfer_t *transfer); +void coproc_spi_select(bool low); +uint8_t coproc_spi_peek(uint32_t *rxData); +uint8_t coproc_spi_transfer(uint32_t txData, uint32_t *rxData); #ifdef __cplusplus } diff --git a/core/defines.h b/core/defines.h index 29c55c1ba..7c3c1d076 100644 --- a/core/defines.h +++ b/core/defines.h @@ -98,6 +98,9 @@ static inline uint32_t from_le32(uint32_t w) { #define to_le16 from_le16 #define to_le32 from_le32 +#define PASTE(x, y) x ## y +#define CONCAT(x, y) PASTE(x, y) + #define GETMASK(index, size) (((1U << (size)) - 1) << (index)) #define READFROM(data, index, size) (((data) & GETMASK((index), (size))) >> (index)) #define WRITE(data, index, size, value) ((data) = ((data) & (~GETMASK((index), (size)))) | ((uint32_t)(value) << (index))) diff --git a/core/spi.c b/core/spi.c index 4e84f3366..87e07045b 100644 --- a/core/spi.c +++ b/core/spi.c @@ -1,4 +1,5 @@ #include "spi.h" +#include "coproc.h" #include "cpu.h" #include "debug/debug.h" #include "emu.h" @@ -30,9 +31,15 @@ static uint8_t null_spi_transfer(uint32_t txData, uint32_t *rxData) { static void spi_set_device_funcs(void) { if (spi.arm) { - spi.device_select = null_spi_select; - spi.device_peek = null_spi_peek; - spi.device_transfer = null_spi_transfer; + if (asic.python) { + spi.device_select = coproc_spi_select; + spi.device_peek = coproc_spi_peek; + spi.device_transfer = coproc_spi_transfer; + } else { + spi.device_select = null_spi_select; + spi.device_peek = null_spi_peek; + spi.device_transfer = null_spi_transfer; + } } else { spi.device_select = panel_spi_select; spi.device_peek = panel_spi_peek; diff --git a/core/uart.c b/core/uart.c index ea4794609..53aa7cba5 100644 --- a/core/uart.c +++ b/core/uart.c @@ -1,4 +1,6 @@ #include "uart.h" +#include "asic.h" +#include "coproc.h" #include "emu.h" #include "interrupt.h" #include "schedule.h" @@ -83,9 +85,14 @@ static void uart_set_device_funcs(void) { uart_set_modem_outputs(0); } else { - /* For non-Python models, discard transmitted characters */ - uart.transmit_char = uart_transmit_null; - uart.receive_char = uart_receive_null; + if (asic.python) { + uart.transmit_char = coproc_uart_transmit; + uart.receive_char = coproc_uart_receive; + } else { + /* For non-Python models, discard transmitted characters */ + uart.transmit_char = uart_transmit_null; + uart.receive_char = uart_receive_null; + } /* Modem outputs seen externally */ uart_set_modem_outputs(uart.mcr & UART_MSR_BITS); } @@ -103,7 +110,7 @@ static uint32_t uart_char_ticks(void) { } static bool uart_timer_should_run(void) { - return uart.txActive || uart.rxTimeoutChars; + return asic.python || uart.txActive || uart.rxTimeoutChars; } static void uart_set_timer(bool force) { diff --git a/gui/qt/CEmu.pro b/gui/qt/CEmu.pro index bcfbd720e..57a14805a 100644 --- a/gui/qt/CEmu.pro +++ b/gui/qt/CEmu.pro @@ -208,7 +208,7 @@ SOURCES += \ ../../core/arm/arm.c \ ../../core/arm/armcpu.c \ ../../core/arm/armmem.c \ - ../../core/arm/armstate.c \ + ../../core/arm/spscqueue.c \ ../../core/arm/sync.c \ ../../core/asic.c \ ../../core/bootver.c \ @@ -294,12 +294,15 @@ SOURCES += ../../tests/autotester/autotester_cli.cpp \ ../../core/os/os-win32.c } +INCLUDEPATH += ../../core/arm/CMSIS/Core/Include + HEADERS += \ ../../tests/autotester/autotester.h \ ../../core/arm/arm.h \ ../../core/arm/armcpu.h \ ../../core/arm/armmem.h \ ../../core/arm/armstate.h \ + ../../core/arm/spscqueue.h \ ../../core/arm/sync.h \ ../../core/asic.h \ ../../core/bootver.h \ diff --git a/gui/qt/CMakeLists.txt b/gui/qt/CMakeLists.txt index 33bbd8b67..b70a0cd9d 100644 --- a/gui/qt/CMakeLists.txt +++ b/gui/qt/CMakeLists.txt @@ -90,7 +90,8 @@ set(CEmu_Sources ../../core/arm/arm.c ../../core/arm/arm.h ../../core/arm/armcpu.c ../../core/arm/armcpu.h ../../core/arm/armmem.c ../../core/arm/armmem.h - ../../core/arm/armstate.c ../../core/arm/armstate.h + ../../core/arm/armstate.h + ../../core/arm/spscqueue.c ../../core/arm/spscqueue.h ../../core/arm/sync.c ../../core/arm/sync.h ../../core/asic.c ../../core/asic.h ../../core/atomics.h @@ -179,6 +180,10 @@ set(CEmu_Sources qt_add_executable(CEmu ${MAYBE_MACOSX_BUNDLE} ${CEmu_Sources}) +target_include_directories(CEmu PRIVATE + ../../core/arm/CMSIS/Core/Include +) + # TODO better, see https://stackoverflow.com/a/21028226/378298 execute_process( COMMAND git describe --abbrev=7 --always diff --git a/gui/qt/mainwindow.cpp b/gui/qt/mainwindow.cpp index edb331b5e..1353fa99e 100644 --- a/gui/qt/mainwindow.cpp +++ b/gui/qt/mainwindow.cpp @@ -11,6 +11,7 @@ #include "../../core/emu.h" #include "../../core/asic.h" #include "../../core/cpu.h" +#include "../../core/coproc.h" #include "../../core/mem.h" #include "../../core/extras.h" #include "../../core/keypad.h" @@ -418,6 +419,7 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U // other gui actions connect(ui->checkAllowGroupDrag, &QCheckBox::stateChanged, this, &MainWindow::setDockGroupDrag); connect(ui->buttonRunSetup, &QPushButton::clicked, this, &MainWindow::runSetup); + connect(ui->buttonChangeArmRom, &QPushButton::clicked, this, &MainWindow::setArmRom); connect(ui->scaleLCD, static_cast(&QSpinBox::valueChanged), this, &MainWindow::setLcdScale); connect(ui->upscaleLCD, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::setLcdUpscale); connect(ui->fullscreenLCD, static_cast(&QComboBox::currentIndexChanged), this, &MainWindow::setLcdFullscreen); @@ -715,6 +717,9 @@ MainWindow::MainWindow(CEmuOpts &cliOpts, QWidget *p) : QMainWindow(p), ui(new U m_dir.setPath(m_config->value(SETTING_CURRENT_DIR, appDir().path()).toString()); + m_pathArmRom = m_config->value(SETTING_ARM_ROM_PATH).toString(); + ui->pathArmRom->setText(m_pathArmRom); + if (!m_config->contains(SETTING_IMAGE_PATH) || m_portable) { QString path = QFileInfo(m_pathConfig).absolutePath() + SETTING_DEFAULT_IMAGE_FILE; if (m_portable) { @@ -1970,6 +1975,9 @@ void MainWindow::showAsicRevInfo(const QList& supportedRevs, int loadedRev, } setCalcSkinTopFromType(python); + ui->labelArmRom->setVisible(python); + ui->pathArmRom->setVisible(python); + ui->buttonChangeArmRom->setVisible(python); } void MainWindow::showEmuSpeed(double emuTime) { @@ -2729,7 +2737,6 @@ void MainWindow::resetEmu() { } void MainWindow::emuCheck(emu_state_t state, emu_data_t type) { - /* don't need to do anything if just loading ram */ if (type == EMU_DATA_RAM && state == EMU_STATE_VALID) { guiEmuValid = true; @@ -2763,6 +2770,7 @@ void MainWindow::emuCheck(emu_state_t state, emu_data_t type) { static_cast(dock->widget())->forceUpdate(); } } + coproc_load(m_pathArmRom.toUtf8().constData()); emu.start(); guiEmuValid = true; } diff --git a/gui/qt/mainwindow.h b/gui/qt/mainwindow.h index bc8ad5ca3..e87b24803 100644 --- a/gui/qt/mainwindow.h +++ b/gui/qt/mainwindow.h @@ -476,6 +476,7 @@ private slots: // settings void setRom(const QString &path); + void setArmRom(); void setImagePath(); void setCalcId(); void setFocusSetting(bool state); @@ -805,6 +806,7 @@ private slots: QPointer m_memWidget = nullptr; QString m_pathRom; + QString m_pathArmRom; QString m_pathRam; QString m_pathImage; QTimer m_timerEmu; @@ -875,6 +877,7 @@ private slots: static const QString SETTING_SLOT_PATHS; static const QString SETTING_IMAGE_PATH; static const QString SETTING_ROM_PATH; + static const QString SETTING_ARM_ROM_PATH; static const QString SETTING_STATUS_INTERVAL; static const QString SETTING_FIRST_RUN; static const QString SETTING_UI_EDIT_MODE; diff --git a/gui/qt/mainwindow.ui b/gui/qt/mainwindow.ui index 81bd0f5fc..2bfaf7d8a 100644 --- a/gui/qt/mainwindow.ui +++ b/gui/qt/mainwindow.ui @@ -9395,6 +9395,13 @@ QPushButton:pressed { 5 + + + + ROM Image + + + @@ -9408,13 +9415,6 @@ QPushButton:pressed { - - - - Settings - - - @@ -9440,15 +9440,15 @@ QPushButton:pressed { - - + + - Saved Image + ARM ROM Image - - + + Qt::NoFocus @@ -9460,15 +9460,8 @@ QPushButton:pressed { - - - - Saved Debug - - - - - + + 0 @@ -9492,8 +9485,38 @@ QPushButton:pressed { - - + + + + Settings + + + + + + + true + + + Qt::NoFocus + + + false + + + true + + + + + + + Saved Image + + + + + 0 @@ -9517,11 +9540,8 @@ QPushButton:pressed { - - - - true - + + Qt::NoFocus @@ -9533,8 +9553,15 @@ QPushButton:pressed { - - + + + + Saved Debug + + + + + Qt::NoFocus @@ -9546,10 +9573,28 @@ QPushButton:pressed { - - + + + + + 0 + 0 + + + + + 0 + 0 + + + + Qt::NoFocus + - ROM Image + Change path + + + false diff --git a/gui/qt/settings.cpp b/gui/qt/settings.cpp index ee3c19c29..bab27d2d7 100644 --- a/gui/qt/settings.cpp +++ b/gui/qt/settings.cpp @@ -5,6 +5,7 @@ #include "utils.h" #include "keypad/qtkeypadbridge.h" +#include "../../core/coproc.h" #include "../../core/cpu.h" #include "../../core/emu.h" #include "../../core/keypad.h" @@ -91,6 +92,7 @@ const QString MainWindow::SETTING_SLOT_NAMES = QStringLiteral("Sl const QString MainWindow::SETTING_SLOT_PATHS = QStringLiteral("Slot/paths"); const QString MainWindow::SETTING_IMAGE_PATH = QStringLiteral("image_path"); const QString MainWindow::SETTING_ROM_PATH = QStringLiteral("rom_path"); +const QString MainWindow::SETTING_ARM_ROM_PATH = QStringLiteral("arm_rom_path"); const QString MainWindow::SETTING_STATUS_INTERVAL = QStringLiteral("status_interval"); const QString MainWindow::SETTING_FIRST_RUN = QStringLiteral("first_run"); const QString MainWindow::SETTING_UI_EDIT_MODE = QStringLiteral("ui_edit_mode"); @@ -144,9 +146,10 @@ void MainWindow::setPortable(bool state) { // Get all new paths, in absolute const QString newConfigPath = QFileInfo((state ? dir.path() : configPath) + SETTING_DEFAULT_CONFIG_FILE).absoluteFilePath(); const QString newConfigDirPath = QDir::cleanPath(QFileInfo(newConfigPath).absolutePath()); + QString newRomPath = m_pathRom; // No change here + QString newArmRomPath = m_pathArmRom; // No change here QString newDebugPath = newConfigDirPath + SETTING_DEFAULT_DEBUG_FILE; QString newImagePath = newConfigDirPath + SETTING_DEFAULT_IMAGE_FILE; - QString newRomPath = m_pathRom; // No change here // Update the FS (still using absolute paths) QFile(m_pathConfig).copy(newConfigPath); @@ -171,9 +174,10 @@ void MainWindow::setPortable(bool state) { // Update new QSettings (memory + FS) m_config = new QSettings(newConfigPath, QSettings::IniFormat); // Path is absolute + m_config->setValue(SETTING_ROM_PATH, newRomPath); + m_config->setValue(SETTING_ARM_ROM_PATH, newArmRomPath); m_config->setValue(SETTING_DEBUGGER_IMAGE_PATH, newDebugPath); m_config->setValue(SETTING_IMAGE_PATH, newImagePath); - m_config->setValue(SETTING_ROM_PATH, newRomPath); m_config->sync(); ui->pathDebug->setText(newDebugPath); @@ -529,6 +533,20 @@ void MainWindow::setCalcSkinTopFromType(bool python) const { ui->calcSkinTop->setStyleSheet(".QFrame { border-image: url(:/skin/resources/skin/" + fileName + ") 0 0 0 0 stretch stretch; }"); } +void MainWindow::setArmRom() { + m_pathArmRom = QFileDialog::getOpenFileName(this, tr("Set ARM ROM Image"), + m_dir.absolutePath(), + tr("ROM files (*.rom);;All files (*.*)")); + if (!m_pathArmRom.isEmpty()) { + m_dir = QFileInfo(m_pathArmRom).absoluteDir(); + m_config->setValue(SETTING_ARM_ROM_PATH, m_pathArmRom); + ui->pathArmRom->setText(m_pathArmRom); + if (guiEmuValid) { + coproc_load(m_pathArmRom.toUtf8().constData()); + } + } +} + void MainWindow::setImagePath() { QString saveImagePath = QFileDialog::getSaveFileName(this, tr("Set saved image to restore from"), m_dir.absolutePath(), From 09ed4f66a1884ad8a9763839f6aded8dc8e26017 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Oct 2023 18:46:09 -0400 Subject: [PATCH 07/26] Mostly fix Windows build, pending C11 threading support --- core/arm/armcpu.c | 28 +++++++++++++++++----------- core/asic.c | 2 -- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index f94a8be9b..3cd5f1a10 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -12,6 +12,12 @@ # define __has_builtin(builtin) 0 #endif +#ifdef _MSC_VER +# define DEBUG_BREAK __debugbreak() +#else +# define DEBUG_BREAK asm("int3") +#endif + #if defined(__GCC_ASM_FLAG_OUTPUTS__) && \ (defined(__i386) || defined(__x86_64__) || \ defined(_M_IX86) || defined(_M_IX64)) @@ -331,17 +337,17 @@ bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) { assert(exc > ARM_Thread_Mode && exc < ARM_Invalid_Exception && "Invalid exception"); - if (cpu->active & 1 << exc) { + if (cpu->active & UINT64_C(1) << exc) { return false; } if (arm->debug && exc == ARM_Exception_HardFault) { - asm("int3"); + DEBUG_BREAK; } if (cpu->exc) { cpu->exc = false; cpu->pc = 0; if (arm->debug) { - asm("int3"); + DEBUG_BREAK; } return false; } @@ -398,7 +404,7 @@ bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) { } uint32_t pc = arm_mem_load_word(arm, cpu->scb.vtor + (exc << 2)) + 1; if (!pc || pc >= UINT32_C(0x80000000)) { - asm("int3"); + DEBUG_BREAK;; } if (!cpu->exc) { cpu->exc = true; @@ -418,7 +424,7 @@ bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) { } cpu->scb.icsr = (cpu->scb.icsr & ~SCB_ICSR_VECTACTIVE_Msk) | (exc & SCB_ICSR_VECTACTIVE_Msk) << SCB_ICSR_VECTACTIVE_Pos; - cpu->active |= 1 << exc; + cpu->active |= UINT64_C(1) << exc; cpu->pc = pc; return true; } @@ -432,7 +438,7 @@ static void arm_cpu_interwork(arm_t *arm, uint32_t addr) { } else { // Exception Return uint32_t sp, val; - assert(!~(addr | 0xF) && cpu->active & 1 << curexc && + assert(!~(addr | 0xF) && cpu->active & UINT64_C(1) << curexc && "Unpredictable exception return"); cpu->active &= ~(1 << curexc); switch (addr) { @@ -492,7 +498,7 @@ static void arm_cpu_interwork(arm_t *arm, uint32_t addr) { } cpu->pc = arm_mem_load_word(arm, sp + 0x18) + 1; if (!cpu->pc || cpu->pc >= UINT32_C(0x80000000)) { - asm("int3"); + DEBUG_BREAK; } assert(cpu->pc & 1 && "Unpredictable exception return"); if (cpu->exc) { @@ -530,7 +536,7 @@ void arm_cpu_execute(arm_t *arm) { arm_cpu_t *cpu = &arm->cpu; uint32_t icsr = cpu->scb.icsr, pc = cpu->pc - 2, opc, val; if (arm->debug && pc >= UINT32_C(0x80000000)) { - asm("int3"); + DEBUG_BREAK; } uint8_t i; arm_exception_number_t curexc = @@ -587,12 +593,12 @@ void arm_cpu_execute(arm_t *arm) { if (arm->debug) { fprintf(stderr, "PC %08X %04X\n", pc, opc); if (!arm->sync.slp) { - asm("int3"); + DEBUG_BREAK; } //if (pc == UINT32_C(0x000010BC) || // pc == UINT32_C(0x000010CA) || // pc == UINT32_C(0x000010F6) || - // pc == UINT32_C(0x00001104)) asm("int3"); + // pc == UINT32_C(0x00001104)) DEBUG_BREAK; } switch (opc >> 12 & 0xF) { case 0: @@ -1135,7 +1141,7 @@ void arm_cpu_execute(arm_t *arm) { } if (!cpu->pc || cpu->pc >= UINT32_C(0x80000000) || cpu->pc - 2 == UINT32_C(0x00006A0C)) { - asm("int3"); + DEBUG_BREAK; } if (unlikely(cpu->exc)) { cpu->exc = false; diff --git a/core/asic.c b/core/asic.c index d28d5e3ba..e74c5105e 100644 --- a/core/asic.c +++ b/core/asic.c @@ -87,8 +87,6 @@ static void plug_devices(void) { add_reset_proc(panel_reset); add_reset_proc(spi_reset); add_reset_proc(uart_reset); - add_reset_proc(arm_mem_reset); - add_reset_proc(arm_cpu_reset); add_reset_proc(coproc_reset); gui_console_printf("[CEmu] Initialized Advanced Peripheral Bus...\n"); From 152191ffd42ac981c6ea13da8594b0cdec3b04fd Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Fri, 16 Aug 2024 00:56:08 -0400 Subject: [PATCH 08/26] Replace pointers to emulated system MMIO with addresses, fix PORT_IOBUS copy-paste error --- core/arm/armmem.c | 207 ++++++++++--------- core/arm/samd21a/include/instance/sbmatrix.h | 2 +- core/arm/samd21a/include/samd21e18a.h | 26 ++- 3 files changed, 138 insertions(+), 97 deletions(-) diff --git a/core/arm/armmem.c b/core/arm/armmem.c index f42051a33..81fc3c847 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -10,6 +10,9 @@ #define FLASH_REGION_SIZE (FLASH_SIZE >> 4) #define FLASH_ROW_SIZE (FLASH_PAGE_SIZE << 2) +#define PORT_PMUX_COUNT 16 +#define PORT_PINCFG_COUNT 32 + #define ARM_SERCOM_SLEEP 4 static uint32_t bitreverse(uint32_t x, uint8_t bits) { @@ -495,9 +498,9 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { case PORT_WRCONFIG_OFFSET >> 2: return PORT_WRCONFIG_RESETVALUE; default: - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + if (addr - (uint32_t)(PORT + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { return PORT_PMUX_RESETVALUE; - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + } else if (addr - (uint32_t)(PORT + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { return PORT_PINCFG_RESETVALUE; } break; @@ -689,9 +692,9 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { case PORT_WRCONFIG_OFFSET >> 2: return PORT_WRCONFIG_RESETVALUE; default: - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + if (addr - (uint32_t)(PORT_IOBUS + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { return PORT_PMUX_RESETVALUE; - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + } else if (addr - (uint32_t)(PORT_IOBUS + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { return PORT_PINCFG_RESETVALUE; } break; @@ -730,52 +733,57 @@ uint32_t arm_mem_load_word(arm_t *arm, uint32_t addr) { } else if (unlikely(addr < SysTick_BASE)) { } else if (unlikely(addr < NVIC_BASE)) { arm_systick_t *systick = &arm->cpu.systick; - if (addr == (uint32_t)&SysTick->CTRL) { - val = systick->ctrl; - systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; - return val; - } else if (addr == (uint32_t)&SysTick->LOAD) { - return systick->load; - } else if (addr == (uint32_t)&SysTick->VAL) { - return systick->val; - } else if (addr == (uint32_t)&SysTick->CALIB) { + switch (addr - SysTick_BASE) { + case 0x000: // CTRL + val = systick->ctrl; + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; + return val; + case 0x004: // LOAD + return systick->load; + case 0x008: // VAL + return systick->val; + case 0x00C: // CALIB + break; + default: + break; } } else if (unlikely(addr < SCB_BASE)) { arm_nvic_t *nvic = &arm->cpu.nvic; - if (addr == (uint32_t)&NVIC->ISER[0] || - addr == (uint32_t)&NVIC->ICER[0]) { + if (addr == NVIC_BASE + 0x000 || // ISER[0] + addr == NVIC_BASE + 0x080) { // ICER[0] return nvic->ier; - } else if (addr == (uint32_t)&NVIC->ISPR[0] || - addr == (uint32_t)&NVIC->ICPR[0]) { + } else if (addr == NVIC_BASE + 0x100 || // ISPR[0] + addr == NVIC_BASE + 0x180) { // ICPR[0] return nvic->ipr; - } else if (addr >= (uint32_t)&NVIC->IP[0] && - addr <= (uint32_t)&NVIC->IP[7]) { + } else if (addr >= NVIC_BASE + 0x300 && + addr < NVIC_BASE + 0x320) { // IP[0] - IP[7] return nvic->ip[addr >> 2 & 7]; } } else { arm_scb_t *scb = &arm->cpu.scb; - if (addr == (uint32_t)&SCB->CPUID) { - return 'A' << SCB_CPUID_IMPLEMENTER_Pos | - 0 << SCB_CPUID_VARIANT_Pos | - 12 << SCB_CPUID_ARCHITECTURE_Pos | - 28 << SCB_CPUID_PARTNO_Pos | - 6 << SCB_CPUID_REVISION_Pos; - } else if (addr == (uint32_t)&SCB->ICSR) { - return scb->icsr; - } else if (addr == (uint32_t)&SCB->VTOR) { - return scb->vtor; - } else if (addr == (uint32_t)&SCB->AIRCR) { - return 0; - } else if (addr == (uint32_t)&SCB->CCR) { - return SCB_CCR_STKALIGN_Msk | - SCB_CCR_UNALIGN_TRP_Msk; - } else if (addr == (uint32_t)&SCB->SHP[0]) { - return scb->shp[0]; - } else if (addr == (uint32_t)&SCB->SHP[1]) { - return scb->shp[1]; - } else if (addr == (uint32_t)&SCB->SHCSR) { - return (scb->icsr & SCB_ICSR_PENDSVSET_Msk) >> - SCB_ICSR_PENDSVSET_Pos << SCB_SHCSR_SVCALLPENDED_Pos; + switch (addr - SCB_BASE) { + case 0x000: // CPUID + return 'A' << SCB_CPUID_IMPLEMENTER_Pos | + 0 << SCB_CPUID_VARIANT_Pos | + 12 << SCB_CPUID_ARCHITECTURE_Pos | + 28 << SCB_CPUID_PARTNO_Pos | + 6 << SCB_CPUID_REVISION_Pos; + case 0x004: // ICSR + return scb->icsr; + case 0x008: // VTOR + return scb->vtor; + case 0x00C: // AIRCR + return 0; + case 0x014: // CCR + return SCB_CCR_STKALIGN_Msk | + SCB_CCR_UNALIGN_TRP_Msk; + case 0x01C: // SHP[0] + return scb->shp[0]; + case 0x020: // SHP[1] + return scb->shp[1]; + case 0x024: // SHCSR + return (scb->icsr & SCB_ICSR_PENDSVSET_Msk) >> + SCB_ICSR_PENDSVSET_Pos << SCB_SHCSR_SVCALLPENDED_Pos; } } if (arm->debug) { @@ -1053,9 +1061,9 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t case PORT_WRCONFIG_OFFSET >> 2: return; default: - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + if (addr - (uint32_t)(PORT + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { return; - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + } else if (addr - (uint32_t)(PORT + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { return; } break; @@ -1091,7 +1099,7 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t } } else { // SBMATRIX switch (addr) { - case (uint32_t)®_SBMATRIX_SFR4: + case (uint32_t)REG_SBMATRIX_SFR4: return; } } @@ -1332,9 +1340,9 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t case PORT_WRCONFIG_OFFSET >> 2: return; default: - if (addr - (uint32_t)&PORT->Group->PMUX < sizeof(PORT->Group->PMUX)) { + if (addr - (uint32_t)(PORT_IOBUS + PORT_PMUX_OFFSET) < (PORT_PMUX_COUNT << 2)) { return; - } else if (addr - (uint32_t)&PORT->Group->PINCFG < sizeof(PORT->Group->PINCFG)) { + } else if (addr - (uint32_t)(PORT_IOBUS + PORT_PINCFG_OFFSET) < (PORT_PINCFG_COUNT << 2)) { return; } break; @@ -1372,71 +1380,80 @@ void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr) { } else if (unlikely(addr < SysTick_BASE)) { } else if (unlikely(addr < NVIC_BASE)) { arm_systick_t *systick = &arm->cpu.systick; - if (addr == (uint32_t)&SysTick->CTRL) { - systick->ctrl = (systick->ctrl & SysTick_CTRL_COUNTFLAG_Msk) | - (val & (SysTick_CTRL_CLKSOURCE_Msk | - SysTick_CTRL_TICKINT_Msk | - SysTick_CTRL_ENABLE_Msk)); - return; - } else if (addr == (uint32_t)&SysTick->LOAD) { - systick->load = val & SysTick_LOAD_RELOAD_Msk; - return; - } else if (addr == (uint32_t)&SysTick->VAL) { - systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; - systick->val = 0; - return; - } else if (addr == (uint32_t)&SysTick->CALIB) { + switch (addr - SysTick_BASE) { + case 0x000: // CTRL + systick->ctrl = (systick->ctrl & SysTick_CTRL_COUNTFLAG_Msk) | + (val & (SysTick_CTRL_CLKSOURCE_Msk | + SysTick_CTRL_TICKINT_Msk | + SysTick_CTRL_ENABLE_Msk)); + return; + case 0x004: // LOAD + systick->load = val & SysTick_LOAD_RELOAD_Msk; + return; + case 0x008: // VAL + systick->ctrl &= ~SysTick_CTRL_COUNTFLAG_Msk; + systick->val = 0; + return; + case 0x00C: // CALIB + break; + default: + break; } } else if (unlikely(addr < SCB_BASE)) { arm_nvic_t *nvic = &arm->cpu.nvic; - if (addr == (uint32_t)&NVIC->ISER[0]) { + if (addr == NVIC_BASE + 0x000) { // ISER[0] nvic->ier |= val; return; - } else if (addr == (uint32_t)&NVIC->ICER[0]) { + } else if (addr == NVIC_BASE + 0x080) { // ICER[0] nvic->ier &= ~val; return; - } else if (addr == (uint32_t)&NVIC->ISPR[0]) { + } else if (addr == NVIC_BASE + 0x100) { // ISPR[0] nvic->ipr |= val; return; - } else if (addr == (uint32_t)&NVIC->ICPR[0]) { + } else if (addr == NVIC_BASE + 0x180) { // ICPR[0] nvic->ipr &= ~val; return; - } else if (addr >= (uint32_t)&NVIC->IP[0] && addr <= (uint32_t)&NVIC->IP[7]) { + } else if (addr >= NVIC_BASE + 0x300 && + addr < NVIC_BASE + 0x320) { // IP[0] - IP[7] nvic->ip[addr >> 2 & 7] = val & UINT32_C(0xC0C0C0C0); return; } } else { arm_scb_t *scb = &arm->cpu.scb; - if (addr == (uint32_t)&SCB->ICSR) { - if (val & SCB_ICSR_NMIPENDSET_Msk) { - scb->icsr |= SCB_ICSR_NMIPENDSET_Msk; - } - if (val & SCB_ICSR_PENDSVSET_Msk) { - scb->icsr |= SCB_ICSR_PENDSVSET_Msk; - } else if (val & SCB_ICSR_PENDSVCLR_Msk) { - scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; - } - if (val & SCB_ICSR_PENDSTSET_Msk) { - scb->icsr |= SCB_ICSR_PENDSTSET_Msk; - } else if (val & SCB_ICSR_PENDSTCLR_Msk) { - scb->icsr &= ~SCB_ICSR_PENDSTSET_Msk; - } - return; - } else if (addr == (uint32_t)&SCB->VTOR) { - scb->vtor = val & SCB_VTOR_TBLOFF_Msk; - return; - } else if (addr == (uint32_t)&SCB->SHP[0]) { - scb->shp[0] = val & UINT32_C(0xC0000000); - return; - } else if (addr == (uint32_t)&SCB->SHP[1]) { - scb->shp[1] = val & UINT32_C(0xC0C00000); - return; - } else if (addr == (uint32_t)&SCB->SHCSR) { - if (val & SCB_SHCSR_SVCALLPENDED_Msk) { - scb->icsr |= SCB_ICSR_PENDSVSET_Msk; - } else { - scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; - } + switch (addr - SCB_BASE) { + case 0x004: // ICSR + if (val & SCB_ICSR_NMIPENDSET_Msk) { + scb->icsr |= SCB_ICSR_NMIPENDSET_Msk; + } + if (val & SCB_ICSR_PENDSVSET_Msk) { + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; + } else if (val & SCB_ICSR_PENDSVCLR_Msk) { + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; + } + if (val & SCB_ICSR_PENDSTSET_Msk) { + scb->icsr |= SCB_ICSR_PENDSTSET_Msk; + } else if (val & SCB_ICSR_PENDSTCLR_Msk) { + scb->icsr &= ~SCB_ICSR_PENDSTSET_Msk; + } + return; + case 0x008: // VTOR + scb->vtor = val & SCB_VTOR_TBLOFF_Msk; + return; + case 0x01C: // SHP[0] + scb->shp[0] = val & UINT32_C(0xC0000000); + return; + case 0x020: // SHP[1] + scb->shp[1] = val & UINT32_C(0xC0C00000); + return; + case 0x024: // SHCSR + if (val & SCB_SHCSR_SVCALLPENDED_Msk) { + scb->icsr |= SCB_ICSR_PENDSVSET_Msk; + } else { + scb->icsr &= ~SCB_ICSR_PENDSVSET_Msk; + } + return; + default: + break; } } if (arm->debug) { diff --git a/core/arm/samd21a/include/instance/sbmatrix.h b/core/arm/samd21a/include/instance/sbmatrix.h index 46de7f304..56116a1e4 100644 --- a/core/arm/samd21a/include/instance/sbmatrix.h +++ b/core/arm/samd21a/include/instance/sbmatrix.h @@ -31,7 +31,7 @@ #define _SAMD21_SBMATRIX_INSTANCE_ /* ========== Register definition for SBMATRIX peripheral ========== */ -#if (defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) +#if (defined(NO_VOLATILE_CONST_IO) || defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__)) #define REG_SBMATRIX_PRAS0 (0x41007080) /**< \brief (SBMATRIX) Priority A for Slave 0 */ #define REG_SBMATRIX_PRBS0 (0x41007084) /**< \brief (SBMATRIX) Priority B for Slave 0 */ #define REG_SBMATRIX_PRAS1 (0x41007088) /**< \brief (SBMATRIX) Priority A for Slave 1 */ diff --git a/core/arm/samd21a/include/samd21e18a.h b/core/arm/samd21a/include/samd21e18a.h index 716d7c9fe..5176bd0f6 100644 --- a/core/arm/samd21a/include/samd21e18a.h +++ b/core/arm/samd21a/include/samd21e18a.h @@ -369,7 +369,7 @@ void I2S_Handler ( void ); /** \defgroup SAMD21E18A_base Peripheral Base Address Definitions */ /*@{*/ -#if defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) +#if defined(NO_VOLATILE_CONST_IO) || defined(__ASSEMBLY__) || defined(__IAR_SYSTEMS_ASM__) #define AC (0x42004400) /**< \brief (AC) APB Base Address */ #define ADC (0x42004000) /**< \brief (ADC) APB Base Address */ #define DAC (0x42004800) /**< \brief (DAC) APB Base Address */ @@ -410,6 +410,30 @@ void I2S_Handler ( void ); #define TCC2 (0x42002800) /**< \brief (TCC2) APB Base Address */ #define USB (0x41005000) /**< \brief (USB) APB Base Address */ #define WDT (0x40001000) /**< \brief (WDT) APB Base Address */ + +#define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ +#define ADC_INST_NUM 1 /**< \brief (ADC) Number of instances */ +#define DAC_INST_NUM 1 /**< \brief (DAC) Number of instances */ +#define DMAC_INST_NUM 1 /**< \brief (DMAC) Number of instances */ +#define DSU_INST_NUM 1 /**< \brief (DSU) Number of instances */ +#define EIC_INST_NUM 1 /**< \brief (EIC) Number of instances */ +#define EVSYS_INST_NUM 1 /**< \brief (EVSYS) Number of instances */ +#define GCLK_INST_NUM 1 /**< \brief (GCLK) Number of instances */ +#define HMATRIXB_INST_NUM 1 /**< \brief (HMATRIXB) Number of instances */ +#define I2S_INST_NUM 1 /**< \brief (I2S) Number of instances */ +#define MTB_INST_NUM 1 /**< \brief (MTB) Number of instances */ +#define NVMCTRL_INST_NUM 1 /**< \brief (NVMCTRL) Number of instances */ +#define PAC_INST_NUM 3 /**< \brief (PAC) Number of instances */ +#define PM_INST_NUM 1 /**< \brief (PM) Number of instances */ +#define PORT_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PORT_IOBUS_INST_NUM 1 /**< \brief (PORT) Number of instances */ +#define PTC_INST_NUM 1 /**< \brief (PTC) Number of instances */ +#define RTC_INST_NUM 1 /**< \brief (RTC) Number of instances */ +#define SERCOM_INST_NUM 4 /**< \brief (SERCOM) Number of instances */ +#define SYSCTRL_INST_NUM 1 /**< \brief (SYSCTRL) Number of instances */ +#define TC_INST_NUM 3 /**< \brief (TC) Number of instances */ +#define TCC_INST_NUM 3 /**< \brief (TCC) Number of instances */ +#define WDT_INST_NUM 1 /**< \brief (WDT) Number of instances */ #else #define AC ((Ac *)0x42004400UL) /**< \brief (AC) APB Base Address */ #define AC_INST_NUM 1 /**< \brief (AC) Number of instances */ From 92dbb6679f88263568548fd23385eeb436d2e298 Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Fri, 16 Aug 2024 14:06:04 +0200 Subject: [PATCH 09/26] armcpu: add macOS arm64 support for DEBUG_BREAK macro --- core/arm/armcpu.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 3cd5f1a10..cd7866a35 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -12,7 +12,9 @@ # define __has_builtin(builtin) 0 #endif -#ifdef _MSC_VER +#if defined(__aarch64__) && defined(__APPLE__) +# define DEBUG_BREAK __builtin_trap() +#elif defined(_MSC_VER) # define DEBUG_BREAK __debugbreak() #else # define DEBUG_BREAK asm("int3") From 2c27c6b75d9672f1d53db037859ec7732e657ea5 Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Fri, 16 Aug 2024 15:02:38 +0200 Subject: [PATCH 10/26] arm: use TinyCThread as fallback if C11 is not available. --- LICENSE | 29 ++ README.md | 2 +- core/arm/armmem.h | 2 +- core/arm/armstate.h | 2 +- core/arm/spscqueue.h | 2 +- core/arm/sync.h | 2 +- core/arm/threading.h | 5 + core/arm/tinycthread.c | 943 +++++++++++++++++++++++++++++++++++++++++ core/arm/tinycthread.h | 507 ++++++++++++++++++++++ gui/qt/CMakeLists.txt | 13 + 10 files changed, 1502 insertions(+), 5 deletions(-) create mode 100644 core/arm/threading.h create mode 100644 core/arm/tinycthread.c create mode 100644 core/arm/tinycthread.h diff --git a/LICENSE b/LICENSE index 79c4bd571..6e4b47e02 100644 --- a/LICENSE +++ b/LICENSE @@ -18,6 +18,8 @@ Portions of this program use code, directly or modified, from: CEmu also uses the APNG-enabled fork of libpng (https://sourceforge.net/projects/libpng-apng/) released under the zlib/libpng License. +If the C11 is not available, CEmu uses gyrovorbis' TinyCThread fork (https://github.com/gyrovorbis/tinycthread) released under the zlib License. + ________________________________________________________ z80e license: @@ -59,3 +61,30 @@ KDMacTouchBar license: GNU LESSER GENERAL PUBLIC LICENSE Version 3 See here: https://github.com/KDAB/KDMacTouchBar/blob/master/LICENSE.LGPL.txt + +________________________________________________________ +TinyCThread license: + +Copyright (c) 2012 Marcus Geelnard +Copyright (c) 2013-2016 Evan Nemerson + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +SPDX-License-Identifier: Zlib diff --git a/README.md b/README.md index c73383c5c..24b63cf2d 100644 --- a/README.md +++ b/README.md @@ -84,5 +84,5 @@ We also welcome more translations. Qt Linguist is a great tool for that (here's ## License CEmu is licensed under the [GPLv3](LICENSE). -_Acknowledgements_: Some CEmu parts are, directly, modified, or inspired, from [z80e](https://github.com/KnightOS/z80e), [Firebird](https://github.com/nspire-emus/firebird), [libtifiles](https://github.com/debrouxl/tilibs), [tivars_lib_cpp](https://github.com/adriweb/tivars_lib_cpp), [KDMacTouchBar](https://github.com/KDAB/KDMacTouchBar), and FatCow's ["Farm-Fresh Web Icons"](http://www.fatcow.com/free-icons). +_Acknowledgements_: Some CEmu parts are, directly, modified, or inspired, from [z80e](https://github.com/KnightOS/z80e), [Firebird](https://github.com/nspire-emus/firebird), [libtifiles](https://github.com/debrouxl/tilibs), [tivars_lib_cpp](https://github.com/adriweb/tivars_lib_cpp), [KDMacTouchBar](https://github.com/KDAB/KDMacTouchBar), [TinyCThread](https://github.com/gyrovorbis/tinycthread) (_gyrovorbis_'s fork), and FatCow's ["Farm-Fresh Web Icons"](http://www.fatcow.com/free-icons). The complete licensing information is available in the [LICENSE](LICENSE) file. diff --git a/core/arm/armmem.h b/core/arm/armmem.h index 509fbb4b5..ff002e1ed 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -12,7 +12,7 @@ #include #include #include -#include +#include "threading.h" typedef struct { __IO PM_CTRL_Type CTRL; /**< \brief Offset: 0x00 (R/W 8) Control */ diff --git a/core/arm/armstate.h b/core/arm/armstate.h index 0358198b1..fe5be058b 100644 --- a/core/arm/armstate.h +++ b/core/arm/armstate.h @@ -8,7 +8,7 @@ #include "sync.h" #include -#include +#include "threading.h" struct arm { sync_t sync; diff --git a/core/arm/spscqueue.h b/core/arm/spscqueue.h index 1fcc9e26c..0f9cdea81 100644 --- a/core/arm/spscqueue.h +++ b/core/arm/spscqueue.h @@ -4,7 +4,7 @@ #include #include #include -#include +#include "threading.h" #ifdef __cplusplus extern "C" { diff --git a/core/arm/sync.h b/core/arm/sync.h index d92da622c..cedc24435 100644 --- a/core/arm/sync.h +++ b/core/arm/sync.h @@ -3,7 +3,7 @@ #include #include -#include +#include "threading.h" #ifdef __cplusplus extern "C" { diff --git a/core/arm/threading.h b/core/arm/threading.h new file mode 100644 index 000000000..c5b488d94 --- /dev/null +++ b/core/arm/threading.h @@ -0,0 +1,5 @@ +#ifdef HAVE_C11_THREADS +#include +#else +#include "tinycthread.h" +#endif diff --git a/core/arm/tinycthread.c b/core/arm/tinycthread.c new file mode 100644 index 000000000..043cd05cf --- /dev/null +++ b/core/arm/tinycthread.c @@ -0,0 +1,943 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard +Copyright (c) 2013-2016 Evan Nemerson + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +SPDX-License-Identifier: Zlib +*/ + +#include "tinycthread.h" + +#ifndef _TTHREAD_CTHREADS_ +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include + #include + #include + #include + #include +#elif defined(_TTHREAD_WIN32_) + #include + #include +#endif + +/* Standard, good-to-have defines */ +#ifndef NULL + #define NULL (void*)0 +#endif +#ifndef TRUE + #define TRUE 1 +#endif +#ifndef FALSE + #define FALSE 0 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + + +int mtx_init(mtx_t *mtx, int type) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + mtx->mRecursive = type & mtx_recursive; + mtx->mTimed = type & mtx_timed; + if (!mtx->mTimed) + { + InitializeCriticalSection(&(mtx->mHandle.cs)); + } + else + { + mtx->mHandle.mut = CreateMutex(NULL, FALSE, NULL); + if (mtx->mHandle.mut == NULL) + { + return thrd_error; + } + } + return thrd_success; +#else + int ret; + pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); + if (type & mtx_recursive) + { + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + } + ret = pthread_mutex_init(mtx, &attr); + pthread_mutexattr_destroy(&attr); + return ret == 0 ? thrd_success : thrd_error; +#endif +} + +void mtx_destroy(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + if (!mtx->mTimed) + { + DeleteCriticalSection(&(mtx->mHandle.cs)); + } + else + { + CloseHandle(mtx->mHandle.mut); + } +#else + pthread_mutex_destroy(mtx); +#endif +} + +int mtx_lock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + if (!mtx->mTimed) + { + EnterCriticalSection(&(mtx->mHandle.cs)); + } + else + { + switch (WaitForSingleObject(mtx->mHandle.mut, INFINITE)) + { + case WAIT_OBJECT_0: + break; + case WAIT_ABANDONED: + default: + return thrd_error; + } + } + + if (!mtx->mRecursive) + { + while(mtx->mAlreadyLocked) Sleep(1); /* Simulate deadlock... */ + mtx->mAlreadyLocked = TRUE; + } + return thrd_success; +#else + return pthread_mutex_lock(mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct timespec current_ts; + DWORD timeoutMs; + + if (!mtx->mTimed) + { + return thrd_error; + } + + timespec_get(¤t_ts, TIME_UTC); + + if ((current_ts.tv_sec > ts->tv_sec) || ((current_ts.tv_sec == ts->tv_sec) && (current_ts.tv_nsec >= ts->tv_nsec))) + { + timeoutMs = 0; + } + else + { + timeoutMs = (DWORD)(ts->tv_sec - current_ts.tv_sec) * 1000; + timeoutMs += (ts->tv_nsec - current_ts.tv_nsec) / 1000000; + timeoutMs += 1; + } + + /* TODO: the timeout for WaitForSingleObject doesn't include time + while the computer is asleep. */ + switch (WaitForSingleObject(mtx->mHandle.mut, timeoutMs)) + { + case WAIT_OBJECT_0: + break; + case WAIT_TIMEOUT: + return thrd_timedout; + case WAIT_ABANDONED: + default: + return thrd_error; + } + + if (!mtx->mRecursive) + { + while(mtx->mAlreadyLocked) Sleep(1); /* Simulate deadlock... */ + mtx->mAlreadyLocked = TRUE; + } + + return thrd_success; +#elif defined(_POSIX_TIMEOUTS) && (_POSIX_TIMEOUTS >= 200112L) && defined(_POSIX_THREADS) && (_POSIX_THREADS >= 200112L) + switch (pthread_mutex_timedlock(mtx, ts)) { + case 0: + return thrd_success; + case ETIMEDOUT: + return thrd_timedout; + default: + return thrd_error; + } +#else + int rc; + struct timespec cur, dur; + + /* Try to acquire the lock and, if we fail, sleep for 5ms. */ + while ((rc = pthread_mutex_trylock (mtx)) == EBUSY) { + timespec_get(&cur, TIME_UTC); + + if ((cur.tv_sec > ts->tv_sec) || ((cur.tv_sec == ts->tv_sec) && (cur.tv_nsec >= ts->tv_nsec))) + { + break; + } + + dur.tv_sec = ts->tv_sec - cur.tv_sec; + dur.tv_nsec = ts->tv_nsec - cur.tv_nsec; + if (dur.tv_nsec < 0) + { + dur.tv_sec--; + dur.tv_nsec += 1000000000; + } + + if ((dur.tv_sec != 0) || (dur.tv_nsec > 5000000)) + { + dur.tv_sec = 0; + dur.tv_nsec = 5000000; + } + + nanosleep(&dur, NULL); + } + + switch (rc) { + case 0: + return thrd_success; + case ETIMEDOUT: + case EBUSY: + return thrd_timedout; + default: + return thrd_error; + } +#endif +} + +int mtx_trylock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + int ret; + + if (!mtx->mTimed) + { + ret = TryEnterCriticalSection(&(mtx->mHandle.cs)) ? thrd_success : thrd_busy; + } + else + { + ret = (WaitForSingleObject(mtx->mHandle.mut, 0) == WAIT_OBJECT_0) ? thrd_success : thrd_busy; + } + + if ((!mtx->mRecursive) && (ret == thrd_success)) + { + if (mtx->mAlreadyLocked) + { + LeaveCriticalSection(&(mtx->mHandle.cs)); + ret = thrd_busy; + } + else + { + mtx->mAlreadyLocked = TRUE; + } + } + return ret; +#else + return (pthread_mutex_trylock(mtx) == 0) ? thrd_success : thrd_busy; +#endif +} + +int mtx_unlock(mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + mtx->mAlreadyLocked = FALSE; + if (!mtx->mTimed) + { + LeaveCriticalSection(&(mtx->mHandle.cs)); + } + else + { + if (!ReleaseMutex(mtx->mHandle.mut)) + { + return thrd_error; + } + } + return thrd_success; +#else + return pthread_mutex_unlock(mtx) == 0 ? thrd_success : thrd_error;; +#endif +} + +#if defined(_TTHREAD_WIN32_) +#define _CONDITION_EVENT_ONE 0 +#define _CONDITION_EVENT_ALL 1 +#endif + +int cnd_init(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + cond->mWaitersCount = 0; + + /* Init critical section */ + InitializeCriticalSection(&cond->mWaitersCountLock); + + /* Init events */ + cond->mEvents[_CONDITION_EVENT_ONE] = CreateEvent(NULL, FALSE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ONE] == NULL) + { + cond->mEvents[_CONDITION_EVENT_ALL] = NULL; + return thrd_error; + } + cond->mEvents[_CONDITION_EVENT_ALL] = CreateEvent(NULL, TRUE, FALSE, NULL); + if (cond->mEvents[_CONDITION_EVENT_ALL] == NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + cond->mEvents[_CONDITION_EVENT_ONE] = NULL; + return thrd_error; + } + + return thrd_success; +#else + return pthread_cond_init(cond, NULL) == 0 ? thrd_success : thrd_error; +#endif +} + +void cnd_destroy(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + if (cond->mEvents[_CONDITION_EVENT_ONE] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ONE]); + } + if (cond->mEvents[_CONDITION_EVENT_ALL] != NULL) + { + CloseHandle(cond->mEvents[_CONDITION_EVENT_ALL]); + } + DeleteCriticalSection(&cond->mWaitersCountLock); +#else + pthread_cond_destroy(cond); +#endif +} + +int cnd_signal(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ONE]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_signal(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_broadcast(cnd_t *cond) +{ +#if defined(_TTHREAD_WIN32_) + int haveWaiters; + + /* Are there any waiters? */ + EnterCriticalSection(&cond->mWaitersCountLock); + haveWaiters = (cond->mWaitersCount > 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we have any waiting threads, send them a signal */ + if(haveWaiters) + { + if (SetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + return thrd_error; + } + } + + return thrd_success; +#else + return pthread_cond_broadcast(cond) == 0 ? thrd_success : thrd_error; +#endif +} + +#if defined(_TTHREAD_WIN32_) +static int _cnd_timedwait_win32(cnd_t *cond, mtx_t *mtx, DWORD timeout) +{ + DWORD result; + int lastWaiter; + + /* Increment number of waiters */ + EnterCriticalSection(&cond->mWaitersCountLock); + ++ cond->mWaitersCount; + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* Release the mutex while waiting for the condition (will decrease + the number of waiters when done)... */ + mtx_unlock(mtx); + + /* Wait for either event to become signaled due to cnd_signal() or + cnd_broadcast() being called */ + result = WaitForMultipleObjects(2, cond->mEvents, FALSE, timeout); + if (result == WAIT_TIMEOUT) + { + /* The mutex is locked again before the function returns, even if an error occurred */ + mtx_lock(mtx); + return thrd_timedout; + } + else if (result == WAIT_FAILED) + { + /* The mutex is locked again before the function returns, even if an error occurred */ + mtx_lock(mtx); + return thrd_error; + } + + /* Check if we are the last waiter */ + EnterCriticalSection(&cond->mWaitersCountLock); + -- cond->mWaitersCount; + lastWaiter = (result == (WAIT_OBJECT_0 + _CONDITION_EVENT_ALL)) && + (cond->mWaitersCount == 0); + LeaveCriticalSection(&cond->mWaitersCountLock); + + /* If we are the last waiter to be notified to stop waiting, reset the event */ + if (lastWaiter) + { + if (ResetEvent(cond->mEvents[_CONDITION_EVENT_ALL]) == 0) + { + /* The mutex is locked again before the function returns, even if an error occurred */ + mtx_lock(mtx); + return thrd_error; + } + } + + /* Re-acquire the mutex */ + mtx_lock(mtx); + + return thrd_success; +} +#endif + +int cnd_wait(cnd_t *cond, mtx_t *mtx) +{ +#if defined(_TTHREAD_WIN32_) + return _cnd_timedwait_win32(cond, mtx, INFINITE); +#else + return pthread_cond_wait(cond, mtx) == 0 ? thrd_success : thrd_error; +#endif +} + +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts) +{ +#if defined(_TTHREAD_WIN32_) + struct timespec now; + if (timespec_get(&now, TIME_UTC) == TIME_UTC) + { + unsigned long long nowInMilliseconds = now.tv_sec * 1000 + now.tv_nsec / 1000000; + unsigned long long tsInMilliseconds = ts->tv_sec * 1000 + ts->tv_nsec / 1000000; + DWORD delta = (tsInMilliseconds > nowInMilliseconds) ? + (DWORD)(tsInMilliseconds - nowInMilliseconds) : 0; + return _cnd_timedwait_win32(cond, mtx, delta); + } + else + return thrd_error; +#else + int ret; + ret = pthread_cond_timedwait(cond, mtx, ts); + if (ret == ETIMEDOUT) + { + return thrd_timedout; + } + return ret == 0 ? thrd_success : thrd_error; +#endif +} + +#if defined(_TTHREAD_WIN32_) +struct TinyCThreadTSSData { + void* value; + tss_t key; + struct TinyCThreadTSSData* next; +}; + +static tss_dtor_t _tinycthread_tss_dtors[1088] = { NULL, }; + +#ifdef _MSC_VER +# define _TTHREAD_LOCAL_ _declspec(thread) +#else +# define _TTHREAD_LOCAL_ _Thread_local +#endif + +static _TTHREAD_LOCAL_ struct TinyCThreadTSSData* _tinycthread_tss_head = NULL; +static _TTHREAD_LOCAL_ struct TinyCThreadTSSData* _tinycthread_tss_tail = NULL; + +static void _tinycthread_tss_cleanup (void); + +static void _tinycthread_tss_cleanup (void) { + struct TinyCThreadTSSData* data; + int iteration; + unsigned int again = 1; + void* value; + + for (iteration = 0 ; iteration < TSS_DTOR_ITERATIONS && again > 0 ; iteration++) + { + again = 0; + for (data = _tinycthread_tss_head ; data != NULL ; data = data->next) + { + if (data->value != NULL) + { + value = data->value; + data->value = NULL; + + if (_tinycthread_tss_dtors[data->key] != NULL) + { + again = 1; + _tinycthread_tss_dtors[data->key](value); + } + } + } + } + + while (_tinycthread_tss_head != NULL) { + data = _tinycthread_tss_head->next; + free (_tinycthread_tss_head); + _tinycthread_tss_head = data; + } + _tinycthread_tss_head = NULL; + _tinycthread_tss_tail = NULL; +} + +static void NTAPI _tinycthread_tss_callback(PVOID h, DWORD dwReason, PVOID pv) +{ + (void)h; + (void)pv; + + if (_tinycthread_tss_head != NULL && (dwReason == DLL_THREAD_DETACH || dwReason == DLL_PROCESS_DETACH)) + { + _tinycthread_tss_cleanup(); + } +} + +#if defined(_MSC_VER) + #ifdef _M_X64 + #pragma const_seg(".CRT$XLB") + #else + #pragma data_seg(".CRT$XLB") + #endif + PIMAGE_TLS_CALLBACK p_thread_callback = _tinycthread_tss_callback; + #ifdef _M_X64 + #pragma data_seg() + #else + #pragma const_seg() + #endif +#else + PIMAGE_TLS_CALLBACK p_thread_callback __attribute__((section(".CRT$XLB"))) = _tinycthread_tss_callback; +#endif + +#endif /* defined(_TTHREAD_WIN32_) */ + +/** Information to pass to the new thread (what to run). */ +typedef struct { + thrd_start_t mFunction; /**< Pointer to the function to be executed. */ + void * mArg; /**< Function argument for the thread function. */ +} _thread_start_info; + +/* Thread wrapper function. */ +#if defined(_TTHREAD_WIN32_) +static DWORD WINAPI _thrd_wrapper_function(LPVOID aArg) +#elif defined(_TTHREAD_POSIX_) +static void * _thrd_wrapper_function(void * aArg) +#endif +{ + thrd_start_t fun; + void *arg; + int res; + + /* Get thread startup information */ + _thread_start_info *ti = (_thread_start_info *) aArg; + fun = ti->mFunction; + arg = ti->mArg; + + /* The thread is responsible for freeing the startup information */ + free((void *)ti); + + /* Call the actual client thread function */ + res = fun(arg); + +#if defined(_TTHREAD_WIN32_) + if (_tinycthread_tss_head != NULL) + { + _tinycthread_tss_cleanup(); + } + + return (DWORD)res; +#else + return (void*)(intptr_t)res; +#endif +} + +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) +{ + /* Fill out the thread startup information (passed to the thread wrapper, + which will eventually free it) */ + _thread_start_info* ti = (_thread_start_info*)malloc(sizeof(_thread_start_info)); + if (ti == NULL) + { + return thrd_nomem; + } + ti->mFunction = func; + ti->mArg = arg; + + /* Create the thread */ +#if defined(_TTHREAD_WIN32_) + *thr = CreateThread(NULL, 0, _thrd_wrapper_function, (LPVOID) ti, 0, NULL); +#elif defined(_TTHREAD_POSIX_) + if(pthread_create(thr, NULL, _thrd_wrapper_function, (void *)ti) != 0) + { + *thr = 0; + } +#endif + + /* Did we fail to create the thread? */ + if(!*thr) + { + free(ti); + return thrd_error; + } + + return thrd_success; +} + +thrd_t thrd_current(void) +{ +#if defined(_TTHREAD_WIN32_) + return GetCurrentThread(); +#else + return pthread_self(); +#endif +} + +int thrd_detach(thrd_t thr) +{ +#if defined(_TTHREAD_WIN32_) + /* https://stackoverflow.com/questions/12744324/how-to-detach-a-thread-on-windows-c#answer-12746081 */ + return CloseHandle(thr) != 0 ? thrd_success : thrd_error; +#else + return pthread_detach(thr) == 0 ? thrd_success : thrd_error; +#endif +} + +int thrd_equal(thrd_t thr0, thrd_t thr1) +{ +#if defined(_TTHREAD_WIN32_) + return GetThreadId(thr0) == GetThreadId(thr1); +#else + return pthread_equal(thr0, thr1); +#endif +} + +void thrd_exit(int res) +{ +#if defined(_TTHREAD_WIN32_) + if (_tinycthread_tss_head != NULL) + { + _tinycthread_tss_cleanup(); + } + + ExitThread((DWORD)res); +#else + pthread_exit((void*)(intptr_t)res); +#endif +} + +int thrd_join(thrd_t thr, int *res) +{ +#if defined(_TTHREAD_WIN32_) + DWORD dwRes; + + if (WaitForSingleObject(thr, INFINITE) == WAIT_FAILED) + { + return thrd_error; + } + if (res != NULL) + { + if (GetExitCodeThread(thr, &dwRes) != 0) + { + *res = (int) dwRes; + } + else + { + return thrd_error; + } + } + CloseHandle(thr); +#elif defined(_TTHREAD_POSIX_) + void *pres; + if (pthread_join(thr, &pres) != 0) + { + return thrd_error; + } + if (res != NULL) + { + *res = (int)(intptr_t)pres; + } +#endif + return thrd_success; +} + +int thrd_sleep(const struct timespec *duration, struct timespec *remaining) +{ +#if !defined(_TTHREAD_WIN32_) + int res = nanosleep(duration, remaining); + if (res == 0) { + return 0; + } else if (errno == EINTR) { + return -1; + } else { + return -2; + } +#else + struct timespec start; + DWORD t; + + timespec_get(&start, TIME_UTC); + + t = SleepEx((DWORD)(duration->tv_sec * 1000 + + duration->tv_nsec / 1000000 + + (((duration->tv_nsec % 1000000) == 0) ? 0 : 1)), + TRUE); + + if (t == 0) { + return 0; + } else { + if (remaining != NULL) { + timespec_get(remaining, TIME_UTC); + remaining->tv_sec -= start.tv_sec; + remaining->tv_nsec -= start.tv_nsec; + if (remaining->tv_nsec < 0) + { + remaining->tv_nsec += 1000000000; + remaining->tv_sec -= 1; + } + } + + return (t == WAIT_IO_COMPLETION) ? -1 : -2; + } +#endif +} + +void thrd_yield(void) +{ +#if defined(_TTHREAD_WIN32_) + /* we are not interesting in a result of this function, calm it down. */ + (void) SwitchToThread(); +#else + sched_yield(); +#endif +} + +int tss_create(tss_t *key, tss_dtor_t dtor) +{ +#if defined(_TTHREAD_WIN32_) + *key = TlsAlloc(); + if (*key == TLS_OUT_OF_INDEXES) + { + return thrd_error; + } + _tinycthread_tss_dtors[*key] = dtor; +#else + if (pthread_key_create(key, dtor) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +void tss_delete(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*) TlsGetValue (key); + struct TinyCThreadTSSData* prev = NULL; + if (data != NULL) + { + if (data == _tinycthread_tss_head) + { + _tinycthread_tss_head = data->next; + } + else + { + prev = _tinycthread_tss_head; + if (prev != NULL) + { + while (prev->next != data) + { + prev = prev->next; + } + } + } + + if (data == _tinycthread_tss_tail) + { + _tinycthread_tss_tail = prev; + } + + free (data); + } + _tinycthread_tss_dtors[key] = NULL; + TlsFree(key); +#else + pthread_key_delete(key); +#endif +} + +void *tss_get(tss_t key) +{ +#if defined(_TTHREAD_WIN32_) + struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*)TlsGetValue(key); + if (data == NULL) + { + return NULL; + } + return data->value; +#else + return pthread_getspecific(key); +#endif +} + +int tss_set(tss_t key, void *val) +{ +#if defined(_TTHREAD_WIN32_) + struct TinyCThreadTSSData* data = (struct TinyCThreadTSSData*)TlsGetValue(key); + if (data == NULL) + { + data = (struct TinyCThreadTSSData*)malloc(sizeof(struct TinyCThreadTSSData)); + if (data == NULL) + { + return thrd_error; + } + + data->value = NULL; + data->key = key; + data->next = NULL; + + if (_tinycthread_tss_tail != NULL) + { + _tinycthread_tss_tail->next = data; + } + else + { + _tinycthread_tss_tail = data; + } + + if (_tinycthread_tss_head == NULL) + { + _tinycthread_tss_head = data; + } + + if (!TlsSetValue(key, data)) + { + free (data); + return thrd_error; + } + } + data->value = val; +#else + if (pthread_setspecific(key, val) != 0) + { + return thrd_error; + } +#endif + return thrd_success; +} + +#if defined(_TTHREAD_EMULATE_TIMESPEC_GET_) +int _tthread_timespec_get(struct timespec *ts, int base) +{ +#if defined(_TTHREAD_WIN32_) + struct _timeb tb; +#elif !defined(CLOCK_REALTIME) + struct timeval tv; +#endif + + if (base != TIME_UTC) + { + return 0; + } + +#if defined(_TTHREAD_WIN32_) + _ftime_s(&tb); + ts->tv_sec = (time_t)tb.time; + ts->tv_nsec = 1000000L * (long)tb.millitm; +#elif defined(CLOCK_REALTIME) + base = (clock_gettime(CLOCK_REALTIME, ts) == 0) ? base : 0; +#else + gettimeofday(&tv, NULL); + ts->tv_sec = (time_t)tv.tv_sec; + ts->tv_nsec = 1000L * (long)tv.tv_usec; +#endif + + return base; +} +#endif /* _TTHREAD_EMULATE_TIMESPEC_GET_ */ + +#if defined(_TTHREAD_WIN32_) +void call_once(once_flag *flag, void (*func)(void)) +{ + /* The idea here is that we use a spin lock (via the + InterlockedCompareExchange function) to restrict access to the + critical section until we have initialized it, then we use the + critical section to block until the callback has completed + execution. */ + while (flag->status < 3) + { + switch (flag->status) + { + case 0: + if (InterlockedCompareExchange (&(flag->status), 1, 0) == 0) { + InitializeCriticalSection(&(flag->lock)); + EnterCriticalSection(&(flag->lock)); + flag->status = 2; + func(); + flag->status = 3; + LeaveCriticalSection(&(flag->lock)); + return; + } + break; + case 1: + break; + case 2: + EnterCriticalSection(&(flag->lock)); + LeaveCriticalSection(&(flag->lock)); + break; + } + } +} +#endif /* defined(_TTHREAD_WIN32_) */ + +#ifdef __cplusplus +} +#endif +#endif diff --git a/core/arm/tinycthread.h b/core/arm/tinycthread.h new file mode 100644 index 000000000..2ad6c3afc --- /dev/null +++ b/core/arm/tinycthread.h @@ -0,0 +1,507 @@ +/* -*- mode: c; tab-width: 2; indent-tabs-mode: nil; -*- +Copyright (c) 2012 Marcus Geelnard +Copyright (c) 2013-2016 Evan Nemerson + +This software is provided 'as-is', without any express or implied +warranty. In no event will the authors be held liable for any damages +arising from the use of this software. + +Permission is granted to anyone to use this software for any purpose, +including commercial applications, and to alter it and redistribute it +freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + + 3. This notice may not be removed or altered from any source + distribution. + +SPDX-License-Identifier: Zlib +*/ + +#ifndef _TINYCTHREAD_H_ +#define _TINYCTHREAD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/** +* @file +* @mainpage TinyCThread API Reference +* +* @section intro_sec Introduction +* TinyCThread is a minimal, portable implementation of basic threading +* classes for C. +* +* They closely mimic the functionality and naming of the C11 standard, and +* should be easily replaceable with the corresponding standard variants. +* +* @section port_sec Portability +* The Win32 variant uses the native Win32 API for implementing the thread +* classes, while for other systems, the POSIX threads API (pthread) is used. +* +* @section misc_sec Miscellaneous +* The following special keywords are available: #_Thread_local. +* +* For more detailed information, browse the different sections of this +* documentation. A good place to start is: +* tinycthread.h. +*/ + +#ifdef _WIN32 +# define NOGDI +# elif !defined(__USE_UNIX98) +# define __USE_UNIX98 +#endif + +/* Which platform are we on? */ +#if !defined(_TTHREAD_PLATFORM_DEFINED_) + #if defined(_WIN32) || defined(__WIN32__) || defined(__WINDOWS__) + #define _TTHREAD_WIN32_ + #elif defined( __DREAMCAST__) + #define _TTHREAD_CTHREADS_ + #include + #else + #define _TTHREAD_POSIX_ + #endif + #define _TTHREAD_PLATFORM_DEFINED_ +#endif + +#ifndef _TTHREAD_CTHREADS_ + +/* Activate some POSIX functionality (e.g. clock_gettime and recursive mutexes) */ +#if defined(_TTHREAD_POSIX_) + #undef _FEATURES_H + #if !defined(_GNU_SOURCE) + #define _GNU_SOURCE + #endif + #if !defined(_POSIX_C_SOURCE) || ((_POSIX_C_SOURCE - 0) < 199309L) + #undef _POSIX_C_SOURCE + #define _POSIX_C_SOURCE 199309L + #endif + #if !defined(_XOPEN_SOURCE) || ((_XOPEN_SOURCE - 0) < 500) + #undef _XOPEN_SOURCE + #define _XOPEN_SOURCE 500 + #endif + #define _XPG6 +#endif + +/* Generic includes */ +#include + +/* Platform specific includes */ +#if defined(_TTHREAD_POSIX_) + #include + #include +#elif defined(_TTHREAD_WIN32_) + #ifndef WIN32_LEAN_AND_MEAN + #define WIN32_LEAN_AND_MEAN + #define __UNDEF_LEAN_AND_MEAN + #endif + #include + #ifdef __UNDEF_LEAN_AND_MEAN + #undef WIN32_LEAN_AND_MEAN + #undef __UNDEF_LEAN_AND_MEAN + #endif + #ifdef __MINGW32__ + /* MinGW has no _ftime_s symbol */ + #define _ftime_s _ftime + #endif +#endif + +/* Compiler-specific information */ +#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L + #define TTHREAD_NORETURN _Noreturn +#elif defined(__GNUC__) + #define TTHREAD_NORETURN __attribute__((__noreturn__)) +#else + #define TTHREAD_NORETURN +#endif + +/* If TIME_UTC is missing, provide it and provide a wrapper for + timespec_get. */ +#ifndef TIME_UTC +#define TIME_UTC 1 +#define _TTHREAD_EMULATE_TIMESPEC_GET_ + +#if defined(_TTHREAD_WIN32_) +struct _tthread_timespec { + time_t tv_sec; + long tv_nsec; +}; +#define timespec _tthread_timespec +#endif + +int _tthread_timespec_get(struct timespec *ts, int base); +#define timespec_get _tthread_timespec_get +#endif + +/** TinyCThread version (major number). */ +#define TINYCTHREAD_VERSION_MAJOR 1 +/** TinyCThread version (minor number). */ +#define TINYCTHREAD_VERSION_MINOR 2 +/** TinyCThread version (full version). */ +#define TINYCTHREAD_VERSION (TINYCTHREAD_VERSION_MAJOR * 100 + TINYCTHREAD_VERSION_MINOR) + +/** +* @def _Thread_local +* Thread local storage keyword. +* A variable that is declared with the @c _Thread_local keyword makes the +* value of the variable local to each thread (known as thread-local storage, +* or TLS). Example usage: +* @code +* // This variable is local to each thread. +* _Thread_local int variable; +* @endcode +* @note The @c _Thread_local keyword is a macro that maps to the corresponding +* compiler directive (e.g. @c __declspec(thread)). +* @note This directive is currently not supported on Mac OS X (it will give +* a compiler error), since compile-time TLS is not supported in the Mac OS X +* executable format. Also, some older versions of MinGW (before GCC 4.x) do +* not support this directive, nor does the Tiny C Compiler. +* @hideinitializer +*/ + +#if !(defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201102L)) && !defined(_Thread_local) + #if defined(__GNUC__) || defined(__INTEL_COMPILER) || defined(__SUNPRO_CC) || defined(__IBMCPP__) + #define _Thread_local __thread + #else + #define _Thread_local __declspec(thread) + #endif +#elif defined(__GNUC__) && defined(__GNUC_MINOR__) && (((__GNUC__ << 8) | __GNUC_MINOR__) < ((4 << 8) | 9)) + #define _Thread_local __thread +#endif + +#define thread_local _Thread_local + +/* Macros */ +#if defined(_TTHREAD_WIN32_) +#define TSS_DTOR_ITERATIONS (4) +#else +#define TSS_DTOR_ITERATIONS PTHREAD_DESTRUCTOR_ITERATIONS +#endif + +/* Function return values */ +enum +{ + thrd_success = 0, /**< The requested operation succeeded */ + thrd_busy = 1, /**< The requested operation failed because a resource requested by a test and return function is already in use */ + thrd_error = 2, /**< The requested operation failed */ + thrd_nomem = 3, /**< The requested operation failed because it was unable to allocate memory */ + thrd_timedout = 4 /**< The time specified in the call was reached without acquiring the requested resource */ +}; + +/* Mutex types */ +enum +{ + mtx_plain = 0, + mtx_recursive = 1, + mtx_timed = 2 +}; + +/* Mutex */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + union { + CRITICAL_SECTION cs; /* Critical section handle (used for non-timed mutexes) */ + HANDLE mut; /* Mutex handle (used for timed mutex) */ + } mHandle; /* Mutex handle */ + int mAlreadyLocked; /* TRUE if the mutex is already locked */ + int mRecursive; /* TRUE if the mutex is recursive */ + int mTimed; /* TRUE if the mutex is timed */ +} mtx_t; +#else +typedef pthread_mutex_t mtx_t; +#endif + +/** Create a mutex object. +* @param mtx A mutex object. +* @param type Bit-mask that must have one of the following six values: +* @li @c mtx_plain for a simple non-recursive mutex +* @li @c mtx_timed for a non-recursive mutex that supports timeout +* @li @c mtx_plain | @c mtx_recursive (same as @c mtx_plain, but recursive) +* @li @c mtx_timed | @c mtx_recursive (same as @c mtx_timed, but recursive) +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_init(mtx_t *mtx, int type); + +/** Release any resources used by the given mutex. +* @param mtx A mutex object. +*/ +void mtx_destroy(mtx_t *mtx); + +/** Lock the given mutex. +* Blocks until the given mutex can be locked. If the mutex is non-recursive, and +* the calling thread already has a lock on the mutex, this call will block +* forever. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_lock(mtx_t *mtx); + +/** Lock the given mutex, or block until a specific point in time. +* Blocks until either the given mutex can be locked, or the specified TIME_UTC +* based time. +* @param mtx A mutex object. +* @param ts A UTC based calendar time +* @return @ref The mtx_timedlock function returns thrd_success on success, or +* thrd_timedout if the time specified was reached without acquiring the +* requested resource, or thrd_error if the request could not be honored. +*/ +int mtx_timedlock(mtx_t *mtx, const struct timespec *ts); + +/** Try to lock the given mutex. +* The specified mutex shall support either test and return or timeout. If the +* mutex is already locked, the function returns without blocking. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_busy if the resource +* requested is already in use, or @ref thrd_error if the request could not be +* honored. +*/ +int mtx_trylock(mtx_t *mtx); + +/** Unlock the given mutex. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int mtx_unlock(mtx_t *mtx); + +/* Condition variable */ +#if defined(_TTHREAD_WIN32_) +typedef struct { + HANDLE mEvents[2]; /* Signal and broadcast event HANDLEs. */ + unsigned int mWaitersCount; /* Count of the number of waiters. */ + CRITICAL_SECTION mWaitersCountLock; /* Serialize access to mWaitersCount. */ +} cnd_t; +#else +typedef pthread_cond_t cnd_t; +#endif + +/** Create a condition variable object. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_init(cnd_t *cond); + +/** Release any resources used by the given condition variable. +* @param cond A condition variable object. +*/ +void cnd_destroy(cnd_t *cond); + +/** Signal a condition variable. +* Unblocks one of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_signal(cnd_t *cond); + +/** Broadcast a condition variable. +* Unblocks all of the threads that are blocked on the given condition variable +* at the time of the call. If no threads are blocked on the condition variable +* at the time of the call, the function does nothing and return success. +* @param cond A condition variable object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_broadcast(cnd_t *cond); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast. When the calling thread becomes unblocked it locks the mutex +* before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int cnd_wait(cnd_t *cond, mtx_t *mtx); + +/** Wait for a condition variable to become signaled. +* The function atomically unlocks the given mutex and endeavors to block until +* the given condition variable is signaled by a call to cnd_signal or to +* cnd_broadcast, or until after the specified time. When the calling thread +* becomes unblocked it locks the mutex before it returns. +* @param cond A condition variable object. +* @param mtx A mutex object. +* @param xt A point in time at which the request will time out (absolute time). +* @return @ref thrd_success upon success, or @ref thrd_timeout if the time +* specified in the call was reached without acquiring the requested resource, or +* @ref thrd_error if the request could not be honored. +*/ +int cnd_timedwait(cnd_t *cond, mtx_t *mtx, const struct timespec *ts); + +/* Thread */ +#if defined(_TTHREAD_WIN32_) +typedef HANDLE thrd_t; +#else +typedef pthread_t thrd_t; +#endif + +/** Thread start function. +* Any thread that is started with the @ref thrd_create() function must be +* started through a function of this type. +* @param arg The thread argument (the @c arg argument of the corresponding +* @ref thrd_create() call). +* @return The thread return value, which can be obtained by another thread +* by using the @ref thrd_join() function. +*/ +typedef int (*thrd_start_t)(void *arg); + +/** Create a new thread. +* @param thr Identifier of the newly created thread. +* @param func A function pointer to the function that will be executed in +* the new thread. +* @param arg An argument to the thread function. +* @return @ref thrd_success on success, or @ref thrd_nomem if no memory could +* be allocated for the thread requested, or @ref thrd_error if the request +* could not be honored. +* @note A thread’s identifier may be reused for a different thread once the +* original thread has exited and either been detached or joined to another +* thread. +*/ +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg); + +/** Identify the calling thread. +* @return The identifier of the calling thread. +*/ +thrd_t thrd_current(void); + +/** Dispose of any resources allocated to the thread when that thread exits. + * @return thrd_success, or thrd_error on error +*/ +int thrd_detach(thrd_t thr); + +/** Compare two thread identifiers. +* The function determines if two thread identifiers refer to the same thread. +* @return Zero if the two thread identifiers refer to different threads. +* Otherwise a nonzero value is returned. +*/ +int thrd_equal(thrd_t thr0, thrd_t thr1); + +/** Terminate execution of the calling thread. +* @param res Result code of the calling thread. +*/ +TTHREAD_NORETURN void thrd_exit(int res); + +/** Wait for a thread to terminate. +* The function joins the given thread with the current thread by blocking +* until the other thread has terminated. +* @param thr The thread to join with. +* @param res If this pointer is not NULL, the function will store the result +* code of the given thread in the integer pointed to by @c res. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int thrd_join(thrd_t thr, int *res); + +/** Put the calling thread to sleep. +* Suspend execution of the calling thread. +* @param duration Interval to sleep for +* @param remaining If non-NULL, this parameter will hold the remaining +* time until time_point upon return. This will +* typically be zero, but if the thread was woken up +* by a signal that is not ignored before duration was +* reached @c remaining will hold a positive time. +* @return 0 (zero) on successful sleep, -1 if an interrupt occurred, +* or a negative value if the operation fails. +*/ +int thrd_sleep(const struct timespec *duration, struct timespec *remaining); + +/** Yield execution to another thread. +* Permit other threads to run, even if the current thread would ordinarily +* continue to run. +*/ +void thrd_yield(void); + +/* Thread local storage */ +#if defined(_TTHREAD_WIN32_) +typedef DWORD tss_t; +#else +typedef pthread_key_t tss_t; +#endif + +/** Destructor function for a thread-specific storage. +* @param val The value of the destructed thread-specific storage. +*/ +typedef void (*tss_dtor_t)(void *val); + +/** Create a thread-specific storage. +* @param key The unique key identifier that will be set if the function is +* successful. +* @param dtor Destructor function. This can be NULL. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +* @note On Windows, the @c dtor will definitely be called when +* appropriate for threads created with @ref thrd_create. It will be +* called for other threads in most cases, the possible exception being +* for DLLs loaded with LoadLibraryEx. In order to be certain, you +* should use @ref thrd_create whenever possible. +*/ +int tss_create(tss_t *key, tss_dtor_t dtor); + +/** Delete a thread-specific storage. +* The function releases any resources used by the given thread-specific +* storage. +* @param key The key that shall be deleted. +*/ +void tss_delete(tss_t key); + +/** Get the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @return The value for the current thread held in the given thread-specific +* storage. +*/ +void *tss_get(tss_t key); + +/** Set the value for a thread-specific storage. +* @param key The thread-specific storage identifier. +* @param val The value of the thread-specific storage to set for the current +* thread. +* @return @ref thrd_success on success, or @ref thrd_error if the request could +* not be honored. +*/ +int tss_set(tss_t key, void *val); + +#if defined(_TTHREAD_WIN32_) + typedef struct { + LONG volatile status; + CRITICAL_SECTION lock; + } once_flag; + #define ONCE_FLAG_INIT {0,} +#else + #define once_flag pthread_once_t + #define ONCE_FLAG_INIT PTHREAD_ONCE_INIT +#endif + +/** Invoke a callback exactly once + * @param flag Flag used to ensure the callback is invoked exactly + * once. + * @param func Callback to invoke. + */ +#if defined(_TTHREAD_WIN32_) + void call_once(once_flag *flag, void (*func)(void)); +#else + #define call_once(flag,func) pthread_once(flag,func) +#endif + +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* _TINYTHREAD_H_ */ diff --git a/gui/qt/CMakeLists.txt b/gui/qt/CMakeLists.txt index b70a0cd9d..26da876bd 100644 --- a/gui/qt/CMakeLists.txt +++ b/gui/qt/CMakeLists.txt @@ -178,6 +178,19 @@ set(CEmu_Sources ${CEmu_Resources} ) +include(CheckCSourceCompiles) +check_c_source_compiles(" + #include + #include + int main(void) { thrd_t thread; mtx_t mutex; tss_t tss; return 0; } + " HAVE_C11_THREADS) +if (HAVE_C11_THREADS) + add_definitions(-DHAVE_C11_THREADS) +else() + message(WARNING "C11 not supported, using tinycthread library as fallback") + set(CEmu_Sources ${CEmu_Sources} ../../core/arm/tinycthread.c ../../core/arm/tinycthread.h) +endif() + qt_add_executable(CEmu ${MAYBE_MACOSX_BUNDLE} ${CEmu_Sources}) target_include_directories(CEmu PRIVATE From 129c20257ed92ff9b53f76a00f629bf388ce8526 Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Fri, 16 Aug 2024 15:03:08 +0200 Subject: [PATCH 11/26] Update some license things --- LICENSE | 5 +++-- README.md | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/LICENSE b/LICENSE index 6e4b47e02..cce46e3ec 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ CEmu is licensed under the GPLv3 - https://www.gnu.org/licenses/gpl-3.0.en.html -Copyright (C) 2015-2019 CEmu contributors +Copyright (C) 2015-2024 CEmu contributors 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 3 of the License, or (at your option) any later version. @@ -15,6 +15,7 @@ Portions of this program use code, directly or modified, from: * tivars_lib_cpp, developed by Adrien "Adriweb" Bertrand * KDMacTouchBar, developed by KDAB * FatCow's "Farm-Fresh Web Icons" (CC 3.0 license) - http://www.fatcow.com/free-icons +* ATMEL's CMSIS & SAMD21A resources (see core/arm/README.md) CEmu also uses the APNG-enabled fork of libpng (https://sourceforge.net/projects/libpng-apng/) released under the zlib/libpng License. @@ -46,7 +47,7 @@ ________________________________________________________ tivars_lib_cpp license: The MIT License (MIT) -Copyright (c) 2015-2019 Adrien Bertrand +Copyright (c) 2015-2024 Adrien Bertrand Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/README.md b/README.md index 24b63cf2d..9177cf618 100644 --- a/README.md +++ b/README.md @@ -84,5 +84,5 @@ We also welcome more translations. Qt Linguist is a great tool for that (here's ## License CEmu is licensed under the [GPLv3](LICENSE). -_Acknowledgements_: Some CEmu parts are, directly, modified, or inspired, from [z80e](https://github.com/KnightOS/z80e), [Firebird](https://github.com/nspire-emus/firebird), [libtifiles](https://github.com/debrouxl/tilibs), [tivars_lib_cpp](https://github.com/adriweb/tivars_lib_cpp), [KDMacTouchBar](https://github.com/KDAB/KDMacTouchBar), [TinyCThread](https://github.com/gyrovorbis/tinycthread) (_gyrovorbis_'s fork), and FatCow's ["Farm-Fresh Web Icons"](http://www.fatcow.com/free-icons). +_Acknowledgements_: Some CEmu parts are, directly, modified, or inspired, from [z80e](https://github.com/KnightOS/z80e), [Firebird](https://github.com/nspire-emus/firebird), [libtifiles](https://github.com/debrouxl/tilibs), [tivars_lib_cpp](https://github.com/adriweb/tivars_lib_cpp), [KDMacTouchBar](https://github.com/KDAB/KDMacTouchBar), [TinyCThread](https://github.com/gyrovorbis/tinycthread) (_gyrovorbis_'s fork), ATMEL's [CMSIS & SAMD21A resources](core/arm/README.md), and FatCow's ["Farm-Fresh Web Icons"](http://www.fatcow.com/free-icons). The complete licensing information is available in the [LICENSE](LICENSE) file. From 9518dd8b5ce63597f5b2aa3815dda8940bc0e70e Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Fri, 16 Aug 2024 15:04:11 +0200 Subject: [PATCH 12/26] ci: add feature/python branch to workflows --- .github/workflows/build.linux.workflow.yml | 4 ++-- .github/workflows/build.mac.workflow.yml | 4 ++-- .github/workflows/build.windows.workflow.yml | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/build.linux.workflow.yml b/.github/workflows/build.linux.workflow.yml index 845fecf1b..8c80f146c 100644 --- a/.github/workflows/build.linux.workflow.yml +++ b/.github/workflows/build.linux.workflow.yml @@ -7,9 +7,9 @@ permissions: on: push: - branches: [ master, test-ci ] + branches: [ master, test-ci, feature/python ] pull_request: - branches: [ master ] + branches: [ master, feature/python ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/build.mac.workflow.yml b/.github/workflows/build.mac.workflow.yml index 229f9da3d..18ff0e36e 100644 --- a/.github/workflows/build.mac.workflow.yml +++ b/.github/workflows/build.mac.workflow.yml @@ -7,9 +7,9 @@ permissions: on: push: - branches: [ master, test-ci ] + branches: [ master, test-ci, feature/python ] pull_request: - branches: [ master ] + branches: [ master, feature/python ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} diff --git a/.github/workflows/build.windows.workflow.yml b/.github/workflows/build.windows.workflow.yml index 2747daf98..7be8265b3 100644 --- a/.github/workflows/build.windows.workflow.yml +++ b/.github/workflows/build.windows.workflow.yml @@ -7,9 +7,9 @@ permissions: on: push: - branches: [ master, test-ci ] + branches: [ master, test-ci, feature/python ] pull_request: - branches: [ master ] + branches: [ master, feature/python ] concurrency: group: ${{ github.workflow }}-${{ github.ref }} From 9c452b93f3a5996245e9a6d4212d9695679b6976 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Mon, 19 Aug 2024 18:47:26 -0400 Subject: [PATCH 13/26] Add MSVC intrinsics to ARM core, fix incorrect carry flag in fallbacks and replace unnecessary 64-bit math --- core/arm/armcpu.c | 130 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 100 insertions(+), 30 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index cd7866a35..7a5323769 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -7,6 +7,9 @@ #include #include #include +#if defined(_MSC_VER) && !defined(__clang__) +#include +#endif #ifndef __has_builtin # define __has_builtin(builtin) 0 @@ -20,9 +23,15 @@ # define DEBUG_BREAK asm("int3") #endif +#if (defined(__GNUC__) || defined(__clang__)) +# define EXTENDED_ASM 1 +#else +# define EXTENDED_ASM 0 +#endif + #if defined(__GCC_ASM_FLAG_OUTPUTS__) && \ (defined(__i386) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_IX64)) + defined(_M_IX86) || defined(_M_X64)) # define FLAGS_FROM_EXTENDED_X86_ASM 1 #else # define FLAGS_FROM_EXTENDED_X86_ASM 0 @@ -34,6 +43,12 @@ # define FLAGS_FROM_OVERFLOW_BUILTINS 0 #endif +#if _MSC_VER >= 1937 && !defined(__clang__) && (defined(_M_IX86) || defined(_M_X64)) +# define FLAGS_FROM_MSVC_INTRINSICS 1 +#else +# define FLAGS_FROM_MSVC_INTRINSICS 0 +#endif + #if __has_builtin(__builtin_constant_p) || __GNUC__ >= 3 // Not sure, so conservative # define HAVE_BUILTIN_CONSTANT_P 1 #else @@ -43,10 +58,21 @@ static uint8_t bitcount9(uint32_t x) { #if __has_builtin(__builtin_popcount) || __GNUC__ >= 4 return __builtin_popcount(x & 0777); +#elif UINT32_MAX >= UINTPTR_MAX + uint32_t res = (x &= 0777), mask = UINT32_C(0x11111111); + res *= UINT32_C(0001001001001); + res >>= 3; +# if EXTENDED_ASM && (defined(__i386__) || defined(_M_IX86)) + __asm__("andl\t%1, %0\nimull\t%1, %0" : "+r"(res) : "r"(mask) : "cc"); +# else + res &= mask; + res *= mask; +#endif + return (res >> 28) + (x >> 8); #else uint64_t res = x & 0777, mask = UINT64_C(0x1111111111111111); res *= UINT64_C(0001001001001); -# if defined(__x86_64__) || defined(_M_IX64) +# if EXTENDED_ASM && (defined(__x86_64__) || defined(_M_X64)) __asm__("andq\t%1, %0\nimulq\t%1, %0" : "+r"(res) : "r"(mask) : "cc"); # else res &= mask; @@ -60,17 +86,24 @@ static uint8_t lowestsetbit32(uint32_t x) { assert(x && "invalid argument"); #if __has_builtin(__builtin_ctz) || __GNUC__ >= 4 return __builtin_ctz(x); +#elif defined(_MSC_VER) && !defined(__clang__) + unsigned long index; + _BitScanForward(&index, x); + return index; #else +# if EXTENDED_ASM && \ + (defined(__i386) || defined(__x86_64__) || \ + defined(_M_IX86) || defined(_M_X64)) uint32_t res; -# if defined(__i386) || defined(__x86_64__) || \ - defined(_M_IX86) || defined(_M_IX64) __asm__("bsfl\t%1, %0" : "+r"(res) : "r"(x) : "cc"); # else - res = 0; - while (!(x & 1)) { - x >>= 1; - ++res; - } + uint8_t res = 0; + x &= -x; + if (x & UINT32_C(0xAAAAAAAA)) res += 1; + if (x & UINT32_C(0xCCCCCCCC)) res += 2; + if (x & UINT32_C(0xF0F0F0F0)) res += 4; + if (x & UINT32_C(0xFF00FF00)) res += 8; + if (x & UINT32_C(0xFFFF0000)) res += 16; # endif return res; #endif @@ -209,13 +242,17 @@ static uint32_t arm_negs(arm_cpu_t *cpu, uint32_t x) { #elif FLAGS_FROM_OVERFLOW_BUILTINS int32_t res; cpu->v = __builtin_sub_overflow(0, (int32_t)x, &res); - cpu->c = x; - return arm_movs(cpu, -x); + cpu->c = !res; + return arm_movs(cpu, res); +#elif FLAGS_FROM_MSVC_INTRINSICS + int32_t res; + cpu->v = _sub_overflow_i32(0, 0, x, &res); + cpu->c = !res; + return arm_movs(cpu, res); #else - int64_t res = UINT64_C(0) - (int32_t)x; - cpu->v = res != (int32_t)res; - cpu->c = (uint32_t)res <= 0; - //cpu->c = 0 >= x; + uint32_t res = -x; + cpu->v = (x & res) >> 31; + cpu->c = !res; return arm_movs(cpu, res); #endif } @@ -229,10 +266,18 @@ static uint32_t arm_adds(arm_cpu_t *cpu, uint32_t x, uint32_t y) { cpu->v = __builtin_add_overflow((int32_t)x, (int32_t)y, &res); cpu->c = __builtin_add_overflow(x, y, &x); return arm_movs(cpu, x); +#elif FLAGS_FROM_MSVC_INTRINSICS + int32_t res; + cpu->v = _add_overflow_i32(0, x, y, &res); + cpu->c = _addcarry_u32(0, x, y, &x); + return arm_movs(cpu, x); #else - int64_t res = (int64_t)(int32_t)x + (int32_t)y; - cpu->v = res != (int32_t)res; - cpu->c = (uint32_t)res < x; + uint32_t res = x + y; + flags->v = ((res ^ x) & (res ^ y)) >> 31; + flags->c = res < x; + //int64_t res = (int64_t)(int32_t)x + (int32_t)y; + //cpu->v = res != (int32_t)res; + //cpu->c = (uint32_t)res < x; //cpu->c = x > ~y; return arm_movs(cpu, res); #endif @@ -247,10 +292,18 @@ static uint32_t arm_subs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { cpu->v = __builtin_sub_overflow((int32_t)x, (int32_t)y, &res); cpu->c = !__builtin_sub_overflow(x, y, &x); return arm_movs(cpu, x); +#elif FLAGS_FROM_MSVC_INTRINSICS + int32_t res; + cpu->v = _sub_overflow_i32(0, x, y, &res); + cpu->c = !_subborrow_u32(0, x, y, &x); + return arm_movs(cpu, x); #else - int64_t res = (int64_t)(int32_t)x - (int32_t)y; - cpu->v = res != (int32_t)res; - cpu->c = (uint32_t)res <= x; + uint32_t res = x - y; + cpu->v = ((x ^ y) & (res ^ x)) >> 31; + cpu->c = res <= x; + //int64_t res = (int64_t)(int32_t)x - (int32_t)y; + //cpu->v = res != (int32_t)res; + //cpu->c = (uint32_t)res <= x; //cpu->c = x >= y; return arm_movs(cpu, res); #endif @@ -268,10 +321,20 @@ static uint32_t arm_adcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { cpu->c = __builtin_add_overflow(x, y, &x); cpu->c |= __builtin_add_overflow(x, carry, &x); return arm_movs(cpu, x); +#elif FLAGS_FROM_MSVC_INTRINSICS + bool carry = cpu->c; + int32_t res; + cpu->v = _add_overflow_i32(carry, x, y, &res); + cpu->c = _addcarry_u32(carry, x, y, &x); + return arm_movs(cpu, x); #else - int64_t res = (uint64_t)(int32_t)x + (int32_t)y + cpu->c; - cpu->v = res != (int32_t)res; - cpu->c = ((uint64_t)x + y + cpu->c) >> 32; + uint32_t res = x + y + cpu->c; + uint32_t carries = (x | y) ^ ((x ^ y) & res); + cpu->c = carries >> 31; + cpu->v = cpu->c ^ (carries >> 30 & 1); + //int64_t res = (uint64_t)(int32_t)x + (int32_t)y + cpu->c; + //cpu->v = res != (int32_t)res; + //cpu->c = ((uint64_t)x + y + cpu->c) >> 32; return arm_movs(cpu, res); #endif } @@ -285,14 +348,21 @@ static uint32_t arm_sbcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { int32_t res; cpu->v = __builtin_sub_overflow(x, y, &res); cpu->v |= __builtin_sub_overflow(res, borrow, &res); - cpu->c = __builtin_sub_overflow(x, y, &x); - cpu->c |= __builtin_sub_overflow(x, borrow, &x); + cpu->c = !__builtin_sub_overflow(x, y, &x); + cpu->c &= !__builtin_sub_overflow(x, borrow, &x); + return arm_movs(cpu, x); +#elif FLAGS_FROM_MSVC_INTRINSICS + bool borrow = !cpu->c; + int32_t res; + cpu->v = _sub_overflow_i32(borrow, x, y, &res); + cpu->c = !_subborrow_u32(borrow, x, y, &x); return arm_movs(cpu, x); #else - int64_t res = (uint64_t)(int32_t)x - (int32_t)y - !cpu->c; - cpu->v = res != (int32_t)res; - cpu->c = ((uint64_t)x - y - !cpu->c) >> 32; - return arm_movs(cpu, res); + return arm_adcs(cpu, x, ~y); + //int64_t res = (uint64_t)(int32_t)x - (int32_t)y - !cpu->c; + //cpu->v = res != (int32_t)res; + //cpu->c = !(((uint64_t)x - y - !cpu->c) >> 32); + //return arm_movs(cpu, res); #endif } From 5026a43e3569464f8ab0ef6490d71eaa29e2a3bd Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Mon, 19 Aug 2024 19:02:35 -0400 Subject: [PATCH 14/26] Fix signed overflow calculation in ADCS/SBCS when using overflow builtins --- core/arm/armcpu.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 7a5323769..a86bb3aa4 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -317,7 +317,7 @@ static uint32_t arm_adcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { bool carry = cpu->c; int32_t res; cpu->v = __builtin_add_overflow(x, y, &res); - cpu->v |= __builtin_add_overflow(res, carry, &res); + cpu->v ^= __builtin_add_overflow(res, carry, &res); cpu->c = __builtin_add_overflow(x, y, &x); cpu->c |= __builtin_add_overflow(x, carry, &x); return arm_movs(cpu, x); @@ -347,7 +347,7 @@ static uint32_t arm_sbcs(arm_cpu_t *cpu, uint32_t x, uint32_t y) { bool borrow = !cpu->c; int32_t res; cpu->v = __builtin_sub_overflow(x, y, &res); - cpu->v |= __builtin_sub_overflow(res, borrow, &res); + cpu->v ^= __builtin_sub_overflow(res, borrow, &res); cpu->c = !__builtin_sub_overflow(x, y, &x); cpu->c &= !__builtin_sub_overflow(x, borrow, &x); return arm_movs(cpu, x); From 89172e87a83eef4cd62db9404416c2f654585593 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Thu, 12 Sep 2024 16:10:47 -0400 Subject: [PATCH 15/26] Prevent ARM crashes from the ASIC not being reset on state load --- core/coproc.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/core/coproc.c b/core/coproc.c index 748a640da..8b2723d52 100644 --- a/core/coproc.c +++ b/core/coproc.c @@ -13,11 +13,20 @@ void coproc_reset(void) { gui_console_printf("[CEmu] Reset Coprocessor Interface...\n"); arm_destroy(coproc.arm); memset(&coproc, 0, sizeof(coproc)); - coproc.arm = arm_create(); + if (asic.python) { + coproc.arm = arm_create(); + } } bool coproc_load(const char *path) { - return arm_load(coproc.arm, path); + if (asic.python && !coproc.arm) { + coproc.arm = arm_create(); + } + if (coproc.arm) { + return arm_load(coproc.arm, path); + } else { + return false; + } } void coproc_uart_transmit(const uart_transfer_t *transfer) { From 0d96e4204711c66221cd449833b95397fbf40c03 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Thu, 12 Sep 2024 20:20:09 -0400 Subject: [PATCH 16/26] Fix PC-relative adds and destination PC of ALU operations --- core/arm/armcpu.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index a86bb3aa4..e8d735364 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -273,8 +273,8 @@ static uint32_t arm_adds(arm_cpu_t *cpu, uint32_t x, uint32_t y) { return arm_movs(cpu, x); #else uint32_t res = x + y; - flags->v = ((res ^ x) & (res ^ y)) >> 31; - flags->c = res < x; + cpu->v = ((res ^ x) & (res ^ y)) >> 31; + cpu->c = res < x; //int64_t res = (int64_t)(int32_t)x + (int32_t)y; //cpu->v = res != (int32_t)res; //cpu->c = (uint32_t)res < x; @@ -777,13 +777,21 @@ void arm_cpu_execute(arm_t *arm) { case 1: // Special data instructions and branch and exchange switch (opc >> 8 & 3) { case 0: // Add Registers - cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] += cpu->r[opc >> 3 & 0xF]; + i = (opc >> 4 & 8) | (opc >> 0 & 7); + cpu->r[i] += cpu->r[opc >> 3 & 0xF]; + if (unlikely(i == 15)) { + cpu->pc = (cpu->pc | 1) + 1; + } break; case 1: // Compare Registers arm_subs(cpu, cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)], cpu->r[opc >> 3 & 0xF]); break; case 2: // Move Registers - cpu->r[(opc >> 4 & 8) | (opc >> 0 & 7)] = cpu->r[opc >> 3 & 0xF]; + i = (opc >> 4 & 8) | (opc >> 0 & 7); + cpu->r[i] = cpu->r[opc >> 3 & 0xF]; + if (unlikely(i == 15)) { + cpu->pc = (cpu->pc | 1) + 1; + } break; case 3: // Branch (with Link) and Exchange val = cpu->r[opc >> 3 & 0xF]; @@ -857,8 +865,8 @@ void arm_cpu_execute(arm_t *arm) { arm_mem_store_word(arm, cpu->r[opc >> 8 & 7], cpu->sp + ((opc >> 0 & 0xFF) << 2)); } break; - case 10: // Generate SP/PC - cpu->r[opc >> 8 & 7] = cpu->r[opc >> 11 & 1 ? 13 : 15] + ((opc >> 0 & 0xFF) << 2); + case 10: // Add SP/PC relative + cpu->r[opc >> 8 & 7] = (opc >> 11 & 1 ? cpu->sp : cpu->pc & ~2) + ((opc >> 0 & 0xFF) << 2); break; case 11: // Miscellaneous 16-bit instructions switch (opc >> 9 & 7) { From 688b01b9f666124fbec512105efa249798199005 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sat, 14 Sep 2024 15:56:00 -0400 Subject: [PATCH 17/26] Fix MSR to stack pointer, add system reset request register --- core/arm/armcpu.c | 4 ++-- core/arm/armmem.c | 10 ++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index e8d735364..6495d25f1 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -1135,8 +1135,8 @@ void arm_cpu_execute(arm_t *arm) { cpu->z = val >> 30 & 1; cpu->n = val >> 31 & 1; break; - case 0x80: - case 0x81: + case 0x08: + case 0x09: *((opc >> 0 & 1) == cpu->spsel ? &cpu->sp : &cpu->altsp) = val >> 0 & ~3; break; case 0x10: diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 81fc3c847..94081fcd7 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -1439,6 +1439,16 @@ void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr) { case 0x008: // VTOR scb->vtor = val & SCB_VTOR_TBLOFF_Msk; return; + case 0x00C: // AIRCR + if ((val & SCB_AIRCR_VECTKEY_Msk) == UINT32_C(0x05FA) << SCB_AIRCR_VECTKEY_Pos) { + if (val & SCB_AIRCR_SYSRESETREQ_Msk) { + arm_mem_reset(&arm->mem, PM_RCAUSE_SYST); + arm_cpu_reset(arm); + spsc_queue_clear(&arm->usart[0]); + spsc_queue_clear(&arm->usart[1]); + } + } + return; case 0x01C: // SHP[0] scb->shp[0] = val & UINT32_C(0xC0000000); return; From fa55f5fd02a57d6d4988fe87ab400905b2ec8a53 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sat, 14 Sep 2024 16:04:18 -0400 Subject: [PATCH 18/26] Allow SPI transmit when receive buffer is full, fix struct layout on MSVC --- core/arm/armmem.c | 32 ++++++++++++++++++-------------- core/arm/armmem.h | 4 ++-- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 94081fcd7..ec379bfa7 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -142,8 +142,8 @@ uint8_t arm_mem_spi_peek(arm_t *arm, uint8_t pin, uint32_t *res) { spi->CTRLA.bit.MODE != SERCOM_SPI_CTRLA_MODE_SPI_SLAVE_Val || !spi->CTRLB.bit.RXEN)) { - *res = 1 << 15; - return 16; + *res = 0; + return 1; } uint8_t bits = 8 | (spi->CTRLB.bit.CHSIZE & 1); *res = spi->BUFFER[1].bit.DATA; @@ -177,24 +177,28 @@ void arm_mem_spi_xfer(arm_t *arm, uint8_t pin, uint32_t val) { } else { spi->BUFFER[2].bit.OVF = true; } - spi->BUFFER[1].bit.VLD = true; + //spi->BUFFER[1].bit.VLD = true; } else { - spi->INTFLAG.bit.DRE = true; spi->INTFLAG.bit.RXC = true; - if (likely(spi->INTEN.bit.DRE || spi->INTEN.bit.RXC)) { + if (likely(spi->INTEN.bit.RXC)) { arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); } spi->BUFFER[3].reg = spi->BUFFER[2].reg; spi->BUFFER[2].reg = spi->BUFFER[1].reg; - if (likely(spi->BUFFER[1].bit.VLD = spi->BUFFER[0].bit.VLD)) { - spi->BUFFER[1].bit.DATA = spi->BUFFER[0].bit.DATA; - spi->BUFFER[0].reg = 0; - } else if (unlikely(spi->CTRLA.bit.MODE == - SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val)) { - spi->INTFLAG.bit.TXC = true; - if (likely(spi->INTEN.bit.TXC)) { - arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); - } + spi->BUFFER[2].bit.VLD = true; + } + spi->INTFLAG.bit.DRE = true; + if (likely(spi->INTEN.bit.DRE)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); + } + if (likely(spi->BUFFER[1].bit.VLD = spi->BUFFER[0].bit.VLD)) { + spi->BUFFER[1].bit.DATA = spi->BUFFER[0].bit.DATA; + spi->BUFFER[0].reg = 0; + } else if (unlikely(spi->CTRLA.bit.MODE == + SERCOM_SPI_CTRLA_MODE_SPI_MASTER_Val)) { + spi->INTFLAG.bit.TXC = true; + if (likely(spi->INTEN.bit.TXC)) { + arm_mem_set_pending(arm, SERCOM0_IRQn + pin, true); } } } diff --git a/core/arm/armmem.h b/core/arm/armmem.h index ff002e1ed..a06ab65d7 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -57,8 +57,8 @@ typedef struct { typedef union { struct { uint16_t DATA:9; /*!< bit: 0.. 8 Data Value */ - bool VLD:1; /*!< bit: 9 Valid Flag */ - bool OVF:1; /*!< bit: 10 Overflow Flag */ + uint16_t VLD:1; /*!< bit: 9 Valid Flag */ + uint16_t OVF:1; /*!< bit: 10 Overflow Flag */ } bit; /*!< Structure used for bit access */ uint16_t reg; /*!< Type used for register access */ } SERCOM_BUFFER_Type; From 42e39568199afc7175c8e03a5891a67db58259d5 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Sep 2024 01:19:14 -0400 Subject: [PATCH 19/26] Reset ARM object on system reset instead of recreating it --- core/coproc.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/core/coproc.c b/core/coproc.c index 8b2723d52..d5079396c 100644 --- a/core/coproc.c +++ b/core/coproc.c @@ -11,11 +11,17 @@ coproc_state_t coproc; void coproc_reset(void) { gui_console_printf("[CEmu] Reset Coprocessor Interface...\n"); - arm_destroy(coproc.arm); - memset(&coproc, 0, sizeof(coproc)); - if (asic.python) { + if (asic.python && !coproc.arm) { coproc.arm = arm_create(); } + if (coproc.arm) { + if (asic.python) { + arm_reset(coproc.arm); + } else { + arm_destroy(coproc.arm); + memset(&coproc, 0, sizeof(coproc)); + } + } } bool coproc_load(const char *path) { From 079982a096d6929a8fe9e4f900614daeb2ea6864 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Sep 2024 01:48:17 -0400 Subject: [PATCH 20/26] Don't zero ARM RAM on reset --- core/arm/armmem.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/arm/armmem.c b/core/arm/armmem.c index ec379bfa7..22779c02d 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -267,6 +267,7 @@ bool arm_mem_init(arm_mem_t *mem) { memset(mem->nvm, ~0, FLASH_SIZE); mem->ram = malloc(HMCRAMC0_SIZE); if (likely(mem->ram)) { + memset(mem->ram, 0, HMCRAMC0_SIZE); return true; free(mem->ram); } @@ -281,7 +282,6 @@ void arm_mem_destroy(arm_mem_t *mem) { } void arm_mem_reset(arm_mem_t *mem, uint8_t rcause) { - memset(mem->ram, 0, HMCRAMC0_SIZE); arm_nvm_clear_page_buffer(mem); mem->pm.RCAUSE.reg = rcause; mem->nvmctrl.INTFLAG.bit.READY = true; From bd6f6dcadd215aec51854da9dd72ed80a447cc0c Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Sep 2024 05:42:42 -0400 Subject: [PATCH 21/26] Implement Auxiliary Flash writes --- core/arm/armmem.c | 73 +++++++++++++++++++++++++++++++---------------- core/arm/armmem.h | 2 +- 2 files changed, 50 insertions(+), 25 deletions(-) diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 22779c02d..27af8a885 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -88,12 +88,15 @@ static bool arm_nvm_region_lock_check(arm_t *arm) { return false; } +static bool arm_nvm_aux_region_check(arm_t *arm) { + return (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & -FLASH_USER_PAGE_SIZE) == NVMCTRL_USER - NVMCTRL_USER_PAGE_ADDRESS; +} + static void arm_nvm_clear_page_buffer(arm_mem_t *mem) { memset(mem->pb, ~0, FLASH_PAGE_SIZE); } -static void arm_nvm_erase_row(arm_t *arm, bool aux) { - assert(!aux && "Not implemented"); +static void arm_nvm_erase_row(arm_t *arm) { if (likely(arm_nvm_region_lock_check(arm))) { memset(&arm->mem.nvm[(arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & (FLASH_SIZE - 1) & -FLASH_ROW_SIZE) >> 2], @@ -101,11 +104,16 @@ static void arm_nvm_erase_row(arm_t *arm, bool aux) { } } -static void arm_nvm_write_page(arm_t *arm, bool aux) { - uint32_t idx = (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & - (FLASH_SIZE - 1) & -FLASH_PAGE_SIZE) >> 2; - assert(!aux && "Not implemented"); +static void arm_nvm_erase_aux_row(arm_t *arm) { + if (likely(arm_nvm_aux_region_check(arm))) { + memset(arm->mem.aux, ~0, FLASH_USER_PAGE_SIZE); + } +} + +static void arm_nvm_write_page(arm_t *arm) { if (likely(arm_nvm_region_lock_check(arm))) { + uint32_t idx = (arm->mem.nvmctrl.ADDR.bit.ADDR << 1 & + (FLASH_SIZE - 1) & -FLASH_PAGE_SIZE) >> 2; for (uint32_t off = 0; off != FLASH_PAGE_SIZE >> 2; ++off) { arm->mem.nvm[idx + off] &= arm->mem.pb[off]; } @@ -113,6 +121,15 @@ static void arm_nvm_write_page(arm_t *arm, bool aux) { arm_nvm_clear_page_buffer(&arm->mem); } +static void arm_nvm_write_aux_page(arm_t *arm) { + if (likely(arm_nvm_aux_region_check(arm))) { + for (uint32_t off = 0; off != FLASH_USER_PAGE_SIZE >> 2; ++off) { + arm->mem.aux[off] &= arm->mem.pb[off]; + } + } + arm_nvm_clear_page_buffer(&arm->mem); +} + static void arm_mem_sercom_reset(SERCOM_Type *sercom) { memset(sercom, 0, sizeof(*sercom)); } @@ -306,14 +323,11 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { return arm->mem.nvm[(addr - FLASH_ADDR) >> 2]; } else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM return arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2]; - } else if (unlikely(addr < HPB0_ADDR)) { - if (addr - NVMCTRL_OTP1 < 8) { - return 0; - } - if (addr - NVMCTRL_OTP2 < 8) { - return 0; + } else if (unlikely(addr < HPB0_ADDR)) { // Auxiliary Flash + if (addr - NVMCTRL_USER < FLASH_USER_PAGE_SIZE) { + return arm->mem.aux[(addr - NVMCTRL_USER) >> 2]; } - if (addr - NVMCTRL_OTP4 < 8) { + if (addr - NVMCTRL_OTP4 < 16) { return 0; } if (addr == 0x80A00C) { @@ -801,21 +815,32 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t uint8_t offset = addr >> 2 & 0xFF; assert(!((addr & 3) | (val & mask)) && "Address should be aligned and mask should be valid"); - if (unlikely(addr - FLASH_ADDR < FLASH_SIZE)) { // Page Buffer + if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM + uint32_t *ptr = &arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2]; + *ptr = (*ptr & mask) | val; + return; + } else if (unlikely(addr - FLASH_ADDR < FLASH_SIZE)) { // Page Buffer if (likely(!(mask & mask >> 16))) { // no 8-bit writes uint32_t *ptr = &arm->mem.pb[((addr - FLASH_ADDR) & (FLASH_PAGE_SIZE - 1)) >> 2]; *ptr = (*ptr & mask) | val; arm->mem.nvmctrl.ADDR.bit.ADDR = (addr - FLASH_ADDR) >> 1 | (mask & 1); if (unlikely(!(mask >> 16) && !~(addr | -FLASH_PAGE_SIZE | 3) && - !arm->mem.nvmctrl.CTRLB.bit.MANW)) { - arm_nvm_write_page(arm, false); + !arm->mem.nvmctrl.CTRLB.bit.MANW)) { + arm_nvm_write_page(arm); + } + return; + } + } else if (unlikely(addr - NVMCTRL_USER < FLASH_USER_PAGE_SIZE)) { // User Page Buffer + if (likely(!(mask & mask >> 16))) { // no 8-bit writes + uint32_t *ptr = &arm->mem.pb[((addr - NVMCTRL_USER) & (FLASH_USER_PAGE_SIZE - 1)) >> 2]; + *ptr = (*ptr & mask) | val; + arm->mem.nvmctrl.ADDR.bit.ADDR = (addr - FLASH_USER_PAGE_ADDR) >> 1 | (mask & 1); + if (unlikely(!(mask >> 16) && !~(addr | -FLASH_USER_PAGE_SIZE | 3) && + !arm->mem.nvmctrl.CTRLB.bit.MANW)) { + arm_nvm_write_aux_page(arm); } return; } - } else if (likely(addr - HMCRAMC0_ADDR < HMCRAMC0_SIZE)) { // Internal SRAM - uint32_t *ptr = &arm->mem.ram[(addr - HMCRAMC0_ADDR) >> 2]; - *ptr = (*ptr & mask) | val; - return; } else if (unlikely(addr < HPB0_ADDR)) { } else if (unlikely(addr < HPB1_ADDR)) { // Peripheral Bridge A uint32_t id = ID_PAC0 + ((addr - HPB0_ADDR) >> 10); @@ -969,16 +994,16 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t if ((val & NVMCTRL_CTRLA_CMDEX_Msk) == NVMCTRL_CTRLA_CMDEX_KEY) { switch (val & NVMCTRL_CTRLA_CMD_Msk) { case NVMCTRL_CTRLA_CMD_ER: - arm_nvm_erase_row(arm, false); + arm_nvm_erase_row(arm); return; case NVMCTRL_CTRLA_CMD_WP: - arm_nvm_write_page(arm, false); + arm_nvm_write_page(arm); return; case NVMCTRL_CTRLA_CMD_EAR: - arm_nvm_erase_row(arm, true); + arm_nvm_erase_aux_row(arm); return; case NVMCTRL_CTRLA_CMD_WAP: - arm_nvm_write_page(arm, true); + arm_nvm_write_aux_page(arm); return; case NVMCTRL_CTRLA_CMD_SF: break; diff --git a/core/arm/armmem.h b/core/arm/armmem.h index a06ab65d7..feca533d6 100644 --- a/core/arm/armmem.h +++ b/core/arm/armmem.h @@ -115,7 +115,7 @@ typedef union { } SERCOM_Type; typedef struct arm_mem { - uint32_t *ram, *nvm, pb[FLASH_PAGE_SIZE >> 2]; + uint32_t *ram, *nvm, pb[FLASH_PAGE_SIZE >> 2], aux[FLASH_USER_PAGE_SIZE >> 2]; PM_Type pm; GCLK_Type gclk; NVMCTRL_Type nvmctrl; From dd7865a931c7f842e8c12ada56bbcb61d6d69404 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Sep 2024 06:34:59 -0400 Subject: [PATCH 22/26] Implement sleep-related registers and enter sleep on WFI when enabled --- core/arm/armcpu.c | 4 ++++ core/arm/armmem.c | 13 ++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index 6495d25f1..b0518c4c1 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -965,6 +965,10 @@ void arm_cpu_execute(arm_t *arm) { case 2: // Wait for Event hint break; case 3: // Wait for Interrupt hint + if ((arm->mem.pm.SLEEP.bit.IDLE == PM_SLEEP_IDLE_APB_Val) && + (arm->cpu.scb.scr & SCB_SCR_SLEEPDEEP_Msk)) { + sync_sleep(&arm->sync); + } break; case 4: // Send Event hint break; diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 27af8a885..98a8cdd28 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -350,6 +350,8 @@ static uint32_t arm_mem_load_any(arm_t *arm, uint32_t addr) { case ID_PM: { PM_Type *pm = &arm->mem.pm; switch (offset) { + case PM_SLEEP_OFFSET >> 2: + return pm->SLEEP.reg << 8; case (PM_CPUSEL_OFFSET | PM_APBASEL_OFFSET | PM_APBBSEL_OFFSET | @@ -792,6 +794,8 @@ uint32_t arm_mem_load_word(arm_t *arm, uint32_t addr) { return scb->vtor; case 0x00C: // AIRCR return 0; + case 0x010: // SCR + return scb->scr; case 0x014: // CCR return SCB_CCR_STKALIGN_Msk | SCB_CCR_UNALIGN_TRP_Msk; @@ -850,6 +854,10 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t case ID_PM: { PM_Type *pm = &arm->mem.pm; switch (offset) { + case PM_SLEEP_OFFSET >> 2: + pm->SLEEP.reg = + ((pm->SLEEP.reg & mask >> 8) | val >> 8) & PM_SLEEP_MASK; + return; case (PM_CPUSEL_OFFSET | PM_APBASEL_OFFSET | PM_APBBSEL_OFFSET | @@ -891,7 +899,7 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t case SYSCTRL_INTENSET_OFFSET >> 2: break; case SYSCTRL_INTFLAG_OFFSET >> 2: - break; + return; case SYSCTRL_PCLKSR_OFFSET >> 2: return; case SYSCTRL_XOSC_OFFSET >> 2: @@ -1478,6 +1486,9 @@ void arm_mem_store_word(arm_t *arm, uint32_t val, uint32_t addr) { } } return; + case 0x010: // SCR + scb->scr = val & (SCB_SCR_SEVONPEND_Msk | SCB_SCR_SLEEPDEEP_Msk | SCB_SCR_SLEEPONEXIT_Msk); + return; case 0x01C: // SHP[0] scb->shp[0] = val & UINT32_C(0xC0000000); return; From 8c82d1b5884bc97f96b3b03f9b4afdc81f3e0e14 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 15 Sep 2024 23:20:14 -0400 Subject: [PATCH 23/26] Improve WFI and sleep implementation --- core/arm/arm.c | 6 +++++- core/arm/armcpu.c | 43 ++++++++++++++++++++++++++----------------- core/arm/armcpu.h | 2 +- core/arm/armmem.c | 4 ++++ 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/core/arm/arm.c b/core/arm/arm.c index 42f624deb..2ac5070e8 100644 --- a/core/arm/arm.c +++ b/core/arm/arm.c @@ -25,7 +25,7 @@ static int arm_thrd(void *context) { uint16_t val; do { arm_cpu_execute(arm); - } while (++i); + } while (++i && !arm->sync.slp); peek = spsc_queue_peek(&arm->usart[0]); if (unlikely(peek != SPSC_QUEUE_INVALID_ENTRY && arm_mem_usart_recv(arm, 3, peek))) { @@ -150,6 +150,7 @@ bool arm_usart_send(arm_t *arm, uint8_t val) { bool success = spsc_queue_enqueue(&arm->usart[0], val); if (likely(success)) { (void)spsc_queue_flush(&arm->usart[0]); + debug_char(false, val); } return success; } @@ -157,5 +158,8 @@ bool arm_usart_send(arm_t *arm, uint8_t val) { bool arm_usart_recv(arm_t *arm, uint8_t *val) { spsc_queue_entry_t entry = spsc_queue_dequeue(&arm->usart[1]); *val = entry; + if (entry != SPSC_QUEUE_INVALID_ENTRY) { + debug_char(true, *val); + } return entry != SPSC_QUEUE_INVALID_ENTRY; } diff --git a/core/arm/armcpu.c b/core/arm/armcpu.c index b0518c4c1..d61119a27 100644 --- a/core/arm/armcpu.c +++ b/core/arm/armcpu.c @@ -423,6 +423,11 @@ bool arm_cpu_exception(arm_t *arm, arm_exception_number_t exc) { } return false; } + cpu->wfi = false; + if (cpu->pm && exc > ARM_Exception_HardFault) { + return false; + } + arm_cpu_tick(arm); cpu->exc = true; sp -= 0x20; @@ -617,19 +622,17 @@ void arm_cpu_execute(arm_t *arm) { arm_cpu_exception(arm, ARM_Exception_HardFault); cpu->exc = false; return; - } - if (unlikely(!cpu->pm && - (icsr & (SCB_ICSR_NMIPENDSET_Msk | - SCB_ICSR_PENDSVSET_Msk | - SCB_ICSR_PENDSTSET_Msk) || - cpu->nvic.ipr & cpu->nvic.ier))) { - if (icsr & SCB_ICSR_NMIPENDSET_Msk) { - if (likely(arm_cpu_exception(arm, ARM_Exception_NMI))) { - cpu->scb.icsr &= ~SCB_ICSR_NMIPENDSET_Msk; - cpu->exc = false; - return; - } - } else if (icsr & SCB_ICSR_PENDSVSET_Msk) { + } else if (unlikely(icsr & SCB_ICSR_NMIPENDSET_Msk)) { + if (likely(arm_cpu_exception(arm, ARM_Exception_NMI))) { + cpu->scb.icsr &= ~SCB_ICSR_NMIPENDSET_Msk; + cpu->exc = false; + return; + } + } else if (unlikely((!cpu->pm || cpu->wfi) && + (icsr & (SCB_ICSR_PENDSVSET_Msk | + SCB_ICSR_PENDSTSET_Msk) || + cpu->nvic.ipr & cpu->nvic.ier))) { + if (icsr & SCB_ICSR_PENDSVSET_Msk) { if (likely(arm_cpu_exception(arm, ARM_Exception_PendSV))) { cpu->scb.icsr &= ~SCB_ICSR_PENDSVSET_Msk; cpu->exc = false; @@ -654,6 +657,15 @@ void arm_cpu_execute(arm_t *arm) { return; } } + if (unlikely(cpu->wfi)) { + if ((arm->mem.pm.SLEEP.bit.IDLE == PM_SLEEP_IDLE_APB_Val) && + (arm->cpu.scb.scr & SCB_SCR_SLEEPDEEP_Msk)) { + sync_sleep(&arm->sync); + } else { + arm_cpu_tick(arm); + } + return; + } arm_cpu_tick(arm); opc = arm_mem_load_half(arm, pc); if (unlikely(cpu->exc)) { @@ -965,10 +977,7 @@ void arm_cpu_execute(arm_t *arm) { case 2: // Wait for Event hint break; case 3: // Wait for Interrupt hint - if ((arm->mem.pm.SLEEP.bit.IDLE == PM_SLEEP_IDLE_APB_Val) && - (arm->cpu.scb.scr & SCB_SCR_SLEEPDEEP_Msk)) { - sync_sleep(&arm->sync); - } + cpu->wfi = true; break; case 4: // Send Event hint break; diff --git a/core/arm/armcpu.h b/core/arm/armcpu.h index 853bd4581..a41c7954d 100644 --- a/core/arm/armcpu.h +++ b/core/arm/armcpu.h @@ -35,7 +35,7 @@ typedef union arm_cpu { struct { uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, ip, sp, lr, pc, altsp; uint64_t active; - bool v, c, z, n, pm, spsel, exc; + bool v, c, z, n, pm, spsel, exc, wfi; arm_systick_t systick; arm_nvic_t nvic; arm_scb_t scb; diff --git a/core/arm/armmem.c b/core/arm/armmem.c index 98a8cdd28..a1f70f42b 100644 --- a/core/arm/armmem.c +++ b/core/arm/armmem.c @@ -1128,6 +1128,10 @@ static void arm_mem_store_any(arm_t *arm, uint32_t val, uint32_t mask, uint32_t switch (offset) { case (USB_CTRLA_OFFSET | USB_SYNCBUSY_OFFSET | USB_QOSCTRL_OFFSET) >> 2: return; + case USB_DEVICE_EPSTATUSSET_OFFSET >> 2: + return; + case USB_DEVICE_EPINTENSET_OFFSET >> 2: + return; } } else if (addr < (uint32_t)SBMATRIX) { // MTB switch (offset) { From 375e58535c9674fe06e7dd4af13e8ea49f53b081 Mon Sep 17 00:00:00 2001 From: Brendan Fletcher Date: Sun, 22 Sep 2024 02:25:41 -0400 Subject: [PATCH 24/26] Are you kidding? (use correct usart index) --- core/arm/arm.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/arm/arm.c b/core/arm/arm.c index 2ac5070e8..4cb56f62e 100644 --- a/core/arm/arm.c +++ b/core/arm/arm.c @@ -35,7 +35,7 @@ static int arm_thrd(void *context) { } if (unlikely(spsc_queue_flush(&arm->usart[1]) && arm_mem_usart_send(arm, 3, &val))) { - bool success = spsc_queue_enqueue(&arm->usart[0], val); + bool success = spsc_queue_enqueue(&arm->usart[1], val); (void)success; assert(success && "Already successfully flushed, so can't fail"); } From 2b8bf28ec97df2317a8a6aa2d30c8ce5b0db9580 Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Thu, 26 Sep 2024 20:02:12 +0200 Subject: [PATCH 25/26] emu.c: info from cert: display isPython. --- core/asic.h | 5 +++++ core/emu.c | 24 +++++++++++++++--------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/core/asic.h b/core/asic.h index 8f0446d33..5b096fb1b 100644 --- a/core/asic.h +++ b/core/asic.h @@ -16,6 +16,11 @@ typedef enum { TI82AEP = 2 } emu_device_t; +typedef enum { + TIMODEL_8384CE = 0x13, + TIMODEL_82AEP = 0x15 +} ti_model_t; + typedef enum { ASIC_REV_AUTO = 0, /* Used only with set_asic_revision() */ ASIC_REV_PRE_A = 1, diff --git a/core/emu.c b/core/emu.c index 62d045952..45ab5a9e4 100644 --- a/core/emu.c +++ b/core/emu.c @@ -100,6 +100,7 @@ emu_state_t emu_load(emu_data_t type, const char *path) { const uint8_t *data; uint32_t outer_field_size; uint32_t data_field_size; + ti_model_t model_id = TIMODEL_8384CE; emu_device_t device_type = TI84PCE; uint32_t offset; size_t size; @@ -139,8 +140,8 @@ emu_state_t emu_load(emu_data_t type, const char *path) { /* Inner 0x801(0) field: calculator model */ if (cert_field_get(outer, outer_field_size, &field_type, &data, &data_field_size)) break; - if (field_type != 0x8012 || (data[0] != 0x13 && data[0] != 0x15)) break; - const enum { MODEL_8384CE=0x13, MODEL_82AEP=0x15 } model_id = data[0]; + if (field_type != 0x8012 || (data[0] != TIMODEL_8384CE && data[0] != TIMODEL_82AEP)) break; + model_id = (ti_model_t)data[0]; /* Inner 0x802(0) field: skip. */ data_field_size = outer_field_size - (data + data_field_size - outer); @@ -177,23 +178,28 @@ emu_state_t emu_load(emu_data_t type, const char *path) { if (data[1] != 0 && data[1] != 1) break; const enum { DEVICE_84PCE=0, DEVICE_83PCE=1 } device_id = data[1]; - gui_console_printf("[CEmu] Info from cert: Device type = 0x%02X (%s). Model = 0x%02X (%s).\n", - device_id, (device_id == DEVICE_84PCE) ? "84+CE-like" : "83PCE-like", - model_id, (model_id == MODEL_8384CE) ? "CE" : "82AEP"); - - if (model_id == MODEL_82AEP && device_id == DEVICE_83PCE) { + if (model_id == TIMODEL_82AEP && device_id == DEVICE_83PCE) { device_type = TI82AEP; gotType = true; - } else if (model_id == MODEL_8384CE && device_id == DEVICE_84PCE) { + } else if (model_id == TIMODEL_8384CE && device_id == DEVICE_84PCE) { device_type = TI84PCE; gotType = true; - } else if (model_id == MODEL_8384CE && device_id == DEVICE_83PCE) { + } else if (model_id == TIMODEL_8384CE && device_id == DEVICE_83PCE) { device_type = TI83PCE; gotType = true; } else { gui_console_err_printf("[CEmu] Got model<->device discrepency!?\n"); } + { + static const uint16_t python_path[] = { 0x0330, 0x0430 }; + bool isPython = !cert_field_find_path(mem.flash.block + 0x3B0001, SIZE_FLASH_SECTOR_64K, python_path, 2, NULL, NULL); + gui_console_printf("[CEmu] Info from cert: Device type = 0x%02X (%s). Model = 0x%02X (%s). Is Python? %s.\n", + device_id, (device_id == DEVICE_84PCE) ? "84+CE-like" : "83PCE-like", + model_id, (model_id == TIMODEL_8384CE) ? "CE" : "82AEP", + isPython ? "Yes" : "No"); + } + gui_console_printf("[CEmu] Loaded ROM Image.\n"); break; } From a9a5a74328f8283c8063e8f5196182e29f57b43e Mon Sep 17 00:00:00 2001 From: Adrien Bertrand Date: Wed, 4 Dec 2024 17:14:16 +0100 Subject: [PATCH 26/26] fix core makefile for ARM emulation files. --- core/Makefile | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/Makefile b/core/Makefile index 3309a3562..56ba87c92 100644 --- a/core/Makefile +++ b/core/Makefile @@ -6,6 +6,7 @@ RM = rm -f # If you want core debug support, add -DDEBUG_SUPPORT # If you want the emulator to run on a different thread than the gui, add -DMULTITHREAD CFLAGS = -Wall -Wextra -fPIC -O3 -std=gnu11 -static +CFLAGS += -Iarm/samd21a/include -Iarm/CMSIS/Core/Include # Add debugging support, with zdis disassembler #CFLAGS += -DDEBUG_SUPPORT @@ -19,6 +20,7 @@ CFLAGS = -Wall -Wextra -fPIC -O3 -std=gnu11 -static rwildcard = $(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2)$(filter $(subst *,%,$2),$d)) OBJS = $(patsubst %.c,%.o,$(filter-out arm/%,$(call rwildcard,,*.c))) +OBJS += arm/tinycthread.o arm/arm.o arm/armcpu.o arm/armmem.o arm/spscqueue.o arm/sync.o STATICLIB = libcemucore.a