From 93628aae033c34b8dee92627a65240c988b1916a Mon Sep 17 00:00:00 2001 From: Udhayanandhan Jayakumar Date: Mon, 30 Jun 2025 22:03:24 +0530 Subject: [PATCH 1/6] Release: v2.0 Highlights: - Added support for xc-dsc toolchain: CMake scripts, linker files - Arch bring-up for dsPIC (Curiosity board): thread creation, early boot, swap - CMake: Improved path detection, removed debug messages, static lib fixes - Interrupt vector table (IVT) initialization and macro definition - MISRA compliance fixes - Various bug fixes, stylistic cleanup, and compliance-related updates Changes: * cmake: Add xc-dsc toolchain support and linker script * arch: dspic: Rename isr_table_vt.ld to vector_table.ld * camke: Fix path detection for build dependencies * cmake: Resolve include path issues * cmake: Remove debug messages * arch: dspic: Add thread creation and init logic * arch: Resolve arch_swap implicit declaration warning * arch: Add vector tables and common ISR wrapper * cmake: Enable compiling assembly files * cmake: Fix static library linking * arch: Support IVT table placement and macros * cmake: Skip init priorities check for xc-dsc * toolchain: Remove stdlib usage (use picolibc instead) * arch: Remove use of unimplemented functions * arch: Early boot sequence implementation * arch: Task swap and main thread entry logic Signed-off-by: Udhayanandhan Jayakumar --- arch/Kconfig | 27 + arch/archs.yml | 3 + arch/dspic/CMakeLists.txt | 8 + arch/dspic/Kconfig | 14 + arch/dspic/core/CMakeLists.txt | 18 + arch/dspic/core/cpu_idle.c | 27 + arch/dspic/core/fatal.c | 81 + arch/dspic/core/init.S | 57 + arch/dspic/core/irq_manage.c | 28 + arch/dspic/core/isr_wrapper.c | 22 + arch/dspic/core/offsets/offsets.c | 9 + arch/dspic/core/prep_c.c | 25 + arch/dspic/core/reset0.S | 38 + arch/dspic/core/reset1.S | 17 + arch/dspic/core/swap.c | 384 +++ arch/dspic/core/thread.c | 50 + arch/dspic/core/tls.c | 32 + arch/dspic/core/vector_table.S | 304 ++ arch/dspic/core/vector_table.h | 42 + arch/dspic/core/vector_table.ld | 11 + arch/dspic/include/dspic/dspicregs.h | 9 + arch/dspic/include/dspic/regdef.h | 9 + arch/dspic/include/kernel_arch_func.h | 89 + arch/dspic/include/offsets_short_arch.h | 11 + boards/microchip/ev74h48a/Kconfig.ev74h48a | 2 + boards/microchip/ev74h48a/board.yml | 7 + .../ev74h48a/ev74h48a_p33ak128mc106.dts | 22 + .../ev74h48a/ev74h48a_p33ak128mc106_defconfig | 20 + .../ev74h48a/ev74h48a_p33ak128mc506.dts | 1 + cmake/bintools/xcdsc/target.cmake | 10 + cmake/bintools/xcdsc/target_bintools.cmake | 28 + cmake/compiler/xcdsc/compiler_flags.cmake | 28 + cmake/compiler/xcdsc/generic.cmake | 21 + cmake/compiler/xcdsc/target.cmake | 16 + cmake/linker/xcdsc/linker_flags.cmake | 29 + cmake/linker/xcdsc/target.cmake | 92 + cmake/linker/xcdsc/target_configure.cmake | 10 + cmake/toolchain/xcdsc/Kconfig | 16 + cmake/toolchain/xcdsc/generic.cmake | 19 + cmake/toolchain/xcdsc/target.cmake | 1 + drivers/console/ram_console.c | 7 +- dts/dspic/p33ak128mc106.dtsi | 60 + include/zephyr/arch/arch_inlines.h | 2 + include/zephyr/arch/cpu.h | 2 + include/zephyr/arch/dspic/arch.h | 114 + include/zephyr/arch/dspic/arch_inlines.h | 16 + include/zephyr/arch/dspic/exception.h | 48 + include/zephyr/arch/dspic/linker.ld | 2977 +++++++++++++++++ include/zephyr/arch/dspic/thread.h | 102 + include/zephyr/arch/exception.h | 2 + include/zephyr/kernel.h | 2 + include/zephyr/kernel/thread_stack.h | 15 +- include/zephyr/linker/linker-defs.h | 2 +- include/zephyr/linker/linker-tool-gcc.h | 3 + include/zephyr/linker/linker-tool-xcdsc.h | 59 + include/zephyr/linker/linker-tool.h | 2 + include/zephyr/toolchain.h | 2 + include/zephyr/toolchain/common.h | 10 +- include/zephyr/toolchain/gcc.h | 25 +- include/zephyr/toolchain/xcdsc.h | 218 ++ kernel/init.c | 4 + kernel/thread.c | 17 +- kernel/timeout.c | 4 + soc/microchip/dspic33/CMakeLists.txt | 1 + soc/microchip/dspic33/Kconfig | 3 + soc/microchip/dspic33/Kconfig.defconfig | 3 + soc/microchip/dspic33/Kconfig.soc | 7 + soc/microchip/dspic33/dspic33a/CMakeLists.txt | 7 + soc/microchip/dspic33/dspic33a/Kconfig | 12 + .../dspic33a/Kconfig.defconfig.p33ak128mc106 | 37 + .../dspic33/dspic33a/Kconfig.defconfig.series | 3 + soc/microchip/dspic33/dspic33a/Kconfig.soc | 21 + soc/microchip/dspic33/dspic33a/power.c | 30 + soc/microchip/dspic33/dspic33a/soc.h | 7 + soc/microchip/dspic33/soc.yml | 9 + 75 files changed, 5452 insertions(+), 18 deletions(-) create mode 100644 arch/dspic/CMakeLists.txt create mode 100644 arch/dspic/Kconfig create mode 100644 arch/dspic/core/CMakeLists.txt create mode 100644 arch/dspic/core/cpu_idle.c create mode 100644 arch/dspic/core/fatal.c create mode 100644 arch/dspic/core/init.S create mode 100644 arch/dspic/core/irq_manage.c create mode 100644 arch/dspic/core/isr_wrapper.c create mode 100644 arch/dspic/core/offsets/offsets.c create mode 100644 arch/dspic/core/prep_c.c create mode 100644 arch/dspic/core/reset0.S create mode 100644 arch/dspic/core/reset1.S create mode 100644 arch/dspic/core/swap.c create mode 100644 arch/dspic/core/thread.c create mode 100644 arch/dspic/core/tls.c create mode 100644 arch/dspic/core/vector_table.S create mode 100644 arch/dspic/core/vector_table.h create mode 100644 arch/dspic/core/vector_table.ld create mode 100644 arch/dspic/include/dspic/dspicregs.h create mode 100644 arch/dspic/include/dspic/regdef.h create mode 100644 arch/dspic/include/kernel_arch_func.h create mode 100644 arch/dspic/include/offsets_short_arch.h create mode 100644 boards/microchip/ev74h48a/Kconfig.ev74h48a create mode 100644 boards/microchip/ev74h48a/board.yml create mode 100644 boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts create mode 100644 boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig create mode 100644 boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts create mode 100644 cmake/bintools/xcdsc/target.cmake create mode 100644 cmake/bintools/xcdsc/target_bintools.cmake create mode 100644 cmake/compiler/xcdsc/compiler_flags.cmake create mode 100644 cmake/compiler/xcdsc/generic.cmake create mode 100644 cmake/compiler/xcdsc/target.cmake create mode 100644 cmake/linker/xcdsc/linker_flags.cmake create mode 100644 cmake/linker/xcdsc/target.cmake create mode 100644 cmake/linker/xcdsc/target_configure.cmake create mode 100644 cmake/toolchain/xcdsc/Kconfig create mode 100644 cmake/toolchain/xcdsc/generic.cmake create mode 100644 cmake/toolchain/xcdsc/target.cmake create mode 100644 dts/dspic/p33ak128mc106.dtsi create mode 100644 include/zephyr/arch/dspic/arch.h create mode 100644 include/zephyr/arch/dspic/arch_inlines.h create mode 100644 include/zephyr/arch/dspic/exception.h create mode 100644 include/zephyr/arch/dspic/linker.ld create mode 100644 include/zephyr/arch/dspic/thread.h create mode 100644 include/zephyr/linker/linker-tool-xcdsc.h create mode 100644 include/zephyr/toolchain/xcdsc.h create mode 100644 soc/microchip/dspic33/CMakeLists.txt create mode 100644 soc/microchip/dspic33/Kconfig create mode 100644 soc/microchip/dspic33/Kconfig.defconfig create mode 100644 soc/microchip/dspic33/Kconfig.soc create mode 100644 soc/microchip/dspic33/dspic33a/CMakeLists.txt create mode 100644 soc/microchip/dspic33/dspic33a/Kconfig create mode 100644 soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 create mode 100644 soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series create mode 100644 soc/microchip/dspic33/dspic33a/Kconfig.soc create mode 100644 soc/microchip/dspic33/dspic33a/power.c create mode 100644 soc/microchip/dspic33/dspic33a/soc.h create mode 100644 soc/microchip/dspic33/soc.yml diff --git a/arch/Kconfig b/arch/Kconfig index d29976d37a453..3fa4bbfb20a3a 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -167,6 +167,28 @@ config RX help Renesas RX architecture +config DSPIC + bool + select ARCH_IS_SET + select STACK_GROWS_UP + select ARCH_HAS_CUSTOM_SWAP_TO_MAIN + select LITTLE_ENDIAN + select ARCH_HAS_THREAD_LOCAL_STORAGE + select TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + select THREAD_LOCAL_STORAGE + select INIT_STACKS + select STACK_SENTINAL + select ATOMIC_OPERATIONS_C + select ARCH_HAS_VECTOR_TABLE_RELOCATION + select CPU_HAS_ICACHE + select ARCH_HAS_CUSTOM_CPU_IDLE + select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE + select DYNAMIC_INTERRUPTS + select CACHE_MANAGEMENT + select TICKLESS_CAPABLE + help + dspic architecture + config ARCH_IS_SET bool help @@ -376,6 +398,11 @@ config STACK_GROWS_UP Select this option if the architecture has upward growing thread stacks. This is not common. +config STACK_SENTINAL + bool + help + It is a debugging and safety feature at the boundaries of the stack. + config NO_UNUSED_STACK_INSPECTION bool help diff --git a/arch/archs.yml b/arch/archs.yml index c8ee38ab43703..2aa0e7f64de3e 100644 --- a/arch/archs.yml +++ b/arch/archs.yml @@ -29,3 +29,6 @@ archs: - name: rx path: rx full_name: Renesas RX + - name: dspic + path: dspic + full_name: Microchip dsPIC diff --git a/arch/dspic/CMakeLists.txt b/arch/dspic/CMakeLists.txt new file mode 100644 index 0000000000000..fc07eabc00031 --- /dev/null +++ b/arch/dspic/CMakeLists.txt @@ -0,0 +1,8 @@ +if(CONFIG_BIG_ENDIAN) + set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-big) +else() + set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little) +endif() +zephyr_include_directories(${XCDSC_TOOLCHAIN_PATH}/support/generic/h/) +zephyr_include_directories(include) +add_subdirectory(core) diff --git a/arch/dspic/Kconfig b/arch/dspic/Kconfig new file mode 100644 index 0000000000000..c8615033e7596 --- /dev/null +++ b/arch/dspic/Kconfig @@ -0,0 +1,14 @@ +menu "DSPIC Options" + depends on DSPIC + +config ARCH + string + default "dspic" + +config NUM_IRQS + default 287 + +config GEN_IRQ_START_VECTOR + default 8 + +endmenu diff --git a/arch/dspic/core/CMakeLists.txt b/arch/dspic/core/CMakeLists.txt new file mode 100644 index 0000000000000..66c2cbef22ff3 --- /dev/null +++ b/arch/dspic/core/CMakeLists.txt @@ -0,0 +1,18 @@ +zephyr_library() + +zephyr_library_sources( + cpu_idle.c + fatal.c + irq_manage.c + isr_wrapper.c + prep_c.c + thread.c + swap.c + tls.c + reset0.S + init.S + vector_table.S + reset1.S +) + +zephyr_linker_sources(ROM_START SORT_KEY 0x04 vector_table.ld) diff --git a/arch/dspic/core/cpu_idle.c b/arch/dspic/core/cpu_idle.c new file mode 100644 index 0000000000000..6636794e2b9e6 --- /dev/null +++ b/arch/dspic/core/cpu_idle.c @@ -0,0 +1,27 @@ +/** + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE +void arch_cpu_idle(void) +{ +} +#endif + +#ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE +void arch_cpu_atomic_idle(unsigned int key) +{ + (void)key; +} +#endif + +FUNC_NORETURN void arch_system_halt(unsigned int reason) +{ + (void)reason; + CODE_UNREACHABLE; +} diff --git a/arch/dspic/core/fatal.c b/arch/dspic/core/fatal.c new file mode 100644 index 0000000000000..5bfccbfcf7a06 --- /dev/null +++ b/arch/dspic/core/fatal.c @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include + +volatile uint32_t reason, address; + +#define EXCEPTION_HANDLER __attribute__((interrupt, no_auto_psv, keep)) + +void EXCEPTION_HANDLER _ReservedTrap7(void); +void __attribute__((weak)) TRAPS_halt_on_error(void); +void EXCEPTION_HANDLER _BusErrorTrap(void); +void EXCEPTION_HANDLER _AddressErrorTrap(void); +void EXCEPTION_HANDLER _IllegalInstructionTrap(void); +void EXCEPTION_HANDLER _MathErrorTrap(void); +void EXCEPTION_HANDLER _StackErrorTrap(void); +void EXCEPTION_HANDLER _GeneralTrap(void); +void EXCEPTION_HANDLER _ReservedTrap0(void); +void EXCEPTION_HANDLER _ReservedTrap7(void); + +void __attribute__((weak)) TRAPS_halt_on_error(void) +{ +} + +/** Bus error.**/ +void EXCEPTION_HANDLER _BusErrorTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Address error.**/ +void EXCEPTION_HANDLER _AddressErrorTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Illegal instruction.**/ +void EXCEPTION_HANDLER _IllegalInstructionTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Math error.**/ +void EXCEPTION_HANDLER _MathErrorTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Stack error.**/ +void EXCEPTION_HANDLER _StackErrorTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Generic error.**/ +void EXCEPTION_HANDLER _GeneralTrap(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Reserved Trap0.**/ +void EXCEPTION_HANDLER _ReservedTrap0(void) +{ + __asm__("nop"); + __asm__("retfie"); +} + +/** Reserved Trap7.**/ +void EXCEPTION_HANDLER _ReservedTrap7(void) +{ + __asm__("nop"); + __asm__("retfie"); +} diff --git a/arch/dspic/core/init.S b/arch/dspic/core/init.S new file mode 100644 index 0000000000000..59b63028e9959 --- /dev/null +++ b/arch/dspic/core/init.S @@ -0,0 +1,57 @@ +.section .init,code +.global __custom_data_init +.global __custom_data_init_extended + +.equ __custom_data_init, __custom_data_init_extended +__custom_data_init_extended: + + .equiv FMT_CLEAR,0 + .equiv FMT_COPY2,1 + .equiv FMT_COPY3,2 + .equiv FMT_CALL, 3 + .equiv FMT_DUO_COPY3,0x1F + +#define DINIT w0 +#define TLSOFFSET w1 +#define TBLOFFSET w9 +#define DSTOFFSET w10 +#define LEN w11 +#define FORMAT w12 + + mov.l w0, TBLOFFSET + bra 4f + +1: + add.l DSTOFFSET,TLSOFFSET,DSTOFFSET + mov.l [TBLOFFSET++], LEN + mov.l [TBLOFFSET++], FORMAT + + cp.b FORMAT, #FMT_CALL + bra nz, 2f + call DSTOFFSET + bra 4f + +2: + cp.b FORMAT, #FMT_CLEAR + bra nz, 2f +9: + sub.l LEN, #1, LEN + repeat LEN + clr.b [DSTOFFSET++] + bra 4f + +2: + cp.b FORMAT, #FMT_COPY2 + bra z, 3f + +3: + sub.l LEN, #1, LEN + repeat LEN + mov.b [TBLOFFSET++], [DSTOFFSET++] + add.l TBLOFFSET, #3, TBLOFFSET + and1.l TBLOFFSET, #0x7C, TBLOFFSET + +4: + sub.l [TBLOFFSET++], #0, DSTOFFSET + bra nz, 1b + return diff --git a/arch/dspic/core/irq_manage.c b/arch/dspic/core/irq_manage.c new file mode 100644 index 0000000000000..489f4002f2023 --- /dev/null +++ b/arch/dspic/core/irq_manage.c @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +void z_irq_spurious(const void *unused) +{ + (void)unused; +} + +void arch_irq_enable(unsigned int irq) +{ + (void)irq; +} + +int arch_irq_is_enabled(unsigned int irq) +{ + (void)irq; + return 0; +} + +void arch_irq_disable(unsigned int irq) +{ + (void)irq; +} diff --git a/arch/dspic/core/isr_wrapper.c b/arch/dspic/core/isr_wrapper.c new file mode 100644 index 0000000000000..bc1f4cf2b0962 --- /dev/null +++ b/arch/dspic/core/isr_wrapper.c @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include + +/* dsPIC33A interrtup exit routine. Will check if a context + * switch is required. If so, z_dspic_do_swap() will be called + * to affect the context switch + */ +void __attribute__((naked)) z_dspic_exc_exit(void) +{ +} + +void __attribute__((interrupt, naked)) _COMMONInterrupt(void) +{ +} diff --git a/arch/dspic/core/offsets/offsets.c b/arch/dspic/core/offsets/offsets.c new file mode 100644 index 0000000000000..18e5952ec94a1 --- /dev/null +++ b/arch/dspic/core/offsets/offsets.c @@ -0,0 +1,9 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +GEN_ABS_SYM_END diff --git a/arch/dspic/core/prep_c.c b/arch/dspic/core/prep_c.c new file mode 100644 index 0000000000000..59c57ec74a7d8 --- /dev/null +++ b/arch/dspic/core/prep_c.c @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +void z_prep_c(void); +/** + * @brief Prepare to and run C code + * + * This routine prepares for the execution of and runs C code. + */ + +void z_prep_c(void) +{ +#if defined(CONFIG_SOC_PREP_HOOK) + soc_prep_hook(); +#endif + z_cstart(); + CODE_UNREACHABLE; +} diff --git a/arch/dspic/core/reset0.S b/arch/dspic/core/reset0.S new file mode 100644 index 0000000000000..b0c8d02d5917b --- /dev/null +++ b/arch/dspic/core/reset0.S @@ -0,0 +1,38 @@ +#include +#include +#include +#include + +;;This reset version support data initialization +;;Refer reset1.S for without data initialization + +.section .text, code ; Use .text to avoid section attribute errors +.weak __start,__user_init, __has_user_init, ___tls_crt_init +.extern __custom_data_init_extended +.extern __user_init + +__start: + ;; Initialize stack pointer and limit + mov.l #__SP_init, w15 ; Stack pointer (W15) + mov.l #__SPLIM_init, w14 ; Stack limit (W14) + + ;; Data initialization + mov.l #__dinit_tbloffset, w0 + cp0.l w0 + bra eq, 1f + clr w1 + rcall __custom_data_init_extended +1: + ;; Thread-local storage init (if available) + mov.l #___tls_crt_init, w0 + cp0.l w0 + bra eq, 1f + rcall ___tls_crt_init +1: + mov.l #__user_init,w0 + cp0.l w0 ; user init functions + bra eq,1f + call __user_init +1: + ;; Call the main application + call _z_prep_c diff --git a/arch/dspic/core/reset1.S b/arch/dspic/core/reset1.S new file mode 100644 index 0000000000000..43624f805926e --- /dev/null +++ b/arch/dspic/core/reset1.S @@ -0,0 +1,17 @@ + +;;This version support without data initialization +;;Refer reset0.S for the data initialization + +.section .text, code +.weak __start +__start: + ;; Initialize stack pointer and limit + mov.l #__SP_init, w15 ; Stack pointer (W15) + mov.l #__SPLIM_init, w14 ; Stack limit (W14) + + mov.l #__user_init,w0 + cp0.l w0 ; user init functions + bra eq,1f + call __user_init +1: + call _z_prep_c ; Call main application diff --git a/arch/dspic/core/swap.c b/arch/dspic/core/swap.c new file mode 100644 index 0000000000000..2abee58a4e8fa --- /dev/null +++ b/arch/dspic/core/swap.c @@ -0,0 +1,384 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include "kswap.h" +#include +#include + +void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, + k_thread_entry_t _main) +{ + (void)stack_ptr; + (void)_main; + z_current_thread_set(main_thread); + + /* w0 will contain main_thread + * Get the offset to callee saved structure + */ + __asm__ volatile("mov.l #0x28, w1\n\t" + "add w1, w0, w1\n\t"); + + /*Restore all registers*/ + __asm__ volatile("mov.l [w1++], w8\n\t" + "mov.l [w1++], w9\n\t" + "mov.l [w1++], w10\n\t" + "mov.l [w1++], w11\n\t" + "mov.l [w1++], w12\n\t" + "mov.l [w1++], w13\n\t" + "mov.l [w1++], w14\n\t" + + "mov.l [w1++], f8\n\t" + "mov.l [w1++], f9\n\t" + "mov.l [w1++], f10\n\t" + "mov.l [w1++], f11\n\t" + "mov.l [w1++], f12\n\t" + "mov.l [w1++], f13\n\t" + "mov.l [w1++], f14\n\t" + "mov.l [w1++], f15\n\t" + "mov.l [w1++], f16\n\t" + "mov.l [w1++], f17\n\t" + "mov.l [w1++], f18\n\t" + "mov.l [w1++], f19\n\t" + "mov.l [w1++], f20\n\t" + "mov.l [w1++], f21\n\t" + "mov.l [w1++], f22\n\t" + "mov.l [w1++], f23\n\t" + "mov.l [w1++], f24\n\t" + "mov.l [w1++], f25\n\t" + "mov.l [w1++], f26\n\t" + "mov.l [w1++], f27\n\t" + "mov.l [w1++], f28\n\t" + "mov.l [w1++], f29\n\t" + "mov.l [w1++], f30\n\t" + "mov.l [w1++], f31\n\t" + + "mov.l #RCOUNT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #CORCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #MODCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XBREV, w2\n\t" + "mov.l [w1++], [w2]\n\t" + + "clr A\n\t" + "clr B\n\t" + "slac.l A, [W1++]\n\t" + "sac.l A, [W1++]\n\t" + "suac.l A, [W1++]\n\t" + "slac.l B, [W1++]\n\t" + "sac.l B, [W1++]\n\t" + "suac.l B, [W1++]\n\t" + + "mov.l [w1++], w15\n\t" + "mov.l [w1++], w14\n\t" + "mov.l #SPLIM, w2\n\t" + "mov.l [w1++], [w2]\n\t"); + + /*pop saved stack frame*/ + __asm__ volatile("pop.l f7\n\t" + "pop.l f6\n\t" + "pop.l f5\n\t" + "pop.l f4\n\t" + "pop.l f3\n\t" + "pop.l f2\n\t" + "pop.l f1\n\t" + "pop.l f0\n\t" + "mov.l [--w15], w7\n\t" + "mov.l [--w15], w6\n\t" + "mov.l [--w15], w5\n\t" + "mov.l [--w15], w4\n\t" + "mov.l [--w15], w3\n\t" + "mov.l [--w15], w2\n\t" + "mov.l [--w15], w1\n\t" + "mov.l [--w15], w0\n\t" + "pop.l fcr\n\t" + "pop.l fsr\n\t" + "pop.l RCOUNT\n\t"); +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); +#endif +} + +int arch_swap(unsigned int key) +{ +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_out(); +#endif + + /* store off key and return value */ + _current->arch.cpu_level = key; + _current->arch.swap_return_value = -EAGAIN; + + /*Check if swap is needed*/ + if (_kernel.ready_q.cache != _current) { + /*Backup the current task context*/ + z_dspic_save_context(); + + /*Switch to next task in queue*/ + z_current_thread_set(_kernel.ready_q.cache); + z_dspic_do_swap(); + } + +#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING + z_thread_mark_switched_in(); +#endif + + /* This arch has only one SP and dosent use any kernel call style ABI + * Which means a return will pollute the next stacks working reg (w0-w4) + * Adding a hack here to return w0 without modification + * TODO: analyse the use of return value from arch_swap + * Make sure the return value is not being intrepreted + * wrongly + */ + register int result __asm__("w0"); + return result; + + /* Context switch is performed here. Returning implies the + * thread has been context-switched-in again. + */ +} + +void __attribute__((naked)) z_dspic_save_context(void) +{ + /* Get the current thread callee_saved context + * TODO: + * Need to change constant 0x8, 0x28 with offset symbols + * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET + */ + __asm__ volatile("mov.l #__kernel, w0\n\t" + "mov.l #0x8, w1\n\t" + "add w0, w1, w1\n\t" + "mov.l [w1], w2\n\t" + "mov.l #0x28, w1\n\t" + "add w2, w1, w1\n\t"); + + /*Save all callee saved registers*/ + __asm__ volatile("mov.l w8, [w1++]\n\t" + "mov.l w9, [w1++]\n\t" + "mov.l w10, [w1++]\n\t" + "mov.l w11, [w1++]\n\t" + "mov.l w12, [w1++]\n\t" + "mov.l w13, [w1++]\n\t" + "mov.l w14, [w1++]\n\t" + + "mov.l f8, [w1++]\n\t" + "mov.l f9, [w1++]\n\t" + "mov.l f10, [w1++]\n\t" + "mov.l f11, [w1++]\n\t" + "mov.l f12, [w1++]\n\t" + "mov.l f13, [w1++]\n\t" + "mov.l f14, [w1++]\n\t" + "mov.l f15, [w1++]\n\t" + "mov.l f16, [w1++]\n\t" + "mov.l f17, [w1++]\n\t" + "mov.l f18, [w1++]\n\t" + "mov.l f19, [w1++]\n\t" + "mov.l f20, [w1++]\n\t" + "mov.l f21, [w1++]\n\t" + "mov.l f22, [w1++]\n\t" + "mov.l f23, [w1++]\n\t" + "mov.l f24, [w1++]\n\t" + "mov.l f25, [w1++]\n\t" + "mov.l f26, [w1++]\n\t" + "mov.l f27, [w1++]\n\t" + "mov.l f28, [w1++]\n\t" + "mov.l f29, [w1++]\n\t" + "mov.l f30, [w1++]\n\t" + "mov.l f31, [w1++]\n\t" + + "mov.l #RCOUNT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #CORCON, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #MODCON, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XMODSRT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XMODEND, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #YMODSRT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #YMODEND, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XBREV, w2\n\t" + "mov.l [w2], [w1++]\n\t" + + "clr A\n\t" + "clr B\n\t" + "slac.l A, [W1++]\n\t" + "sac.l A, [W1++]\n\t" + "suac.l A, [W1++]\n\t" + "slac.l B, [W1++]\n\t" + "sac.l B, [W1++]\n\t" + "suac.l B, [W1++]\n\t" + + "mov.l w15, [w1++]\n\t" + "mov.l w14, [w1++]\n\t" + "mov.l #SPLIM, w2\n\t" + "mov.l [w2], [w1++]\n\t"); +} + +/* routine which swaps the context. Needs to be written in assembly */ +void __attribute__((naked)) z_dspic_do_swap(void) +{ + /*Adjust stack for co-operative swap*/ + __asm__ volatile( + /*Check if in interrupt context*/ + "mov.l w0, [w15++]\n\t" + "mov.l sr, w0\n\t" + "and #0xe0, w0\n\t" + "bra nz, 1f\n\t" + + /*Not in interrupt context*/ + "mov.l [--w15], w0\n\t" + "push RCOUNT\n\t" + "push.l fsr\n\t" + "push.l fcr\n\t" + "mov.l w0, [w15++]\n\t" + "mov.l w1, [w15++]\n\t" + "mov.l w2, [w15++]\n\t" + "mov.l w3, [w15++]\n\t" + "mov.l w4, [w15++]\n\t" + "mov.l w5, [w15++]\n\t" + "mov.l w6, [w15++]\n\t" + "mov.l w7, [w15++]\n\t" + "push.l f0\n\t" + "push.l f1\n\t" + "push.l f2\n\t" + "push.l f3\n\t" + "push.l f4\n\t" + "push.l f5\n\t" + "push.l f6\n\t" + "push.l f7\n\t" + "mov.l w0, [w15++]\n\t" + + /*In interrupt context*/ + "1:\n\t" + "mov.l [--w15], w0\n\t"); + + /* Get the current thread callee_saved context + * TODO: + * Need to change constant 0x8, 0x28 with offset symbols + * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET + */ + __asm__ volatile("mov.l #__kernel, w0\n\t" + "mov.l #0x8, w1\n\t" + "add w0, w1, w1\n\t" + "mov.l [w1], w2\n\t" + "mov.l #0x28, w1\n\t" + "add w2, w1, w1\n\t"); + + /*Restore all registers*/ + __asm__ volatile("mov.l [w1++], w8\n\t" + "mov.l [w1++], w9\n\t" + "mov.l [w1++], w10\n\t" + "mov.l [w1++], w11\n\t" + "mov.l [w1++], w12\n\t" + "mov.l [w1++], w13\n\t" + "mov.l [w1++], w14\n\t" + + "mov.l [w1++], f8\n\t" + "mov.l [w1++], f9\n\t" + "mov.l [w1++], f10\n\t" + "mov.l [w1++], f11\n\t" + "mov.l [w1++], f12\n\t" + "mov.l [w1++], f13\n\t" + "mov.l [w1++], f14\n\t" + "mov.l [w1++], f15\n\t" + "mov.l [w1++], f16\n\t" + "mov.l [w1++], f17\n\t" + "mov.l [w1++], f18\n\t" + "mov.l [w1++], f19\n\t" + "mov.l [w1++], f20\n\t" + "mov.l [w1++], f21\n\t" + "mov.l [w1++], f22\n\t" + "mov.l [w1++], f23\n\t" + "mov.l [w1++], f24\n\t" + "mov.l [w1++], f25\n\t" + "mov.l [w1++], f26\n\t" + "mov.l [w1++], f27\n\t" + "mov.l [w1++], f28\n\t" + "mov.l [w1++], f29\n\t" + "mov.l [w1++], f30\n\t" + "mov.l [w1++], f31\n\t" + + "mov.l #RCOUNT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #CORCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #MODCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XBREV, w2\n\t" + "mov.l [w1++], [w2]\n\t" + + "clr A\n\t" + "clr B\n\t" + "slac.l A, [W1++]\n\t" + "sac.l A, [W1++]\n\t" + "suac.l A, [W1++]\n\t" + "slac.l B, [W1++]\n\t" + "sac.l B, [W1++]\n\t" + "suac.l B, [W1++]\n\t" + + "mov.l [w1++], w15\n\t" + "mov.l [w1++], w14\n\t" + "mov.l #SPLIM, w2\n\t" + "mov.l [w1++], [w2]\n\t"); + + /*pop exception/swap saved stack frame*/ + __asm__ volatile( + /* Check context and only pop the + * esf if in thread context + */ + "mov.l w0, [w15++]\n\t" + "mov.l sr, w0\n\t" + "and #0xe0, w0\n\t" + "bra nz, 1f\n\t" + + /*Thread context*/ + "pop.l f7\n\t" + "pop.l f6\n\t" + "pop.l f5\n\t" + "pop.l f4\n\t" + "pop.l f3\n\t" + "pop.l f2\n\t" + "pop.l f1\n\t" + "pop.l f0\n\t" + "mov.l [--w15], w7\n\t" + "mov.l [--w15], w6\n\t" + "mov.l [--w15], w5\n\t" + "mov.l [--w15], w4\n\t" + "mov.l [--w15], w3\n\t" + "mov.l [--w15], w2\n\t" + "mov.l [--w15], w1\n\t" + "mov.l [--w15], w0\n\t" + "pop.l fcr\n\t" + "pop.l fsr\n\t" + "pop RCOUNT\n\t" + + /*Interrupt context*/ + "1:\n\t" + "nop\n\t"); +} diff --git a/arch/dspic/core/thread.c b/arch/dspic/core/thread.c new file mode 100644 index 0000000000000..72c470a16995f --- /dev/null +++ b/arch/dspic/core/thread.c @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#define RAM_END 0x00007FFC + +void z_thread_entry(k_thread_entry_t thread, void *arg1, void *arg2, void *arg3); + +void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *stack_ptr, + k_thread_entry_t entry, void *p1, void *p2, void *p3) +{ + (void)stack; + struct arch_esf *init_frame; + + /* Initial stack frame for thread */ + init_frame = (struct arch_esf *)Z_STACK_PTR_ALIGN( + Z_STACK_PTR_TO_FRAME(struct arch_esf, stack_ptr)); + /* Setting all register to zero*/ + (void)memset(init_frame, 0, sizeof(struct arch_esf)); + + /* Setup initial stack frame*/ + init_frame->W0 = (uint32_t)entry; + init_frame->W1 = (uint32_t)(void *)p1; + init_frame->W2 = (uint32_t)(void *)p2; + init_frame->W3 = (uint32_t)(void *)p3; + + /* Initial cpu status register with default value*/ + init_frame->FSR = DSPIC_STATUS_DEFAULT; + + /** + * set the pc to the zephyr common thread entry function + * Z_thread_entry(entry, p1, p2, p3) + */ + init_frame->PC = (uint32_t)z_thread_entry; + init_frame->FRAME = (uint32_t)(void *)init_frame - (uint32_t)1; + + /** + * Set the stack top to the esf structure. The context switch + * code will be using this field to set the stack pointer of + * the switched thread + */ + thread->callee_saved.stack = (uint32_t)(void *)init_frame + (sizeof(struct arch_esf)); + thread->callee_saved.frame = (uint32_t)&init_frame->RCOUNT; + /*TODO: Need to handle splim properly*/ + thread->callee_saved.splim = RAM_END; +} diff --git a/arch/dspic/core/tls.c b/arch/dspic/core/tls.c new file mode 100644 index 0000000000000..b9c6f5898906a --- /dev/null +++ b/arch/dspic/core/tls.c @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include + +size_t arch_tls_stack_setup(struct k_thread *new_thread, char *stack_ptr) +{ + /* Align the memory according to the alignment requirement */ + uint32_t align = _tls_align(); + char *stack_p = stack_ptr; + + /* Calculate how many bytes were added to align the pointer */ + uint32_t align_bytes = (align - (uint32_t)(void *)(stack_p) % align); + + /* this could be optimized based on the range of values of align*/ + stack_p = (void *)((uint32_t)(void *)stack_p + align_bytes); + + /* since the dsPIC33A stack grows upwards, the current tls area is setTo the beginning of + * the stack pointer + */ + new_thread->tls = POINTER_TO_UINT(stack_p); + + /* setup the TLS data/bss area first.*/ + _init_tls(stack_p); + + return _tls_size() + align_bytes; +} diff --git a/arch/dspic/core/vector_table.S b/arch/dspic/core/vector_table.S new file mode 100644 index 0000000000000..28b8302bc0b58 --- /dev/null +++ b/arch/dspic/core/vector_table.S @@ -0,0 +1,304 @@ +#include +#include +#include "vector_table.h" + +.global __ReservedTrap0 +.global __BusErrorTrap +.global __AddressErrorTrap +.global __IllegalInstructionTrap +.global __MathErrorTrap +.global __StackErrorTrap +.global __GeneralTrap +.global __ReservedTrap7 +.global __COMMONInterrupt + +.section .exc_vector_table._vector_table_section, code +.global __vector_table +__vector_table: + .long __ReservedTrap0 + .long __BusErrorTrap + .long __IllegalInstructionTrap + .long __AddressErrorTrap + .long __StackErrorTrap + .long __MathErrorTrap + .long __GeneralTrap + .long __ReservedTrap7 + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt + .long __COMMONInterrupt diff --git a/arch/dspic/core/vector_table.h b/arch/dspic/core/vector_table.h new file mode 100644 index 0000000000000..e3000ab6c7657 --- /dev/null +++ b/arch/dspic/core/vector_table.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2013-2015 Wind River Systems, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Definitions for the boot vector table + * + * + * Definitions for the boot vector table. + * + * System exception handler names all have the same format: + * + * __ + * + * No other symbol has the same format, so they are easy to spot. + */ + +#ifndef ZEPHYR_ARCH_DSPIC_VECTOR_TABLE_H_ +#define ZEPHYR_ARCH_DSPIC_VECTOR_TABLE_H_ + +#ifdef _ASMLANGUAGE + +#include +#include +#include + +#else /* _ASMLANGUAGE */ + +#ifdef __cplusplus +extern "C" { +#endif +extern void *_vector_table[CONFIG_NUM_IRQS]; +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_ARCH_ARM_CORE_AARCH32_CORTEX_M_VECTOR_TABLE_H_ */ diff --git a/arch/dspic/core/vector_table.ld b/arch/dspic/core/vector_table.ld new file mode 100644 index 0000000000000..3db6ed2674c26 --- /dev/null +++ b/arch/dspic/core/vector_table.ld @@ -0,0 +1,11 @@ +_vector_start = .; +KEEP(*(.exc_vector_table)) +KEEP(*(.exc_vector_table.*)) + +#if LINKER_ZEPHYR_FINAL && defined(CONFIG_ISR_TABLES_LOCAL_DECLARATION) +INCLUDE isr_tables_vt.ld +#else +KEEP(*(.vectors)) +#endif + +_vector_end = .; diff --git a/arch/dspic/include/dspic/dspicregs.h b/arch/dspic/include/dspic/dspicregs.h new file mode 100644 index 0000000000000..0fceb0ea23da8 --- /dev/null +++ b/arch/dspic/include/dspic/dspicregs.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_DSPIC_REGS_H_ +#define ZEPHYR_ARCH_DSPIC_REGS_H_ + +#endif /* ZEPHYR_ARCH_DSPIC_REGS_H_ */ diff --git a/arch/dspic/include/dspic/regdef.h b/arch/dspic/include/dspic/regdef.h new file mode 100644 index 0000000000000..e2d95402895a6 --- /dev/null +++ b/arch/dspic/include/dspic/regdef.h @@ -0,0 +1,9 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_DSPIC_REG_DEF_H_ +#define ZEPHYR_ARCH_DSPIC_REG_DEF_H_ + +#endif /* ZEPHYR_ARCH_DSPIC_REGS_H_ */ diff --git a/arch/dspic/include/kernel_arch_func.h b/arch/dspic/include/kernel_arch_func.h new file mode 100644 index 0000000000000..2cb5f487e890d --- /dev/null +++ b/arch/dspic/include/kernel_arch_func.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private kernel definitions + * + * This file contains private kernel function/macro definitions and various + * other definitions for the DSPIC processor architecture. + */ + +#ifndef ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_FUNC_H_ +#define ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_FUNC_H_ + +#ifndef _ASMLANGUAGE + +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void z_dspic_save_context(void); +void z_dspic_do_swap(void); + +/* dsPIC33A interrupt functionality initialization */ +static ALWAYS_INLINE void z_dspic_interrupt_init(void) +{ + /** + * clear all the interrupts, set the interrupt flag status + * registers to zero. + */ + + IFS0 = 0x0; + IFS1 = 0x0; + IFS2 = 0x0; + IFS3 = 0x0; + IFS4 = 0x0; + IFS5 = 0x0; + IFS6 = 0x0; + IFS7 = 0x0; + IFS8 = 0x0; + + /* enable nested interrupts */ + INTCON1bits.NSTDIS = 0; + /* enable global interrupts */ + INTCON1bits.GIE = 1; +} + +/* dsPIC33A fault initialization */ +static ALWAYS_INLINE void z_dspic_fault_init(void) +{ + /* nothing to be done */ +} + +/** + * Architecture specific kernel init function. Will initialize the + * interrupt and exception handling. This function is called from + * zephyr z_cstart() routine. + */ +static ALWAYS_INLINE void arch_kernel_init(void) +{ + z_dspic_interrupt_init(); + z_dspic_fault_init(); +#ifdef CONFIG_SOC_PER_CORE_INIT_HOOK + soc_per_core_init_hook(); +#endif /* CONFIG_SOC_PER_CORE_INIT_HOOK */ +} + +static ALWAYS_INLINE void arch_thread_return_value_set(struct k_thread *thread, unsigned int value) +{ + (void)thread; + (void)value; +} + +int arch_swap(unsigned int key); + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_FUNC_H_ */ diff --git a/arch/dspic/include/offsets_short_arch.h b/arch/dspic/include/offsets_short_arch.h new file mode 100644 index 0000000000000..da0a5db01cdd3 --- /dev/null +++ b/arch/dspic/include/offsets_short_arch.h @@ -0,0 +1,11 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_DSPIC_INCLUDE_OFFSETS_SHORT_ARCH_H_ +#define ZEPHYR_ARCH_DSPIC_INCLUDE_OFFSETS_SHORT_ARCH_H_ + +#include + +#endif /* ZEPHYR_ARCH_DSPIC_INCLUDE_OFFSETS_SHORT_ARCH_H_ */ diff --git a/boards/microchip/ev74h48a/Kconfig.ev74h48a b/boards/microchip/ev74h48a/Kconfig.ev74h48a new file mode 100644 index 0000000000000..dae0aa1309a22 --- /dev/null +++ b/boards/microchip/ev74h48a/Kconfig.ev74h48a @@ -0,0 +1,2 @@ +config BOARD_EV74H48A + select SOC_P33AK128MC106 if BOARD_EV74H48A_P33AK128MC106 diff --git a/boards/microchip/ev74h48a/board.yml b/boards/microchip/ev74h48a/board.yml new file mode 100644 index 0000000000000..d3e8b7b2b38f7 --- /dev/null +++ b/boards/microchip/ev74h48a/board.yml @@ -0,0 +1,7 @@ +board: + name: ev74h48a + full_name: dsPIC33A Curiosity Platform Development Board + vendor: microchip + socs: + - name: p33ak128mc106 + - name: p33ak256mc506 diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts new file mode 100644 index 0000000000000..edb8f3bd089c1 --- /dev/null +++ b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts @@ -0,0 +1,22 @@ +/dts-v1/; +#include "p33ak128mc106.dtsi" + +/ { + model = "Microchip dsPIC33A Curiosity Platform Development Board"; + compatible = "microchip,ev74h48a-p33ak128mc106"; + + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0; + }; +}; + +&cpu0 { + clock-frequency = <8000000>; + status = "okay"; + cpu-power-states = <&idle>; +}; + +&timer1 { + status = "okay"; +}; diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig new file mode 100644 index 0000000000000..0be34a7de4122 --- /dev/null +++ b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig @@ -0,0 +1,20 @@ +# Enables the RAM-based console backend for logging output. +CONFIG_CONSOLE=y +CONFIG_RAM_CONSOLE=y + +# Enables support for GPIO drivers on the target platform. +# CONFIG_GPIO=y + +# Defines the system hardware clock frequency as 8 MHz. +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=8000000 + +# Configures the system tick rate to 1000 ticks per second (1 ms tick interval). +CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 + +# Specifies a single-core configuration for the SoC. +CONFIG_MP_MAX_NUM_CPUS=1 + +# For XC-DSC toolchain the default check init script of zephyr will fail +# because of an extra prepended underscore on symbols generated, +# For this reason keeping it disabled +CONFIG_CHECK_INIT_PRIORITIES=n diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts new file mode 100644 index 0000000000000..9213a07beb6d8 --- /dev/null +++ b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts @@ -0,0 +1 @@ +/*Nothing here */ diff --git a/cmake/bintools/xcdsc/target.cmake b/cmake/bintools/xcdsc/target.cmake new file mode 100644 index 0000000000000..70f4029a1408e --- /dev/null +++ b/cmake/bintools/xcdsc/target.cmake @@ -0,0 +1,10 @@ +# locate the required XC-DSC binary tools. +find_program(CMAKE_OBJCOPY NAMES ${XCDSC_BIN_PREFIX}objcopy PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_OBJDUMP NAMES ${XCDSC_BIN_PREFIX}objdump PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_READELF NAMES ${XCDSC_BIN_PREFIX}readelf PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +find_program(CMAKE_STRIP NAMES ${XCDSC_BIN_PREFIX}strip PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +# Archive Rules Setup +SET(CMAKE_C_ARCHIVE_CREATE " -q ") +SET(CMAKE_C_ARCHIVE_FINISH " -q ") +# Include bin tool properties +include(${ZEPHYR_BASE}/cmake/bintools/xcdsc/target_bintools.cmake) diff --git a/cmake/bintools/xcdsc/target_bintools.cmake b/cmake/bintools/xcdsc/target_bintools.cmake new file mode 100644 index 0000000000000..c1f4ac2047fb7 --- /dev/null +++ b/cmake/bintools/xcdsc/target_bintools.cmake @@ -0,0 +1,28 @@ +# Usage of the objcopy utility (aliased as elfconvert) for converting ELF binaries into other formats,such as hex, binary, etc. +set_property(TARGET bintools PROPERTY elfconvert_command ${CMAKE_OBJCOPY}) +# List of format the tool supports for converting, for example, +# GNU tools uses objectcopy, which supports the following: ihex, srec, binary +set_property(TARGET bintools PROPERTY elfconvert_formats ihex srec binary) +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_all "-S") +set_property(TARGET bintools PROPERTY elfconvert_flag_strip_debug "-g") +set_property(TARGET bintools PROPERTY elfconvert_flag_intarget "--input-target=") +set_property(TARGET bintools PROPERTY elfconvert_flag_outtarget "--output-target=") +set_property(TARGET bintools PROPERTY elfconvert_flag_section_remove "--remove-section=") + +# Usage of the objdump utility for producing human-readable disassembly listings from ELF binaries +set_property(TARGET bintools PROPERTY disassembly_command ${CMAKE_OBJDUMP}) +set_property(TARGET bintools PROPERTY disassembly_flag -d) + +set_property(TARGET bintools PROPERTY disassembly_flag_final "") +set_property(TARGET bintools PROPERTY disassembly_flag_inline_source -S) +# Usage of the strip utility for removing symbols from ELF binaries to ensure that final images include only the necessary code and data, improving load times and reducing footprint. +set_property(TARGET bintools PROPERTY strip_command ${CMAKE_STRIP}) +set_property(TARGET bintools PROPERTY strip_flag_all --strip-all) +set_property(TARGET bintools PROPERTY strip_flag_debug --strip-debug) +#Usage of readelf. How to invoke and configure the readelf utility for examining ELF binaries +set_property(TARGET bintools PROPERTY readelf_command ${CMAKE_READELF}) +set_property(TARGET bintools PROPERTY readelf_flag "") +set_property(TARGET bintools PROPERTY readelf_flag_final "") +set_property(TARGET bintools PROPERTY readelf_flag_headers -e) +set_property(TARGET bintools PROPERTY readelf_flag_infile "") +set_property(TARGET bintools PROPERTY readelf_flag_outfile ">;" ) diff --git a/cmake/compiler/xcdsc/compiler_flags.cmake b/cmake/compiler/xcdsc/compiler_flags.cmake new file mode 100644 index 0000000000000..976a396460632 --- /dev/null +++ b/cmake/compiler/xcdsc/compiler_flags.cmake @@ -0,0 +1,28 @@ +# Enable basic debug information +set_compiler_property(PROPERTY debug -g) +# Optimization for debug builds +set_compiler_property(PROPERTY optimization_debug -O1) +set_compiler_property(PROPERTY optimization_speed -O1) +# Optimize for size +set_compiler_property(PROPERTY optimization_size -O1) +set_compiler_property(PROPERTY optimization_size_aggressive -O1) +# Basic warnings +check_set_compiler_property(PROPERTY warning_base -Wall -Wformat -Wformat-security -Wno-format-zero-length -Wno-unused-but-set-variable ) +# Compiler flags for imacros. The specific header must be appended by user. +set_compiler_property(PROPERTY imacros -imacros) +# Use the default C Language standard +set_compiler_property(PROPERTY cstd -std=) +# Linker script usage +set_compiler_property(PROPERTY linker_script -Wl,-T) +# Additional compiler flags for dspic(XC-DSC-Specific Flags). +# Save intermediate files (optional, helpful for inspection) +set_compiler_property(PROPERTY save_temps -save-temps=obj) +# Smart I/O conversion for format strings (safe printf optimizations) +list(APPEND TOOLCHAIN_C_FLAGS -msmart-io=1) +# Disable SFR access warnings +list(APPEND TOOLCHAIN_C_FLAGS -msfr-warn=off) +# Disable instruction scheduling (for stability) +list(APPEND TOOLCHAIN_C_FLAGS -fno-schedule-insns -fno-schedule-insns2) +list(APPEND TOOLCHAIN_C_FLAGS -fno-omit-frame-pointer) +# assembler compiler flags for imacros. The specific header must be appended by user. +set_property(TARGET asm PROPERTY imacros -imacros) \ No newline at end of file diff --git a/cmake/compiler/xcdsc/generic.cmake b/cmake/compiler/xcdsc/generic.cmake new file mode 100644 index 0000000000000..8dad7c4c2113e --- /dev/null +++ b/cmake/compiler/xcdsc/generic.cmake @@ -0,0 +1,21 @@ +set(CMAKE_SYSTEM_NAME Generic) +set(CMAKE_SYSTEM_PROCESSOR ${ARCH}) +# Find and validate the xc-dsc-gcc compiler binary +find_program(CMAKE_C_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH REQUIRED ) +add_definitions(-D__XC_DSC__) +# Get compiler version +execute_process( + COMMAND ${CMAKE_C_COMPILER} --version + OUTPUT_VARIABLE XCDSC_VERSION_STR + ERROR_VARIABLE XCDSC_VERSION_ERR + OUTPUT_STRIP_TRAILING_WHITESPACE ) +# Verify that the installed version is v3.30 or higher +if("${XCDSC_VERSION_STR}" MATCHES ".*v([0-9]+)\\.([0-9]+).*") + string(REGEX REPLACE ".*v([0-9]+)\\.([0-9]+).*" "\\1\\2" __XCDSC_VERSION__ "${XCDSC_VERSION_STR}") + math(EXPR XCDSC_VERSION_INT "${__XCDSC_VERSION__}") + if(XCDSC_VERSION_INT LESS 330) + message(FATAL_ERROR "XC-DSC compiler v3.30 or newer is required. Found version: ${XCDSC_VERSION_STR}") + endif() +else() + message(FATAL_ERROR "Unable to detect XC-DSC compiler version from: '${XCDSC_VERSION_STR}'") +endif() diff --git a/cmake/compiler/xcdsc/target.cmake b/cmake/compiler/xcdsc/target.cmake new file mode 100644 index 0000000000000..670bd84a7bae5 --- /dev/null +++ b/cmake/compiler/xcdsc/target.cmake @@ -0,0 +1,16 @@ +# Set default C compiler if not already set +find_program(CMAKE_C_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH ) +# XC-DSC toolchain does not support C++, so set CXX to fallback to gcc (or a dummy) # This prevents CMake errors if C++ is requested (even if unused) +find_program(CMAKE_CXX_COMPILER gcc) +# Set assembler explicitly +find_program(CMAKE_ASM_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH ) +# Target CPU (must match user platform) +set(TARGET_CPU "33AK128MC106") +list(APPEND TOOLCHAIN_C_FLAGS -mcpu=${TARGET_CPU}) +# Picolibc and standard includes(if supported in toolchain) +list(APPEND TOOLCHAIN_C_FLAGS + -I${XCDSC_TOOLCHAIN_PATH}/include/picolibc + -isystem${XCDSC_TOOLCHAIN_PATH}/include/picolibc/gcc + -isystem${XCDSC_TOOLCHAIN_PATH}/include/picolibc/bits + -isystem${XCDSC_TOOLCHAIN_PATH}/include + -isystem${ZEPHYR_BASE}/include/zephyr) diff --git a/cmake/linker/xcdsc/linker_flags.cmake b/cmake/linker/xcdsc/linker_flags.cmake new file mode 100644 index 0000000000000..cb99a4775b360 --- /dev/null +++ b/cmake/linker/xcdsc/linker_flags.cmake @@ -0,0 +1,29 @@ +# The fundamental linker flags always applied to every Zephyr build for XC-DSC +check_set_linker_property( + TARGET linker PROPERTY base ${LINKERFLAGPREFIX},--check-sections + # Check to not check section addresses for overlaps. + ${LINKERFLAGPREFIX},--data-init + # initialize all data sections.Check to support initialized data. + ${LINKERFLAGPREFIX},--pack-data + # pack initialized data into the smallest possible blocks + ${LINKERFLAGPREFIX},--handles + # enable special support for dsPIC interrupt/exception handlers + ${LINKERFLAGPREFIX},--no-isr + # disable default interrupt routine + ${LINKERFLAGPREFIX},--no-ivt + # do not generate ivt or aivt + # Check to create an interrupt function for unused vectors. + ${LINKERFLAGPREFIX},--no-gc-sections + # preserve all sections (do not garbage-collect unused code/data) + ${LINKERFLAGPREFIX},--fill-upper=0 + # zero-fill any gaps above defined sections + ${LINKERFLAGPREFIX},--no-force-link + # do not force-link all library objects + ${LINKERFLAGPREFIX},--smart-io + # enable Smart-IO format‐string optimizations + ${LINKERFLAGPREFIX}, -L${XCDSC_TOOLCHAIN_PATH}/lib + # Set picolib lib path from xc-dsc toolchain to link + ${LINKERFLAGPREFIX}, -lc-pico-elf + # link picolib from xc-dsc toolchain + + ) diff --git a/cmake/linker/xcdsc/target.cmake b/cmake/linker/xcdsc/target.cmake new file mode 100644 index 0000000000000..e6ee42fdcd74a --- /dev/null +++ b/cmake/linker/xcdsc/target.cmake @@ -0,0 +1,92 @@ +# Set Linker Symbol Properties +set_property(TARGET linker PROPERTY devices_start_symbol "_device_list_start") +# Locate linker binary +set_ifndef(LINKERFLAGPREFIX -Wl) +set(XCDSC_BIN_PREFIX xc-dsc-) +find_program(CMAKE_LINKER NAMES ${XCDSC_BIN_PREFIX}ld PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) +# Generate linker script using preprocessor +macro(configure_linker_script linker_script_gen linker_pass_define) + set(extra_dependencies ${ARGN}) + if(DEFINED SOC_LINKER_SCRIPT) + cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) + set(soc_linker_script_includes -I${soc_linker_script_includes}) + endif() + add_custom_command( OUTPUT + ${linker_script_gen} + DEPENDS + ${LINKER_SCRIPT} + ${AUTOCONF_H} + ${extra_dependencies} + ${linker_script_dep} + COMMAND ${CMAKE_C_COMPILER} -x assembler-with-cpp -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} + -D__XCDSC_LINKER_CMD__ + -imacros ${AUTOCONF_H} + -I${ZEPHYR_BASE}/include + -imacros${ZEPHYR_BASE}/include/zephyr/linker/sections.h + -imacros${ZEPHYR_BASE}/include/zephyr/linker/linker-defs.h + -imacros${ZEPHYR_BASE}/include/zephyr/linker/linker-tool-gcc.h + -I${PROJECT_BINARY_DIR}/include/generated + -I${XCDSC_TOOLCHAIN_PATH}/include/ + ${soc_linker_script_includes} + ${template_script_defines} + -E ${LINKER_SCRIPT} # Preprocess only do not compile + -P # Prevent generation of debug `#line' directives. + -o ${linker_script_gen} + VERBATIM + WORKING_DIRECTORY + ${PROJECT_BINARY_DIR} + COMMAND_EXPAND_LISTS ) +endmacro() +# Force Inclusion of Undefined Symbols +# Force symbols to be entered in the output file as undefined symbols +function(toolchain_ld_force_undefined_symbols) + foreach(symbol ${ARGN}) + zephyr_link_libraries(${LINKERFLAGPREFIX},-u,${symbol}) + endforeach() +endfunction() + +# Define final ELF Linking Rule +function(toolchain_ld_link_elf) +cmake_parse_arguments( + TOOLCHAIN_LD_LINK_ELF # prefix of output variables + "" # list of names of the boolean arguments + "TARGET_ELF;OUTPUT_MAP;LINKER_SCRIPT" # list of names of scalar arguments + "LIBRARIES_PRE_SCRIPT;LIBRARIES_POST_SCRIPT;DEPENDENCIES" # list of names of list arguments + ${ARGN} # input args to parse + ) + file(TOUCH ${PROJECT_BINARY_DIR}/memoryfile.xml) + target_link_libraries( + ${TOOLCHAIN_LD_LINK_ELF_TARGET_ELF} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_PRE_SCRIPT} + ${TOPT} + ${TOOLCHAIN_LD_LINK_ELF_LINKER_SCRIPT} + ${TOOLCHAIN_LD_LINK_ELF_LIBRARIES_POST_SCRIPT} + ${LINKERFLAGPREFIX},-Map=${TOOLCHAIN_LD_LINK_ELF_OUTPUT_MAP} + ${LINKERFLAGPREFIX},--start-group + c99-pic30-elf + ${LINKERFLAGPREFIX},--end-group + ${LINKERFLAGPREFIX},--report-mem + ${LINKERFLAGPREFIX},--memorysummary ${PROJECT_BINARY_DIR}/memoryfile.xml + ${LINKERFLAGPREFIX},--whole-archive + ${WHOLE_ARCHIVE_LIBS} + ${LINKERFLAGPREFIX},--no-whole-archive + ${NO_WHOLE_ARCHIVE_LIBS} + ${LINKERFLAGPREFIX},-L${PROJECT_BINARY_DIR} + ${TOOLCHAIN_LD_LINK_ELF_DEPENDENCIES} ) +endfunction(toolchain_ld_link_elf) +# Finalize Link Execution Behaviour +macro(toolchain_linker_finalize) + get_property(zephyr_std_libs TARGET linker PROPERTY lib_include_dir) + get_property(link_order TARGET linker PROPERTY link_order_library) + foreach(lib ${link_order}) + get_property(link_flag TARGET linker PROPERTY ${lib}_library) + list(APPEND zephyr_std_libs "${link_flag}") + endforeach() + string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") + set(link_libraries " -o ${zephyr_std_libs}") + set(common_link "${link_libraries}") + set(CMAKE_ASM_LINK_EXECUTABLE "${common_link}") + set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") +endmacro() +# Load toolchain_ld-family macros +include(${ZEPHYR_BASE}/cmake/linker/${LINKER}/target_configure.cmake) diff --git a/cmake/linker/xcdsc/target_configure.cmake b/cmake/linker/xcdsc/target_configure.cmake new file mode 100644 index 0000000000000..c453b7e7fc79f --- /dev/null +++ b/cmake/linker/xcdsc/target_configure.cmake @@ -0,0 +1,10 @@ +macro(toolchain_ld_configure_files) +configure_file( ${ZEPHYR_BASE}/include/zephyr/arch/common/app_data_alignment.ld + ${PROJECT_BINARY_DIR}/include/generated/app_data_alignment.ld) + configure_file( ${ZEPHYR_BASE}/include/zephyr/linker/app_smem.ld + ${PROJECT_BINARY_DIR}/include/generated/app_smem.ld) + if(CONFIG_LINKER_USE_PINNED_SECTION) + configure_file( ${ZEPHYR_BASE}/include/zephyr/linker/app_smem_pinned.ld + ${PROJECT_BINARY_DIR}/include/generated/app_smem_pinned.ld) + endif() +endmacro() diff --git a/cmake/toolchain/xcdsc/Kconfig b/cmake/toolchain/xcdsc/Kconfig new file mode 100644 index 0000000000000..82b04e2ba711a --- /dev/null +++ b/cmake/toolchain/xcdsc/Kconfig @@ -0,0 +1,16 @@ +config TOOLCHAIN_XCDSC + bool "MPLAB XC-DSC toolchain" + select HAVE_CUSTOM_LINKER_SCRIPT + help + Enable support for compiling with MPLAB XC-DSC toolchain for dsPIC. +config PICOLIBC_SUPPORTED + def_bool y + help + XC-DSC toolchain supports picolib for C development. +config TOOLCHAIN_XCDSC_SUPPORTS_THREAD_LOCAL_STORAGE + bool "XC-DSC toolchain supports TLS" + def_bool y + select TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE + help + Set this if the XC-DSC toolchain being used for the build supports + thread local storage. diff --git a/cmake/toolchain/xcdsc/generic.cmake b/cmake/toolchain/xcdsc/generic.cmake new file mode 100644 index 0000000000000..faa9174c61b5f --- /dev/null +++ b/cmake/toolchain/xcdsc/generic.cmake @@ -0,0 +1,19 @@ +zephyr_get(XCDSC_TOOLCHAIN_PATH) +# Set toolchain module name to xcdsc +set(COMPILER xcdsc) +set(LINKER xcdsc) +set(BINTOOLS xcdsc) +# Set base directory where binaries are available +if(XCDSC_TOOLCHAIN_PATH) + set(TOOLCHAIN_HOME ${XCDSC_TOOLCHAIN_PATH}/bin/) + set(XCDSC_BIN_PREFIX xc-dsc-) + set(CROSS_COMPILE ${XCDSC_TOOLCHAIN_PATH}/bin/xc-dsc-) +endif() +if(NOT EXISTS ${XCDSC_TOOLCHAIN_PATH}) + message(FATAL_ERROR "Nothing found at XCDSC_TOOLCHAIN_PATH: '${XCDSC_TOOLCHAIN_PATH}'") +else() # Support for picolibc is indicated by the presence of 'picolibc.h' in the toolchain path. + file(GLOB_RECURSE picolibc_header ${XCDSC_TOOLCHAIN_PATH}/include/picolibc/picolibc.h) + if(picolibc_header) + set(TOOLCHAIN_HAS_PICOLIBC ON CACHE BOOL "True if toolchain supports picolibc") + endif() +endif() diff --git a/cmake/toolchain/xcdsc/target.cmake b/cmake/toolchain/xcdsc/target.cmake new file mode 100644 index 0000000000000..59b4e22882b19 --- /dev/null +++ b/cmake/toolchain/xcdsc/target.cmake @@ -0,0 +1 @@ +set (ARCH dspic) \ No newline at end of file diff --git a/drivers/console/ram_console.c b/drivers/console/ram_console.c index 9544544fb5bd2..0206926d50e2d 100644 --- a/drivers/console/ram_console.c +++ b/drivers/console/ram_console.c @@ -7,7 +7,6 @@ * SPDX-License-Identifier: Apache-2.0 */ - #include #include #include @@ -23,7 +22,7 @@ #error "Custom RAM console buffer exceeds the section size!" #endif -#define RAM_CONSOLE_BUF_ATTR \ +#define RAM_CONSOLE_BUF_ATTR \ __attribute__((__section__(LINKER_DT_NODE_REGION_NAME(DT_CHOSEN(zephyr_ram_console))))) #else #define RAM_CONSOLE_BUF_ATTR @@ -53,8 +52,10 @@ static int ram_console_init(void) ram_console = ram_console_buf, #endif __printk_hook_install(ram_console_out); - __stdout_hook_install(ram_console_out); +#ifdef TO_BE_IMPLEMENTED_LATER + __stdout_hook_install(ram_console_out); +#endif return 0; } diff --git a/dts/dspic/p33ak128mc106.dtsi b/dts/dspic/p33ak128mc106.dtsi new file mode 100644 index 0000000000000..e29d6eece8571 --- /dev/null +++ b/dts/dspic/p33ak128mc106.dtsi @@ -0,0 +1,60 @@ +/** + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/ { + model = "Microchip dsPIC33A Curiosity Platform Development Board"; + compatible = "microchip,p33ak128mc106"; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu0: cpu@0 { + device_type = "cpu"; + compatible = "microchip,dsPIC33A"; + reg = <0>; + clock-frequency = <8000000>; + status = "okay"; + cpu-power-states = <&idle>; + }; + + power-states { + idle: idle { + compatible = "zephyr,power-state"; + power-state-name = "suspend-to-idle"; + min-residency-us = <1000>; + }; + }; + }; + + aliases { + soc = &soc; + }; + + + soc: soc { + compatible = "microchip,p33ak128mc106-soc"; + #address-cells = <1>; + #size-cells = <0>; + + flash0: flash@800004 { + compatible = "zephyr,flash"; + reg = <0x800004 0x1FFFC>; + label = "FLASH"; + }; + + sram0: memory@4000 { + compatible = "zephyr,memory"; + reg = <0x4000 0x4000>; + label = "SRAM"; + }; + + timer1: timer@1E00 { + compatible = "microchip,dspic33-timer"; + reg = <0x1E00 0x10>; + label = "TIMER_1"; + }; + }; +}; diff --git a/include/zephyr/arch/arch_inlines.h b/include/zephyr/arch/arch_inlines.h index 6d7e70f0f1956..ed92a280087df 100644 --- a/include/zephyr/arch/arch_inlines.h +++ b/include/zephyr/arch/arch_inlines.h @@ -32,6 +32,8 @@ #include #elif defined(CONFIG_RX) #include +#elif defined(CONFIG_DSPIC) +#include #endif #endif /* ZEPHYR_INCLUDE_ARCH_INLINES_H_ */ diff --git a/include/zephyr/arch/cpu.h b/include/zephyr/arch/cpu.h index a526f98fa04c6..7a9ae982edb81 100644 --- a/include/zephyr/arch/cpu.h +++ b/include/zephyr/arch/cpu.h @@ -31,6 +31,8 @@ #include #elif defined(CONFIG_RX) #include +#elif defined(CONFIG_DSPIC) +#include #endif #endif /* ZEPHYR_INCLUDE_ARCH_CPU_H_ */ diff --git a/include/zephyr/arch/dspic/arch.h b/include/zephyr/arch/dspic/arch.h new file mode 100644 index 0000000000000..062ba8164e409 --- /dev/null +++ b/include/zephyr/arch/dspic/arch.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_H_ +#define ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define ARCH_STACK_PTR_ALIGN 4 + +#define DSPIC_STATUS_DEFAULT 0 + +#ifndef _ASMLANGUAGE + +#ifdef __cplusplus +extern "C" { +#endif + +void arch_irq_enable(unsigned int irq); +void arch_irq_disable(unsigned int irq); +int arch_irq_is_enabled(unsigned int irq); +void z_irq_spurious(const void *unused); + +/** + * Configure a static interrupt. + * + * All arguments must be computable by the compiler at build time. + * + * @param irq_p IRQ line number + * @param priority_p Interrupt priority + * @param isr_p Interrupt service routine + * @param isr_param_p ISR parameter + * @param flags_p IRQ options + * + * @return The vector assigned to this interrupt + */ +#define ARCH_IRQ_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ + { \ + Z_ISR_DECLARE(irq_p, 0, isr_p, isr_param_p); \ + z_dspic_irq_priority_set(irq_p, priority_p, flags_p); \ + } + +#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ + { \ + Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p, isr_param_p); \ + z_dspic_irq_priority_set(irq_p, priority_p, flags_p); \ + } + +/* helper function to set the priority of the interrupt */ +static ALWAYS_INLINE void z_dspic_irq_priority_set(unsigned int irq, unsigned int prio, + uint32_t flags) +{ +} + +static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) +{ +} + +static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) +{ + return 0; +} + +static ALWAYS_INLINE unsigned int arch_irq_lock(void) +{ + return 0; +} + +static ALWAYS_INLINE bool arch_is_in_isr(void) +{ + return 0; +} + +static ALWAYS_INLINE void arch_nop(void) +{ + __asm__ volatile("nop"); +} + +extern uint32_t sys_clock_cycle_get_32(void); + +static inline uint32_t arch_k_cycle_get_32(void) +{ +#ifdef TO_BE_IMPLEMENTED_LATER + return sys_clock_cycle_get_32(); +#else + return 0; +#endif +} + +extern uint64_t sys_clock_cycle_get_64(void); + +static inline uint64_t arch_k_cycle_get_64(void) +{ + return sys_clock_cycle_get_64(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_H_ */ diff --git a/include/zephyr/arch/dspic/arch_inlines.h b/include/zephyr/arch/dspic/arch_inlines.h new file mode 100644 index 0000000000000..a72e438bfdbc6 --- /dev/null +++ b/include/zephyr/arch/dspic/arch_inlines.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_INLINES_H +#define ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_INLINES_H + +#include + +static ALWAYS_INLINE unsigned int arch_num_cpus(void) +{ + return CONFIG_MP_MAX_NUM_CPUS; +} + +#endif /* ZEPHYR_INCLUDE_ARCH_DSPIC_ARCH_INLINES_H */ diff --git a/include/zephyr/arch/dspic/exception.h b/include/zephyr/arch/dspic/exception.h new file mode 100644 index 0000000000000..6723c67e312fa --- /dev/null +++ b/include/zephyr/arch/dspic/exception.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_DSPIC_EXCEPTION_H_ +#define ZEPHYR_INCLUDE_ARCH_DSPIC_EXCEPTION_H_ + +#ifndef _ASMLANGUAGE +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +struct arch_esf { + uint32_t PC; /* Program counter*/ + uint32_t FRAME; /* Previous frame pointer*/ + uint32_t RCOUNT; /* repeat count register*/ + uint32_t FSR; /* Floating point status register */ + uint32_t FCR; /* Floating point control register*/ + uint32_t W0; /* working register W0 */ + uint32_t W1; /* working register W0 */ + uint32_t W2; /* working register W0 */ + uint32_t W3; /* working register W0 */ + uint32_t W4; /* working register W0 */ + uint32_t W5; /* working register W0 */ + uint32_t W6; /* working register W0 */ + uint32_t W7; /* working register W0 */ + uint32_t F0; /* Floating point register F0 */ + uint32_t F1; /* Floating point register F1 */ + uint32_t F2; /* Floating point register F2 */ + uint32_t F3; /* Floating point register F3 */ + uint32_t F4; /* Floating point register F4 */ + uint32_t F5; /* Floating point register F5 */ + uint32_t F6; /* Floating point register F6 */ + uint32_t F7; /* Floating point register F7 */ +}; +typedef struct arch_esf arch_esf_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_DSPIC_EXCEPTION_H_ */ diff --git a/include/zephyr/arch/dspic/linker.ld b/include/zephyr/arch/dspic/linker.ld new file mode 100644 index 0000000000000..dc3065209dc16 --- /dev/null +++ b/include/zephyr/arch/dspic/linker.ld @@ -0,0 +1,2977 @@ +/* + * Generic Zephyr Linker Script + *. + * Note: For some of the input sections such as init levels and + * data sections and kernel objects needs to be added via + * linker script fragment files, At this point, only have added those + * input sections required and kept minimal because when adding + * linker script linker fragment files, it affects the syntax of + * XC-DSC Linker. + */ + +#include +#include + +#include +#include +#include +#include + +/* Define memory regions based on the original script */ +#define FLASH_BASE_ADDRESS 0x800000 +#define FLASH_SIZE 128 +#define SRAM_BASE_ADDRESS 0x4000 +#define SRAM_SIZE 16 + +/* Define Zephyr's standard memory region names */ +#define ROMABLE_REGION program +#define RAMABLE_REGION data + +OUTPUT_ARCH("33AK128MC106") +CRT0_STARTUP(reset0.S.obj) +CRT1_STARTUP(reset1.S.obj) +CRT_STARTMODE(crt_start_mode_normal) + +MEMORY +{ + /* Memory map from the original target-specific script */ + program (xr) : ORIGIN = FLASH_BASE_ADDRESS, LENGTH = (FLASH_SIZE * 1K) + data (a!xr) : ORIGIN = SRAM_BASE_ADDRESS, LENGTH = (SRAM_SIZE * 1K) + /* Used by and documented in include/linker/intlist.ld */ + IDT_LIST (wx) : ORIGIN = 0xFFFFFFFF, LENGTH = 0 +} + +SECTIONS +{ + /* Start of the ROM-based sections */ + GROUP_START(ROMABLE_REGION) + + SECTION_PROLOGUE(.rom_start,,) + { + LONG(ABSOLUTE(__start)); + . = ALIGN(4); + /* Located in generated directory. This file is populated by calling + * zephyr_linker_sources(ROM_START ...). This typically contains the vector + * table and debug information. + */ + #include + + } GROUP_LINK_IN(ROMABLE_REGION) + + /* + * This is the main code and read-only data section. + * Zephyr's GROUP_LINK_IN macro handles all .text.* and .rodata.* + * sections automatically. This replaces the manual .text section + * from the original script. + */ + SECTION_PROLOGUE(._TEXT_SECTION_NAME,,) + { + __text_region_start = .; + *(.init); + *(.text); + *(.text*); + *(.user_init); + KEEP (*(.handle)); + KEEP (*(.isr*)); + *(.lib*); + ___rodata_region_start = .; + *(.rodata) *(.rodata.*) + ___rodata_region_end = .; + *(.rodata) /* Read-Only Data */ + ___static_thread_data_list_start = .; + KEEP(*(SORT(.static_thread_data*))) + ___static_thread_data_list_end = .; + . = ALIGN(4); + } GROUP_LINK_IN(ROMABLE_REGION) + __text_region_end = .; + ITERABLE_SECTION_ROM_NUMERIC(service, Z_LINK_ITERABLE_SUBALIGN) + . = ALIGN(4); + GROUP_END(ROMABLE_REGION) + + /* Start of the RAM-based sections */ + GROUP_START(RAMABLE_REGION) + + /* + * This aligns the start of RAM as required. + * The VMA (Virtual Memory Address) is in RAM, + * while the LMA (Load Memory Address) is in FLASH. + */ + . = SRAM_BASE_ADDRESS; + + /* + * This section handles initialized data. The data is loaded from FLASH + * and copied to RAM at boot time. This replaces the manual .data + * section from the original script. + */ + SECTION_PROLOGUE(.data,,) + { + __data_region_start = .; + *(.data) + *(".data.*") + __device_list_start = .; + KEEP(*(SORT(.z_device*))) + __device_list_end = .; + /* Initialization levels: Early -> Application */ + ___init_EARLY_start = .; + KEEP(*(SORT(.init_EARLY*))) + ___init_PRE_KERNEL_1_start = .; + KEEP(*(SORT(.init_PRE_KERNEL_1*))) + ___init_PRE_KERNEL_2_start = .; + KEEP(*(SORT(.init_PRE_KERNEL_2*))) + ___init_POST_KERNEL_start = .; + KEEP(*(SORT(.init_POST_KERNEL*))) + ___init_APPLICATION_start = .; + KEEP(*(SORT(.init_APPLICATION*))) + ___init_SMP_start = .; + KEEP(*(SORT(.init_SMP*))) + ___init_end = .; + __data_region_start = .; + + } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + + + /* + * This section handles uninitialized data (BSS). It occupies space + * only in RAM and is zeroed out at boot. This replaces the manual + * .bss section from the original script. + */ + SECTION_DATA_PROLOGUE(._BSS_SECTION_NAME,,) + { + . = ALIGN(4); + ___bss_start = .; + *(.bss) + *(.bss.*) + *(COMMON) + ___bss_end = .; + } GROUP_LINK_IN(RAMABLE_REGION) + + GROUP_END(RAMABLE_REGION) +} + +/* +** ============== Equates for SFR Addresses ============= +*/ +PC = 0x0; +_PC = 0x0; +_PCbits = 0x0; + SPLIM = 0x4; +_SPLIM = 0x4; +_SPLIMbits = 0x4; + RCOUNT = 0x8; +_RCOUNT = 0x8; + DISIIPL = 0xC; +_DISIIPL = 0xC; +_DISIIPLbits = 0xC; + CORCON = 0x10; +_CORCON = 0x10; +_CORCONbits = 0x10; + MODCON = 0x14; +_MODCON = 0x14; +_MODCONbits = 0x14; + XMODSRT = 0x18; +_XMODSRT = 0x18; +_XMODSRTbits = 0x18; + XMODEND = 0x1C; +_XMODEND = 0x1C; +_XMODENDbits = 0x1C; + YMODSRT = 0x20; +_YMODSRT = 0x20; +_YMODSRTbits = 0x20; + YMODEND = 0x24; +_YMODEND = 0x24; +_YMODENDbits = 0x24; + XBREV = 0x28; +_XBREV = 0x28; +_XBREVbits = 0x28; + PCTRAP = 0x2C; +_PCTRAP = 0x2C; +_PCTRAPbits = 0x2C; + FEX = 0x30; +_FEX = 0x30; + FEX2 = 0x34; +_FEX2 = 0x34; + PCHOLD = 0x38; +_PCHOLD = 0x38; +_PCHOLDbits = 0x38; + VFA = 0x3C; +_VFA = 0x3C; +_VFAbits = 0x3C; + INTCON1 = 0x70; +_INTCON1 = 0x70; +_INTCON1bits = 0x70; + INTCON2 = 0x74; +_INTCON2 = 0x74; +_INTCON2bits = 0x74; + INTCON3 = 0x78; +_INTCON3 = 0x78; +_INTCON3bits = 0x78; + INTCON4 = 0x7C; +_INTCON4 = 0x7C; +_INTCON4bits = 0x7C; + INTCON5 = 0x80; +_INTCON5 = 0x80; +_INTCON5bits = 0x80; + INTTREG = 0x84; +_INTTREG = 0x84; +_INTTREGbits = 0x84; + IVTBASE = 0x88; +_IVTBASE = 0x88; + IVTCREG = 0x8C; +_IVTCREG = 0x8C; +_IVTCREGbits = 0x8C; + IFS0 = 0x90; +_IFS0 = 0x90; +_IFS0bits = 0x90; + IFS1 = 0x94; +_IFS1 = 0x94; +_IFS1bits = 0x94; + IFS2 = 0x98; +_IFS2 = 0x98; +_IFS2bits = 0x98; + IFS3 = 0x9C; +_IFS3 = 0x9C; +_IFS3bits = 0x9C; + IFS4 = 0xA0; +_IFS4 = 0xA0; +_IFS4bits = 0xA0; + IFS5 = 0xA4; +_IFS5 = 0xA4; +_IFS5bits = 0xA4; + IFS6 = 0xA8; +_IFS6 = 0xA8; +_IFS6bits = 0xA8; + IFS7 = 0xAC; +_IFS7 = 0xAC; +_IFS7bits = 0xAC; + IFS8 = 0xB0; +_IFS8 = 0xB0; +_IFS8bits = 0xB0; + IEC0 = 0xB4; +_IEC0 = 0xB4; +_IEC0bits = 0xB4; + IEC1 = 0xB8; +_IEC1 = 0xB8; +_IEC1bits = 0xB8; + IEC2 = 0xBC; +_IEC2 = 0xBC; +_IEC2bits = 0xBC; + IEC3 = 0xC0; +_IEC3 = 0xC0; +_IEC3bits = 0xC0; + IEC4 = 0xC4; +_IEC4 = 0xC4; +_IEC4bits = 0xC4; + IEC5 = 0xC8; +_IEC5 = 0xC8; +_IEC5bits = 0xC8; + IEC6 = 0xCC; +_IEC6 = 0xCC; +_IEC6bits = 0xCC; + IEC7 = 0xD0; +_IEC7 = 0xD0; +_IEC7bits = 0xD0; + IEC8 = 0xD4; +_IEC8 = 0xD4; +_IEC8bits = 0xD4; + IPC0 = 0xD8; +_IPC0 = 0xD8; +_IPC0bits = 0xD8; + IPC1 = 0xDC; +_IPC1 = 0xDC; +_IPC1bits = 0xDC; + IPC2 = 0xE0; +_IPC2 = 0xE0; +_IPC2bits = 0xE0; + IPC3 = 0xE4; +_IPC3 = 0xE4; +_IPC3bits = 0xE4; + IPC4 = 0xE8; +_IPC4 = 0xE8; +_IPC4bits = 0xE8; + IPC5 = 0xEC; +_IPC5 = 0xEC; +_IPC5bits = 0xEC; + IPC6 = 0xF0; +_IPC6 = 0xF0; +_IPC6bits = 0xF0; + IPC7 = 0xF4; +_IPC7 = 0xF4; +_IPC7bits = 0xF4; + IPC8 = 0xF8; +_IPC8 = 0xF8; +_IPC8bits = 0xF8; + IPC9 = 0xFC; +_IPC9 = 0xFC; +_IPC9bits = 0xFC; + IPC10 = 0x100; +_IPC10 = 0x100; +_IPC10bits = 0x100; + IPC11 = 0x104; +_IPC11 = 0x104; +_IPC11bits = 0x104; + IPC12 = 0x108; +_IPC12 = 0x108; +_IPC12bits = 0x108; + IPC13 = 0x10C; +_IPC13 = 0x10C; +_IPC13bits = 0x10C; + IPC14 = 0x110; +_IPC14 = 0x110; +_IPC14bits = 0x110; + IPC15 = 0x114; +_IPC15 = 0x114; +_IPC15bits = 0x114; + IPC16 = 0x118; +_IPC16 = 0x118; +_IPC16bits = 0x118; + IPC17 = 0x11C; +_IPC17 = 0x11C; +_IPC17bits = 0x11C; + IPC18 = 0x120; +_IPC18 = 0x120; +_IPC18bits = 0x120; + IPC19 = 0x124; +_IPC19 = 0x124; +_IPC19bits = 0x124; + IPC20 = 0x128; +_IPC20 = 0x128; +_IPC20bits = 0x128; + IPC21 = 0x12C; +_IPC21 = 0x12C; +_IPC21bits = 0x12C; + IPC22 = 0x130; +_IPC22 = 0x130; +_IPC22bits = 0x130; + IPC23 = 0x134; +_IPC23 = 0x134; +_IPC23bits = 0x134; + IPC24 = 0x138; +_IPC24 = 0x138; +_IPC24bits = 0x138; + IPC25 = 0x13C; +_IPC25 = 0x13C; +_IPC25bits = 0x13C; + IPC26 = 0x140; +_IPC26 = 0x140; +_IPC26bits = 0x140; + IPC27 = 0x144; +_IPC27 = 0x144; +_IPC27bits = 0x144; + IPC28 = 0x148; +_IPC28 = 0x148; +_IPC28bits = 0x148; + IPC29 = 0x14C; +_IPC29 = 0x14C; +_IPC29bits = 0x14C; + IPC35 = 0x160; +_IPC35 = 0x160; +_IPC35bits = 0x160; + PORTA = 0x200; +_PORTA = 0x200; +_PORTAbits = 0x200; + LATA = 0x204; +_LATA = 0x204; +_LATAbits = 0x204; + TRISA = 0x208; +_TRISA = 0x208; +_TRISAbits = 0x208; + CNSTATA = 0x20C; +_CNSTATA = 0x20C; +_CNSTATAbits = 0x20C; + CNFA = 0x210; +_CNFA = 0x210; +_CNFAbits = 0x210; + PORTB = 0x214; +_PORTB = 0x214; +_PORTBbits = 0x214; + LATB = 0x218; +_LATB = 0x218; +_LATBbits = 0x218; + TRISB = 0x21C; +_TRISB = 0x21C; +_TRISBbits = 0x21C; + CNSTATB = 0x220; +_CNSTATB = 0x220; +_CNSTATBbits = 0x220; + CNFB = 0x224; +_CNFB = 0x224; +_CNFBbits = 0x224; + PORTC = 0x228; +_PORTC = 0x228; +_PORTCbits = 0x228; + LATC = 0x22C; +_LATC = 0x22C; +_LATCbits = 0x22C; + TRISC = 0x230; +_TRISC = 0x230; +_TRISCbits = 0x230; + CNSTATC = 0x234; +_CNSTATC = 0x234; +_CNSTATCbits = 0x234; + CNFC = 0x238; +_CNFC = 0x238; +_CNFCbits = 0x238; + PORTD = 0x23C; +_PORTD = 0x23C; +_PORTDbits = 0x23C; + LATD = 0x240; +_LATD = 0x240; +_LATDbits = 0x240; + TRISD = 0x244; +_TRISD = 0x244; +_TRISDbits = 0x244; + CNSTATD = 0x248; +_CNSTATD = 0x248; +_CNSTATDbits = 0x248; + CNFD = 0x24C; +_CNFD = 0x24C; +_CNFDbits = 0x24C; + CRCCON = 0x2C8; +_CRCCON = 0x2C8; +_CRCCONbits = 0x2C8; + CRCXOR = 0x2CC; +_CRCXOR = 0x2CC; +_CRCXORbits = 0x2CC; + CRCDAT = 0x2D0; +_CRCDAT = 0x2D0; + CRCWDAT = 0x2D4; +_CRCWDAT = 0x2D4; + UCPROT = 0x2E0; +_UCPROT = 0x2E0; +_UCPROTbits = 0x2E0; + IRTCTRL = 0x2E4; +_IRTCTRL = 0x2E4; +_IRTCTRLbits = 0x2E4; + IRTSTAT = 0x2E8; +_IRTSTAT = 0x2E8; + PR0CTRL = 0x300; +_PR0CTRL = 0x300; +_PR0CTRLbits = 0x300; + PR0ST = 0x304; +_PR0ST = 0x304; +_PR0STbits = 0x304; + PR0END = 0x308; +_PR0END = 0x308; +_PR0ENDbits = 0x308; + PR0LOCK = 0x30C; +_PR0LOCK = 0x30C; +_PR0LOCKbits = 0x30C; + PR1CTRL = 0x310; +_PR1CTRL = 0x310; +_PR1CTRLbits = 0x310; + PR1ST = 0x314; +_PR1ST = 0x314; +_PR1STbits = 0x314; + PR1END = 0x318; +_PR1END = 0x318; +_PR1ENDbits = 0x318; + PR1LOCK = 0x31C; +_PR1LOCK = 0x31C; +_PR1LOCKbits = 0x31C; + PR2CTRL = 0x320; +_PR2CTRL = 0x320; +_PR2CTRLbits = 0x320; + PR2ST = 0x324; +_PR2ST = 0x324; +_PR2STbits = 0x324; + PR2END = 0x328; +_PR2END = 0x328; +_PR2ENDbits = 0x328; + PR2LOCK = 0x32C; +_PR2LOCK = 0x32C; +_PR2LOCKbits = 0x32C; + PR3CTRL = 0x330; +_PR3CTRL = 0x330; +_PR3CTRLbits = 0x330; + PR3ST = 0x334; +_PR3ST = 0x334; +_PR3STbits = 0x334; + PR3END = 0x338; +_PR3END = 0x338; +_PR3ENDbits = 0x338; + PR3LOCK = 0x33C; +_PR3LOCK = 0x33C; +_PR3LOCKbits = 0x33C; + PR4CTRL = 0x340; +_PR4CTRL = 0x340; +_PR4CTRLbits = 0x340; + PR4ST = 0x344; +_PR4ST = 0x344; +_PR4STbits = 0x344; + PR4END = 0x348; +_PR4END = 0x348; +_PR4ENDbits = 0x348; + PR4LOCK = 0x34C; +_PR4LOCK = 0x34C; +_PR4LOCKbits = 0x34C; + PR5CTRL = 0x350; +_PR5CTRL = 0x350; +_PR5CTRLbits = 0x350; + PR5ST = 0x354; +_PR5ST = 0x354; +_PR5STbits = 0x354; + PR5END = 0x358; +_PR5END = 0x358; +_PR5ENDbits = 0x358; + PR5LOCK = 0x35C; +_PR5LOCK = 0x35C; +_PR5LOCKbits = 0x35C; + PR6CTRL = 0x360; +_PR6CTRL = 0x360; +_PR6CTRLbits = 0x360; + PR6ST = 0x364; +_PR6ST = 0x364; +_PR6STbits = 0x364; + PR6END = 0x368; +_PR6END = 0x368; +_PR6ENDbits = 0x368; + PR6LOCK = 0x36C; +_PR6LOCK = 0x36C; +_PR6LOCKbits = 0x36C; + PR7CTRL = 0x370; +_PR7CTRL = 0x370; +_PR7CTRLbits = 0x370; + PR7ST = 0x374; +_PR7ST = 0x374; +_PR7STbits = 0x374; + PR7END = 0x378; +_PR7END = 0x378; +_PR7ENDbits = 0x378; + PR7LOCK = 0x37C; +_PR7LOCK = 0x37C; +_PR7LOCKbits = 0x37C; + BMXINITPR = 0x770; +_BMXINITPR = 0x770; +_BMXINITPRbits = 0x770; + BMXIRAML = 0x774; +_BMXIRAML = 0x774; + BMXIRAMH = 0x778; +_BMXIRAMH = 0x778; + BMXXDATERR = 0x77C; +_BMXXDATERR = 0x77C; +_BMXXDATERRbits = 0x77C; + BMXYDATERR = 0x780; +_BMXYDATERR = 0x780; +_BMXYDATERRbits = 0x780; + BMXDMAERR = 0x784; +_BMXDMAERR = 0x784; +_BMXDMAERRbits = 0x784; + BMXNVMERR = 0x788; +_BMXNVMERR = 0x788; +_BMXNVMERRbits = 0x788; + BMXICDERR = 0x78C; +_BMXICDERR = 0x78C; +_BMXICDERRbits = 0x78C; + AD1CON = 0x800; +_AD1CON = 0x800; +_AD1CONbits = 0x800; + AD1DATAOVR = 0x804; +_AD1DATAOVR = 0x804; + AD1STAT = 0x808; +_AD1STAT = 0x808; +_AD1STATbits = 0x808; + AD1CMPSTAT = 0x80C; +_AD1CMPSTAT = 0x80C; +_AD1CMPSTATbits = 0x80C; + AD1SWTRG = 0x810; +_AD1SWTRG = 0x810; +_AD1SWTRGbits = 0x810; + AD1CH0CON = 0x814; +_AD1CH0CON = 0x814; +_AD1CH0CONbits = 0x814; + AD1CH0DATA = 0x818; +_AD1CH0DATA = 0x818; + AD1CH0CNT = 0x81C; +_AD1CH0CNT = 0x81C; +_AD1CH0CNTbits = 0x81C; + AD1CH0CMPLO = 0x820; +_AD1CH0CMPLO = 0x820; + AD1CH0CMPHI = 0x824; +_AD1CH0CMPHI = 0x824; + AD1CH0ACC = 0x828; +_AD1CH0ACC = 0x828; + AD1CH1CON = 0x82C; +_AD1CH1CON = 0x82C; +_AD1CH1CONbits = 0x82C; + AD1CH1DATA = 0x830; +_AD1CH1DATA = 0x830; + AD1CH1CNT = 0x834; +_AD1CH1CNT = 0x834; +_AD1CH1CNTbits = 0x834; + AD1CH1CMPLO = 0x838; +_AD1CH1CMPLO = 0x838; + AD1CH1CMPHI = 0x83C; +_AD1CH1CMPHI = 0x83C; + AD1CH1ACC = 0x840; +_AD1CH1ACC = 0x840; + AD1CH2CON = 0x844; +_AD1CH2CON = 0x844; +_AD1CH2CONbits = 0x844; + AD1CH2DATA = 0x848; +_AD1CH2DATA = 0x848; + AD1CH2CNT = 0x84C; +_AD1CH2CNT = 0x84C; +_AD1CH2CNTbits = 0x84C; + AD1CH2CMPLO = 0x850; +_AD1CH2CMPLO = 0x850; + AD1CH2CMPHI = 0x854; +_AD1CH2CMPHI = 0x854; + AD1CH2ACC = 0x858; +_AD1CH2ACC = 0x858; + AD1CH3CON = 0x85C; +_AD1CH3CON = 0x85C; +_AD1CH3CONbits = 0x85C; + AD1CH3DATA = 0x860; +_AD1CH3DATA = 0x860; + AD1CH3CNT = 0x864; +_AD1CH3CNT = 0x864; +_AD1CH3CNTbits = 0x864; + AD1CH3CMPLO = 0x868; +_AD1CH3CMPLO = 0x868; + AD1CH3CMPHI = 0x86C; +_AD1CH3CMPHI = 0x86C; + AD1CH3ACC = 0x870; +_AD1CH3ACC = 0x870; + AD1CH4CON = 0x874; +_AD1CH4CON = 0x874; +_AD1CH4CONbits = 0x874; + AD1CH4DATA = 0x878; +_AD1CH4DATA = 0x878; + AD1CH4CNT = 0x87C; +_AD1CH4CNT = 0x87C; +_AD1CH4CNTbits = 0x87C; + AD1CH4CMPLO = 0x880; +_AD1CH4CMPLO = 0x880; + AD1CH4CMPHI = 0x884; +_AD1CH4CMPHI = 0x884; + AD1CH4ACC = 0x888; +_AD1CH4ACC = 0x888; + AD1CH5CON = 0x88C; +_AD1CH5CON = 0x88C; +_AD1CH5CONbits = 0x88C; + AD1CH5DATA = 0x890; +_AD1CH5DATA = 0x890; + AD1CH5CNT = 0x894; +_AD1CH5CNT = 0x894; +_AD1CH5CNTbits = 0x894; + AD1CH5CMPLO = 0x898; +_AD1CH5CMPLO = 0x898; + AD1CH5CMPHI = 0x89C; +_AD1CH5CMPHI = 0x89C; + AD1CH5ACC = 0x8A0; +_AD1CH5ACC = 0x8A0; + AD1CH6CON = 0x8A4; +_AD1CH6CON = 0x8A4; +_AD1CH6CONbits = 0x8A4; + AD1CH6DATA = 0x8A8; +_AD1CH6DATA = 0x8A8; + AD1CH6CNT = 0x8AC; +_AD1CH6CNT = 0x8AC; +_AD1CH6CNTbits = 0x8AC; + AD1CH6CMPLO = 0x8B0; +_AD1CH6CMPLO = 0x8B0; + AD1CH6CMPHI = 0x8B4; +_AD1CH6CMPHI = 0x8B4; + AD1CH6ACC = 0x8B8; +_AD1CH6ACC = 0x8B8; + AD1CH7CON = 0x8BC; +_AD1CH7CON = 0x8BC; +_AD1CH7CONbits = 0x8BC; + AD1CH7DATA = 0x8C0; +_AD1CH7DATA = 0x8C0; + AD1CH7CNT = 0x8C4; +_AD1CH7CNT = 0x8C4; +_AD1CH7CNTbits = 0x8C4; + AD1CH7CMPLO = 0x8C8; +_AD1CH7CMPLO = 0x8C8; + AD1CH7CMPHI = 0x8CC; +_AD1CH7CMPHI = 0x8CC; + AD1CH7ACC = 0x8D0; +_AD1CH7ACC = 0x8D0; + AD1CH8CON = 0x8D4; +_AD1CH8CON = 0x8D4; +_AD1CH8CONbits = 0x8D4; + AD1CH8DATA = 0x8D8; +_AD1CH8DATA = 0x8D8; + AD1CH8CNT = 0x8DC; +_AD1CH8CNT = 0x8DC; +_AD1CH8CNTbits = 0x8DC; + AD1CH8CMPLO = 0x8E0; +_AD1CH8CMPLO = 0x8E0; + AD1CH8CMPHI = 0x8E4; +_AD1CH8CMPHI = 0x8E4; + AD1CH8ACC = 0x8E8; +_AD1CH8ACC = 0x8E8; + AD1CH9CON = 0x8EC; +_AD1CH9CON = 0x8EC; +_AD1CH9CONbits = 0x8EC; + AD1CH9DATA = 0x8F0; +_AD1CH9DATA = 0x8F0; + AD1CH9CNT = 0x8F4; +_AD1CH9CNT = 0x8F4; +_AD1CH9CNTbits = 0x8F4; + AD1CH9CMPLO = 0x8F8; +_AD1CH9CMPLO = 0x8F8; + AD1CH9CMPHI = 0x8FC; +_AD1CH9CMPHI = 0x8FC; + AD1CH9ACC = 0x900; +_AD1CH9ACC = 0x900; + AD1CH10CON = 0x904; +_AD1CH10CON = 0x904; +_AD1CH10CONbits = 0x904; + AD1CH10DATA = 0x908; +_AD1CH10DATA = 0x908; + AD1CH10CNT = 0x90C; +_AD1CH10CNT = 0x90C; +_AD1CH10CNTbits = 0x90C; + AD1CH10CMPLO = 0x910; +_AD1CH10CMPLO = 0x910; + AD1CH10CMPHI = 0x914; +_AD1CH10CMPHI = 0x914; + AD1CH10ACC = 0x918; +_AD1CH10ACC = 0x918; + AD1CH11CON = 0x91C; +_AD1CH11CON = 0x91C; +_AD1CH11CONbits = 0x91C; + AD1CH11DATA = 0x920; +_AD1CH11DATA = 0x920; + AD1CH11CNT = 0x924; +_AD1CH11CNT = 0x924; +_AD1CH11CNTbits = 0x924; + AD1CH11CMPLO = 0x928; +_AD1CH11CMPLO = 0x928; + AD1CH11CMPHI = 0x92C; +_AD1CH11CMPHI = 0x92C; + AD1CH11ACC = 0x930; +_AD1CH11ACC = 0x930; + AD1CH12CON = 0x934; +_AD1CH12CON = 0x934; +_AD1CH12CONbits = 0x934; + AD1CH12DATA = 0x938; +_AD1CH12DATA = 0x938; + AD1CH12CNT = 0x93C; +_AD1CH12CNT = 0x93C; +_AD1CH12CNTbits = 0x93C; + AD1CH12CMPLO = 0x940; +_AD1CH12CMPLO = 0x940; + AD1CH12CMPHI = 0x944; +_AD1CH12CMPHI = 0x944; + AD1CH12ACC = 0x948; +_AD1CH12ACC = 0x948; + AD1CH13CON = 0x94C; +_AD1CH13CON = 0x94C; +_AD1CH13CONbits = 0x94C; + AD1CH13DATA = 0x950; +_AD1CH13DATA = 0x950; + AD1CH13CNT = 0x954; +_AD1CH13CNT = 0x954; +_AD1CH13CNTbits = 0x954; + AD1CH13CMPLO = 0x958; +_AD1CH13CMPLO = 0x958; + AD1CH13CMPHI = 0x95C; +_AD1CH13CMPHI = 0x95C; + AD1CH13ACC = 0x960; +_AD1CH13ACC = 0x960; + AD1CH14CON = 0x964; +_AD1CH14CON = 0x964; +_AD1CH14CONbits = 0x964; + AD1CH14DATA = 0x968; +_AD1CH14DATA = 0x968; + AD1CH14CNT = 0x96C; +_AD1CH14CNT = 0x96C; +_AD1CH14CNTbits = 0x96C; + AD1CH14CMPLO = 0x970; +_AD1CH14CMPLO = 0x970; + AD1CH14CMPHI = 0x974; +_AD1CH14CMPHI = 0x974; + AD1CH14ACC = 0x978; +_AD1CH14ACC = 0x978; + AD1CH15CON = 0x97C; +_AD1CH15CON = 0x97C; +_AD1CH15CONbits = 0x97C; + AD1CH15DATA = 0x980; +_AD1CH15DATA = 0x980; + AD1CH15CNT = 0x984; +_AD1CH15CNT = 0x984; +_AD1CH15CNTbits = 0x984; + AD1CH15CMPLO = 0x988; +_AD1CH15CMPLO = 0x988; + AD1CH15CMPHI = 0x98C; +_AD1CH15CMPHI = 0x98C; + AD1CH15ACC = 0x990; +_AD1CH15ACC = 0x990; + AD1CH16CON = 0x994; +_AD1CH16CON = 0x994; +_AD1CH16CONbits = 0x994; + AD1CH16DATA = 0x998; +_AD1CH16DATA = 0x998; + AD1CH16CNT = 0x99C; +_AD1CH16CNT = 0x99C; +_AD1CH16CNTbits = 0x99C; + AD1CH16CMPLO = 0x9A0; +_AD1CH16CMPLO = 0x9A0; + AD1CH16CMPHI = 0x9A4; +_AD1CH16CMPHI = 0x9A4; + AD1CH16ACC = 0x9A8; +_AD1CH16ACC = 0x9A8; + AD1CH17CON = 0x9AC; +_AD1CH17CON = 0x9AC; +_AD1CH17CONbits = 0x9AC; + AD1CH17DATA = 0x9B0; +_AD1CH17DATA = 0x9B0; + AD1CH17CNT = 0x9B4; +_AD1CH17CNT = 0x9B4; +_AD1CH17CNTbits = 0x9B4; + AD1CH17CMPLO = 0x9B8; +_AD1CH17CMPLO = 0x9B8; + AD1CH17CMPHI = 0x9BC; +_AD1CH17CMPHI = 0x9BC; + AD1CH17ACC = 0x9C0; +_AD1CH17ACC = 0x9C0; + AD1CH18CON = 0x9C4; +_AD1CH18CON = 0x9C4; +_AD1CH18CONbits = 0x9C4; + AD1CH18DATA = 0x9C8; +_AD1CH18DATA = 0x9C8; + AD1CH18CNT = 0x9CC; +_AD1CH18CNT = 0x9CC; +_AD1CH18CNTbits = 0x9CC; + AD1CH18CMPLO = 0x9D0; +_AD1CH18CMPLO = 0x9D0; + AD1CH18CMPHI = 0x9D4; +_AD1CH18CMPHI = 0x9D4; + AD1CH18ACC = 0x9D8; +_AD1CH18ACC = 0x9D8; + AD1CH19CON = 0x9DC; +_AD1CH19CON = 0x9DC; +_AD1CH19CONbits = 0x9DC; + AD1CH19DATA = 0x9E0; +_AD1CH19DATA = 0x9E0; + AD1CH19CNT = 0x9E4; +_AD1CH19CNT = 0x9E4; +_AD1CH19CNTbits = 0x9E4; + AD1CH19CMPLO = 0x9E8; +_AD1CH19CMPLO = 0x9E8; + AD1CH19CMPHI = 0x9EC; +_AD1CH19CMPHI = 0x9EC; + AD1CH19ACC = 0x9F0; +_AD1CH19ACC = 0x9F0; + AD2CON = 0xA00; +_AD2CON = 0xA00; +_AD2CONbits = 0xA00; + AD2DATAOVR = 0xA04; +_AD2DATAOVR = 0xA04; + AD2STAT = 0xA08; +_AD2STAT = 0xA08; +_AD2STATbits = 0xA08; + AD2CMPSTAT = 0xA0C; +_AD2CMPSTAT = 0xA0C; +_AD2CMPSTATbits = 0xA0C; + AD2SWTRG = 0xA10; +_AD2SWTRG = 0xA10; +_AD2SWTRGbits = 0xA10; + AD2CH0CON = 0xA14; +_AD2CH0CON = 0xA14; +_AD2CH0CONbits = 0xA14; + AD2CH0DATA = 0xA18; +_AD2CH0DATA = 0xA18; + AD2CH0CNT = 0xA1C; +_AD2CH0CNT = 0xA1C; +_AD2CH0CNTbits = 0xA1C; + AD2CH0CMPLO = 0xA20; +_AD2CH0CMPLO = 0xA20; + AD2CH0CMPHI = 0xA24; +_AD2CH0CMPHI = 0xA24; + AD2CH0ACC = 0xA28; +_AD2CH0ACC = 0xA28; + AD2CH1CON = 0xA2C; +_AD2CH1CON = 0xA2C; +_AD2CH1CONbits = 0xA2C; + AD2CH1DATA = 0xA30; +_AD2CH1DATA = 0xA30; + AD2CH1CNT = 0xA34; +_AD2CH1CNT = 0xA34; +_AD2CH1CNTbits = 0xA34; + AD2CH1CMPLO = 0xA38; +_AD2CH1CMPLO = 0xA38; + AD2CH1CMPHI = 0xA3C; +_AD2CH1CMPHI = 0xA3C; + AD2CH1ACC = 0xA40; +_AD2CH1ACC = 0xA40; + AD2CH2CON = 0xA44; +_AD2CH2CON = 0xA44; +_AD2CH2CONbits = 0xA44; + AD2CH2DATA = 0xA48; +_AD2CH2DATA = 0xA48; + AD2CH2CNT = 0xA4C; +_AD2CH2CNT = 0xA4C; +_AD2CH2CNTbits = 0xA4C; + AD2CH2CMPLO = 0xA50; +_AD2CH2CMPLO = 0xA50; + AD2CH2CMPHI = 0xA54; +_AD2CH2CMPHI = 0xA54; + AD2CH2ACC = 0xA58; +_AD2CH2ACC = 0xA58; + AD2CH3CON = 0xA5C; +_AD2CH3CON = 0xA5C; +_AD2CH3CONbits = 0xA5C; + AD2CH3DATA = 0xA60; +_AD2CH3DATA = 0xA60; + AD2CH3CNT = 0xA64; +_AD2CH3CNT = 0xA64; +_AD2CH3CNTbits = 0xA64; + AD2CH3CMPLO = 0xA68; +_AD2CH3CMPLO = 0xA68; + AD2CH3CMPHI = 0xA6C; +_AD2CH3CMPHI = 0xA6C; + AD2CH3ACC = 0xA70; +_AD2CH3ACC = 0xA70; + AD2CH4CON = 0xA74; +_AD2CH4CON = 0xA74; +_AD2CH4CONbits = 0xA74; + AD2CH4DATA = 0xA78; +_AD2CH4DATA = 0xA78; + AD2CH4CNT = 0xA7C; +_AD2CH4CNT = 0xA7C; +_AD2CH4CNTbits = 0xA7C; + AD2CH4CMPLO = 0xA80; +_AD2CH4CMPLO = 0xA80; + AD2CH4CMPHI = 0xA84; +_AD2CH4CMPHI = 0xA84; + AD2CH4ACC = 0xA88; +_AD2CH4ACC = 0xA88; + AD2CH5CON = 0xA8C; +_AD2CH5CON = 0xA8C; +_AD2CH5CONbits = 0xA8C; + AD2CH5DATA = 0xA90; +_AD2CH5DATA = 0xA90; + AD2CH5CNT = 0xA94; +_AD2CH5CNT = 0xA94; +_AD2CH5CNTbits = 0xA94; + AD2CH5CMPLO = 0xA98; +_AD2CH5CMPLO = 0xA98; + AD2CH5CMPHI = 0xA9C; +_AD2CH5CMPHI = 0xA9C; + AD2CH5ACC = 0xAA0; +_AD2CH5ACC = 0xAA0; + AD2CH6CON = 0xAA4; +_AD2CH6CON = 0xAA4; +_AD2CH6CONbits = 0xAA4; + AD2CH6DATA = 0xAA8; +_AD2CH6DATA = 0xAA8; + AD2CH6CNT = 0xAAC; +_AD2CH6CNT = 0xAAC; +_AD2CH6CNTbits = 0xAAC; + AD2CH6CMPLO = 0xAB0; +_AD2CH6CMPLO = 0xAB0; + AD2CH6CMPHI = 0xAB4; +_AD2CH6CMPHI = 0xAB4; + AD2CH6ACC = 0xAB8; +_AD2CH6ACC = 0xAB8; + AD2CH7CON = 0xABC; +_AD2CH7CON = 0xABC; +_AD2CH7CONbits = 0xABC; + AD2CH7DATA = 0xAC0; +_AD2CH7DATA = 0xAC0; + AD2CH7CNT = 0xAC4; +_AD2CH7CNT = 0xAC4; +_AD2CH7CNTbits = 0xAC4; + AD2CH7CMPLO = 0xAC8; +_AD2CH7CMPLO = 0xAC8; + AD2CH7CMPHI = 0xACC; +_AD2CH7CMPHI = 0xACC; + AD2CH7ACC = 0xAD0; +_AD2CH7ACC = 0xAD0; + AD2CH8CON = 0xAD4; +_AD2CH8CON = 0xAD4; +_AD2CH8CONbits = 0xAD4; + AD2CH8DATA = 0xAD8; +_AD2CH8DATA = 0xAD8; + AD2CH8CNT = 0xADC; +_AD2CH8CNT = 0xADC; +_AD2CH8CNTbits = 0xADC; + AD2CH8CMPLO = 0xAE0; +_AD2CH8CMPLO = 0xAE0; + AD2CH8CMPHI = 0xAE4; +_AD2CH8CMPHI = 0xAE4; + AD2CH8ACC = 0xAE8; +_AD2CH8ACC = 0xAE8; + AD2CH9CON = 0xAEC; +_AD2CH9CON = 0xAEC; +_AD2CH9CONbits = 0xAEC; + AD2CH9DATA = 0xAF0; +_AD2CH9DATA = 0xAF0; + AD2CH9CNT = 0xAF4; +_AD2CH9CNT = 0xAF4; +_AD2CH9CNTbits = 0xAF4; + AD2CH9CMPLO = 0xAF8; +_AD2CH9CMPLO = 0xAF8; + AD2CH9CMPHI = 0xAFC; +_AD2CH9CMPHI = 0xAFC; + AD2CH9ACC = 0xB00; +_AD2CH9ACC = 0xB00; + AD2CH10CON = 0xB04; +_AD2CH10CON = 0xB04; +_AD2CH10CONbits = 0xB04; + AD2CH10DATA = 0xB08; +_AD2CH10DATA = 0xB08; + AD2CH10CNT = 0xB0C; +_AD2CH10CNT = 0xB0C; +_AD2CH10CNTbits = 0xB0C; + AD2CH10CMPLO = 0xB10; +_AD2CH10CMPLO = 0xB10; + AD2CH10CMPHI = 0xB14; +_AD2CH10CMPHI = 0xB14; + AD2CH10ACC = 0xB18; +_AD2CH10ACC = 0xB18; + AD2CH11CON = 0xB1C; +_AD2CH11CON = 0xB1C; +_AD2CH11CONbits = 0xB1C; + AD2CH11DATA = 0xB20; +_AD2CH11DATA = 0xB20; + AD2CH11CNT = 0xB24; +_AD2CH11CNT = 0xB24; +_AD2CH11CNTbits = 0xB24; + AD2CH11CMPLO = 0xB28; +_AD2CH11CMPLO = 0xB28; + AD2CH11CMPHI = 0xB2C; +_AD2CH11CMPHI = 0xB2C; + AD2CH11ACC = 0xB30; +_AD2CH11ACC = 0xB30; + AD2CH12CON = 0xB34; +_AD2CH12CON = 0xB34; +_AD2CH12CONbits = 0xB34; + AD2CH12DATA = 0xB38; +_AD2CH12DATA = 0xB38; + AD2CH12CNT = 0xB3C; +_AD2CH12CNT = 0xB3C; +_AD2CH12CNTbits = 0xB3C; + AD2CH12CMPLO = 0xB40; +_AD2CH12CMPLO = 0xB40; + AD2CH12CMPHI = 0xB44; +_AD2CH12CMPHI = 0xB44; + AD2CH12ACC = 0xB48; +_AD2CH12ACC = 0xB48; + AD2CH13CON = 0xB4C; +_AD2CH13CON = 0xB4C; +_AD2CH13CONbits = 0xB4C; + AD2CH13DATA = 0xB50; +_AD2CH13DATA = 0xB50; + AD2CH13CNT = 0xB54; +_AD2CH13CNT = 0xB54; +_AD2CH13CNTbits = 0xB54; + AD2CH13CMPLO = 0xB58; +_AD2CH13CMPLO = 0xB58; + AD2CH13CMPHI = 0xB5C; +_AD2CH13CMPHI = 0xB5C; + AD2CH13ACC = 0xB60; +_AD2CH13ACC = 0xB60; + AD2CH14CON = 0xB64; +_AD2CH14CON = 0xB64; +_AD2CH14CONbits = 0xB64; + AD2CH14DATA = 0xB68; +_AD2CH14DATA = 0xB68; + AD2CH14CNT = 0xB6C; +_AD2CH14CNT = 0xB6C; +_AD2CH14CNTbits = 0xB6C; + AD2CH14CMPLO = 0xB70; +_AD2CH14CMPLO = 0xB70; + AD2CH14CMPHI = 0xB74; +_AD2CH14CMPHI = 0xB74; + AD2CH14ACC = 0xB78; +_AD2CH14ACC = 0xB78; + AD2CH15CON = 0xB7C; +_AD2CH15CON = 0xB7C; +_AD2CH15CONbits = 0xB7C; + AD2CH15DATA = 0xB80; +_AD2CH15DATA = 0xB80; + AD2CH15CNT = 0xB84; +_AD2CH15CNT = 0xB84; +_AD2CH15CNTbits = 0xB84; + AD2CH15CMPLO = 0xB88; +_AD2CH15CMPLO = 0xB88; + AD2CH15CMPHI = 0xB8C; +_AD2CH15CMPHI = 0xB8C; + AD2CH15ACC = 0xB90; +_AD2CH15ACC = 0xB90; + AD2CH16CON = 0xB94; +_AD2CH16CON = 0xB94; +_AD2CH16CONbits = 0xB94; + AD2CH16DATA = 0xB98; +_AD2CH16DATA = 0xB98; + AD2CH16CNT = 0xB9C; +_AD2CH16CNT = 0xB9C; +_AD2CH16CNTbits = 0xB9C; + AD2CH16CMPLO = 0xBA0; +_AD2CH16CMPLO = 0xBA0; + AD2CH16CMPHI = 0xBA4; +_AD2CH16CMPHI = 0xBA4; + AD2CH16ACC = 0xBA8; +_AD2CH16ACC = 0xBA8; + AD2CH17CON = 0xBAC; +_AD2CH17CON = 0xBAC; +_AD2CH17CONbits = 0xBAC; + AD2CH17DATA = 0xBB0; +_AD2CH17DATA = 0xBB0; + AD2CH17CNT = 0xBB4; +_AD2CH17CNT = 0xBB4; +_AD2CH17CNTbits = 0xBB4; + AD2CH17CMPLO = 0xBB8; +_AD2CH17CMPLO = 0xBB8; + AD2CH17CMPHI = 0xBBC; +_AD2CH17CMPHI = 0xBBC; + AD2CH17ACC = 0xBC0; +_AD2CH17ACC = 0xBC0; + AD2CH18CON = 0xBC4; +_AD2CH18CON = 0xBC4; +_AD2CH18CONbits = 0xBC4; + AD2CH18DATA = 0xBC8; +_AD2CH18DATA = 0xBC8; + AD2CH18CNT = 0xBCC; +_AD2CH18CNT = 0xBCC; +_AD2CH18CNTbits = 0xBCC; + AD2CH18CMPLO = 0xBD0; +_AD2CH18CMPLO = 0xBD0; + AD2CH18CMPHI = 0xBD4; +_AD2CH18CMPHI = 0xBD4; + AD2CH18ACC = 0xBD8; +_AD2CH18ACC = 0xBD8; + AD2CH19CON = 0xBDC; +_AD2CH19CON = 0xBDC; +_AD2CH19CONbits = 0xBDC; + AD2CH19DATA = 0xBE0; +_AD2CH19DATA = 0xBE0; + AD2CH19CNT = 0xBE4; +_AD2CH19CNT = 0xBE4; +_AD2CH19CNTbits = 0xBE4; + AD2CH19CMPLO = 0xBE8; +_AD2CH19CMPLO = 0xBE8; + AD2CH19CMPHI = 0xBEC; +_AD2CH19CMPHI = 0xBEC; + AD2CH19ACC = 0xBF0; +_AD2CH19ACC = 0xBF0; + PCLKCON = 0x1000; +_PCLKCON = 0x1000; +_PCLKCONbits = 0x1000; + FSCL = 0x1004; +_FSCL = 0x1004; +_FSCLbits = 0x1004; + FSMINPER = 0x1008; +_FSMINPER = 0x1008; +_FSMINPERbits = 0x1008; + MPHASE = 0x100C; +_MPHASE = 0x100C; +_MPHASEbits = 0x100C; + MDC = 0x1010; +_MDC = 0x1010; +_MDCbits = 0x1010; + MPER = 0x1014; +_MPER = 0x1014; +_MPERbits = 0x1014; + LFSR = 0x1018; +_LFSR = 0x1018; +_LFSRbits = 0x1018; + CMBTRIG = 0x101C; +_CMBTRIG = 0x101C; +_CMBTRIGbits = 0x101C; + LOGCONA = 0x1020; +_LOGCONA = 0x1020; +_LOGCONAbits = 0x1020; + LOGCONB = 0x1024; +_LOGCONB = 0x1024; +_LOGCONBbits = 0x1024; + LOGCONC = 0x1028; +_LOGCONC = 0x1028; +_LOGCONCbits = 0x1028; + LOGCOND = 0x102C; +_LOGCOND = 0x102C; +_LOGCONDbits = 0x102C; + LOGCONE = 0x1030; +_LOGCONE = 0x1030; +_LOGCONEbits = 0x1030; + LOGCONF = 0x1034; +_LOGCONF = 0x1034; +_LOGCONFbits = 0x1034; + PWMEVTA = 0x1038; +_PWMEVTA = 0x1038; +_PWMEVTAbits = 0x1038; + PWMEVTB = 0x103C; +_PWMEVTB = 0x103C; +_PWMEVTBbits = 0x103C; + PWMEVTC = 0x1040; +_PWMEVTC = 0x1040; +_PWMEVTCbits = 0x1040; + PWMEVTD = 0x1044; +_PWMEVTD = 0x1044; +_PWMEVTDbits = 0x1044; + PWMEVTE = 0x1048; +_PWMEVTE = 0x1048; +_PWMEVTEbits = 0x1048; + PWMEVTF = 0x104C; +_PWMEVTF = 0x104C; +_PWMEVTFbits = 0x104C; + PG1CON = 0x1050; +_PG1CON = 0x1050; +_PG1CONbits = 0x1050; + PG1STAT = 0x1054; +_PG1STAT = 0x1054; +_PG1STATbits = 0x1054; + PG1IOCON = 0x1058; +_PG1IOCON = 0x1058; +_PG1IOCONbits = 0x1058; + PG1EVT = 0x105C; +_PG1EVT = 0x105C; +_PG1EVTbits = 0x105C; + PG1FPCI = 0x1060; +_PG1FPCI = 0x1060; +_PG1FPCIbits = 0x1060; + PG1CLPCI = 0x1064; +_PG1CLPCI = 0x1064; +_PG1CLPCIbits = 0x1064; + PG1FFPCI = 0x1068; +_PG1FFPCI = 0x1068; +_PG1FFPCIbits = 0x1068; + PG1SPCI = 0x106C; +_PG1SPCI = 0x106C; +_PG1SPCIbits = 0x106C; + PG1LEB = 0x1070; +_PG1LEB = 0x1070; +_PG1LEBbits = 0x1070; + PG1PHASE = 0x1074; +_PG1PHASE = 0x1074; +_PG1PHASEbits = 0x1074; + PG1DC = 0x1078; +_PG1DC = 0x1078; +_PG1DCbits = 0x1078; + PG1DCA = 0x107C; +_PG1DCA = 0x107C; +_PG1DCAbits = 0x107C; + PG1PER = 0x1080; +_PG1PER = 0x1080; +_PG1PERbits = 0x1080; + PG1TRIGA = 0x1084; +_PG1TRIGA = 0x1084; +_PG1TRIGAbits = 0x1084; + PG1TRIGB = 0x1088; +_PG1TRIGB = 0x1088; +_PG1TRIGBbits = 0x1088; + PG1TRIGC = 0x108C; +_PG1TRIGC = 0x108C; +_PG1TRIGCbits = 0x108C; + PG1DT = 0x1090; +_PG1DT = 0x1090; +_PG1DTbits = 0x1090; + PG1CAP = 0x1094; +_PG1CAP = 0x1094; +_PG1CAPbits = 0x1094; + PG2CON = 0x1098; +_PG2CON = 0x1098; +_PG2CONbits = 0x1098; + PG2STAT = 0x109C; +_PG2STAT = 0x109C; +_PG2STATbits = 0x109C; + PG2IOCON = 0x10A0; +_PG2IOCON = 0x10A0; +_PG2IOCONbits = 0x10A0; + PG2EVT = 0x10A4; +_PG2EVT = 0x10A4; +_PG2EVTbits = 0x10A4; + PG2FPCI = 0x10A8; +_PG2FPCI = 0x10A8; +_PG2FPCIbits = 0x10A8; + PG2CLPCI = 0x10AC; +_PG2CLPCI = 0x10AC; +_PG2CLPCIbits = 0x10AC; + PG2FFPCI = 0x10B0; +_PG2FFPCI = 0x10B0; +_PG2FFPCIbits = 0x10B0; + PG2SPCI = 0x10B4; +_PG2SPCI = 0x10B4; +_PG2SPCIbits = 0x10B4; + PG2LEB = 0x10B8; +_PG2LEB = 0x10B8; +_PG2LEBbits = 0x10B8; + PG2PHASE = 0x10BC; +_PG2PHASE = 0x10BC; +_PG2PHASEbits = 0x10BC; + PG2DC = 0x10C0; +_PG2DC = 0x10C0; +_PG2DCbits = 0x10C0; + PG2DCA = 0x10C4; +_PG2DCA = 0x10C4; +_PG2DCAbits = 0x10C4; + PG2PER = 0x10C8; +_PG2PER = 0x10C8; +_PG2PERbits = 0x10C8; + PG2TRIGA = 0x10CC; +_PG2TRIGA = 0x10CC; +_PG2TRIGAbits = 0x10CC; + PG2TRIGB = 0x10D0; +_PG2TRIGB = 0x10D0; +_PG2TRIGBbits = 0x10D0; + PG2TRIGC = 0x10D4; +_PG2TRIGC = 0x10D4; +_PG2TRIGCbits = 0x10D4; + PG2DT = 0x10D8; +_PG2DT = 0x10D8; +_PG2DTbits = 0x10D8; + PG2CAP = 0x10DC; +_PG2CAP = 0x10DC; +_PG2CAPbits = 0x10DC; + PG3CON = 0x10E0; +_PG3CON = 0x10E0; +_PG3CONbits = 0x10E0; + PG3STAT = 0x10E4; +_PG3STAT = 0x10E4; +_PG3STATbits = 0x10E4; + PG3IOCON = 0x10E8; +_PG3IOCON = 0x10E8; +_PG3IOCONbits = 0x10E8; + PG3EVT = 0x10EC; +_PG3EVT = 0x10EC; +_PG3EVTbits = 0x10EC; + PG3FPCI = 0x10F0; +_PG3FPCI = 0x10F0; +_PG3FPCIbits = 0x10F0; + PG3CLPCI = 0x10F4; +_PG3CLPCI = 0x10F4; +_PG3CLPCIbits = 0x10F4; + PG3FFPCI = 0x10F8; +_PG3FFPCI = 0x10F8; +_PG3FFPCIbits = 0x10F8; + PG3SPCI = 0x10FC; +_PG3SPCI = 0x10FC; +_PG3SPCIbits = 0x10FC; + PG3LEB = 0x1100; +_PG3LEB = 0x1100; +_PG3LEBbits = 0x1100; + PG3PHASE = 0x1104; +_PG3PHASE = 0x1104; +_PG3PHASEbits = 0x1104; + PG3DC = 0x1108; +_PG3DC = 0x1108; +_PG3DCbits = 0x1108; + PG3DCA = 0x110C; +_PG3DCA = 0x110C; +_PG3DCAbits = 0x110C; + PG3PER = 0x1110; +_PG3PER = 0x1110; +_PG3PERbits = 0x1110; + PG3TRIGA = 0x1114; +_PG3TRIGA = 0x1114; +_PG3TRIGAbits = 0x1114; + PG3TRIGB = 0x1118; +_PG3TRIGB = 0x1118; +_PG3TRIGBbits = 0x1118; + PG3TRIGC = 0x111C; +_PG3TRIGC = 0x111C; +_PG3TRIGCbits = 0x111C; + PG3DT = 0x1120; +_PG3DT = 0x1120; +_PG3DTbits = 0x1120; + PG3CAP = 0x1124; +_PG3CAP = 0x1124; +_PG3CAPbits = 0x1124; + PG4CON = 0x1128; +_PG4CON = 0x1128; +_PG4CONbits = 0x1128; + PG4STAT = 0x112C; +_PG4STAT = 0x112C; +_PG4STATbits = 0x112C; + PG4IOCON = 0x1130; +_PG4IOCON = 0x1130; +_PG4IOCONbits = 0x1130; + PG4EVT = 0x1134; +_PG4EVT = 0x1134; +_PG4EVTbits = 0x1134; + PG4FPCI = 0x1138; +_PG4FPCI = 0x1138; +_PG4FPCIbits = 0x1138; + PG4CLPCI = 0x113C; +_PG4CLPCI = 0x113C; +_PG4CLPCIbits = 0x113C; + PG4FFPCI = 0x1140; +_PG4FFPCI = 0x1140; +_PG4FFPCIbits = 0x1140; + PG4SPCI = 0x1144; +_PG4SPCI = 0x1144; +_PG4SPCIbits = 0x1144; + PG4LEB = 0x1148; +_PG4LEB = 0x1148; +_PG4LEBbits = 0x1148; + PG4PHASE = 0x114C; +_PG4PHASE = 0x114C; +_PG4PHASEbits = 0x114C; + PG4DC = 0x1150; +_PG4DC = 0x1150; +_PG4DCbits = 0x1150; + PG4DCA = 0x1154; +_PG4DCA = 0x1154; +_PG4DCAbits = 0x1154; + PG4PER = 0x1158; +_PG4PER = 0x1158; +_PG4PERbits = 0x1158; + PG4TRIGA = 0x115C; +_PG4TRIGA = 0x115C; +_PG4TRIGAbits = 0x115C; + PG4TRIGB = 0x1160; +_PG4TRIGB = 0x1160; +_PG4TRIGBbits = 0x1160; + PG4TRIGC = 0x1164; +_PG4TRIGC = 0x1164; +_PG4TRIGCbits = 0x1164; + PG4DT = 0x1168; +_PG4DT = 0x1168; +_PG4DTbits = 0x1168; + PG4CAP = 0x116C; +_PG4CAP = 0x116C; +_PG4CAPbits = 0x116C; + U1CON = 0x1700; +_U1CON = 0x1700; +_U1CONbits = 0x1700; + U1STAT = 0x1704; +_U1STAT = 0x1704; +_U1STATbits = 0x1704; + U1BRG = 0x1708; +_U1BRG = 0x1708; +_U1BRGbits = 0x1708; + U1RXB = 0x170C; +_U1RXB = 0x170C; +_U1RXBbits = 0x170C; + U1TXB = 0x1710; +_U1TXB = 0x1710; +_U1TXBbits = 0x1710; + U1PA = 0x1714; +_U1PA = 0x1714; +_U1PAbits = 0x1714; + U1PB = 0x1718; +_U1PB = 0x1718; +_U1PBbits = 0x1718; + U1CHK = 0x171C; +_U1CHK = 0x171C; +_U1CHKbits = 0x171C; + U1SCCON = 0x1720; +_U1SCCON = 0x1720; +_U1SCCONbits = 0x1720; + U1UIR = 0x1724; +_U1UIR = 0x1724; +_U1UIRbits = 0x1724; + U2CON = 0x1740; +_U2CON = 0x1740; +_U2CONbits = 0x1740; + U2STAT = 0x1744; +_U2STAT = 0x1744; +_U2STATbits = 0x1744; + U2BRG = 0x1748; +_U2BRG = 0x1748; +_U2BRGbits = 0x1748; + U2RXB = 0x174C; +_U2RXB = 0x174C; +_U2RXBbits = 0x174C; + U2TXB = 0x1750; +_U2TXB = 0x1750; +_U2TXBbits = 0x1750; + U2PA = 0x1754; +_U2PA = 0x1754; +_U2PAbits = 0x1754; + U2PB = 0x1758; +_U2PB = 0x1758; +_U2PBbits = 0x1758; + U2CHK = 0x175C; +_U2CHK = 0x175C; +_U2CHKbits = 0x175C; + U2SCCON = 0x1760; +_U2SCCON = 0x1760; +_U2SCCONbits = 0x1760; + U2UIR = 0x1764; +_U2UIR = 0x1764; +_U2UIRbits = 0x1764; + U3CON = 0x1780; +_U3CON = 0x1780; +_U3CONbits = 0x1780; + U3STAT = 0x1784; +_U3STAT = 0x1784; +_U3STATbits = 0x1784; + U3BRG = 0x1788; +_U3BRG = 0x1788; +_U3BRGbits = 0x1788; + U3RXB = 0x178C; +_U3RXB = 0x178C; +_U3RXBbits = 0x178C; + U3TXB = 0x1790; +_U3TXB = 0x1790; +_U3TXBbits = 0x1790; + U3PA = 0x1794; +_U3PA = 0x1794; +_U3PAbits = 0x1794; + U3PB = 0x1798; +_U3PB = 0x1798; +_U3PBbits = 0x1798; + U3CHK = 0x179C; +_U3CHK = 0x179C; +_U3CHKbits = 0x179C; + U3SCCON = 0x17A0; +_U3SCCON = 0x17A0; +_U3SCCONbits = 0x17A0; + U3UIR = 0x17A4; +_U3UIR = 0x17A4; +_U3UIRbits = 0x17A4; + SPI1CON1 = 0x1800; +_SPI1CON1 = 0x1800; +_SPI1CON1bits = 0x1800; + SPI1CON2 = 0x1804; +_SPI1CON2 = 0x1804; +_SPI1CON2bits = 0x1804; + SPI1STAT = 0x1808; +_SPI1STAT = 0x1808; +_SPI1STATbits = 0x1808; + SPI1BUF = 0x180C; +_SPI1BUF = 0x180C; + SPI1BRG = 0x1810; +_SPI1BRG = 0x1810; +_SPI1BRGbits = 0x1810; + SPI1IMSK = 0x1814; +_SPI1IMSK = 0x1814; +_SPI1IMSKbits = 0x1814; + SPI1URDT = 0x1818; +_SPI1URDT = 0x1818; + SPI2CON1 = 0x1820; +_SPI2CON1 = 0x1820; +_SPI2CON1bits = 0x1820; + SPI2CON2 = 0x1824; +_SPI2CON2 = 0x1824; +_SPI2CON2bits = 0x1824; + SPI2STAT = 0x1828; +_SPI2STAT = 0x1828; +_SPI2STATbits = 0x1828; + SPI2BUF = 0x182C; +_SPI2BUF = 0x182C; + SPI2BRG = 0x1830; +_SPI2BRG = 0x1830; +_SPI2BRGbits = 0x1830; + SPI2IMSK = 0x1834; +_SPI2IMSK = 0x1834; +_SPI2IMSKbits = 0x1834; + SPI2URDT = 0x1838; +_SPI2URDT = 0x1838; + SPI3CON1 = 0x1840; +_SPI3CON1 = 0x1840; +_SPI3CON1bits = 0x1840; + SPI3CON2 = 0x1844; +_SPI3CON2 = 0x1844; +_SPI3CON2bits = 0x1844; + SPI3STAT = 0x1848; +_SPI3STAT = 0x1848; +_SPI3STATbits = 0x1848; + SPI3BUF = 0x184C; +_SPI3BUF = 0x184C; + SPI3BRG = 0x1850; +_SPI3BRG = 0x1850; +_SPI3BRGbits = 0x1850; + SPI3IMSK = 0x1854; +_SPI3IMSK = 0x1854; +_SPI3IMSKbits = 0x1854; + SPI3URDT = 0x1858; +_SPI3URDT = 0x1858; + I2C1CON1 = 0x1880; +_I2C1CON1 = 0x1880; +_I2C1CON1bits = 0x1880; + I2C1STAT1 = 0x1884; +_I2C1STAT1 = 0x1884; +_I2C1STAT1bits = 0x1884; + I2C1ADD = 0x1888; +_I2C1ADD = 0x1888; +_I2C1ADDbits = 0x1888; + I2C1MSK = 0x188C; +_I2C1MSK = 0x188C; +_I2C1MSKbits = 0x188C; + I2C1HBRG = 0x1890; +_I2C1HBRG = 0x1890; +_I2C1HBRGbits = 0x1890; + I2C1TRN = 0x1894; +_I2C1TRN = 0x1894; +_I2C1TRNbits = 0x1894; + I2C1RCV = 0x1898; +_I2C1RCV = 0x1898; +_I2C1RCVbits = 0x1898; + I2C1CON2 = 0x189C; +_I2C1CON2 = 0x189C; +_I2C1CON2bits = 0x189C; + I2C1LBRG = 0x18A0; +_I2C1LBRG = 0x18A0; +_I2C1LBRGbits = 0x18A0; + I2C1INTC = 0x18A4; +_I2C1INTC = 0x18A4; +_I2C1INTCbits = 0x18A4; + I2C1STAT2 = 0x18A8; +_I2C1STAT2 = 0x18A8; +_I2C1STAT2bits = 0x18A8; + I2C1PEC = 0x18AC; +_I2C1PEC = 0x18AC; +_I2C1PECbits = 0x18AC; + I2C1BTO = 0x18B0; +_I2C1BTO = 0x18B0; +_I2C1BTObits = 0x18B0; + I2C1HBCTO = 0x18B4; +_I2C1HBCTO = 0x18B4; +_I2C1HBCTObits = 0x18B4; + I2C1CBCTO = 0x18B8; +_I2C1CBCTO = 0x18B8; +_I2C1CBCTObits = 0x18B8; + I2C1BITO = 0x18BC; +_I2C1BITO = 0x18BC; +_I2C1BITObits = 0x18BC; + I2C1SDASUT = 0x18C0; +_I2C1SDASUT = 0x18C0; +_I2C1SDASUTbits = 0x18C0; + I2C2CON1 = 0x18D0; +_I2C2CON1 = 0x18D0; +_I2C2CON1bits = 0x18D0; + I2C2STAT1 = 0x18D4; +_I2C2STAT1 = 0x18D4; +_I2C2STAT1bits = 0x18D4; + I2C2ADD = 0x18D8; +_I2C2ADD = 0x18D8; +_I2C2ADDbits = 0x18D8; + I2C2MSK = 0x18DC; +_I2C2MSK = 0x18DC; +_I2C2MSKbits = 0x18DC; + I2C2HBRG = 0x18E0; +_I2C2HBRG = 0x18E0; +_I2C2HBRGbits = 0x18E0; + I2C2TRN = 0x18E4; +_I2C2TRN = 0x18E4; +_I2C2TRNbits = 0x18E4; + I2C2RCV = 0x18E8; +_I2C2RCV = 0x18E8; +_I2C2RCVbits = 0x18E8; + I2C2CON2 = 0x18EC; +_I2C2CON2 = 0x18EC; +_I2C2CON2bits = 0x18EC; + I2C2LBRG = 0x18F0; +_I2C2LBRG = 0x18F0; +_I2C2LBRGbits = 0x18F0; + I2C2INTC = 0x18F4; +_I2C2INTC = 0x18F4; +_I2C2INTCbits = 0x18F4; + I2C2STAT2 = 0x18F8; +_I2C2STAT2 = 0x18F8; +_I2C2STAT2bits = 0x18F8; + I2C2PEC = 0x18FC; +_I2C2PEC = 0x18FC; +_I2C2PECbits = 0x18FC; + I2C2BTO = 0x1900; +_I2C2BTO = 0x1900; +_I2C2BTObits = 0x1900; + I2C2HBCTO = 0x1904; +_I2C2HBCTO = 0x1904; +_I2C2HBCTObits = 0x1904; + I2C2CBCTO = 0x1908; +_I2C2CBCTO = 0x1908; +_I2C2CBCTObits = 0x1908; + I2C2BITO = 0x190C; +_I2C2BITO = 0x190C; +_I2C2BITObits = 0x190C; + I2C2SDASUT = 0x1910; +_I2C2SDASUT = 0x1910; +_I2C2SDASUTbits = 0x1910; + SENT1CON1 = 0x19C0; +_SENT1CON1 = 0x19C0; +_SENT1CON1bits = 0x19C0; + SENT1CON2 = 0x19C4; +_SENT1CON2 = 0x19C4; +_SENT1CON2bits = 0x19C4; + SENT1CON3 = 0x19C8; +_SENT1CON3 = 0x19C8; +_SENT1CON3bits = 0x19C8; + SENT1STAT = 0x19CC; +_SENT1STAT = 0x19CC; +_SENT1STATbits = 0x19CC; + SENT1SYNC = 0x19D0; +_SENT1SYNC = 0x19D0; +_SENT1SYNCbits = 0x19D0; + SENT1DAT = 0x19D4; +_SENT1DAT = 0x19D4; +_SENT1DATbits = 0x19D4; + SENT2CON1 = 0x19E0; +_SENT2CON1 = 0x19E0; +_SENT2CON1bits = 0x19E0; + SENT2CON2 = 0x19E4; +_SENT2CON2 = 0x19E4; +_SENT2CON2bits = 0x19E4; + SENT2CON3 = 0x19E8; +_SENT2CON3 = 0x19E8; +_SENT2CON3bits = 0x19E8; + SENT2STAT = 0x19EC; +_SENT2STAT = 0x19EC; +_SENT2STATbits = 0x19EC; + SENT2SYNC = 0x19F0; +_SENT2SYNC = 0x19F0; +_SENT2SYNCbits = 0x19F0; + SENT2DAT = 0x19F4; +_SENT2DAT = 0x19F4; +_SENT2DATbits = 0x19F4; + QEI1CON = 0x1A00; +_QEI1CON = 0x1A00; +_QEI1CONbits = 0x1A00; + QEI1IOC = 0x1A04; +_QEI1IOC = 0x1A04; +_QEI1IOCbits = 0x1A04; + QEI1STAT = 0x1A08; +_QEI1STAT = 0x1A08; +_QEI1STATbits = 0x1A08; + POS1CNT = 0x1A0C; +_POS1CNT = 0x1A0C; + POS1HLD = 0x1A10; +_POS1HLD = 0x1A10; + VEL1CNT = 0x1A14; +_VEL1CNT = 0x1A14; + VEL1HLD = 0x1A18; +_VEL1HLD = 0x1A18; + INT1TMR = 0x1A1C; +_INT1TMR = 0x1A1C; + INT1HLD = 0x1A20; +_INT1HLD = 0x1A20; + INDX1CNT = 0x1A24; +_INDX1CNT = 0x1A24; + INDX1HLD = 0x1A28; +_INDX1HLD = 0x1A28; + QEI1GEC = 0x1A2C; +_QEI1GEC = 0x1A2C; + QEI1LEC = 0x1A30; +_QEI1LEC = 0x1A30; + CCP1CON1 = 0x1B00; +_CCP1CON1 = 0x1B00; +_CCP1CON1bits = 0x1B00; + CCP1CON2 = 0x1B04; +_CCP1CON2 = 0x1B04; +_CCP1CON2bits = 0x1B04; + CCP1CON3 = 0x1B08; +_CCP1CON3 = 0x1B08; +_CCP1CON3bits = 0x1B08; + CCP1STAT = 0x1B0C; +_CCP1STAT = 0x1B0C; +_CCP1STATbits = 0x1B0C; + CCP1TMR = 0x1B10; +_CCP1TMR = 0x1B10; +_CCP1TMRbits = 0x1B10; + CCP1PR = 0x1B14; +_CCP1PR = 0x1B14; +_CCP1PRbits = 0x1B14; + CCP1RA = 0x1B18; +_CCP1RA = 0x1B18; +_CCP1RAbits = 0x1B18; + CCP1RB = 0x1B1C; +_CCP1RB = 0x1B1C; +_CCP1RBbits = 0x1B1C; + CCP1BUF = 0x1B20; +_CCP1BUF = 0x1B20; +_CCP1BUFbits = 0x1B20; + CCP2CON1 = 0x1B30; +_CCP2CON1 = 0x1B30; +_CCP2CON1bits = 0x1B30; + CCP2CON2 = 0x1B34; +_CCP2CON2 = 0x1B34; +_CCP2CON2bits = 0x1B34; + CCP2CON3 = 0x1B38; +_CCP2CON3 = 0x1B38; +_CCP2CON3bits = 0x1B38; + CCP2STAT = 0x1B3C; +_CCP2STAT = 0x1B3C; +_CCP2STATbits = 0x1B3C; + CCP2TMR = 0x1B40; +_CCP2TMR = 0x1B40; +_CCP2TMRbits = 0x1B40; + CCP2PR = 0x1B44; +_CCP2PR = 0x1B44; +_CCP2PRbits = 0x1B44; + CCP2RA = 0x1B48; +_CCP2RA = 0x1B48; +_CCP2RAbits = 0x1B48; + CCP2RB = 0x1B4C; +_CCP2RB = 0x1B4C; +_CCP2RBbits = 0x1B4C; + CCP2BUF = 0x1B50; +_CCP2BUF = 0x1B50; +_CCP2BUFbits = 0x1B50; + CCP3CON1 = 0x1B60; +_CCP3CON1 = 0x1B60; +_CCP3CON1bits = 0x1B60; + CCP3CON2 = 0x1B64; +_CCP3CON2 = 0x1B64; +_CCP3CON2bits = 0x1B64; + CCP3CON3 = 0x1B68; +_CCP3CON3 = 0x1B68; +_CCP3CON3bits = 0x1B68; + CCP3STAT = 0x1B6C; +_CCP3STAT = 0x1B6C; +_CCP3STATbits = 0x1B6C; + CCP3TMR = 0x1B70; +_CCP3TMR = 0x1B70; +_CCP3TMRbits = 0x1B70; + CCP3PR = 0x1B74; +_CCP3PR = 0x1B74; +_CCP3PRbits = 0x1B74; + CCP3RA = 0x1B78; +_CCP3RA = 0x1B78; +_CCP3RAbits = 0x1B78; + CCP3RB = 0x1B7C; +_CCP3RB = 0x1B7C; +_CCP3RBbits = 0x1B7C; + CCP3BUF = 0x1B80; +_CCP3BUF = 0x1B80; +_CCP3BUFbits = 0x1B80; + CCP4CON1 = 0x1B90; +_CCP4CON1 = 0x1B90; +_CCP4CON1bits = 0x1B90; + CCP4CON2 = 0x1B94; +_CCP4CON2 = 0x1B94; +_CCP4CON2bits = 0x1B94; + CCP4CON3 = 0x1B98; +_CCP4CON3 = 0x1B98; +_CCP4CON3bits = 0x1B98; + CCP4STAT = 0x1B9C; +_CCP4STAT = 0x1B9C; +_CCP4STATbits = 0x1B9C; + CCP4TMR = 0x1BA0; +_CCP4TMR = 0x1BA0; +_CCP4TMRbits = 0x1BA0; + CCP4PR = 0x1BA4; +_CCP4PR = 0x1BA4; +_CCP4PRbits = 0x1BA4; + CCP4RA = 0x1BA8; +_CCP4RA = 0x1BA8; +_CCP4RAbits = 0x1BA8; + CCP4RB = 0x1BAC; +_CCP4RB = 0x1BAC; +_CCP4RBbits = 0x1BAC; + CCP4BUF = 0x1BB0; +_CCP4BUF = 0x1BB0; +_CCP4BUFbits = 0x1BB0; + DACCTRL1 = 0x1D40; +_DACCTRL1 = 0x1D40; +_DACCTRL1bits = 0x1D40; + DACCTRL2 = 0x1D44; +_DACCTRL2 = 0x1D44; +_DACCTRL2bits = 0x1D44; + DAC1CON = 0x1D48; +_DAC1CON = 0x1D48; +_DAC1CONbits = 0x1D48; + DAC1DAT = 0x1D4C; +_DAC1DAT = 0x1D4C; +_DAC1DATbits = 0x1D4C; + DAC1SLPCON = 0x1D50; +_DAC1SLPCON = 0x1D50; +_DAC1SLPCONbits = 0x1D50; + DAC1SLPDAT = 0x1D54; +_DAC1SLPDAT = 0x1D54; +_DAC1SLPDATbits = 0x1D54; + DAC2CON = 0x1D58; +_DAC2CON = 0x1D58; +_DAC2CONbits = 0x1D58; + DAC2DAT = 0x1D5C; +_DAC2DAT = 0x1D5C; +_DAC2DATbits = 0x1D5C; + DAC2SLPCON = 0x1D60; +_DAC2SLPCON = 0x1D60; +_DAC2SLPCONbits = 0x1D60; + DAC2SLPDAT = 0x1D64; +_DAC2SLPDAT = 0x1D64; +_DAC2SLPDATbits = 0x1D64; + DAC3CON = 0x1D68; +_DAC3CON = 0x1D68; +_DAC3CONbits = 0x1D68; + DAC3DAT = 0x1D6C; +_DAC3DAT = 0x1D6C; +_DAC3DATbits = 0x1D6C; + DAC3SLPCON = 0x1D70; +_DAC3SLPCON = 0x1D70; +_DAC3SLPCONbits = 0x1D70; + DAC3SLPDAT = 0x1D74; +_DAC3SLPDAT = 0x1D74; +_DAC3SLPDATbits = 0x1D74; + T1CON = 0x1E00; +_T1CON = 0x1E00; +_T1CONbits = 0x1E00; + TMR1 = 0x1E04; +_TMR1 = 0x1E04; + PR1 = 0x1E08; +_PR1 = 0x1E08; + HPCCON = 0x1E10; +_HPCCON = 0x1E10; +_HPCCONbits = 0x1E10; + HPSEL0 = 0x1E14; +_HPSEL0 = 0x1E14; +_HPSEL0bits = 0x1E14; + HPSEL1 = 0x1E18; +_HPSEL1 = 0x1E18; +_HPSEL1bits = 0x1E18; + HPCCNTL0 = 0x1E20; +_HPCCNTL0 = 0x1E20; + HPCCNTH0 = 0x1E24; +_HPCCNTH0 = 0x1E24; + HPCCNTL1 = 0x1E28; +_HPCCNTL1 = 0x1E28; + HPCCNTH1 = 0x1E2C; +_HPCCNTH1 = 0x1E2C; + HPCCNTL2 = 0x1E30; +_HPCCNTL2 = 0x1E30; + HPCCNTH2 = 0x1E34; +_HPCCNTH2 = 0x1E34; + HPCCNTL3 = 0x1E38; +_HPCCNTL3 = 0x1E38; + HPCCNTH3 = 0x1E3C; +_HPCCNTH3 = 0x1E3C; + HPCCNTL4 = 0x1E40; +_HPCCNTL4 = 0x1E40; + HPCCNTH4 = 0x1E44; +_HPCCNTH4 = 0x1E44; + HPCCNTL5 = 0x1E48; +_HPCCNTL5 = 0x1E48; + HPCCNTH5 = 0x1E4C; +_HPCCNTH5 = 0x1E4C; + HPCCNTL6 = 0x1E50; +_HPCCNTL6 = 0x1E50; + HPCCNTH6 = 0x1E54; +_HPCCNTH6 = 0x1E54; + HPCCNTL7 = 0x1E58; +_HPCCNTL7 = 0x1E58; + HPCCNTH7 = 0x1E5C; +_HPCCNTH7 = 0x1E5C; + CHECON = 0x1E60; +_CHECON = 0x1E60; +_CHECONbits = 0x1E60; + CHESTAT = 0x1E64; +_CHESTAT = 0x1E64; +_CHESTATbits = 0x1E64; + CHEFLTINJ = 0x1E68; +_CHEFLTINJ = 0x1E68; +_CHEFLTINJbits = 0x1E68; + PACCON1 = 0x1E80; +_PACCON1 = 0x1E80; +_PACCON1bits = 0x1E80; + PACCON2 = 0x1E84; +_PACCON2 = 0x1E84; +_PACCON2bits = 0x1E84; + IOIM1CON = 0x1E90; +_IOIM1CON = 0x1E90; +_IOIM1CONbits = 0x1E90; + IOIM1BCON = 0x1E94; +_IOIM1BCON = 0x1E94; +_IOIM1BCONbits = 0x1E94; + IOIM1STAT = 0x1E98; +_IOIM1STAT = 0x1E98; +_IOIM1STATbits = 0x1E98; + IOIM2CON = 0x1E9C; +_IOIM2CON = 0x1E9C; +_IOIM2CONbits = 0x1E9C; + IOIM2BCON = 0x1EA0; +_IOIM2BCON = 0x1EA0; +_IOIM2BCONbits = 0x1EA0; + IOIM2STAT = 0x1EA4; +_IOIM2STAT = 0x1EA4; +_IOIM2STATbits = 0x1EA4; + IOIM3CON = 0x1EA8; +_IOIM3CON = 0x1EA8; +_IOIM3CONbits = 0x1EA8; + IOIM3BCON = 0x1EAC; +_IOIM3BCON = 0x1EAC; +_IOIM3BCONbits = 0x1EAC; + IOIM3STAT = 0x1EB0; +_IOIM3STAT = 0x1EB0; +_IOIM3STATbits = 0x1EB0; + IOIM4CON = 0x1EB4; +_IOIM4CON = 0x1EB4; +_IOIM4CONbits = 0x1EB4; + IOIM4BCON = 0x1EB8; +_IOIM4BCON = 0x1EB8; +_IOIM4BCONbits = 0x1EB8; + IOIM4STAT = 0x1EBC; +_IOIM4STAT = 0x1EBC; +_IOIM4STATbits = 0x1EBC; + B1SCDATA0L = 0x1F00; +_B1SCDATA0L = 0x1F00; + B1SCDATA0H = 0x1F04; +_B1SCDATA0H = 0x1F04; + B1SCDATA1L = 0x1F08; +_B1SCDATA1L = 0x1F08; + B1SCDATA1H = 0x1F0C; +_B1SCDATA1H = 0x1F0C; + B1SCDATA2L = 0x1F10; +_B1SCDATA2L = 0x1F10; + B1SCDATA2H = 0x1F14; +_B1SCDATA2H = 0x1F14; + B1SCDATA3L = 0x1F18; +_B1SCDATA3L = 0x1F18; + B1SCDATA3H = 0x1F1C; +_B1SCDATA3H = 0x1F1C; + B1IDS0 = 0x1F80; +_B1IDS0 = 0x1F80; +_B1IDS0bits = 0x1F80; + B1RDATA0 = 0x1F80; +_B1RDATA0 = 0x1F80; +_B1RDATA0bits = 0x1F80; + B1IDS1 = 0x1F84; +_B1IDS1 = 0x1F84; +_B1IDS1bits = 0x1F84; + B1RDATA1 = 0x1F84; +_B1RDATA1 = 0x1F84; +_B1RDATA1bits = 0x1F84; + B1IDS2 = 0x1F88; +_B1IDS2 = 0x1F88; +_B1IDS2bits = 0x1F88; + B1RDATA2 = 0x1F88; +_B1RDATA2 = 0x1F88; +_B1RDATA2bits = 0x1F88; + B1IDS3 = 0x1F8C; +_B1IDS3 = 0x1F8C; +_B1IDS3bits = 0x1F8C; + B1RDATA3 = 0x1F8C; +_B1RDATA3 = 0x1F8C; +_B1RDATA3bits = 0x1F8C; + B1IDS4 = 0x1F90; +_B1IDS4 = 0x1F90; +_B1IDS4bits = 0x1F90; + B1RDATA4 = 0x1F90; +_B1RDATA4 = 0x1F90; +_B1RDATA4bits = 0x1F90; + B1IDS5 = 0x1F94; +_B1IDS5 = 0x1F94; +_B1IDS5bits = 0x1F94; + B1RDATA5 = 0x1F94; +_B1RDATA5 = 0x1F94; +_B1RDATA5bits = 0x1F94; + B1IDS6 = 0x1F98; +_B1IDS6 = 0x1F98; +_B1IDS6bits = 0x1F98; + B1RDATA6 = 0x1F98; +_B1RDATA6 = 0x1F98; +_B1RDATA6bits = 0x1F98; + B1IDS7 = 0x1F9C; +_B1IDS7 = 0x1F9C; +_B1IDS7bits = 0x1F9C; + B1RDATA7 = 0x1F9C; +_B1RDATA7 = 0x1F9C; +_B1RDATA7bits = 0x1F9C; + B1CLTCON0 = 0x1FC0; +_B1CLTCON0 = 0x1FC0; +_B1CLTCON0bits = 0x1FC0; + B1CLTCON1 = 0x1FC4; +_B1CLTCON1 = 0x1FC4; +_B1CLTCON1bits = 0x1FC4; + B1CLTCON2 = 0x1FC8; +_B1CLTCON2 = 0x1FC8; +_B1CLTCON2bits = 0x1FC8; + B1CLTCON3 = 0x1FCC; +_B1CLTCON3 = 0x1FCC; +_B1CLTCON3bits = 0x1FCC; + B1RCCON = 0x1FE0; +_B1RCCON = 0x1FE0; +_B1RCCONbits = 0x1FE0; + B1CTRLCON = 0x1FE4; +_B1CTRLCON = 0x1FE4; +_B1CTRLCONbits = 0x1FE4; + B1CCON = 0x1FE8; +_B1CCON = 0x1FE8; +_B1CCONbits = 0x1FE8; + B1CHCON = 0x1FEC; +_B1CHCON = 0x1FEC; +_B1CHCONbits = 0x1FEC; + B1STAT = 0x1FF0; +_B1STAT = 0x1FF0; +_B1STATbits = 0x1FF0; + B1INSTR = 0x1FF4; +_B1INSTR = 0x1FF4; +_B1INSTRbits = 0x1FF4; + B1CHSTAT = 0x1FF8; +_B1CHSTAT = 0x1FF8; +_B1CHSTATbits = 0x1FF8; + B1CON = 0x1FFC; +_B1CON = 0x1FFC; +_B1CONbits = 0x1FFC; + DMACON = 0x2300; +_DMACON = 0x2300; +_DMACONbits = 0x2300; + DMABUF = 0x2304; +_DMABUF = 0x2304; + DMALOW = 0x2308; +_DMALOW = 0x2308; +_DMALOWbits = 0x2308; + DMAHIGH = 0x230C; +_DMAHIGH = 0x230C; +_DMAHIGHbits = 0x230C; + DMA0CH = 0x2310; +_DMA0CH = 0x2310; +_DMA0CHbits = 0x2310; + DMA0SEL = 0x2314; +_DMA0SEL = 0x2314; +_DMA0SELbits = 0x2314; + DMA0STAT = 0x2318; +_DMA0STAT = 0x2318; +_DMA0STATbits = 0x2318; + DMA0SRC = 0x231C; +_DMA0SRC = 0x231C; +_DMA0SRCbits = 0x231C; + DMA0DST = 0x2320; +_DMA0DST = 0x2320; +_DMA0DSTbits = 0x2320; + DMA0CNT = 0x2324; +_DMA0CNT = 0x2324; +_DMA0CNTbits = 0x2324; + DMA0CLR = 0x2328; +_DMA0CLR = 0x2328; + DMA0SET = 0x232C; +_DMA0SET = 0x232C; + DMA0INV = 0x2330; +_DMA0INV = 0x2330; + DMA0MSK = 0x2334; +_DMA0MSK = 0x2334; + DMA0PAT = 0x2338; +_DMA0PAT = 0x2338; + DMA1CH = 0x233C; +_DMA1CH = 0x233C; +_DMA1CHbits = 0x233C; + DMA1SEL = 0x2340; +_DMA1SEL = 0x2340; +_DMA1SELbits = 0x2340; + DMA1STAT = 0x2344; +_DMA1STAT = 0x2344; +_DMA1STATbits = 0x2344; + DMA1SRC = 0x2348; +_DMA1SRC = 0x2348; +_DMA1SRCbits = 0x2348; + DMA1DST = 0x234C; +_DMA1DST = 0x234C; +_DMA1DSTbits = 0x234C; + DMA1CNT = 0x2350; +_DMA1CNT = 0x2350; +_DMA1CNTbits = 0x2350; + DMA1CLR = 0x2354; +_DMA1CLR = 0x2354; + DMA1SET = 0x2358; +_DMA1SET = 0x2358; + DMA1INV = 0x235C; +_DMA1INV = 0x235C; + DMA1MSK = 0x2360; +_DMA1MSK = 0x2360; + DMA1PAT = 0x2364; +_DMA1PAT = 0x2364; + DMA2CH = 0x2368; +_DMA2CH = 0x2368; +_DMA2CHbits = 0x2368; + DMA2SEL = 0x236C; +_DMA2SEL = 0x236C; +_DMA2SELbits = 0x236C; + DMA2STAT = 0x2370; +_DMA2STAT = 0x2370; +_DMA2STATbits = 0x2370; + DMA2SRC = 0x2374; +_DMA2SRC = 0x2374; +_DMA2SRCbits = 0x2374; + DMA2DST = 0x2378; +_DMA2DST = 0x2378; +_DMA2DSTbits = 0x2378; + DMA2CNT = 0x237C; +_DMA2CNT = 0x237C; +_DMA2CNTbits = 0x237C; + DMA2CLR = 0x2380; +_DMA2CLR = 0x2380; + DMA2SET = 0x2384; +_DMA2SET = 0x2384; + DMA2INV = 0x2388; +_DMA2INV = 0x2388; + DMA2MSK = 0x238C; +_DMA2MSK = 0x238C; + DMA2PAT = 0x2390; +_DMA2PAT = 0x2390; + DMA3CH = 0x2394; +_DMA3CH = 0x2394; +_DMA3CHbits = 0x2394; + DMA3SEL = 0x2398; +_DMA3SEL = 0x2398; +_DMA3SELbits = 0x2398; + DMA3STAT = 0x239C; +_DMA3STAT = 0x239C; +_DMA3STATbits = 0x239C; + DMA3SRC = 0x23A0; +_DMA3SRC = 0x23A0; +_DMA3SRCbits = 0x23A0; + DMA3DST = 0x23A4; +_DMA3DST = 0x23A4; +_DMA3DSTbits = 0x23A4; + DMA3CNT = 0x23A8; +_DMA3CNT = 0x23A8; +_DMA3CNTbits = 0x23A8; + DMA3CLR = 0x23AC; +_DMA3CLR = 0x23AC; + DMA3SET = 0x23B0; +_DMA3SET = 0x23B0; + DMA3INV = 0x23B4; +_DMA3INV = 0x23B4; + DMA3MSK = 0x23B8; +_DMA3MSK = 0x23B8; + DMA3PAT = 0x23BC; +_DMA3PAT = 0x23BC; + DMA4CH = 0x23C0; +_DMA4CH = 0x23C0; +_DMA4CHbits = 0x23C0; + DMA4SEL = 0x23C4; +_DMA4SEL = 0x23C4; +_DMA4SELbits = 0x23C4; + DMA4STAT = 0x23C8; +_DMA4STAT = 0x23C8; +_DMA4STATbits = 0x23C8; + DMA4SRC = 0x23CC; +_DMA4SRC = 0x23CC; +_DMA4SRCbits = 0x23CC; + DMA4DST = 0x23D0; +_DMA4DST = 0x23D0; +_DMA4DSTbits = 0x23D0; + DMA4CNT = 0x23D4; +_DMA4CNT = 0x23D4; +_DMA4CNTbits = 0x23D4; + DMA4CLR = 0x23D8; +_DMA4CLR = 0x23D8; + DMA4SET = 0x23DC; +_DMA4SET = 0x23DC; + DMA4INV = 0x23E0; +_DMA4INV = 0x23E0; + DMA4MSK = 0x23E4; +_DMA4MSK = 0x23E4; + DMA4PAT = 0x23E8; +_DMA4PAT = 0x23E8; + DMA5CH = 0x23EC; +_DMA5CH = 0x23EC; +_DMA5CHbits = 0x23EC; + DMA5SEL = 0x23F0; +_DMA5SEL = 0x23F0; +_DMA5SELbits = 0x23F0; + DMA5STAT = 0x23F4; +_DMA5STAT = 0x23F4; +_DMA5STATbits = 0x23F4; + DMA5SRC = 0x23F8; +_DMA5SRC = 0x23F8; +_DMA5SRCbits = 0x23F8; + DMA5DST = 0x23FC; +_DMA5DST = 0x23FC; +_DMA5DSTbits = 0x23FC; + DMA5CNT = 0x2400; +_DMA5CNT = 0x2400; +_DMA5CNTbits = 0x2400; + DMA5CLR = 0x2404; +_DMA5CLR = 0x2404; + DMA5SET = 0x2408; +_DMA5SET = 0x2408; + DMA5INV = 0x240C; +_DMA5INV = 0x240C; + DMA5MSK = 0x2410; +_DMA5MSK = 0x2410; + DMA5PAT = 0x2414; +_DMA5PAT = 0x2414; + NVMCON = 0x3000; +_NVMCON = 0x3000; +_NVMCONbits = 0x3000; + NVMADR = 0x3004; +_NVMADR = 0x3004; +_NVMADRbits = 0x3004; + NVMDATA0 = 0x3008; +_NVMDATA0 = 0x3008; + NVMDATA1 = 0x300C; +_NVMDATA1 = 0x300C; + NVMDATA2 = 0x3010; +_NVMDATA2 = 0x3010; + NVMDATA3 = 0x3014; +_NVMDATA3 = 0x3014; + NVMSRCADR = 0x3018; +_NVMSRCADR = 0x3018; +_NVMSRCADRbits = 0x3018; + NVMECCCON = 0x301C; +_NVMECCCON = 0x301C; +_NVMECCCONbits = 0x301C; + NVMECCSTAT = 0x3020; +_NVMECCSTAT = 0x3020; +_NVMECCSTATbits = 0x3020; + NVMECCFPTR = 0x3024; +_NVMECCFPTR = 0x3024; +_NVMECCFPTRbits = 0x3024; + NVMECCFADDR = 0x3028; +_NVMECCFADDR = 0x3028; +_NVMECCFADDRbits = 0x3028; + NVMECCEADDR = 0x302C; +_NVMECCEADDR = 0x302C; +_NVMECCEADDRbits = 0x302C; + NVMECCEDATA0 = 0x3030; +_NVMECCEDATA0 = 0x3030; + NVMECCEDATA1 = 0x3034; +_NVMECCEDATA1 = 0x3034; + NVMECCEDATA2 = 0x3038; +_NVMECCEDATA2 = 0x3038; + NVMECCEDATA3 = 0x303C; +_NVMECCEDATA3 = 0x303C; + NVMECCVAL = 0x3040; +_NVMECCVAL = 0x3040; +_NVMECCVALbits = 0x3040; + NVMECCSYND = 0x3044; +_NVMECCSYND = 0x3044; +_NVMECCSYNDbits = 0x3044; + NVMCRCCON = 0x3048; +_NVMCRCCON = 0x3048; +_NVMCRCCONbits = 0x3048; + NVMCRCST = 0x304C; +_NVMCRCST = 0x304C; +_NVMCRCSTbits = 0x304C; + NVMCRCEND = 0x3050; +_NVMCRCEND = 0x3050; +_NVMCRCENDbits = 0x3050; + NVMCRCSEED = 0x3054; +_NVMCRCSEED = 0x3054; + NVMCRCDATA = 0x3058; +_NVMCRCDATA = 0x3058; + OSCCTRL = 0x3100; +_OSCCTRL = 0x3100; +_OSCCTRLbits = 0x3100; + OSCCFG = 0x3104; +_OSCCFG = 0x3104; +_OSCCFGbits = 0x3104; + CLKFAIL = 0x3108; +_CLKFAIL = 0x3108; +_CLKFAILbits = 0x3108; + SCSFAIL = 0x310C; +_SCSFAIL = 0x310C; +_SCSFAILbits = 0x310C; + CLK1CON = 0x3118; +_CLK1CON = 0x3118; +_CLK1CONbits = 0x3118; + CLK1DIV = 0x311C; +_CLK1DIV = 0x311C; +_CLK1DIVbits = 0x311C; + CLK2CON = 0x3120; +_CLK2CON = 0x3120; +_CLK2CONbits = 0x3120; + CLK2DIV = 0x3124; +_CLK2DIV = 0x3124; +_CLK2DIVbits = 0x3124; + CLK3CON = 0x3128; +_CLK3CON = 0x3128; +_CLK3CONbits = 0x3128; + CLK3DIV = 0x312C; +_CLK3DIV = 0x312C; +_CLK3DIVbits = 0x312C; + CLK4CON = 0x3130; +_CLK4CON = 0x3130; +_CLK4CONbits = 0x3130; + CLK4DIV = 0x3134; +_CLK4DIV = 0x3134; +_CLK4DIVbits = 0x3134; + CLK5CON = 0x3138; +_CLK5CON = 0x3138; +_CLK5CONbits = 0x3138; + CLK5DIV = 0x313C; +_CLK5DIV = 0x313C; +_CLK5DIVbits = 0x313C; + CLK6CON = 0x3140; +_CLK6CON = 0x3140; +_CLK6CONbits = 0x3140; + CLK6DIV = 0x3144; +_CLK6DIV = 0x3144; +_CLK6DIVbits = 0x3144; + CLK7CON = 0x3148; +_CLK7CON = 0x3148; +_CLK7CONbits = 0x3148; + CLK7DIV = 0x314C; +_CLK7DIV = 0x314C; +_CLK7DIVbits = 0x314C; + CLK8CON = 0x3150; +_CLK8CON = 0x3150; +_CLK8CONbits = 0x3150; + CLK8DIV = 0x3154; +_CLK8DIV = 0x3154; +_CLK8DIVbits = 0x3154; + CLK9CON = 0x3158; +_CLK9CON = 0x3158; +_CLK9CONbits = 0x3158; + CLK9DIV = 0x315C; +_CLK9DIV = 0x315C; +_CLK9DIVbits = 0x315C; + CLK10CON = 0x3160; +_CLK10CON = 0x3160; +_CLK10CONbits = 0x3160; + CLK10DIV = 0x3164; +_CLK10DIV = 0x3164; +_CLK10DIVbits = 0x3164; + CLK11CON = 0x3168; +_CLK11CON = 0x3168; +_CLK11CONbits = 0x3168; + CLK11DIV = 0x316C; +_CLK11DIV = 0x316C; +_CLK11DIVbits = 0x316C; + CLK12CON = 0x3170; +_CLK12CON = 0x3170; +_CLK12CONbits = 0x3170; + CLK12DIV = 0x3174; +_CLK12DIV = 0x3174; +_CLK12DIVbits = 0x3174; + CLK13CON = 0x3178; +_CLK13CON = 0x3178; +_CLK13CONbits = 0x3178; + CLK13DIV = 0x317C; +_CLK13DIV = 0x317C; +_CLK13DIVbits = 0x317C; + PLL1CON = 0x3180; +_PLL1CON = 0x3180; +_PLL1CONbits = 0x3180; + PLL1DIV = 0x3184; +_PLL1DIV = 0x3184; +_PLL1DIVbits = 0x3184; + VCO1DIV = 0x3188; +_VCO1DIV = 0x3188; +_VCO1DIVbits = 0x3188; + PLL2CON = 0x318C; +_PLL2CON = 0x318C; +_PLL2CONbits = 0x318C; + PLL2DIV = 0x3190; +_PLL2DIV = 0x3190; +_PLL2DIVbits = 0x3190; + VCO2DIV = 0x3194; +_VCO2DIV = 0x3194; +_VCO2DIVbits = 0x3194; + RCON = 0x3198; +_RCON = 0x3198; +_RCONbits = 0x3198; + CLKDIAG = 0x319C; +_CLKDIAG = 0x319C; +_CLKDIAGbits = 0x319C; + CM1CON = 0x3200; +_CM1CON = 0x3200; +_CM1CONbits = 0x3200; + CM1STAT = 0x3204; +_CM1STAT = 0x3204; +_CM1STATbits = 0x3204; + CM1WINPR = 0x3208; +_CM1WINPR = 0x3208; + CM1SEL = 0x320C; +_CM1SEL = 0x320C; +_CM1SELbits = 0x320C; + CM1BUF = 0x3210; +_CM1BUF = 0x3210; + CM1SAT = 0x3214; +_CM1SAT = 0x3214; + CM1HFAIL = 0x3218; +_CM1HFAIL = 0x3218; + CM1LFAIL = 0x321C; +_CM1LFAIL = 0x321C; + CM1HWARN = 0x3220; +_CM1HWARN = 0x3220; + CM1LWARN = 0x3224; +_CM1LWARN = 0x3224; + CM2CON = 0x3230; +_CM2CON = 0x3230; +_CM2CONbits = 0x3230; + CM2STAT = 0x3234; +_CM2STAT = 0x3234; +_CM2STATbits = 0x3234; + CM2WINPR = 0x3238; +_CM2WINPR = 0x3238; + CM2SEL = 0x323C; +_CM2SEL = 0x323C; +_CM2SELbits = 0x323C; + CM2BUF = 0x3240; +_CM2BUF = 0x3240; + CM2SAT = 0x3244; +_CM2SAT = 0x3244; + CM2HFAIL = 0x3248; +_CM2HFAIL = 0x3248; + CM2LFAIL = 0x324C; +_CM2LFAIL = 0x324C; + CM2HWARN = 0x3250; +_CM2HWARN = 0x3250; + CM2LWARN = 0x3254; +_CM2LWARN = 0x3254; + CM3CON = 0x3260; +_CM3CON = 0x3260; +_CM3CONbits = 0x3260; + CM3STAT = 0x3264; +_CM3STAT = 0x3264; +_CM3STATbits = 0x3264; + CM3WINPR = 0x3268; +_CM3WINPR = 0x3268; + CM3SEL = 0x326C; +_CM3SEL = 0x326C; +_CM3SELbits = 0x326C; + CM3BUF = 0x3270; +_CM3BUF = 0x3270; + CM3SAT = 0x3274; +_CM3SAT = 0x3274; + CM3HFAIL = 0x3278; +_CM3HFAIL = 0x3278; + CM3LFAIL = 0x327C; +_CM3LFAIL = 0x327C; + CM3HWARN = 0x3280; +_CM3HWARN = 0x3280; + CM3LWARN = 0x3284; +_CM3LWARN = 0x3284; + CM4CON = 0x3290; +_CM4CON = 0x3290; +_CM4CONbits = 0x3290; + CM4STAT = 0x3294; +_CM4STAT = 0x3294; +_CM4STATbits = 0x3294; + CM4WINPR = 0x3298; +_CM4WINPR = 0x3298; + CM4SEL = 0x329C; +_CM4SEL = 0x329C; +_CM4SELbits = 0x329C; + CM4BUF = 0x32A0; +_CM4BUF = 0x32A0; + CM4SAT = 0x32A4; +_CM4SAT = 0x32A4; + CM4HFAIL = 0x32A8; +_CM4HFAIL = 0x32A8; + CM4LFAIL = 0x32AC; +_CM4LFAIL = 0x32AC; + CM4HWARN = 0x32B0; +_CM4HWARN = 0x32B0; + CM4LWARN = 0x32B4; +_CM4LWARN = 0x32B4; + FRCTUN = 0x32C0; +_FRCTUN = 0x32C0; +_FRCTUNbits = 0x32C0; + BFRCTUN = 0x32C4; +_BFRCTUN = 0x32C4; +_BFRCTUNbits = 0x32C4; + WDTCON = 0x32C8; +_WDTCON = 0x32C8; +_WDTCONbits = 0x32C8; + PTGCON = 0x3500; +_PTGCON = 0x3500; +_PTGCONbits = 0x3500; + PTGBTE = 0x3504; +_PTGBTE = 0x3504; + PTGHOLD = 0x3508; +_PTGHOLD = 0x3508; +_PTGHOLDbits = 0x3508; + PTGT0LIM = 0x350C; +_PTGT0LIM = 0x350C; +_PTGT0LIMbits = 0x350C; + PTGT1LIM = 0x3510; +_PTGT1LIM = 0x3510; +_PTGT1LIMbits = 0x3510; + PTGSDLIM = 0x3514; +_PTGSDLIM = 0x3514; +_PTGSDLIMbits = 0x3514; + PTGC0LIM = 0x3518; +_PTGC0LIM = 0x3518; +_PTGC0LIMbits = 0x3518; + PTGC1LIM = 0x351C; +_PTGC1LIM = 0x351C; +_PTGC1LIMbits = 0x351C; + PTGADJ = 0x3520; +_PTGADJ = 0x3520; +_PTGADJbits = 0x3520; + PTGL0 = 0x3524; +_PTGL0 = 0x3524; +_PTGL0bits = 0x3524; + PTGQPTR = 0x3528; +_PTGQPTR = 0x3528; +_PTGQPTRbits = 0x3528; + PTGQUE0 = 0x3530; +_PTGQUE0 = 0x3530; +_PTGQUE0bits = 0x3530; + PTGQUE1 = 0x3534; +_PTGQUE1 = 0x3534; +_PTGQUE1bits = 0x3534; + PTGQUE2 = 0x3538; +_PTGQUE2 = 0x3538; +_PTGQUE2bits = 0x3538; + PTGQUE3 = 0x353C; +_PTGQUE3 = 0x353C; +_PTGQUE3bits = 0x353C; + PTGQUE4 = 0x3540; +_PTGQUE4 = 0x3540; +_PTGQUE4bits = 0x3540; + PTGQUE5 = 0x3544; +_PTGQUE5 = 0x3544; +_PTGQUE5bits = 0x3544; + PTGQUE6 = 0x3548; +_PTGQUE6 = 0x3548; +_PTGQUE6bits = 0x3548; + PTGQUE7 = 0x354C; +_PTGQUE7 = 0x354C; +_PTGQUE7bits = 0x354C; + RAMXECCCON = 0x3580; +_RAMXECCCON = 0x3580; +_RAMXECCCONbits = 0x3580; + RAMXECCSTAT = 0x3584; +_RAMXECCSTAT = 0x3584; +_RAMXECCSTATbits = 0x3584; + RAMXECCFPTR = 0x3588; +_RAMXECCFPTR = 0x3588; +_RAMXECCFPTRbits = 0x3588; + RAMXECCFADDR = 0x358C; +_RAMXECCFADDR = 0x358C; + RAMXECCEADDR = 0x3590; +_RAMXECCEADDR = 0x3590; + RAMXECCEDATA = 0x3594; +_RAMXECCEDATA = 0x3594; + RAMXECCVAL = 0x3598; +_RAMXECCVAL = 0x3598; +_RAMXECCVALbits = 0x3598; + RAMXECCSYND = 0x359C; +_RAMXECCSYND = 0x359C; +_RAMXECCSYNDbits = 0x359C; + PWBXECCCON = 0x35A0; +_PWBXECCCON = 0x35A0; +_PWBXECCCONbits = 0x35A0; + PWBXECCSTAT = 0x35A4; +_PWBXECCSTAT = 0x35A4; +_PWBXECCSTATbits = 0x35A4; + PWBXECCFPTR = 0x35A8; +_PWBXECCFPTR = 0x35A8; +_PWBXECCFPTRbits = 0x35A8; + PWBXECCFADDR = 0x35AC; +_PWBXECCFADDR = 0x35AC; + PWBXECCEADDR = 0x35B0; +_PWBXECCEADDR = 0x35B0; + PWBXECCEDATA = 0x35B4; +_PWBXECCEDATA = 0x35B4; + PWBXECCVAL = 0x35B8; +_PWBXECCVAL = 0x35B8; +_PWBXECCVALbits = 0x35B8; + PWBXECCSYND = 0x35BC; +_PWBXECCSYND = 0x35BC; +_PWBXECCSYNDbits = 0x35BC; + RAMYECCCON = 0x35C0; +_RAMYECCCON = 0x35C0; +_RAMYECCCONbits = 0x35C0; + RAMYECCSTAT = 0x35C4; +_RAMYECCSTAT = 0x35C4; +_RAMYECCSTATbits = 0x35C4; + RAMYECCFPTR = 0x35C8; +_RAMYECCFPTR = 0x35C8; +_RAMYECCFPTRbits = 0x35C8; + RAMYECCFADDR = 0x35CC; +_RAMYECCFADDR = 0x35CC; + RAMYECCEADDR = 0x35D0; +_RAMYECCEADDR = 0x35D0; + RAMYECCEDATA = 0x35D4; +_RAMYECCEDATA = 0x35D4; + RAMYECCVAL = 0x35D8; +_RAMYECCVAL = 0x35D8; +_RAMYECCVALbits = 0x35D8; + RAMYECCSYND = 0x35DC; +_RAMYECCSYND = 0x35DC; +_RAMYECCSYNDbits = 0x35DC; + PWBYECCCON = 0x35E0; +_PWBYECCCON = 0x35E0; +_PWBYECCCONbits = 0x35E0; + PWBYECCSTAT = 0x35E4; +_PWBYECCSTAT = 0x35E4; +_PWBYECCSTATbits = 0x35E4; + PWBYECCFPTR = 0x35E8; +_PWBYECCFPTR = 0x35E8; +_PWBYECCFPTRbits = 0x35E8; + PWBYECCFADDR = 0x35EC; +_PWBYECCFADDR = 0x35EC; + PWBYECCEADDR = 0x35F0; +_PWBYECCEADDR = 0x35F0; + PWBYECCEDATA = 0x35F4; +_PWBYECCEDATA = 0x35F4; + PWBYECCVAL = 0x35F8; +_PWBYECCVAL = 0x35F8; +_PWBYECCVALbits = 0x35F8; + PWBYECCSYND = 0x35FC; +_PWBYECCSYND = 0x35FC; +_PWBYECCSYNDbits = 0x35FC; + ANSELA = 0x3640; +_ANSELA = 0x3640; +_ANSELAbits = 0x3640; + ODCA = 0x3644; +_ODCA = 0x3644; +_ODCAbits = 0x3644; + CNPUA = 0x3648; +_CNPUA = 0x3648; +_CNPUAbits = 0x3648; + CNPDA = 0x364C; +_CNPDA = 0x364C; +_CNPDAbits = 0x364C; + CNCONA = 0x3650; +_CNCONA = 0x3650; +_CNCONAbits = 0x3650; + CNEN0A = 0x3654; +_CNEN0A = 0x3654; +_CNEN0Abits = 0x3654; + CNEN1A = 0x3658; +_CNEN1A = 0x3658; +_CNEN1Abits = 0x3658; + ANSELB = 0x3664; +_ANSELB = 0x3664; +_ANSELBbits = 0x3664; + ODCB = 0x3668; +_ODCB = 0x3668; +_ODCBbits = 0x3668; + CNPUB = 0x366C; +_CNPUB = 0x366C; +_CNPUBbits = 0x366C; + CNPDB = 0x3670; +_CNPDB = 0x3670; +_CNPDBbits = 0x3670; + CNCONB = 0x3674; +_CNCONB = 0x3674; +_CNCONBbits = 0x3674; + CNEN0B = 0x3678; +_CNEN0B = 0x3678; +_CNEN0Bbits = 0x3678; + CNEN1B = 0x367C; +_CNEN1B = 0x367C; +_CNEN1Bbits = 0x367C; + ANSELC = 0x3688; +_ANSELC = 0x3688; + ODCC = 0x368C; +_ODCC = 0x368C; +_ODCCbits = 0x368C; + CNPUC = 0x3690; +_CNPUC = 0x3690; +_CNPUCbits = 0x3690; + CNPDC = 0x3694; +_CNPDC = 0x3694; +_CNPDCbits = 0x3694; + CNCONC = 0x3698; +_CNCONC = 0x3698; +_CNCONCbits = 0x3698; + CNEN0C = 0x369C; +_CNEN0C = 0x369C; +_CNEN0Cbits = 0x369C; + CNEN1C = 0x36A0; +_CNEN1C = 0x36A0; +_CNEN1Cbits = 0x36A0; + ANSELD = 0x36AC; +_ANSELD = 0x36AC; + ODCD = 0x36B0; +_ODCD = 0x36B0; +_ODCDbits = 0x36B0; + CNPUD = 0x36B4; +_CNPUD = 0x36B4; +_CNPUDbits = 0x36B4; + CNPDD = 0x36B8; +_CNPDD = 0x36B8; +_CNPDDbits = 0x36B8; + CNCOND = 0x36BC; +_CNCOND = 0x36BC; +_CNCONDbits = 0x36BC; + CNEN0D = 0x36C0; +_CNEN0D = 0x36C0; +_CNEN0Dbits = 0x36C0; + CNEN1D = 0x36C4; +_CNEN1D = 0x36C4; +_CNEN1Dbits = 0x36C4; + RPCON = 0x3900; +_RPCON = 0x3900; +_RPCONbits = 0x3900; + RPINR0 = 0x3904; +_RPINR0 = 0x3904; +_RPINR0bits = 0x3904; + RPINR1 = 0x3908; +_RPINR1 = 0x3908; +_RPINR1bits = 0x3908; + RPINR2 = 0x390C; +_RPINR2 = 0x390C; +_RPINR2bits = 0x390C; + RPINR5 = 0x3918; +_RPINR5 = 0x3918; +_RPINR5bits = 0x3918; + RPINR6 = 0x391C; +_RPINR6 = 0x391C; +_RPINR6bits = 0x391C; + RPINR7 = 0x3920; +_RPINR7 = 0x3920; +_RPINR7bits = 0x3920; + RPINR9 = 0x3928; +_RPINR9 = 0x3928; +_RPINR9bits = 0x3928; + RPINR10 = 0x392C; +_RPINR10 = 0x392C; +_RPINR10bits = 0x392C; + RPINR11 = 0x3930; +_RPINR11 = 0x3930; +_RPINR11bits = 0x3930; + RPINR13 = 0x3938; +_RPINR13 = 0x3938; +_RPINR13bits = 0x3938; + RPINR14 = 0x393C; +_RPINR14 = 0x393C; +_RPINR14bits = 0x393C; + RPINR15 = 0x3940; +_RPINR15 = 0x3940; +_RPINR15bits = 0x3940; + RPINR17 = 0x3948; +_RPINR17 = 0x3948; +_RPINR17bits = 0x3948; + RPINR18 = 0x394C; +_RPINR18 = 0x394C; +_RPINR18bits = 0x394C; + RPINR19 = 0x3950; +_RPINR19 = 0x3950; +_RPINR19bits = 0x3950; + RPINR20 = 0x3954; +_RPINR20 = 0x3954; +_RPINR20bits = 0x3954; + RPINR21 = 0x3958; +_RPINR21 = 0x3958; +_RPINR21bits = 0x3958; + RPOR0 = 0x3980; +_RPOR0 = 0x3980; +_RPOR0bits = 0x3980; + RPOR1 = 0x3984; +_RPOR1 = 0x3984; +_RPOR1bits = 0x3984; + RPOR2 = 0x3988; +_RPOR2 = 0x3988; +_RPOR2bits = 0x3988; + RPOR4 = 0x3990; +_RPOR4 = 0x3990; +_RPOR4bits = 0x3990; + RPOR5 = 0x3994; +_RPOR5 = 0x3994; +_RPOR5bits = 0x3994; + RPOR6 = 0x3998; +_RPOR6 = 0x3998; +_RPOR6bits = 0x3998; + RPOR8 = 0x39A0; +_RPOR8 = 0x39A0; +_RPOR8bits = 0x39A0; + RPOR9 = 0x39A4; +_RPOR9 = 0x39A4; +_RPOR9bits = 0x39A4; + RPOR10 = 0x39A8; +_RPOR10 = 0x39A8; +_RPOR10bits = 0x39A8; + RPOR12 = 0x39B0; +_RPOR12 = 0x39B0; +_RPOR12bits = 0x39B0; + RPOR13 = 0x39B4; +_RPOR13 = 0x39B4; +_RPOR13bits = 0x39B4; + RPOR14 = 0x39B8; +_RPOR14 = 0x39B8; +_RPOR14bits = 0x39B8; + RPOR15 = 0x39BC; +_RPOR15 = 0x39BC; +_RPOR15bits = 0x39BC; + RPOR16 = 0x39C0; +_RPOR16 = 0x39C0; +_RPOR16bits = 0x39C0; + RPOR17 = 0x39C4; +_RPOR17 = 0x39C4; +_RPOR17bits = 0x39C4; + RPOR18 = 0x39C8; +_RPOR18 = 0x39C8; +_RPOR18bits = 0x39C8; + RPOR19 = 0x39CC; +_RPOR19 = 0x39CC; +_RPOR19bits = 0x39CC; + DMTCON = 0x3A00; +_DMTCON = 0x3A00; +_DMTCONbits = 0x3A00; + DMTPRECLR = 0x3A04; +_DMTPRECLR = 0x3A04; +_DMTPRECLRbits = 0x3A04; + DMTCLR = 0x3A08; +_DMTCLR = 0x3A08; +_DMTCLRbits = 0x3A08; + DMTSTAT = 0x3A0C; +_DMTSTAT = 0x3A0C; +_DMTSTATbits = 0x3A0C; + DMTCNT = 0x3A10; +_DMTCNT = 0x3A10; + PSCNT = 0x3A14; +_PSCNT = 0x3A14; + PSINTV = 0x3A18; +_PSINTV = 0x3A18; + PPPC = 0x3A1C; +_PPPC = 0x3A1C; +_PPPCbits = 0x3A1C; + PPC = 0x3A20; +_PPC = 0x3A20; +_PPCbits = 0x3A20; + PMD1 = 0x3A44; +_PMD1 = 0x3A44; +_PMD1bits = 0x3A44; + PMD2 = 0x3A48; +_PMD2 = 0x3A48; +_PMD2bits = 0x3A48; + PMD3 = 0x3A4C; +_PMD3 = 0x3A4C; +_PMD3bits = 0x3A4C; + PMD4 = 0x3A50; +_PMD4 = 0x3A50; +_PMD4bits = 0x3A50; + CLC1CON = 0x3A60; +_CLC1CON = 0x3A60; +_CLC1CONbits = 0x3A60; + CLC1SEL = 0x3A64; +_CLC1SEL = 0x3A64; +_CLC1SELbits = 0x3A64; + CLC1GLS = 0x3A68; +_CLC1GLS = 0x3A68; +_CLC1GLSbits = 0x3A68; + CLC2CON = 0x3A70; +_CLC2CON = 0x3A70; +_CLC2CONbits = 0x3A70; + CLC2SEL = 0x3A74; +_CLC2SEL = 0x3A74; +_CLC2SELbits = 0x3A74; + CLC2GLS = 0x3A78; +_CLC2GLS = 0x3A78; +_CLC2GLSbits = 0x3A78; + CLC3CON = 0x3A80; +_CLC3CON = 0x3A80; +_CLC3CONbits = 0x3A80; + CLC3SEL = 0x3A84; +_CLC3SEL = 0x3A84; +_CLC3SELbits = 0x3A84; + CLC3GLS = 0x3A88; +_CLC3GLS = 0x3A88; +_CLC3GLSbits = 0x3A88; + CLC4CON = 0x3A90; +_CLC4CON = 0x3A90; +_CLC4CONbits = 0x3A90; + CLC4SEL = 0x3A94; +_CLC4SEL = 0x3A94; +_CLC4SELbits = 0x3A94; + CLC4GLS = 0x3A98; +_CLC4GLS = 0x3A98; +_CLC4GLSbits = 0x3A98; + MBISTCON = 0x3AA0; +_MBISTCON = 0x3AA0; +_MBISTCONbits = 0x3AA0; + IBIASCON = 0x3AA4; +_IBIASCON = 0x3AA4; +_IBIASCONbits = 0x3AA4; + AMP1CON1 = 0x3AB0; +_AMP1CON1 = 0x3AB0; +_AMP1CON1bits = 0x3AB0; + AMP1CON2 = 0x3AB4; +_AMP1CON2 = 0x3AB4; +_AMP1CON2bits = 0x3AB4; + AMP2CON1 = 0x3AB8; +_AMP2CON1 = 0x3AB8; +_AMP2CON1bits = 0x3AB8; + AMP2CON2 = 0x3ABC; +_AMP2CON2 = 0x3ABC; +_AMP2CON2bits = 0x3ABC; + AMP3CON1 = 0x3AC0; +_AMP3CON1 = 0x3AC0; +_AMP3CON1bits = 0x3AC0; + AMP3CON2 = 0x3AC4; +_AMP3CON2 = 0x3AC4; +_AMP3CON2bits = 0x3AC4; +/* +** ======= Base Addresses for Various Peripherals and ACC ====== +*/ + + SPI1 = 0x1808; +_SPI1 = 0x1808; + SPI2 = 0x1828; +_SPI2 = 0x1828; + SPI3 = 0x1848; +_SPI3 = 0x1848; diff --git a/include/zephyr/arch/dspic/thread.h b/include/zephyr/arch/dspic/thread.h new file mode 100644 index 0000000000000..a70b79be3d14a --- /dev/null +++ b/include/zephyr/arch/dspic/thread.h @@ -0,0 +1,102 @@ +/** + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Per-arch thread definition + * + * This file contains definitions for + * + * struct _thread_arch + * struct _callee_saved + * + * necessary to instantiate instances of struct k_thread. + */ + +#ifndef ZEPHYR_INCLUDE_ARCH_DSPIC_THREAD_H_ +#define ZEPHYR_INCLUDE_ARCH_DSPIC_THREAD_H_ + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * The following structure defines the list of registers that need to be + * saved/restored when a cooperative context switch occurs. + */ +struct _callee_saved { + uint32_t W8; /* working register w8 */ + uint32_t W9; /* working register w9 */ + uint32_t W10; /* working register w10 */ + uint32_t W11; /* working register w11 */ + uint32_t W12; /* working register w12 */ + uint32_t W13; /* working register w13 */ + uint32_t W14; /* working register w14 */ + + uint32_t F8; /* Floating point register F8 */ + uint32_t F9; /* Floating point register F8 */ + uint32_t F10; /* Floating point register F8 */ + uint32_t F11; /* Floating point register F8 */ + uint32_t F12; /* Floating point register F8 */ + uint32_t F13; /* Floating point register F8 */ + uint32_t F14; /* Floating point register F8 */ + uint32_t F15; /* Floating point register F8 */ + uint32_t F16; /* Floating point register F8 */ + uint32_t F17; /* Floating point register F8 */ + uint32_t F18; /* Floating point register F8 */ + uint32_t F19; /* Floating point register F8 */ + uint32_t F20; /* Floating point register F8 */ + uint32_t F21; /* Floating point register F8 */ + uint32_t F22; /* Floating point register F8 */ + uint32_t F23; /* Floating point register F8 */ + uint32_t F24; /* Floating point register F8 */ + uint32_t F25; /* Floating point register F8 */ + uint32_t F26; /* Floating point register F8 */ + uint32_t F27; /* Floating point register F8 */ + uint32_t F28; /* Floating point register F8 */ + uint32_t F29; /* Floating point register F8 */ + uint32_t F30; /* Floating point register F8 */ + uint32_t F31; /* Floating point register F8 */ + + uint32_t Rcount; /* repeat loop counter register */ + uint32_t Corcon; /* core mode control register */ + uint32_t modcon; /* Modulo addressing control register */ + uint32_t xmodsrt; /* X AGU modulo addressing start register */ + uint32_t xmodend; /* X AGU modulo addressing end register */ + uint32_t ymodsrt; /* Y AGU modulo addressing start register */ + uint32_t ymodend; /* Y AGU modulo addressing end register */ + uint32_t Xbrev; /*X AGU reversal addressing control register */ + + uint32_t AccL; /* Lower 32 bits of accumulator A */ + uint32_t AccH; /* Higher 32 bits of accumulator A */ + uint32_t AccU; /* sign extended upper bits of Accumulator A */ + uint32_t BccL; /* Lower 32 bits of accumulator B */ + uint32_t BccH; /* Higher 32 bits of accumulator B */ + uint32_t BccU; /* sign extended upper bits of Accumulator B */ + + uint32_t stack; /* stack pointer, W15 register*/ + uint32_t frame; /* Frame pointer, w14 register */ + uint32_t splim; /* stack limit register */ +}; +typedef struct _callee_saved _callee_saved_t; + +struct _thread_arch { + /* current cpu priority level */ + uint32_t cpu_level; + + /* stack limit value for the thread */ + uint32_t splim; + + /* return value of z_swap */ + uint32_t swap_return_value; +}; +typedef struct _thread_arch _thread_arch_t; + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_INCLUDE_ARCH_DSPIC_THREAD_H_ */ diff --git a/include/zephyr/arch/exception.h b/include/zephyr/arch/exception.h index 68487be0cbd88..c8b99d37ec93d 100644 --- a/include/zephyr/arch/exception.h +++ b/include/zephyr/arch/exception.h @@ -30,6 +30,8 @@ #include #elif defined(CONFIG_RX) #include +#elif defined(CONFIG_DSPIC) +#include #endif #endif /* ZEPHYR_INCLUDE_ARCH_EXCEPTION_H_ */ diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index 614b2eab1b9b8..f1a9661d64b0e 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -6347,7 +6347,9 @@ __syscall int k_poll_signal_raise(struct k_poll_signal *sig, int result); */ static inline void k_cpu_idle(void) { +#ifdef TO_BE_IMPLEMENTED_LATER arch_cpu_idle(); +#endif } /** diff --git a/include/zephyr/kernel/thread_stack.h b/include/zephyr/kernel/thread_stack.h index 2989624e04367..b14c544a851eb 100644 --- a/include/zephyr/kernel/thread_stack.h +++ b/include/zephyr/kernel/thread_stack.h @@ -68,7 +68,11 @@ struct __packed z_thread_stack_element { */ static inline char *z_stack_ptr_align(char *ptr) { +#ifdef CONFIG_STACK_GROWS_UP + return (char *)ROUND_UP(ptr, ARCH_STACK_PTR_ALIGN); +#else return (char *)ROUND_DOWN(ptr, ARCH_STACK_PTR_ALIGN); +#endif /* CONFIG_STACK_GROWS_UP */ } #define Z_STACK_PTR_ALIGN(ptr) ((uintptr_t)z_stack_ptr_align((char *)(ptr))) @@ -85,8 +89,15 @@ static inline char *z_stack_ptr_align(char *ptr) * @param ptr Initial aligned stack pointer value * @return Pointer to stack frame struct within the stack buffer */ -#define Z_STACK_PTR_TO_FRAME(type, ptr) \ - (type *)((ptr) - sizeof(type)) +#ifdef CONFIG_STACK_GROWS_UP +/** + * For architectures with upward growing stack, the frame pointer + * is same as that of the initial stack pointer itself. + */ +#define Z_STACK_PTR_TO_FRAME(type, ptr) (type *)((ptr)) +#else +#define Z_STACK_PTR_TO_FRAME(type, ptr) (type *)((ptr) - sizeof(type)) +#endif /* CONFIG_STACK_GROWS_UP */ #ifdef ARCH_KERNEL_STACK_RESERVED #define K_KERNEL_STACK_RESERVED ((size_t)ARCH_KERNEL_STACK_RESERVED) diff --git a/include/zephyr/linker/linker-defs.h b/include/zephyr/linker/linker-defs.h index 6415b0a490bf6..ee907e37f0f21 100644 --- a/include/zephyr/linker/linker-defs.h +++ b/include/zephyr/linker/linker-defs.h @@ -41,7 +41,7 @@ * by default. As a workaroud for symbols defined in linker scripts to be * available in C code, an alias with a leading underscore has to be provided. */ -#if defined(CONFIG_RX) +#if defined(CONFIG_RX) || defined(CONFIG_DSPIC) #define PLACE_SYMBOL_HERE(symbol) \ symbol = .; \ PROVIDE(_CONCAT(_, symbol) = symbol) diff --git a/include/zephyr/linker/linker-tool-gcc.h b/include/zephyr/linker/linker-tool-gcc.h index bc6b0ddaae6ff..389115dce20d1 100644 --- a/include/zephyr/linker/linker-tool-gcc.h +++ b/include/zephyr/linker/linker-tool-gcc.h @@ -59,6 +59,9 @@ OUTPUT_FORMAT("elf32-sparc") #elif defined(CONFIG_RX) OUTPUT_FORMAT("elf32-rx-le") +#elif defined(CONFIG_DSPIC) + OUTPUT_FORMAT("elf32-pic30") + OUTPUT_ARCH("33AK128MC106") #else #error Arch not supported. #endif diff --git a/include/zephyr/linker/linker-tool-xcdsc.h b/include/zephyr/linker/linker-tool-xcdsc.h new file mode 100644 index 0000000000000..a68523d4a3f72 --- /dev/null +++ b/include/zephyr/linker/linker-tool-xcdsc.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2023, Google, Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief LLVM LLD linker defs + * + * This header file defines the necessary macros used by the linker script for + * use with the XCDSC Linker. + */ + +#ifndef ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ +#define ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ + +#include + +/** + * @def SECTION_PROLOGUE + * + * The SECTION_PROLOGUE() macro is used to define the beginning of a section. + * + * When --omagic (-N) option is provided to LLD then only the first output + * section of given region has aligned LMA (by default, without --omagic, LLD + * aligns LMA and VMA of every section to the same value) and the difference + * between VMA addresses (0 is this is the first section) is added. + * The difference between LMA and VMA is constant for every section, so this + * emulates ALIGN_WITH_INPUT option present in GNU LD (required by XIP systems). + * + * The --omagic flag is defined in cmake/linker/lld/target_baremetal.cmake + * + * @param name Name of the output section + * @param options Section options, such as (NOLOAD), or left blank + * @param align Alignment directives, such as SUBALIGN(). May be blank. + */ +#undef SECTION_PROLOGUE +#define SECTION_PROLOGUE(name, options, align) name options : align + +/** + * @def SECTION_DATA_PROLOGUE + * + * Same as for SECTION_PROLOGUE(), except that this one must be used + * for data sections which on XIP platforms will have differing + * virtual and load addresses (i.e. they'll be copied into RAM at + * program startup). Such a section must also use + * GROUP_DATA_LINK_IN to specify the correct output load address. + * + * This is equivalent to SECTION_PROLOGUE() when linking using LLD. + * + * @param name Name of the output section + * @param options Section options, or left blank + * @param align Alignment directives, such as SUBALIGN(). May be blank. + */ +#undef SECTION_DATA_PROLOGUE +#define SECTION_DATA_PROLOGUE(name, options, align) SECTION_PROLOGUE(name, options, align) + +#endif /* ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ */ diff --git a/include/zephyr/linker/linker-tool.h b/include/zephyr/linker/linker-tool.h index 9b63ea89939c7..1557da3b6cfc1 100644 --- a/include/zephyr/linker/linker-tool.h +++ b/include/zephyr/linker/linker-tool.h @@ -22,6 +22,8 @@ #include #elif defined(__LLD_LINKER_CMD__) #include +#elif defined(__XCDSC_LINKER_CMD__) +#include #else #error "Unknown toolchain" #endif diff --git a/include/zephyr/toolchain.h b/include/zephyr/toolchain.h index 6fca58a7b2ff9..97791cb189877 100644 --- a/include/zephyr/toolchain.h +++ b/include/zephyr/toolchain.h @@ -48,6 +48,8 @@ #include #elif defined(__llvm__) || (defined(_LINKER) && defined(__LLD_LINKER_CMD__)) #include +#elif defined(__XC_DSC__) || defined(__XCDSC_LINKER_CMD__) +#include #elif defined(__GNUC__) || (defined(_LINKER) && defined(__GCC_LINKER_CMD__)) #include #else diff --git a/include/zephyr/toolchain/common.h b/include/zephyr/toolchain/common.h index b52c26d2ddd8d..d9b29505eff20 100644 --- a/include/zephyr/toolchain/common.h +++ b/include/zephyr/toolchain/common.h @@ -76,7 +76,7 @@ #if defined(CONFIG_X86) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || \ defined(CONFIG_RISCV) || defined(CONFIG_XTENSA) || defined(CONFIG_MIPS) || \ - defined(CONFIG_ARCH_POSIX) || defined(CONFIG_RX) + defined(CONFIG_ARCH_POSIX) || defined(CONFIG_RX) || defined(CONFIG_DSPIC) #define ALIGN(x) .balign x #elif defined(CONFIG_ARC) /* .align assembler directive is supported by all ARC toolchains and it is @@ -127,13 +127,17 @@ #define PERFOPT_ALIGN .align 4 + #elif defined(CONFIG_DSPIC) + + #define PERFOPT_ALIGN .align 4 + #else #error Architecture unsupported - #endif +#endif - #define GC_SECTION(sym) SECTION .text.##sym, "ax" +#define GC_SECTION(sym) SECTION.text.##sym, "ax" #endif /* _ASMLANGUAGE */ diff --git a/include/zephyr/toolchain/gcc.h b/include/zephyr/toolchain/gcc.h index 4d3d85858d3d4..85802c26da320 100644 --- a/include/zephyr/toolchain/gcc.h +++ b/include/zephyr/toolchain/gcc.h @@ -598,14 +598,25 @@ do { \ "\n\t.type\t" #name ",#object") #elif defined(CONFIG_RX) -#define GEN_ABSOLUTE_SYM(name, value) \ - __asm__(".global\t" #name "\n\t.equ\t" #name \ - ",%c0" \ - "\n\t.type\t" #name ",%%object" : : "n"(value)) +#define GEN_ABSOLUTE_SYM(name, value) \ + __asm__(".global\t" #name "\n\t.equ\t" #name \ + ",%c0" \ + "\n\t.type\t" #name ",%%object" : : "n"(value)) + +#define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ + __asm__(".global\t" #name \ + "\n\t.equ\t" #name "," #value \ + "\n\t.type\t" #name ",#object") + +#elif defined(CONFIG_DSPIC) +#define GEN_ABSOLUTE_SYM(name, value) \ + __asm__(".global\t" #name "\n\t.equ\t" #name \ + ",%c0" \ + "\n\t.type\t" #name ",%%object" : : "n"(value)) -#define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ - __asm__(".global\t" #name \ - "\n\t.equ\t" #name "," #value \ +#define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ + __asm__(".global\t" #name \ + "\n\t.equ\t" #name "," #value \ "\n\t.type\t" #name ",#object") #else diff --git a/include/zephyr/toolchain/xcdsc.h b/include/zephyr/toolchain/xcdsc.h new file mode 100644 index 0000000000000..7848c3bd64959 --- /dev/null +++ b/include/zephyr/toolchain/xcdsc.h @@ -0,0 +1,218 @@ +/* + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_XCDSC_H_ +#define ZEPHYR_INCLUDE_TOOLCHAIN_XCDSC_H_ + +#ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ +#error Please do not include toolchain-specific headers directly, use instead +#endif + +#include +#include + +#define Z_STRINGIFY(x) #x +#define STRINGIFY(s) Z_STRINGIFY(s) + +/* Double indirection to ensure section names are expanded before + * stringification + */ +/* + * XC-DSC does not support using deprecated attribute in enum, + * so just nullify it here to avoid compilation errors. + */ +#define __deprecated + +#define __in_section(a, b, c) \ + __attribute__((section("." STRINGIFY(a) "." STRINGIFY(b) "." STRINGIFY(c)))) +#define __in_section_unique(seg) \ + __attribute__((section("." STRINGIFY(seg) "." STRINGIFY(__COUNTER__)))) + +#define __in_section_unique_named(seg, name) \ + __attribute__((section("." STRINGIFY(seg) "." STRINGIFY(__COUNTER__) "." STRINGIFY(name)))) +#define CODE_UNREACHABLE __builtin_unreachable() + +#define __used __attribute__((__used__)) +#define __unused __attribute__((__unused__)) +#define __maybe_unused __attribute__((__unused__)) + +/* + * *********REDEFINED****** + * #if defined(__cplusplus) && (__cplusplus >= 201103L) + * #define BUILD_ASSERT(EXPR, MSG...) static_assert(EXPR, "" MSG) + * #elif defined(__XC_DSC__) + * #define BUILD_ASSERT(EXPR, MSG...) _Static_assert(EXPR, "" MSG) + * #endif + */ +#ifndef __printf_like +/* + * The Zephyr stdint convention enforces int32_t = int, int64_t = long long, + * and intptr_t = long so that short string format length modifiers can be + * used universally across ILP32 and LP64 architectures. Without that it + * is possible for ILP32 toolchains to have int32_t = long and intptr_t = int + * clashing with the Zephyr convention and generating pointless warnings + * as they're still the same size. Inhibit the format argument type + * validation in that case and let the other configs do it. + */ +#define __printf_like(f, a) +#endif + +#ifndef __packed +#define __packed __attribute__((__packed__)) +#endif + +#ifndef __aligned +#define __aligned(x) __attribute__((__aligned__(x))) +#endif + +#ifndef __noinline +#define __noinline __attribute__((noinline)) +#endif + +#ifndef __attribute_const__ +#define __attribute_const__ __attribute__((__const__)) +#endif + +#ifndef __attribute_nonnull +#define __attribute_nonnull(...) __attribute__((nonnull(__VA_ARGS__))) +#endif + +#ifndef __fallthrough +#if __GNUC__ >= 7 +#define __fallthrough __attribute__((fallthrough)) +#else +#define __fallthrough +#endif /* __GNUC__ >= 7 */ +#endif + +#define ARG_UNUSED(x) (void)(x) + +#define likely(x) (__builtin_expect((bool)!!(x), true) != 0L) +#define unlikely(x) (__builtin_expect((bool)!!(x), false) != 0L) + +#ifndef _ASMLANGUAGE + +static inline int popcount(unsigned int x) +{ + int count = 0; + + while (x) { + count += x & 1; + x >>= 1; + } + return count; +} + +#define POPCOUNT(x) popcount(x) +#else +#define POPCOUNT(x) __builtin_popcount(x) +#endif + +#ifndef __no_optimization +#define __no_optimization __attribute__((optimize("-O0"))) +#endif + +#ifndef __weak +#define __weak __attribute__((__weak__)) +#endif + +#define _NODATA_SECTION(segment) __attribute__((section(#segment))) +#define FUNC_NO_STACK_PROTECTOR +#define FUNC_NORETURN __attribute__((__noreturn__)) + +/* create an extern reference to the absolute symbol */ + +#define GEN_OFFSET_EXTERN(name) extern const char name[] + +#define GEN_ABS_SYM_BEGIN(name) \ + EXTERN_C void name(void); \ + void name(void) \ + { + +#define GEN_ABS_SYM_END } + +/* No special prefixes necessary for constants in this arch AFAICT */ +#define GEN_ABSOLUTE_SYM(name, value) \ + __asm__(".global\t" #name "\n\t.equ\t" #name ",%0" \ + "\n\t.type\t" #name ",%%object" \ + : \ + : "n"(value)) + +#define GEN_ABSOLUTE_SYM_KCONFIG(name, value) \ + __asm__(".global\t" #name "\n\t.equ\t" #name "," #value "\n\t.type\t" #name ",%object") + +#define compiler_barrier() \ + do { \ + __asm__ __volatile__("" ::: "memory"); \ + } while (false) + +/** @brief Return larger value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. + * + * @note Macro has limited usage compared to the standard macro as it cannot be + * used: + * - to generate constant integer, e.g. __aligned(Z_MAX(4,5)) + * - static variable, e.g. array like static uint8_t array[Z_MAX(...)]; + */ +#define Z_MAX(a, b) \ + ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + (_value_a_ > _value_b_) ? _value_a_ : _value_b_; \ + }) + +/** @brief Return smaller value of two provided expressions. + * + * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for + * macro limitations. + */ +#define Z_MIN(a, b) \ + ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(a) _value_a_ = (a); \ + __typeof__(b) _value_b_ = (b); \ + (_value_a_ < _value_b_) ? _value_a_ : _value_b_; \ + }) + +/** @brief Return a value clamped to a given range. + * + * Macro ensures that expressions are evaluated only once. See @ref Z_MAX for + * macro limitations. + */ +#define Z_CLAMP(val, low, high) \ + ({ \ + /* random suffix to avoid naming conflict */ \ + __typeof__(val) _value_val_ = (val); \ + __typeof__(low) _value_low_ = (low); \ + __typeof__(high) _value_high_ = (high); \ + (_value_val_ < _value_low_) ? _value_low_ \ + : (_value_val_ > _value_high_) ? _value_high_ \ + : _value_val_; \ + }) + +/** + * @brief Calculate power of two ceiling for some nonzero value + * + * @param x Nonzero unsigned long value + * @return X rounded up to the next power of two + */ +#define Z_POW2_CEIL(x) ((x) <= 2UL ? (x) : (1UL << (8 * sizeof(long) - __builtin_clzl((x) - 1)))) + +/** + * @brief Check whether or not a value is a power of 2 + * + * @param x The value to check + * @return true if x is a power of 2, false otherwise + */ +#define Z_IS_POW2(x) (((x) != 0) && (((x) & ((x) - 1)) == 0)) + +/* + * To reuse as much as possible from the llvm.h header we only redefine the + * __GENERIC_SECTION and Z_GENERIC_SECTION macros here to include the `used` keyword. + */ + +#define ZRESTRICT restrict +#endif /* ZEPHYR_INCLUDE_TOOLCHAIN_XSDSC_H_ */ diff --git a/kernel/init.c b/kernel/init.c index 2ab9804c7cf0e..180a93c7dc5b7 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -806,10 +806,14 @@ FUNC_NORETURN void z_cstart(void) z_device_state_init(); #if CONFIG_SOC_EARLY_INIT_HOOK +#ifdef TO_BE_IMPLEMENTED_LATER soc_early_init_hook(); #endif +#endif #if CONFIG_BOARD_EARLY_INIT_HOOK +#ifdef TO_BE_IMPLEMENTED_LATER board_early_init_hook(); +#endif #endif /* perform basic hardware initialization */ z_sys_init_run_level(INIT_LEVEL_PRE_KERNEL_1); diff --git a/kernel/thread.c b/kernel/thread.c index f77d70ce494fb..9f01309717864 100644 --- a/kernel/thread.c +++ b/kernel/thread.c @@ -446,10 +446,17 @@ static char *setup_thread_stack(struct k_thread *new_thread, #else /* CONFIG_THREAD_STACK_MEM_MAPPED */ - /* Initial stack pointer at the high end of the stack object, may - * be reduced later in this function by TLS or random offset +#ifdef CONFIG_STACK_GROWS_UP + /* Initial stack pointer at the low end of the stack object, + * may be moved forward later in this function by TLS offset + */ + stack_ptr = (char *)stack; +#else + /* Initial stack pointer at the high end of the stack object, + * may be reduced later in this function by TLS or random offset */ stack_ptr = (char *)stack + stack_obj_size; +#endif /* CONFIG_STACK_GROWS_UP */ #endif /* CONFIG_THREAD_STACK_MEM_MAPPED */ @@ -496,7 +503,13 @@ static char *setup_thread_stack(struct k_thread *new_thread, new_thread->stack_info.size = stack_buf_size; new_thread->stack_info.delta = delta; #endif /* CONFIG_THREAD_STACK_INFO */ +#ifdef CONFIG_STACK_GROWS_UP + /* for upward growing stack, increment the stack pointer to reserve space */ + stack_ptr += delta; +#else /* CONFIG_STACK_GROWS_UP */ + /* for downward growing stack, decreament the stack pointer to reserve space */ stack_ptr -= delta; +#endif /* CONFIG_STACK_GROWS_UP */ return stack_ptr; } diff --git a/kernel/timeout.c b/kernel/timeout.c index f698a0779e5a7..77f063297983d 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -81,7 +81,11 @@ static int32_t elapsed(void) * will be non-zero while sys_clock_announce() is executing and zero * otherwise. */ +#ifdef TO_BE_IMPLEMENTED_LATER return announce_remaining == 0 ? sys_clock_elapsed() : 0U; +#else + return 0; +#endif } static int32_t next_timeout(int32_t ticks_elapsed) diff --git a/soc/microchip/dspic33/CMakeLists.txt b/soc/microchip/dspic33/CMakeLists.txt new file mode 100644 index 0000000000000..ac7ce7faba730 --- /dev/null +++ b/soc/microchip/dspic33/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(${SOC_SERIES}) diff --git a/soc/microchip/dspic33/Kconfig b/soc/microchip/dspic33/Kconfig new file mode 100644 index 0000000000000..433f85dcd0adb --- /dev/null +++ b/soc/microchip/dspic33/Kconfig @@ -0,0 +1,3 @@ +if SOC_FAMILY_MICROCHIP_DSPIC33 + rsource "*/Kconfig" +endif # SOC_FAMILY_MICROCHIP_DSPIC33 diff --git a/soc/microchip/dspic33/Kconfig.defconfig b/soc/microchip/dspic33/Kconfig.defconfig new file mode 100644 index 0000000000000..e2e757438b31f --- /dev/null +++ b/soc/microchip/dspic33/Kconfig.defconfig @@ -0,0 +1,3 @@ +if SOC_FAMILY_MICROCHIP_DSPIC33 + rsource "*/Kconfig.defconfig.series" +endif # SOC_FAMILY_MICROCHIP_DSPIC33 diff --git a/soc/microchip/dspic33/Kconfig.soc b/soc/microchip/dspic33/Kconfig.soc new file mode 100644 index 0000000000000..4b36a09005e4f --- /dev/null +++ b/soc/microchip/dspic33/Kconfig.soc @@ -0,0 +1,7 @@ +config SOC_FAMILY_MICROCHIP_DSPIC33 + bool + +config SOC_FAMILY + default "microchip_dspic33" if SOC_FAMILY_MICROCHIP_DSPIC33 + +rsource "*/Kconfig.soc" diff --git a/soc/microchip/dspic33/dspic33a/CMakeLists.txt b/soc/microchip/dspic33/dspic33a/CMakeLists.txt new file mode 100644 index 0000000000000..f12efdf7c8b82 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/CMakeLists.txt @@ -0,0 +1,7 @@ +zephyr_include_directories(.) +zephyr_sources_ifdef(CONFIG_PM power.c ) + +set(SOC_LINKER_SCRIPT + ${ZEPHYR_BASE}/include/zephyr/arch/dspic/linker.ld + CACHE INTERNAL "" +) diff --git a/soc/microchip/dspic33/dspic33a/Kconfig b/soc/microchip/dspic33/dspic33a/Kconfig new file mode 100644 index 0000000000000..ce8ff7f2ca322 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig @@ -0,0 +1,12 @@ +config SOC_SERIES_DSPIC33A + select DSPIC + select CPU_HAS_FPU + select CPU_HAS_DSP + select FPU + select SOC_EARLY_INIT_HOOK + select BOARD_EARLY_INIT_HOOK + # select GEN_ISR_TABLES + # select GEN_IRQ_VECTOR_TABLE + # select GEN_SW_ISR_TABLE + select HAS_PM + select PM diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 new file mode 100644 index 0000000000000..cd3bef7a30a1b --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 @@ -0,0 +1,37 @@ +if SOC_P33AK128MC106 + +config UART_CONSOLE + default n + +config FLASH_SIZE + default 128 + +config FLASH_BASE_ADDRESS + default 0x00800000 + +config SRAM_SIZE + default 80 + +config SRAM_BASE_ADDRESS + default 0x010000 + +config MAIN_STACK_SIZE + default 128 + +config IDLE_STACK_SIZE + default 512 + +config MINIMAL_LIBC_SUPPORTED + bool + default n + +config NEWLIB_LIBC_SUPPORTED + bool + default n + +# Picolibc with C++ support in Zephyr SDK is handled by Zephyr SDK's own Kconfig. +config PICOLIBC_SUPPORTED + bool + default n + +endif # SOC_P33AK128MC106 diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series new file mode 100644 index 0000000000000..0b4508e0cee9b --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series @@ -0,0 +1,3 @@ +if SOC_SERIES_DSPIC33A + rsource "Kconfig.defconfig.p33ak*" +endif # SOC_SERIES_DSPIC33A diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.soc b/soc/microchip/dspic33/dspic33a/Kconfig.soc new file mode 100644 index 0000000000000..ebf2f71a41fdb --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.soc @@ -0,0 +1,21 @@ +config SOC_SERIES_DSPIC33A + bool + +select SOC_FAMILY_MICROCHIP_DSPIC33 + help + Enable support for Microchip DSPIC33 DSC series + +config SOC_SERIES + default "dspic33a" if SOC_SERIES_DSPIC33A + +config SOC_P33AK128MC106 + bool + select SOC_SERIES_DSPIC33A + +config SOC_P33AK256MC506 + bool + select SOC_SERIES_DSPIC33A + +config SOC + default "p33ak128mc106" if SOC_P33AK128MC106 + default "p33ak256mc506" if SOC_P33AK256MC506 diff --git a/soc/microchip/dspic33/dspic33a/power.c b/soc/microchip/dspic33/dspic33a/power.c new file mode 100644 index 0000000000000..e0dbf0b32f3ad --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/power.c @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include + +void pm_state_set(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + break; + default: + break; + } +} + +void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) +{ + ARG_UNUSED(substate_id); + switch (state) { + case PM_STATE_SUSPEND_TO_IDLE: + break; + default: + break; + } +} diff --git a/soc/microchip/dspic33/dspic33a/soc.h b/soc/microchip/dspic33/dspic33a/soc.h new file mode 100644 index 0000000000000..92893e79eabfb --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/soc.h @@ -0,0 +1,7 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/* Clock Frequency */ +#define DSPIC_SYSCLK_FREQ 8000000 /* 8 MHz */ diff --git a/soc/microchip/dspic33/soc.yml b/soc/microchip/dspic33/soc.yml new file mode 100644 index 0000000000000..7df418defe8dc --- /dev/null +++ b/soc/microchip/dspic33/soc.yml @@ -0,0 +1,9 @@ +family: +- name: microchip_dspic33 + series: + - name: dspic33a + socs: + - name: p33ak128mc106 + - name: p33ak256mc506 + cpuclusters: + - name: cpu0 From 968f3167abfde9f8924004f3baa21b30f51d6103 Mon Sep 17 00:00:00 2001 From: Muhammed Zamroodh Date: Mon, 7 Jul 2025 15:37:25 +0530 Subject: [PATCH 2/6] arch, soc: add copyright and license headers Add copyright and license headers to Kconfigs and other files Signed-off-by: Muhammed Zamroodh --- arch/dspic/Kconfig | 3 +++ arch/dspic/core/init.S | 5 +++++ arch/dspic/core/offsets/offsets.c | 1 + arch/dspic/core/reset0.S | 5 +++++ arch/dspic/core/reset1.S | 4 ++++ arch/dspic/core/vector_table.S | 5 +++++ boards/microchip/ev74h48a/Kconfig.ev74h48a | 3 +++ cmake/toolchain/xcdsc/Kconfig | 3 +++ include/zephyr/toolchain/xcdsc.h | 1 + soc/microchip/dspic33/Kconfig | 3 +++ soc/microchip/dspic33/Kconfig.defconfig | 3 +++ soc/microchip/dspic33/Kconfig.soc | 3 +++ soc/microchip/dspic33/dspic33a/Kconfig | 3 +++ .../dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 | 3 +++ soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series | 3 +++ soc/microchip/dspic33/dspic33a/Kconfig.soc | 3 +++ 16 files changed, 51 insertions(+) diff --git a/arch/dspic/Kconfig b/arch/dspic/Kconfig index c8615033e7596..401a1a0985640 100644 --- a/arch/dspic/Kconfig +++ b/arch/dspic/Kconfig @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + menu "DSPIC Options" depends on DSPIC diff --git a/arch/dspic/core/init.S b/arch/dspic/core/init.S index 59b63028e9959..5477cb3e49ad8 100644 --- a/arch/dspic/core/init.S +++ b/arch/dspic/core/init.S @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + .section .init,code .global __custom_data_init .global __custom_data_init_extended diff --git a/arch/dspic/core/offsets/offsets.c b/arch/dspic/core/offsets/offsets.c index 18e5952ec94a1..c88caaf2ce939 100644 --- a/arch/dspic/core/offsets/offsets.c +++ b/arch/dspic/core/offsets/offsets.c @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Microchip Technology Inc. * SPDX-License-Identifier: Apache-2.0 */ diff --git a/arch/dspic/core/reset0.S b/arch/dspic/core/reset0.S index b0c8d02d5917b..b0126d5183f2e 100644 --- a/arch/dspic/core/reset0.S +++ b/arch/dspic/core/reset0.S @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + #include #include #include diff --git a/arch/dspic/core/reset1.S b/arch/dspic/core/reset1.S index 43624f805926e..c8db2021c28de 100644 --- a/arch/dspic/core/reset1.S +++ b/arch/dspic/core/reset1.S @@ -1,3 +1,7 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ ;;This version support without data initialization ;;Refer reset0.S for the data initialization diff --git a/arch/dspic/core/vector_table.S b/arch/dspic/core/vector_table.S index 28b8302bc0b58..c495e87f96f6f 100644 --- a/arch/dspic/core/vector_table.S +++ b/arch/dspic/core/vector_table.S @@ -1,3 +1,8 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + #include #include #include "vector_table.h" diff --git a/boards/microchip/ev74h48a/Kconfig.ev74h48a b/boards/microchip/ev74h48a/Kconfig.ev74h48a index dae0aa1309a22..b2698d589d6ae 100644 --- a/boards/microchip/ev74h48a/Kconfig.ev74h48a +++ b/boards/microchip/ev74h48a/Kconfig.ev74h48a @@ -1,2 +1,5 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + config BOARD_EV74H48A select SOC_P33AK128MC106 if BOARD_EV74H48A_P33AK128MC106 diff --git a/cmake/toolchain/xcdsc/Kconfig b/cmake/toolchain/xcdsc/Kconfig index 82b04e2ba711a..923c90caf1c82 100644 --- a/cmake/toolchain/xcdsc/Kconfig +++ b/cmake/toolchain/xcdsc/Kconfig @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + config TOOLCHAIN_XCDSC bool "MPLAB XC-DSC toolchain" select HAVE_CUSTOM_LINKER_SCRIPT diff --git a/include/zephyr/toolchain/xcdsc.h b/include/zephyr/toolchain/xcdsc.h index 7848c3bd64959..67e59535f1c63 100644 --- a/include/zephyr/toolchain/xcdsc.h +++ b/include/zephyr/toolchain/xcdsc.h @@ -1,4 +1,5 @@ /* + * Copyright (c) 2025, Microchip Technology Inc. * SPDX-License-Identifier: Apache-2.0 */ diff --git a/soc/microchip/dspic33/Kconfig b/soc/microchip/dspic33/Kconfig index 433f85dcd0adb..0c0e4f2fe05aa 100644 --- a/soc/microchip/dspic33/Kconfig +++ b/soc/microchip/dspic33/Kconfig @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + if SOC_FAMILY_MICROCHIP_DSPIC33 rsource "*/Kconfig" endif # SOC_FAMILY_MICROCHIP_DSPIC33 diff --git a/soc/microchip/dspic33/Kconfig.defconfig b/soc/microchip/dspic33/Kconfig.defconfig index e2e757438b31f..e6769d6f9e91d 100644 --- a/soc/microchip/dspic33/Kconfig.defconfig +++ b/soc/microchip/dspic33/Kconfig.defconfig @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + if SOC_FAMILY_MICROCHIP_DSPIC33 rsource "*/Kconfig.defconfig.series" endif # SOC_FAMILY_MICROCHIP_DSPIC33 diff --git a/soc/microchip/dspic33/Kconfig.soc b/soc/microchip/dspic33/Kconfig.soc index 4b36a09005e4f..9f99de815576f 100644 --- a/soc/microchip/dspic33/Kconfig.soc +++ b/soc/microchip/dspic33/Kconfig.soc @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + config SOC_FAMILY_MICROCHIP_DSPIC33 bool diff --git a/soc/microchip/dspic33/dspic33a/Kconfig b/soc/microchip/dspic33/dspic33a/Kconfig index ce8ff7f2ca322..a46ff9baa903c 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig +++ b/soc/microchip/dspic33/dspic33a/Kconfig @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + config SOC_SERIES_DSPIC33A select DSPIC select CPU_HAS_FPU diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 index cd3bef7a30a1b..9c509d888257d 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + if SOC_P33AK128MC106 config UART_CONSOLE diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series index 0b4508e0cee9b..72f99ab38fa01 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + if SOC_SERIES_DSPIC33A rsource "Kconfig.defconfig.p33ak*" endif # SOC_SERIES_DSPIC33A diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.soc b/soc/microchip/dspic33/dspic33a/Kconfig.soc index ebf2f71a41fdb..69cde09e0b3c1 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig.soc +++ b/soc/microchip/dspic33/dspic33a/Kconfig.soc @@ -1,3 +1,6 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + config SOC_SERIES_DSPIC33A bool From b62dbccf3e0fd7ad6c606563b1b6314aec783085 Mon Sep 17 00:00:00 2001 From: Muhammed Zamroodh Date: Thu, 10 Jul 2025 11:59:06 +0530 Subject: [PATCH 3/6] linker: place const custom sections in RAM The custom const sections are placed in FLASH and being copied from .dinit to Flash again, We can avoid that by placing the section in RAM to begin with Signed-off-by: Muhammed Zamroodh --- include/zephyr/linker/linker-tool-gcc.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/zephyr/linker/linker-tool-gcc.h b/include/zephyr/linker/linker-tool-gcc.h index 389115dce20d1..e6f40d678c7d4 100644 --- a/include/zephyr/linker/linker-tool-gcc.h +++ b/include/zephyr/linker/linker-tool-gcc.h @@ -118,6 +118,8 @@ #define GROUP_ROM_LINK_IN(vregion, lregion) #elif defined(K_MEM_IS_VM_KERNEL) #define GROUP_ROM_LINK_IN(vregion, lregion) > vregion AT > lregion +#elif defined(__XC_DSC__) || defined(__XCDSC_LINKER_CMD__) +#define GROUP_ROM_LINK_IN(vregion, lregion) > vregion #else #define GROUP_ROM_LINK_IN(vregion, lregion) > lregion #endif @@ -138,6 +140,8 @@ #define GROUP_DATA_LINK_IN(vregion, lregion) #elif defined(CONFIG_XIP) || defined(K_MEM_IS_VM_KERNEL) #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion AT > lregion +#elif defined(__XC_DSC__) || defined(__XCDSC_LINKER_CMD__) +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion #else #define GROUP_DATA_LINK_IN(vregion, lregion) > vregion #endif @@ -158,6 +162,8 @@ #define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > lregion #elif defined(CONFIG_XIP) #define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion AT > vregion +#elif defined(__XC_DSC__) || defined(__XCDSC_LINKER_CMD__) +#define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion #else #define GROUP_NOLOAD_LINK_IN(vregion, lregion) > vregion #endif From e120593bc1bd1d2f26bdd806feb5f07fa624c41f Mon Sep 17 00:00:00 2001 From: Adhil Xavier Date: Fri, 18 Jul 2025 11:07:28 +0530 Subject: [PATCH 4/6] Release: v3.0 Highlights: - Context switching and thread creation - Timer driver and system timer integartion - UART driver and LOG integration - Fixes for linking and toolchain support - Power management (idle state) - Interrupt support in OS - Twister and flash support - General fixes Signed-off-by: Muhammed Zamroodh --- arch/Kconfig | 4 - arch/dspic/Kconfig | 10 +- arch/dspic/core/CMakeLists.txt | 2 +- arch/dspic/core/cpu_idle.c | 9 +- arch/dspic/core/fatal.c | 92 +++-- arch/dspic/core/irq_manage.c | 49 ++- arch/dspic/core/isr_wrapper.c | 32 +- arch/dspic/core/swap.c | 343 +----------------- arch/dspic/core/thread.c | 10 +- arch/dspic/core/vector_table.S | 284 +-------------- arch/dspic/include/kernel_arch_func.h | 16 +- arch/dspic/include/kernel_arch_swap.h | 288 +++++++++++++++ .../Kconfig.dspic33a_curiosity | 5 + .../dspic33/dspic33a_curiosity/board.cmake | 16 + .../dspic33a_curiosity}/board.yml | 2 +- .../dspic33a_curiosity_p33ak128mc106.dts | 38 ++ .../dspic33a_curiosity_p33ak128mc106.yaml | 14 + ...spic33a_curiosity_p33ak128mc106_defconfig} | 22 +- .../dspic33a_curiosity_p33ak128mc506.dts} | 0 boards/microchip/ev74h48a/Kconfig.ev74h48a | 5 - .../ev74h48a/ev74h48a_p33ak128mc106.dts | 22 -- cmake/compiler/xcdsc/generic.cmake | 2 +- cmake/linker/xcdsc/target.cmake | 6 +- drivers/console/ram_console.c | 2 +- drivers/serial/CMakeLists.txt | 1 + drivers/serial/Kconfig | 1 + drivers/serial/Kconfig.dspic_uart | 10 + drivers/serial/uart_dspic.c | 117 ++++++ drivers/timer/CMakeLists.txt | 1 + drivers/timer/Kconfig | 1 + drivers/timer/Kconfig.mchp_dspic33 | 10 + drivers/timer/mchp_dspic33_timer.c | 190 ++++++++++ .../microchip,dspic33-intc.yaml | 19 + .../serial/microchip,dspic33-uart.yaml | 19 + .../timer/microchip,dspic33-timer.yaml | 26 ++ dts/dspic/p33ak128mc106.dtsi | 35 +- include/zephyr/arch/dspic/arch.h | 38 +- include/zephyr/arch/dspic/exception.h | 17 +- include/zephyr/arch/dspic/linker.ld | 96 +++-- include/zephyr/kernel.h | 2 - include/zephyr/linker/common-ram.ld | 7 +- .../common-rom/common-rom-kernel-devices.ld | 2 - include/zephyr/linker/iterable_sections.h | 3 + include/zephyr/linker/linker-tool-xcdsc.h | 74 +++- include/zephyr/linker/section_tags.h | 11 +- include/zephyr/toolchain/xcdsc.h | 32 +- kernel/init.c | 4 +- kernel/timeout.c | 4 - samples/hello_world/src/main.c | 2 +- scripts/schemas/twister/platform-schema.yaml | 1 + scripts/west_commands/runners/__init__.py | 1 + scripts/west_commands/runners/ipecmd.py | 126 +++++++ .../dspic33a_curiosity_p33ak128mc106.overlay | 14 + snippets/ram-console/snippet.yml | 3 + soc/microchip/dspic33/Kconfig.soc | 4 + soc/microchip/dspic33/dspic33a/CMakeLists.txt | 1 + soc/microchip/dspic33/dspic33a/Kconfig | 6 +- .../dspic33a/Kconfig.defconfig.p33ak128mc106 | 17 +- soc/microchip/dspic33/dspic33a/power.c | 4 + 59 files changed, 1375 insertions(+), 797 deletions(-) create mode 100644 arch/dspic/include/kernel_arch_swap.h create mode 100644 boards/microchip/dspic33/dspic33a_curiosity/Kconfig.dspic33a_curiosity create mode 100644 boards/microchip/dspic33/dspic33a_curiosity/board.cmake rename boards/microchip/{ev74h48a => dspic33/dspic33a_curiosity}/board.yml (84%) create mode 100644 boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.dts create mode 100644 boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.yaml rename boards/microchip/{ev74h48a/ev74h48a_p33ak128mc106_defconfig => dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig} (55%) rename boards/microchip/{ev74h48a/ev74h48a_p33ak128mc506.dts => dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc506.dts} (100%) delete mode 100644 boards/microchip/ev74h48a/Kconfig.ev74h48a delete mode 100644 boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts create mode 100644 drivers/serial/Kconfig.dspic_uart create mode 100644 drivers/serial/uart_dspic.c create mode 100644 drivers/timer/Kconfig.mchp_dspic33 create mode 100644 drivers/timer/mchp_dspic33_timer.c create mode 100644 dts/bindings/interrupt-controller/microchip,dspic33-intc.yaml create mode 100644 dts/bindings/serial/microchip,dspic33-uart.yaml create mode 100644 dts/bindings/timer/microchip,dspic33-timer.yaml create mode 100644 scripts/west_commands/runners/ipecmd.py create mode 100644 snippets/ram-console/boards/dspic33a_curiosity_p33ak128mc106.overlay diff --git a/arch/Kconfig b/arch/Kconfig index 3fa4bbfb20a3a..e07082c1d6f2e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -171,7 +171,6 @@ config DSPIC bool select ARCH_IS_SET select STACK_GROWS_UP - select ARCH_HAS_CUSTOM_SWAP_TO_MAIN select LITTLE_ENDIAN select ARCH_HAS_THREAD_LOCAL_STORAGE select TOOLCHAIN_SUPPORTS_THREAD_LOCAL_STORAGE @@ -181,9 +180,6 @@ config DSPIC select ATOMIC_OPERATIONS_C select ARCH_HAS_VECTOR_TABLE_RELOCATION select CPU_HAS_ICACHE - select ARCH_HAS_CUSTOM_CPU_IDLE - select ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE - select DYNAMIC_INTERRUPTS select CACHE_MANAGEMENT select TICKLESS_CAPABLE help diff --git a/arch/dspic/Kconfig b/arch/dspic/Kconfig index 401a1a0985640..45ebe011c0ff7 100644 --- a/arch/dspic/Kconfig +++ b/arch/dspic/Kconfig @@ -8,10 +8,16 @@ config ARCH string default "dspic" +config GEN_ISR_TABLES + default y + +config DYNAMIC_INTERRUPTS + default n + config NUM_IRQS - default 287 + default 279 config GEN_IRQ_START_VECTOR - default 8 + default 0 endmenu diff --git a/arch/dspic/core/CMakeLists.txt b/arch/dspic/core/CMakeLists.txt index 66c2cbef22ff3..ecc7a0ea64868 100644 --- a/arch/dspic/core/CMakeLists.txt +++ b/arch/dspic/core/CMakeLists.txt @@ -15,4 +15,4 @@ zephyr_library_sources( reset1.S ) -zephyr_linker_sources(ROM_START SORT_KEY 0x04 vector_table.ld) +zephyr_linker_sources(ROM_START SORT_KEY 0x00 vector_table.ld) diff --git a/arch/dspic/core/cpu_idle.c b/arch/dspic/core/cpu_idle.c index 6636794e2b9e6..d3d984f5aa986 100644 --- a/arch/dspic/core/cpu_idle.c +++ b/arch/dspic/core/cpu_idle.c @@ -6,17 +6,24 @@ #include #include #include +#include #ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_IDLE void arch_cpu_idle(void) { + __builtin_disable_interrupts(); + Idle(); + __builtin_enable_interrupts(); } #endif #ifndef CONFIG_ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE void arch_cpu_atomic_idle(unsigned int key) { - (void)key; + __builtin_disable_interrupts(); + Idle(); + arch_irq_unlock(key); + __builtin_enable_interrupts(); } #endif diff --git a/arch/dspic/core/fatal.c b/arch/dspic/core/fatal.c index 5bfccbfcf7a06..c9b9e75185af6 100644 --- a/arch/dspic/core/fatal.c +++ b/arch/dspic/core/fatal.c @@ -4,12 +4,23 @@ */ #include +#include + +#ifndef _ASMLANGUAGE +#include +#ifdef __cplusplus +extern "C" { +#endif + +LOG_MODULE_REGISTER(dspic, 4); volatile uint32_t reason, address; -#define EXCEPTION_HANDLER __attribute__((interrupt, no_auto_psv, keep)) +#define EXCEPTION_HANDLER __attribute__((interrupt, no_auto_psv, weak)) +#define BUS_ERROR_MASK 0xF +#define MATH_ERROR_MASK 0x1F +#define GENERAL_TRAP_MASK 0x8000000Fu -void EXCEPTION_HANDLER _ReservedTrap7(void); void __attribute__((weak)) TRAPS_halt_on_error(void); void EXCEPTION_HANDLER _BusErrorTrap(void); void EXCEPTION_HANDLER _AddressErrorTrap(void); @@ -20,62 +31,93 @@ void EXCEPTION_HANDLER _GeneralTrap(void); void EXCEPTION_HANDLER _ReservedTrap0(void); void EXCEPTION_HANDLER _ReservedTrap7(void); +void EXCEPTION_HANDLER _ReservedTrap0(void) +{ +} +void EXCEPTION_HANDLER _ReservedTrap7(void) +{ +} + void __attribute__((weak)) TRAPS_halt_on_error(void) { + /* stay here forever */ + while (1) { + } } /** Bus error.**/ void EXCEPTION_HANDLER _BusErrorTrap(void) { - __asm__("nop"); - __asm__("retfie"); + /* Identify bus error via INTCON3, fetch trap address from + * PCTRAP, and reset error flags + */ + reason = INTCON3 & BUS_ERROR_MASK; + address = PCTRAP; + LOG_ERR("ERROR !!! Exception reason = %d, address = 0x%x\n", reason, address); + INTCON3 &= ~(BUS_ERROR_MASK); + PCTRAP = 0; + TRAPS_halt_on_error(); } /** Address error.**/ void EXCEPTION_HANDLER _AddressErrorTrap(void) { - __asm__("nop"); - __asm__("retfie"); + /* fetch trap address from PCTRAP + * and reset error flags + */ + address = PCTRAP; + LOG_ERR("ERROR !!! Exception reason = %s, address = 0x%x\n", "Address Error", address); + INTCON1bits.ADDRERR = 0; + PCTRAP = 0; + TRAPS_halt_on_error(); } /** Illegal instruction.**/ void EXCEPTION_HANDLER _IllegalInstructionTrap(void) { - __asm__("nop"); - __asm__("retfie"); + address = PCTRAP; + LOG_ERR("ERROR !!! Exception reason = %s, address = 0x%x\n", "Illegal Instruction", + address); + INTCON1bits.BADOPERR = 0; + PCTRAP = 0; + TRAPS_halt_on_error(); } /** Math error.**/ void EXCEPTION_HANDLER _MathErrorTrap(void) { - __asm__("nop"); - __asm__("retfie"); + /* Identify math error via INTCON4, fetch trap address from + * PCTRAP, and reset error flags + */ + reason = INTCON4 & MATH_ERROR_MASK; + address = PCTRAP; + LOG_ERR("ERROR !!! Exception reason = %d, address = 0x%x\n", reason, address); + INTCON4 &= ~(MATH_ERROR_MASK); + PCTRAP = 0; + TRAPS_halt_on_error(); } /** Stack error.**/ void EXCEPTION_HANDLER _StackErrorTrap(void) { - __asm__("nop"); - __asm__("retfie"); + INTCON1bits.STKERR = 0; + PCTRAP = 0; + TRAPS_halt_on_error(); } /** Generic error.**/ void EXCEPTION_HANDLER _GeneralTrap(void) { - __asm__("nop"); - __asm__("retfie"); + reason = INTCON5 & GENERAL_TRAP_MASK; + address = PCTRAP; + LOG_ERR("ERROR !!! Exception reason = %d, address = 0x%x\n", reason, address); + INTCON5 &= ~(GENERAL_TRAP_MASK); + PCTRAP = 0; + TRAPS_halt_on_error(); } -/** Reserved Trap0.**/ -void EXCEPTION_HANDLER _ReservedTrap0(void) -{ - __asm__("nop"); - __asm__("retfie"); +#ifdef __cplusplus } +#endif -/** Reserved Trap7.**/ -void EXCEPTION_HANDLER _ReservedTrap7(void) -{ - __asm__("nop"); - __asm__("retfie"); -} +#endif /* _ASMLANGUAGE */ diff --git a/arch/dspic/core/irq_manage.c b/arch/dspic/core/irq_manage.c index 489f4002f2023..51f9eb1328060 100644 --- a/arch/dspic/core/irq_manage.c +++ b/arch/dspic/core/irq_manage.c @@ -6,23 +6,62 @@ #include #include +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + void z_irq_spurious(const void *unused) { - (void)unused; + ARG_UNUSED(unused); + while (1) { + } + return; } void arch_irq_enable(unsigned int irq) { - (void)irq; + volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4, + &IEC5, &IEC6, &IEC7, &IEC8}; + + unsigned int reg_index = irq / (sizeof(uint32_t) << 3); + unsigned int bit_pos = irq % (sizeof(uint32_t) << 3); + + /* Enable the interrupt by setting it's bit in interrupt enable register*/ + *int_enable_reg[reg_index] |= (uint32_t)(1u << bit_pos); + + return; } int arch_irq_is_enabled(unsigned int irq) { - (void)irq; - return 0; + volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4, + &IEC5, &IEC6, &IEC7, &IEC8}; + + unsigned int reg_index = irq / (sizeof(uint32_t) << 3); + unsigned int bit_pos = irq % (sizeof(uint32_t) << 3); + + return ((*int_enable_reg[reg_index] >> bit_pos) & 0x1u); } void arch_irq_disable(unsigned int irq) { - (void)irq; + volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4, + &IEC5, &IEC6, &IEC7, &IEC8}; + + unsigned int reg_index = irq / (sizeof(uint32_t) << 3); + unsigned int bit_pos = irq % (sizeof(uint32_t) << 3); + + /* Disable the interrupt by clearing it's bit in interrupt enable register*/ + *int_enable_reg[reg_index] &= (uint32_t)(~(1u << bit_pos)); + + return; } + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ diff --git a/arch/dspic/core/isr_wrapper.c b/arch/dspic/core/isr_wrapper.c index bc1f4cf2b0962..6a083bc538f2b 100644 --- a/arch/dspic/core/isr_wrapper.c +++ b/arch/dspic/core/isr_wrapper.c @@ -6,17 +6,43 @@ #include #include #include -#include #include +#include /* dsPIC33A interrtup exit routine. Will check if a context * switch is required. If so, z_dspic_do_swap() will be called * to affect the context switch */ -void __attribute__((naked)) z_dspic_exc_exit(void) +static inline __attribute__((always_inline)) void z_dspic_exc_exit(void) { +#ifdef CONFIG_PREEMPT_ENABLED + if ((_current_cpu->nested == 0) && (_kernel.ready_q.cache != _current) && + !k_is_pre_kernel()) { + z_dspic_do_swap(); + } + +#endif /* CONFIG_PREEMPT_ENABLED */ +#ifdef CONFIG_STACK_SENTINEL + z_check_stack_sentinel(); +#endif /* CONFIG_STACK_SENTINEL */ + return; } -void __attribute__((interrupt, naked)) _COMMONInterrupt(void) +void __attribute__((interrupt)) _isr_wrapper(void) { +#ifdef CONFIG_TRACING_ISR + sys_trace_isr_enter(); +#endif /* CONFIG_TRACING_ISR */ + + _current_cpu->nested++; + int32_t irq_number = INTTREGbits.VECNUM - 9; + const struct _isr_table_entry *entry = &_sw_isr_table[irq_number]; + (entry->isr)(entry->arg); + _current_cpu->nested--; + +#ifdef CONFIG_TRACING_ISR + sys_trace_isr_exit(); +#endif /* CONFIG_TRACING_ISR */ + + z_dspic_exc_exit(); } diff --git a/arch/dspic/core/swap.c b/arch/dspic/core/swap.c index 2abee58a4e8fa..32f329c76df33 100644 --- a/arch/dspic/core/swap.c +++ b/arch/dspic/core/swap.c @@ -6,112 +6,10 @@ #include #include #include -#include "kswap.h" #include #include - -void arch_switch_to_main_thread(struct k_thread *main_thread, char *stack_ptr, - k_thread_entry_t _main) -{ - (void)stack_ptr; - (void)_main; - z_current_thread_set(main_thread); - - /* w0 will contain main_thread - * Get the offset to callee saved structure - */ - __asm__ volatile("mov.l #0x28, w1\n\t" - "add w1, w0, w1\n\t"); - - /*Restore all registers*/ - __asm__ volatile("mov.l [w1++], w8\n\t" - "mov.l [w1++], w9\n\t" - "mov.l [w1++], w10\n\t" - "mov.l [w1++], w11\n\t" - "mov.l [w1++], w12\n\t" - "mov.l [w1++], w13\n\t" - "mov.l [w1++], w14\n\t" - - "mov.l [w1++], f8\n\t" - "mov.l [w1++], f9\n\t" - "mov.l [w1++], f10\n\t" - "mov.l [w1++], f11\n\t" - "mov.l [w1++], f12\n\t" - "mov.l [w1++], f13\n\t" - "mov.l [w1++], f14\n\t" - "mov.l [w1++], f15\n\t" - "mov.l [w1++], f16\n\t" - "mov.l [w1++], f17\n\t" - "mov.l [w1++], f18\n\t" - "mov.l [w1++], f19\n\t" - "mov.l [w1++], f20\n\t" - "mov.l [w1++], f21\n\t" - "mov.l [w1++], f22\n\t" - "mov.l [w1++], f23\n\t" - "mov.l [w1++], f24\n\t" - "mov.l [w1++], f25\n\t" - "mov.l [w1++], f26\n\t" - "mov.l [w1++], f27\n\t" - "mov.l [w1++], f28\n\t" - "mov.l [w1++], f29\n\t" - "mov.l [w1++], f30\n\t" - "mov.l [w1++], f31\n\t" - - "mov.l #RCOUNT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #CORCON, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #MODCON, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XMODSRT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XMODEND, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #YMODSRT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #YMODEND, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XBREV, w2\n\t" - "mov.l [w1++], [w2]\n\t" - - "clr A\n\t" - "clr B\n\t" - "slac.l A, [W1++]\n\t" - "sac.l A, [W1++]\n\t" - "suac.l A, [W1++]\n\t" - "slac.l B, [W1++]\n\t" - "sac.l B, [W1++]\n\t" - "suac.l B, [W1++]\n\t" - - "mov.l [w1++], w15\n\t" - "mov.l [w1++], w14\n\t" - "mov.l #SPLIM, w2\n\t" - "mov.l [w1++], [w2]\n\t"); - - /*pop saved stack frame*/ - __asm__ volatile("pop.l f7\n\t" - "pop.l f6\n\t" - "pop.l f5\n\t" - "pop.l f4\n\t" - "pop.l f3\n\t" - "pop.l f2\n\t" - "pop.l f1\n\t" - "pop.l f0\n\t" - "mov.l [--w15], w7\n\t" - "mov.l [--w15], w6\n\t" - "mov.l [--w15], w5\n\t" - "mov.l [--w15], w4\n\t" - "mov.l [--w15], w3\n\t" - "mov.l [--w15], w2\n\t" - "mov.l [--w15], w1\n\t" - "mov.l [--w15], w0\n\t" - "pop.l fcr\n\t" - "pop.l fsr\n\t" - "pop.l RCOUNT\n\t"); -#ifdef CONFIG_INSTRUMENT_THREAD_SWITCHING - z_thread_mark_switched_in(); -#endif -} +#include +#include "kswap.h" int arch_swap(unsigned int key) { @@ -125,11 +23,6 @@ int arch_swap(unsigned int key) /*Check if swap is needed*/ if (_kernel.ready_q.cache != _current) { - /*Backup the current task context*/ - z_dspic_save_context(); - - /*Switch to next task in queue*/ - z_current_thread_set(_kernel.ready_q.cache); z_dspic_do_swap(); } @@ -144,6 +37,7 @@ int arch_swap(unsigned int key) * Make sure the return value is not being intrepreted * wrongly */ + irq_unlock(key); register int result __asm__("w0"); return result; @@ -151,234 +45,3 @@ int arch_swap(unsigned int key) * thread has been context-switched-in again. */ } - -void __attribute__((naked)) z_dspic_save_context(void) -{ - /* Get the current thread callee_saved context - * TODO: - * Need to change constant 0x8, 0x28 with offset symbols - * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET - */ - __asm__ volatile("mov.l #__kernel, w0\n\t" - "mov.l #0x8, w1\n\t" - "add w0, w1, w1\n\t" - "mov.l [w1], w2\n\t" - "mov.l #0x28, w1\n\t" - "add w2, w1, w1\n\t"); - - /*Save all callee saved registers*/ - __asm__ volatile("mov.l w8, [w1++]\n\t" - "mov.l w9, [w1++]\n\t" - "mov.l w10, [w1++]\n\t" - "mov.l w11, [w1++]\n\t" - "mov.l w12, [w1++]\n\t" - "mov.l w13, [w1++]\n\t" - "mov.l w14, [w1++]\n\t" - - "mov.l f8, [w1++]\n\t" - "mov.l f9, [w1++]\n\t" - "mov.l f10, [w1++]\n\t" - "mov.l f11, [w1++]\n\t" - "mov.l f12, [w1++]\n\t" - "mov.l f13, [w1++]\n\t" - "mov.l f14, [w1++]\n\t" - "mov.l f15, [w1++]\n\t" - "mov.l f16, [w1++]\n\t" - "mov.l f17, [w1++]\n\t" - "mov.l f18, [w1++]\n\t" - "mov.l f19, [w1++]\n\t" - "mov.l f20, [w1++]\n\t" - "mov.l f21, [w1++]\n\t" - "mov.l f22, [w1++]\n\t" - "mov.l f23, [w1++]\n\t" - "mov.l f24, [w1++]\n\t" - "mov.l f25, [w1++]\n\t" - "mov.l f26, [w1++]\n\t" - "mov.l f27, [w1++]\n\t" - "mov.l f28, [w1++]\n\t" - "mov.l f29, [w1++]\n\t" - "mov.l f30, [w1++]\n\t" - "mov.l f31, [w1++]\n\t" - - "mov.l #RCOUNT, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #CORCON, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #MODCON, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #XMODSRT, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #XMODEND, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #YMODSRT, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #YMODEND, w2\n\t" - "mov.l [w2], [w1++]\n\t" - "mov.l #XBREV, w2\n\t" - "mov.l [w2], [w1++]\n\t" - - "clr A\n\t" - "clr B\n\t" - "slac.l A, [W1++]\n\t" - "sac.l A, [W1++]\n\t" - "suac.l A, [W1++]\n\t" - "slac.l B, [W1++]\n\t" - "sac.l B, [W1++]\n\t" - "suac.l B, [W1++]\n\t" - - "mov.l w15, [w1++]\n\t" - "mov.l w14, [w1++]\n\t" - "mov.l #SPLIM, w2\n\t" - "mov.l [w2], [w1++]\n\t"); -} - -/* routine which swaps the context. Needs to be written in assembly */ -void __attribute__((naked)) z_dspic_do_swap(void) -{ - /*Adjust stack for co-operative swap*/ - __asm__ volatile( - /*Check if in interrupt context*/ - "mov.l w0, [w15++]\n\t" - "mov.l sr, w0\n\t" - "and #0xe0, w0\n\t" - "bra nz, 1f\n\t" - - /*Not in interrupt context*/ - "mov.l [--w15], w0\n\t" - "push RCOUNT\n\t" - "push.l fsr\n\t" - "push.l fcr\n\t" - "mov.l w0, [w15++]\n\t" - "mov.l w1, [w15++]\n\t" - "mov.l w2, [w15++]\n\t" - "mov.l w3, [w15++]\n\t" - "mov.l w4, [w15++]\n\t" - "mov.l w5, [w15++]\n\t" - "mov.l w6, [w15++]\n\t" - "mov.l w7, [w15++]\n\t" - "push.l f0\n\t" - "push.l f1\n\t" - "push.l f2\n\t" - "push.l f3\n\t" - "push.l f4\n\t" - "push.l f5\n\t" - "push.l f6\n\t" - "push.l f7\n\t" - "mov.l w0, [w15++]\n\t" - - /*In interrupt context*/ - "1:\n\t" - "mov.l [--w15], w0\n\t"); - - /* Get the current thread callee_saved context - * TODO: - * Need to change constant 0x8, 0x28 with offset symbols - * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET - */ - __asm__ volatile("mov.l #__kernel, w0\n\t" - "mov.l #0x8, w1\n\t" - "add w0, w1, w1\n\t" - "mov.l [w1], w2\n\t" - "mov.l #0x28, w1\n\t" - "add w2, w1, w1\n\t"); - - /*Restore all registers*/ - __asm__ volatile("mov.l [w1++], w8\n\t" - "mov.l [w1++], w9\n\t" - "mov.l [w1++], w10\n\t" - "mov.l [w1++], w11\n\t" - "mov.l [w1++], w12\n\t" - "mov.l [w1++], w13\n\t" - "mov.l [w1++], w14\n\t" - - "mov.l [w1++], f8\n\t" - "mov.l [w1++], f9\n\t" - "mov.l [w1++], f10\n\t" - "mov.l [w1++], f11\n\t" - "mov.l [w1++], f12\n\t" - "mov.l [w1++], f13\n\t" - "mov.l [w1++], f14\n\t" - "mov.l [w1++], f15\n\t" - "mov.l [w1++], f16\n\t" - "mov.l [w1++], f17\n\t" - "mov.l [w1++], f18\n\t" - "mov.l [w1++], f19\n\t" - "mov.l [w1++], f20\n\t" - "mov.l [w1++], f21\n\t" - "mov.l [w1++], f22\n\t" - "mov.l [w1++], f23\n\t" - "mov.l [w1++], f24\n\t" - "mov.l [w1++], f25\n\t" - "mov.l [w1++], f26\n\t" - "mov.l [w1++], f27\n\t" - "mov.l [w1++], f28\n\t" - "mov.l [w1++], f29\n\t" - "mov.l [w1++], f30\n\t" - "mov.l [w1++], f31\n\t" - - "mov.l #RCOUNT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #CORCON, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #MODCON, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XMODSRT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XMODEND, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #YMODSRT, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #YMODEND, w2\n\t" - "mov.l [w1++], [w2]\n\t" - "mov.l #XBREV, w2\n\t" - "mov.l [w1++], [w2]\n\t" - - "clr A\n\t" - "clr B\n\t" - "slac.l A, [W1++]\n\t" - "sac.l A, [W1++]\n\t" - "suac.l A, [W1++]\n\t" - "slac.l B, [W1++]\n\t" - "sac.l B, [W1++]\n\t" - "suac.l B, [W1++]\n\t" - - "mov.l [w1++], w15\n\t" - "mov.l [w1++], w14\n\t" - "mov.l #SPLIM, w2\n\t" - "mov.l [w1++], [w2]\n\t"); - - /*pop exception/swap saved stack frame*/ - __asm__ volatile( - /* Check context and only pop the - * esf if in thread context - */ - "mov.l w0, [w15++]\n\t" - "mov.l sr, w0\n\t" - "and #0xe0, w0\n\t" - "bra nz, 1f\n\t" - - /*Thread context*/ - "pop.l f7\n\t" - "pop.l f6\n\t" - "pop.l f5\n\t" - "pop.l f4\n\t" - "pop.l f3\n\t" - "pop.l f2\n\t" - "pop.l f1\n\t" - "pop.l f0\n\t" - "mov.l [--w15], w7\n\t" - "mov.l [--w15], w6\n\t" - "mov.l [--w15], w5\n\t" - "mov.l [--w15], w4\n\t" - "mov.l [--w15], w3\n\t" - "mov.l [--w15], w2\n\t" - "mov.l [--w15], w1\n\t" - "mov.l [--w15], w0\n\t" - "pop.l fcr\n\t" - "pop.l fsr\n\t" - "pop RCOUNT\n\t" - - /*Interrupt context*/ - "1:\n\t" - "nop\n\t"); -} diff --git a/arch/dspic/core/thread.c b/arch/dspic/core/thread.c index 72c470a16995f..2ab6d2861b5d1 100644 --- a/arch/dspic/core/thread.c +++ b/arch/dspic/core/thread.c @@ -7,6 +7,7 @@ #include #define RAM_END 0x00007FFC +#define DSPIC_STATUS_DEFAULT 0 void z_thread_entry(k_thread_entry_t thread, void *arg1, void *arg2, void *arg3); @@ -36,7 +37,12 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *sta * Z_thread_entry(entry, p1, p2, p3) */ init_frame->PC = (uint32_t)z_thread_entry; - init_frame->FRAME = (uint32_t)(void *)init_frame - (uint32_t)1; + /* FRAME pointer used as LR for initial swap function + * In swap function we enter with one SP and exits with another SP + * As the swap function is a naked function, it won't use FP but use that + * place for LR (for the 1st swap, we need to populate initial LR in FP) + */ + init_frame->FRAME = (uint32_t)(void *)init_frame + (sizeof(struct arch_esf)); /** * Set the stack top to the esf structure. The context switch @@ -44,7 +50,7 @@ void arch_new_thread(struct k_thread *thread, k_thread_stack_t *stack, char *sta * the switched thread */ thread->callee_saved.stack = (uint32_t)(void *)init_frame + (sizeof(struct arch_esf)); - thread->callee_saved.frame = (uint32_t)&init_frame->RCOUNT; + thread->callee_saved.frame = (uint32_t)thread->callee_saved.stack; /*TODO: Need to handle splim properly*/ thread->callee_saved.splim = RAM_END; } diff --git a/arch/dspic/core/vector_table.S b/arch/dspic/core/vector_table.S index c495e87f96f6f..8014503095c56 100644 --- a/arch/dspic/core/vector_table.S +++ b/arch/dspic/core/vector_table.S @@ -15,9 +15,10 @@ .global __StackErrorTrap .global __GeneralTrap .global __ReservedTrap7 -.global __COMMONInterrupt +.global _isr_wrapper -.section .exc_vector_table._vector_table_section, code + +.section .exc_vector_table._vector_table_section,code .global __vector_table __vector_table: .long __ReservedTrap0 @@ -28,282 +29,3 @@ __vector_table: .long __MathErrorTrap .long __GeneralTrap .long __ReservedTrap7 - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt - .long __COMMONInterrupt diff --git a/arch/dspic/include/kernel_arch_func.h b/arch/dspic/include/kernel_arch_func.h index 2cb5f487e890d..28bcd17a875ce 100644 --- a/arch/dspic/include/kernel_arch_func.h +++ b/arch/dspic/include/kernel_arch_func.h @@ -25,8 +25,7 @@ extern "C" { #endif -void z_dspic_save_context(void); -void z_dspic_do_swap(void); +extern uint32_t vector_start; /* dsPIC33A interrupt functionality initialization */ static ALWAYS_INLINE void z_dspic_interrupt_init(void) @@ -35,7 +34,6 @@ static ALWAYS_INLINE void z_dspic_interrupt_init(void) * clear all the interrupts, set the interrupt flag status * registers to zero. */ - IFS0 = 0x0; IFS1 = 0x0; IFS2 = 0x0; @@ -45,11 +43,21 @@ static ALWAYS_INLINE void z_dspic_interrupt_init(void) IFS6 = 0x0; IFS7 = 0x0; IFS8 = 0x0; - /* enable nested interrupts */ INTCON1bits.NSTDIS = 0; /* enable global interrupts */ INTCON1bits.GIE = 1; + + /** + * After a reset default values IVTBASEWR will be having value 1, IVTBASELK will be 0 + * even though writing to these bits to make sure IVTBASE register is writable. + */ + PACCON1bits.IVTBASELK = 0; + PACCON1bits.IVTBASEWR = 1; + /* set the new base address */ + IVTBASE = (uint32_t)((void *)&vector_start); + PACCON1bits.IVTBASEWR = 0; + PACCON1bits.IVTBASELK = 1; } /* dsPIC33A fault initialization */ diff --git a/arch/dspic/include/kernel_arch_swap.h b/arch/dspic/include/kernel_arch_swap.h new file mode 100644 index 0000000000000..cd2a1953297e9 --- /dev/null +++ b/arch/dspic/include/kernel_arch_swap.h @@ -0,0 +1,288 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief Private kernel arch swap functions + * + * This file contains function helpers for dspic arch specific thread swap + * helper functions + */ + +#ifndef ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_SWAP_H_ +#define ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_SWAP_H_ + +#ifndef _ASMLANGUAGE + +#include +#include +#include +#include +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#include "kswap.h" + +static inline __attribute__((always_inline)) void z_dspic_save_context(void) +{ + /*Adjust stack for co-operative swap*/ + __asm__ volatile( + /*Check if in interrupt context*/ + "mov.l w0, [w15++]\n\t" + "mov.l sr, w0\n\t" + "and #0xe0, w0\n\t" + "bra nz, 1f\n\t" + + /*Not in interrupt context*/ + "mov.l [--w15], w0\n\t" + /*This unlink is needed to match esf*/ + "ulnk\n\t" + "push RCOUNT\n\t" + "push.l fsr\n\t" + "push.l fcr\n\t" + "mov.l w0, [w15++]\n\t" + "mov.l w1, [w15++]\n\t" + "mov.l w2, [w15++]\n\t" + "mov.l w3, [w15++]\n\t" + "mov.l w4, [w15++]\n\t" + "mov.l w5, [w15++]\n\t" + "mov.l w6, [w15++]\n\t" + "mov.l w7, [w15++]\n\t" + "mov.l w8, [w15++]\n\t" + "push.l f0\n\t" + "push.l f1\n\t" + "push.l f2\n\t" + "push.l f3\n\t" + "push.l f4\n\t" + "push.l f5\n\t" + "push.l f6\n\t" + "push.l f7\n\t" + "lnk #0x0\n\t" + /*in isr lnk is done after esf push*/ + "mov.l w0, [w15++]\n\t" + + /*In interrupt context*/ + "1:\n\t" + "mov.l [--w15], w0\n\t"); + + /* Get the current thread callee_saved context + * TODO: + * Need to change constant 0x8, 0x28 with offset symbols + * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET + */ + __asm__ volatile("mov.l #__kernel, w0\n\t" + "mov.l #0x8, w1\n\t" + "add w0, w1, w1\n\t" + "mov.l [w1], w2\n\t" + "mov.l #0x28, w1\n\t" + "add w2, w1, w1\n\t"); + + /*Save all callee saved registers*/ + __asm__ volatile("mov.l w8, [w1++]\n\t" + "mov.l w9, [w1++]\n\t" + "mov.l w10, [w1++]\n\t" + "mov.l w11, [w1++]\n\t" + "mov.l w12, [w1++]\n\t" + "mov.l w13, [w1++]\n\t" + "mov.l w14, [w1++]\n\t" + + "mov.l f8, [w1++]\n\t" + "mov.l f9, [w1++]\n\t" + "mov.l f10, [w1++]\n\t" + "mov.l f11, [w1++]\n\t" + "mov.l f12, [w1++]\n\t" + "mov.l f13, [w1++]\n\t" + "mov.l f14, [w1++]\n\t" + "mov.l f15, [w1++]\n\t" + "mov.l f16, [w1++]\n\t" + "mov.l f17, [w1++]\n\t" + "mov.l f18, [w1++]\n\t" + "mov.l f19, [w1++]\n\t" + "mov.l f20, [w1++]\n\t" + "mov.l f21, [w1++]\n\t" + "mov.l f22, [w1++]\n\t" + "mov.l f23, [w1++]\n\t" + "mov.l f24, [w1++]\n\t" + "mov.l f25, [w1++]\n\t" + "mov.l f26, [w1++]\n\t" + "mov.l f27, [w1++]\n\t" + "mov.l f28, [w1++]\n\t" + "mov.l f29, [w1++]\n\t" + "mov.l f30, [w1++]\n\t" + "mov.l f31, [w1++]\n\t" + + "mov.l #RCOUNT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #CORCON, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #MODCON, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XMODSRT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XMODEND, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #YMODSRT, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #YMODEND, w2\n\t" + "mov.l [w2], [w1++]\n\t" + "mov.l #XBREV, w2\n\t" + "mov.l [w2], [w1++]\n\t" + + "clr A\n\t" + "clr B\n\t" + "slac.l A, [W1++]\n\t" + "sac.l A, [W1++]\n\t" + "suac.l A, [W1++]\n\t" + "slac.l B, [W1++]\n\t" + "sac.l B, [W1++]\n\t" + "suac.l B, [W1++]\n\t" + + "mov.l w15, [w1++]\n\t" + "mov.l w14, [w1++]\n\t" + "mov.l #SPLIM, w2\n\t" + "mov.l [w2], [w1++]\n\t"); +} + +static inline __attribute__((always_inline)) void z_dspic_restore_context(void) +{ + /* Get the current thread callee_saved context + * TODO: + * Need to change constant 0x8, 0x28 with offset symbols + * ___cpu_t_current_OFFSET, ___thread_t_callee_saved_OFFSET + */ + __asm__ volatile("mov.l #__kernel, w0\n\t" + "mov.l #0x8, w1\n\t" + "add w0, w1, w1\n\t" + "mov.l [w1], w2\n\t" + "mov.l #0x28, w1\n\t" + "add w2, w1, w1\n\t"); + + /*Restore all registers*/ + __asm__ volatile("mov.l [w1++], w8\n\t" + "mov.l [w1++], w9\n\t" + "mov.l [w1++], w10\n\t" + "mov.l [w1++], w11\n\t" + "mov.l [w1++], w12\n\t" + "mov.l [w1++], w13\n\t" + "mov.l [w1++], w14\n\t" + + "mov.l [w1++], f8\n\t" + "mov.l [w1++], f9\n\t" + "mov.l [w1++], f10\n\t" + "mov.l [w1++], f11\n\t" + "mov.l [w1++], f12\n\t" + "mov.l [w1++], f13\n\t" + "mov.l [w1++], f14\n\t" + "mov.l [w1++], f15\n\t" + "mov.l [w1++], f16\n\t" + "mov.l [w1++], f17\n\t" + "mov.l [w1++], f18\n\t" + "mov.l [w1++], f19\n\t" + "mov.l [w1++], f20\n\t" + "mov.l [w1++], f21\n\t" + "mov.l [w1++], f22\n\t" + "mov.l [w1++], f23\n\t" + "mov.l [w1++], f24\n\t" + "mov.l [w1++], f25\n\t" + "mov.l [w1++], f26\n\t" + "mov.l [w1++], f27\n\t" + "mov.l [w1++], f28\n\t" + "mov.l [w1++], f29\n\t" + "mov.l [w1++], f30\n\t" + "mov.l [w1++], f31\n\t" + + "mov.l #RCOUNT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #CORCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #MODCON, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODSRT, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #YMODEND, w2\n\t" + "mov.l [w1++], [w2]\n\t" + "mov.l #XBREV, w2\n\t" + "mov.l [w1++], [w2]\n\t" + + "clr A\n\t" + "clr B\n\t" + "slac.l A, [W1++]\n\t" + "sac.l A, [W1++]\n\t" + "suac.l A, [W1++]\n\t" + "slac.l B, [W1++]\n\t" + "sac.l B, [W1++]\n\t" + "suac.l B, [W1++]\n\t" + + "mov.l [w1++], w15\n\t" + "mov.l [w1++], w14\n\t" + "mov.l #SPLIM, w2\n\t" + "mov.l [w1++], [w2]\n\t"); + + /*pop exception/swap saved stack frame*/ + __asm__ volatile( + /* Check context and only pop the + * esf if in thread context + */ + "mov.l w0, [w15++]\n\t" + "mov.l sr, w0\n\t" + "and #0xe0, w0\n\t" + "mov.l [--w15], w0\n\t" + "bra nz, 1f\n\t" + + /*in isr the unlink is done before esf pop*/ + "ulnk\n\t" + /*Thread context*/ + "pop.l f7\n\t" + "pop.l f6\n\t" + "pop.l f5\n\t" + "pop.l f4\n\t" + "pop.l f3\n\t" + "pop.l f2\n\t" + "pop.l f1\n\t" + "pop.l f0\n\t" + "mov.l [--w15], w8\n\t" + "mov.l [--w15], w7\n\t" + "mov.l [--w15], w6\n\t" + "mov.l [--w15], w5\n\t" + "mov.l [--w15], w4\n\t" + "mov.l [--w15], w3\n\t" + "mov.l [--w15], w2\n\t" + "mov.l [--w15], w1\n\t" + "mov.l [--w15], w0\n\t" + "pop.l fcr\n\t" + "pop.l fsr\n\t" + "pop RCOUNT\n\t" + "lnk #0x0\n\t" + + /*Interrupt context*/ + "1:\n\t" + "nop\n\t"); +} + +/* routine which swaps the context. Needs to be written in assembly */ +static inline __attribute__((always_inline)) void z_dspic_do_swap(void) +{ + z_dspic_save_context(); + + /*Switch to next task in queue*/ + z_current_thread_set(_kernel.ready_q.cache); + + z_dspic_restore_context(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ + +#endif /* ZEPHYR_ARCH_DSPIC_INCLUDE_KERNEL_ARCH_SWAP_H_ */ diff --git a/boards/microchip/dspic33/dspic33a_curiosity/Kconfig.dspic33a_curiosity b/boards/microchip/dspic33/dspic33a_curiosity/Kconfig.dspic33a_curiosity new file mode 100644 index 0000000000000..f0e2ba4c20ae4 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/Kconfig.dspic33a_curiosity @@ -0,0 +1,5 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config BOARD_DSPIC33A_CURIOSITY + select SOC_P33AK128MC106 if BOARD_DSPIC33A_CURIOSITY_P33AK128MC106 diff --git a/boards/microchip/dspic33/dspic33a_curiosity/board.cmake b/boards/microchip/dspic33/dspic33a_curiosity/board.cmake new file mode 100644 index 0000000000000..2138e0440d0bd --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/board.cmake @@ -0,0 +1,16 @@ +# Board-specific CMake configuration for DSPIC33A curiosity board +# SPDX-License-Identifier: Apache-2.0 +set(XCDSC_ZEPHYR_HOME ${XCDSC_TOOLCHAIN_PATH}/bin) +set(XCDSC_GNU_PREFIX xc-dsc-) + +set(BOARD_FLASH_RUNNER ipecmd) +set(BOARD_DEBUG_RUNNER mdb) + +if(CONFIG_BOARD_DSPIC33A_CURIOSITY_P33AK128MC106) + message(STATUS "device selected") + board_runner_args(ipecmd "--device=33AK128MC106" "--flash-tool=PKOB4") +endif() + +board_finalize_runner_args(ipecmd) + +set_property(GLOBAL PROPERTY BOARD_SUPPORTS_DEBUGGER TRUE) diff --git a/boards/microchip/ev74h48a/board.yml b/boards/microchip/dspic33/dspic33a_curiosity/board.yml similarity index 84% rename from boards/microchip/ev74h48a/board.yml rename to boards/microchip/dspic33/dspic33a_curiosity/board.yml index d3e8b7b2b38f7..561db73fdf4a9 100644 --- a/boards/microchip/ev74h48a/board.yml +++ b/boards/microchip/dspic33/dspic33a_curiosity/board.yml @@ -1,5 +1,5 @@ board: - name: ev74h48a + name: dspic33a_curiosity full_name: dsPIC33A Curiosity Platform Development Board vendor: microchip socs: diff --git a/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.dts b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.dts new file mode 100644 index 0000000000000..1ae8e10b0a118 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.dts @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include "p33ak128mc106.dtsi" + +/ { + model = "Microchip dsPIC33A Curiosity Platform Development Board"; + compatible = "microchip,dspic33a-criosity-p33ak128mc106"; + + chosen { + zephyr,flash = &flash0; + zephyr,sram = &sram0; + zephyr,serial = &uart1; + zephyr,console = &uart1; + }; + + aliases { + uart-0 = &uart1; + }; +}; + +&cpu0 { + clock-frequency = <8000000>; + status = "okay"; + cpu-power-states = <&idle>; +}; + +&timer1 { + clock-frequency = <8000000>; + status = "okay"; +}; + +&uart1 { + status = "okay"; +}; diff --git a/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.yaml b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.yaml new file mode 100644 index 0000000000000..153574ec0de35 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106.yaml @@ -0,0 +1,14 @@ +identifier: dspic33a_curiosity/p33ak128mc106 +name: EV74H48A EVB DSPIC33AK128MC106 +type: mcu +arch: dspic +toolchain: + - xcdsc +ram: 16 +flash: 128 +supported: + - uart + - timer +testing: + default: true +vendor: microchip diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig similarity index 55% rename from boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig rename to boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig index 0be34a7de4122..cbfee96cec289 100644 --- a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106_defconfig +++ b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig @@ -1,6 +1,24 @@ -# Enables the RAM-based console backend for logging output. +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +CONFIG_LOG=y +CONFIG_LOG_MODE_MINIMAL=y +CONFIG_PRINTK=y CONFIG_CONSOLE=y -CONFIG_RAM_CONSOLE=y +CONFIG_STDOUT_CONSOLE=n + +# For LOG_MODE_MINIMAL using UART +CONFIG_UART_CONSOLE=y +CONFIG_LOG_PRINTK=n +CONFIG_EARLY_CONSOLE=y +CONFIG_SERIAL=y + +# for LOG_MODE_IMMEDIATE using UART +# Uncomment below if using LOG_MODE_IMMEDIATE instead +# CONFIG_UART_CONSOLE=y +# CONFIG_LOG_ALWAYS_RUNTIME=y +# CONFIG_EARLY_CONSOLE=y +# CONFIG_SERIAL=y # Enables support for GPIO drivers on the target platform. # CONFIG_GPIO=y diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc506.dts similarity index 100% rename from boards/microchip/ev74h48a/ev74h48a_p33ak128mc506.dts rename to boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc506.dts diff --git a/boards/microchip/ev74h48a/Kconfig.ev74h48a b/boards/microchip/ev74h48a/Kconfig.ev74h48a deleted file mode 100644 index b2698d589d6ae..0000000000000 --- a/boards/microchip/ev74h48a/Kconfig.ev74h48a +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2025, Microchip Technology Inc. -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_EV74H48A - select SOC_P33AK128MC106 if BOARD_EV74H48A_P33AK128MC106 diff --git a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts b/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts deleted file mode 100644 index edb8f3bd089c1..0000000000000 --- a/boards/microchip/ev74h48a/ev74h48a_p33ak128mc106.dts +++ /dev/null @@ -1,22 +0,0 @@ -/dts-v1/; -#include "p33ak128mc106.dtsi" - -/ { - model = "Microchip dsPIC33A Curiosity Platform Development Board"; - compatible = "microchip,ev74h48a-p33ak128mc106"; - - chosen { - zephyr,flash = &flash0; - zephyr,sram = &sram0; - }; -}; - -&cpu0 { - clock-frequency = <8000000>; - status = "okay"; - cpu-power-states = <&idle>; -}; - -&timer1 { - status = "okay"; -}; diff --git a/cmake/compiler/xcdsc/generic.cmake b/cmake/compiler/xcdsc/generic.cmake index 8dad7c4c2113e..7b5dd556de348 100644 --- a/cmake/compiler/xcdsc/generic.cmake +++ b/cmake/compiler/xcdsc/generic.cmake @@ -2,7 +2,7 @@ set(CMAKE_SYSTEM_NAME Generic) set(CMAKE_SYSTEM_PROCESSOR ${ARCH}) # Find and validate the xc-dsc-gcc compiler binary find_program(CMAKE_C_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH REQUIRED ) -add_definitions(-D__XC_DSC__) +set(CMAKE_C_FLAGS -D__XC_DSC__) # Get compiler version execute_process( COMMAND ${CMAKE_C_COMPILER} --version diff --git a/cmake/linker/xcdsc/target.cmake b/cmake/linker/xcdsc/target.cmake index e6ee42fdcd74a..0f152caabaaec 100644 --- a/cmake/linker/xcdsc/target.cmake +++ b/cmake/linker/xcdsc/target.cmake @@ -6,6 +6,8 @@ set(XCDSC_BIN_PREFIX xc-dsc-) find_program(CMAKE_LINKER NAMES ${XCDSC_BIN_PREFIX}ld PATHS ${TOOLCHAIN_HOME} NO_DEFAULT_PATH) # Generate linker script using preprocessor macro(configure_linker_script linker_script_gen linker_pass_define) + set(template_script_defines ${linker_pass_define}) + list(TRANSFORM template_script_defines PREPEND "-D") set(extra_dependencies ${ARGN}) if(DEFINED SOC_LINKER_SCRIPT) cmake_path(GET SOC_LINKER_SCRIPT PARENT_PATH soc_linker_script_includes) @@ -19,6 +21,8 @@ macro(configure_linker_script linker_script_gen linker_pass_define) ${extra_dependencies} ${linker_script_dep} COMMAND ${CMAKE_C_COMPILER} -x assembler-with-cpp -MD -MF ${linker_script_gen}.dep -MT ${linker_script_gen} + -D_LINKER + -D_ASM_LANGUAGE -D__XCDSC_LINKER_CMD__ -imacros ${AUTOCONF_H} -I${ZEPHYR_BASE}/include @@ -83,7 +87,7 @@ macro(toolchain_linker_finalize) list(APPEND zephyr_std_libs "${link_flag}") endforeach() string(REPLACE ";" " " zephyr_std_libs "${zephyr_std_libs}") - set(link_libraries " -o ${zephyr_std_libs}") + set(link_libraries " -o ${zephyr_std_libs}") set(common_link "${link_libraries}") set(CMAKE_ASM_LINK_EXECUTABLE "${common_link}") set(CMAKE_C_LINK_EXECUTABLE " ${common_link}") diff --git a/drivers/console/ram_console.c b/drivers/console/ram_console.c index 0206926d50e2d..57bb6d5f51ec1 100644 --- a/drivers/console/ram_console.c +++ b/drivers/console/ram_console.c @@ -53,7 +53,7 @@ static int ram_console_init(void) #endif __printk_hook_install(ram_console_out); -#ifdef TO_BE_IMPLEMENTED_LATER +#ifndef CONFIG_DSPIC __stdout_hook_install(ram_console_out); #endif return 0; diff --git a/drivers/serial/CMakeLists.txt b/drivers/serial/CMakeLists.txt index 96574f8714ad2..91fd10c3d1a3e 100644 --- a/drivers/serial/CMakeLists.txt +++ b/drivers/serial/CMakeLists.txt @@ -31,6 +31,7 @@ zephyr_library_sources_ifdef(CONFIG_UART_CC23X0 uart_cc23x0.c) zephyr_library_sources_ifdef(CONFIG_UART_CC32XX uart_cc32xx.c) zephyr_library_sources_ifdef(CONFIG_UART_CDNS uart_cdns.c) zephyr_library_sources_ifdef(CONFIG_UART_CMSDK_APB uart_cmsdk_apb.c) +zephyr_library_sources_ifdef(CONFIG_UART_DSPIC uart_dspic.c) zephyr_library_sources_ifdef(CONFIG_UART_EFINIX_SAPPIHIRE uart_efinix_sapphire.c) zephyr_library_sources_ifdef(CONFIG_UART_EMUL uart_emul.c) zephyr_library_sources_ifdef(CONFIG_UART_ENE_KB106X uart_ene_kb106x.c) diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ea3fbed123bac..75b851b5eecc5 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -172,6 +172,7 @@ rsource "Kconfig.cc23x0" rsource "Kconfig.cc32xx" rsource "Kconfig.cdns" rsource "Kconfig.cmsdk_apb" +rsource "Kconfig.dspic_uart" rsource "Kconfig.efinix_sapphire" rsource "Kconfig.emul" rsource "Kconfig.ene" diff --git a/drivers/serial/Kconfig.dspic_uart b/drivers/serial/Kconfig.dspic_uart new file mode 100644 index 0000000000000..bf582fb128c66 --- /dev/null +++ b/drivers/serial/Kconfig.dspic_uart @@ -0,0 +1,10 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + + +config UART_DSPIC + bool "dsPIC33A UART driver" + default y + select SERIAL_HAS_DRIVER + help + Enable support for the dsPIC33A UART driver. diff --git a/drivers/serial/uart_dspic.c b/drivers/serial/uart_dspic.c new file mode 100644 index 0000000000000..c8f1542012669 --- /dev/null +++ b/drivers/serial/uart_dspic.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include + +#ifndef _ASMLANGUAGE +#include +#endif + +#define DT_DRV_COMPAT microchip_dspic33_uart + +#define OFFSET_MODE 0x00U +#define OFFSET_STA 0x04U +#define OFFSET_TXREG 0x10U +#define OFFSET_BRG 0x08U +#define OFFSET_RXREG 0x0CU +#define BIT_UTXEN 0x00000020U +#define BIT_URXEN 0x00000010U +#define BIT_UARTEN 0x00008000U +#define BIT_TXBF 0x00100000U +#define BIT_RXBE 0x00020000U +#define FRACTIONAL_BRG 0x8000000U + +#define CALCULATE_BRG(baudrate) \ + ((ceil(((double)(sys_clock_hw_cycles_per_sec())) / ((double)(2U * (baudrate)))))) +const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(uart1)); +static struct k_spinlock lock; + +struct uart_dspic_config { + uint32_t base; + uint32_t baudrate; +}; + +static void uart_dspic_poll_out(const struct device *dev, unsigned char c) +{ + k_spinlock_key_t key; + const struct uart_dspic_config *cfg = dev->config; + volatile uint32_t *UxSTA = (void *)(cfg->base + OFFSET_STA); + volatile uint32_t *UxTXREG = (void *)(cfg->base + OFFSET_TXREG); + + /* Wait until there is space in the TX FIFO */ + while ((bool)(void *)((*UxSTA) & BIT_TXBF)) { + ; + } + key = k_spin_lock(&lock); + *UxTXREG = c; + k_spin_unlock(&lock, key); +} + +static int uart_dspic_poll_in(const struct device *dev, unsigned char *c) +{ + k_spinlock_key_t key; + const struct uart_dspic_config *cfg = dev->config; + volatile uint32_t *UxSTA = (void *)(cfg->base + OFFSET_STA); + volatile uint32_t *UxRXREG = (void *)(cfg->base + OFFSET_RXREG); + int ret_val; + + key = k_spin_lock(&lock); + /* If receiver buffer is empty, return -1 */ + if ((*UxSTA & BIT_RXBE) != 0U) { + ret_val = -EPERM; + } + + else { + *c = *UxRXREG & 0xFF; + ret_val = 0; + } + + k_spin_unlock(&lock, key); + return ret_val; +} + +static int uart_dspic_init(const struct device *dev) +{ + LATB = 0x0040UL; + TRISB = 0x0FBFUL; + ANSELA = 0x0FFFUL; + ANSELB = 0x033FUL; + + /* Assign U1TX to RP23 and U1RX to RP24*/ + _RP23R = 9; + _U1RXR = 24; + const struct uart_dspic_config *cfg = dev->config; + volatile uint32_t *UxCON = (void *)(cfg->base + OFFSET_MODE); + + /* Setting the baudrate */ + *UxCON = FRACTIONAL_BRG; + volatile uint32_t *UxBRG = (void *)(cfg->base + OFFSET_BRG); + *UxBRG = (uint32_t)CALCULATE_BRG(cfg->baudrate); + + /* Enable UART */ + *UxCON |= BIT_UARTEN | BIT_UTXEN | BIT_URXEN; + + return 0; +} + +static const struct uart_driver_api uart_dspic_api = { + .poll_out = uart_dspic_poll_out, + .poll_in = uart_dspic_poll_in, +}; + +#define UART_DSPIC_INIT(inst) \ + static const struct uart_dspic_config uart_dspic_config_##inst = { \ + .base = DT_REG_ADDR(DT_INST(inst, microchip_dspic33_uart)), \ + .baudrate = DT_PROP(DT_INST(inst, microchip_dspic33_uart), current_speed), \ + }; \ + DEVICE_DT_INST_DEFINE(inst, uart_dspic_init, NULL, NULL, &uart_dspic_config_##inst, \ + PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, &uart_dspic_api); + +DT_INST_FOREACH_STATUS_OKAY(UART_DSPIC_INIT) diff --git a/drivers/timer/CMakeLists.txt b/drivers/timer/CMakeLists.txt index 3c488da9a3e72..d068a832fda24 100644 --- a/drivers/timer/CMakeLists.txt +++ b/drivers/timer/CMakeLists.txt @@ -21,6 +21,7 @@ zephyr_library_sources_ifdef(CONFIG_ITE_IT51XXX_TIMER ite_it51xxx_timer.c) zephyr_library_sources_ifdef(CONFIG_ITE_IT8XXX2_TIMER ite_it8xxx2_timer.c) zephyr_library_sources_ifdef(CONFIG_LEON_GPTIMER leon_gptimer.c) zephyr_library_sources_ifdef(CONFIG_LITEX_TIMER litex_timer.c) +zephyr_library_sources_ifdef(CONFIG_MCHP_DSPIC33_TIMER mchp_dspic33_timer.c) zephyr_library_sources_ifdef(CONFIG_MCHP_MEC5_KTIMER mchp_mec5_ktimer.c) zephyr_library_sources_ifdef(CONFIG_MCHP_XEC_RTOS_TIMER mchp_xec_rtos_timer.c) zephyr_library_sources_ifdef(CONFIG_MCHP_SAM_PIT64B_TIMER mchp_sam_pit64b_timer.c) diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index c154370c45630..484e1040482aa 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -78,6 +78,7 @@ source "drivers/timer/Kconfig.it51xxx" source "drivers/timer/Kconfig.ite_it8xxx2" source "drivers/timer/Kconfig.leon_gptimer" source "drivers/timer/Kconfig.litex" +source "drivers/timer/Kconfig.mchp_dspic33" source "drivers/timer/Kconfig.mchp_xec_rtos" source "drivers/timer/Kconfig.mchp_sam" source "drivers/timer/Kconfig.mcux_gpt" diff --git a/drivers/timer/Kconfig.mchp_dspic33 b/drivers/timer/Kconfig.mchp_dspic33 new file mode 100644 index 0000000000000..7868244f1c0c6 --- /dev/null +++ b/drivers/timer/Kconfig.mchp_dspic33 @@ -0,0 +1,10 @@ +# Copyright (C) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config MCHP_DSPIC33_TIMER + bool "Microchip DSPIC33A timer" + default y + depends on DT_HAS_MICROCHIP_DSPIC33_TIMER_ENABLED + help + This module implements a kernel device driver for the Microchip + DSPIC33A timer 1 diff --git a/drivers/timer/mchp_dspic33_timer.c b/drivers/timer/mchp_dspic33_timer.c new file mode 100644 index 0000000000000..ec0470fe206d2 --- /dev/null +++ b/drivers/timer/mchp_dspic33_timer.c @@ -0,0 +1,190 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#ifndef ZEPHYR_ARCH_DSPIC33AK_INCLUDE_ARCH_H_ +#define ZEPHYR_ARCH_DSPIC33AK_INCLUDE_ARCH_H_ + +#define DT_DRV_COMPAT microchip_dspic33_timer + +#include +#include +#include +#include +#include +#include + +#define TIMER1_CYCLES_PER_TICK \ + ((sys_clock_hw_cycles_per_sec()) / \ + (2 * DT_INST_PROP(0, prescalar) * CONFIG_SYS_CLOCK_TICKS_PER_SEC)) + +#define MAX_TIMER_CLOCK_CYCLES 0xFFFFFFFFu +static struct k_spinlock lock; + +uint8_t map_prescaler_to_bits(uint32_t val) +{ + uint8_t ret_val; + + switch (val) { + case 1: + ret_val = 0b00; + break; + case 8: + ret_val = 0b01; + break; + case 64: + ret_val = 0b10; + break; + case 128: + ret_val = 0b11; + break; + default: + ret_val = 0b00; + break; + } + return ret_val; +} + +static void configure_timer1(void) +{ + const uint32_t timer_count = (uint32_t)TIMER1_CYCLES_PER_TICK - 1U; + + /* clear timer control and timer count register */ + T1CONbits.ON = 0; + T1CONbits.TCS = 0; + T1CONbits.TCKPS = map_prescaler_to_bits(DT_INST_PROP(0, prescalar)); + TMR1 = 0; + IEC1bits.T1IE = 0; + IFS1bits.T1IF = 0; + + /* set the time out count */ + PR1 = (uint32_t)timer_count; + + /* Start the timer. */ + T1CONbits.ON = 1; +} + +/** + * @brief Return the current 32-bit cycle count from a hardware timer + */ +uint32_t sys_clock_cycle_get_32(void) +{ + return TMR1; +} + +uint32_t sys_clock_elapsed(void) +{ + uint32_t ticks_elapsed; + k_spinlock_key_t key; + + do { + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + ticks_elapsed = 0; + break; + } + key = k_spin_lock(&lock); + + /* Compute the number of ticks from the last sys_clock_announce callback. + * Since timer1 counter always starts from 0 when the sys_clock_announce + * Call is made, the ticks elapsed is current timer1 count divided by + * Number of cycles per tick + */ + ticks_elapsed = (uint32_t)TMR1 < (uint32_t)TIMER1_CYCLES_PER_TICK + ? 0 + : (uint32_t)TMR1 / (uint32_t)TIMER1_CYCLES_PER_TICK; + k_spin_unlock(&lock, key); + } while (0); + + return ticks_elapsed; +} + +void sys_clock_set_timeout(int32_t ticks, bool idle) +{ + uint32_t next_count; + k_spinlock_key_t key; + + ARG_UNUSED(idle); + + do { + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + + /* If it is not in tickles mode, no need to change the + * Timeout interval, it will periodically interrupt + * At every tick + */ + break; + } + + /* check if it is K_TICKS_FOREVER, is so set to max cycles */ + next_count = (ticks == K_TICKS_FOREVER) + ? MAX_TIMER_CLOCK_CYCLES + : (uint32_t)(ticks * TIMER1_CYCLES_PER_TICK); + key = k_spin_lock(&lock); + + /* clear the timer1 counter register and set the period register to the + * New timeout value. This should be done with TIMER1 disabled + */ + T1CONbits.ON = 0; + TMR1 = 0; + PR1 = next_count; + T1CONbits.ON = 1; + k_spin_unlock(&lock, key); + } while (0); + +} + +/* Timer1 ISR */ +static void timer1_isr(const void *arg) +{ + uint32_t elapsed_ticks; + k_spinlock_key_t key; + + ARG_UNUSED(arg); + + /* compute the number of elapsed ticks. For both tickles and tick + * Based kernel, it will be the period count divided by the number + * Of cycles per tick. For tickles, the period would have been set + * To the next event time. + */ + elapsed_ticks = (uint32_t)PR1 / (uint32_t)TIMER1_CYCLES_PER_TICK; + key = k_spin_lock(&lock); + + /* Clear the timer interrupt flag status bit*/ + IFS1bits.T1IF = 0; + + if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { + /* If not in tickles mode set the interrupt to happen at the next + * Tick. Clear the timer1 counter register and set the period register + * to the tick timeout value. This should be done with TIMER1 disabled. + */ + T1CONbits.ON = 0; + PR1 = (uint32_t)TIMER1_CYCLES_PER_TICK; + T1CONbits.ON = 1; + } + k_spin_unlock(&lock, key); + + /* notify the kernel about the tick */ + sys_clock_announce(elapsed_ticks); +} + +/* Initialize the system clock driver */ +int sys_clock_driver_init(void) +{ + /* connect the timer1 isr to the interrupt. The interrupt number + * Is obtained from the timer device node + */ + IRQ_CONNECT(DT_INST_IRQN(0), DT_INST_IRQ(0, priority), timer1_isr, NULL, 0); + + /* configure timer1 with cycles per tic as the Period count. + * Every interrupt will reload the period register with the + * next interrupt tick count + */ + configure_timer1(); + irq_enable(DT_INST_IRQN(0)); + return 0; +} + +#endif /* ZEPHYR_ARCH_DSPIC33AK_INCLUDE_ARCH_H_ */ + +SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/dts/bindings/interrupt-controller/microchip,dspic33-intc.yaml b/dts/bindings/interrupt-controller/microchip,dspic33-intc.yaml new file mode 100644 index 0000000000000..8db2f9f30ef8f --- /dev/null +++ b/dts/bindings/interrupt-controller/microchip,dspic33-intc.yaml @@ -0,0 +1,19 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip dsPIC33 Interrupt Controller + +compatible: "microchip,dspic33-intc" + +include: [interrupt-controller.yaml, base.yaml] + +properties: + interrupt-controller: + type: boolean + + "#interrupt-cells": + const: 2 + +interrupt-cells: + - irq + - priority diff --git a/dts/bindings/serial/microchip,dspic33-uart.yaml b/dts/bindings/serial/microchip,dspic33-uart.yaml new file mode 100644 index 0000000000000..be59014316e1c --- /dev/null +++ b/dts/bindings/serial/microchip,dspic33-uart.yaml @@ -0,0 +1,19 @@ +# microchip,dspic33-uart.yaml + +description: Microchip dsPIC33 UART controller + +compatible: "microchip,dspic33-uart" + +include: uart-controller.yaml + +properties: + reg: + required: true + + clock-frequency: + type: int + required: true + + status: + type: string + required: true diff --git a/dts/bindings/timer/microchip,dspic33-timer.yaml b/dts/bindings/timer/microchip,dspic33-timer.yaml new file mode 100644 index 0000000000000..e2029a20c5189 --- /dev/null +++ b/dts/bindings/timer/microchip,dspic33-timer.yaml @@ -0,0 +1,26 @@ +# Copyright (c) 2025 Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +description: Microchip DSPIC33 timer + +compatible: "microchip,dspic33-timer" + +include: base.yaml + +properties: + reg: + required: true + + clock-frequency: + type: int + required: true + + prescalar: + type: int + required: true + + interrupts: + required: true + + label: + type: string diff --git a/dts/dspic/p33ak128mc106.dtsi b/dts/dspic/p33ak128mc106.dtsi index e29d6eece8571..ad37b0c94029d 100644 --- a/dts/dspic/p33ak128mc106.dtsi +++ b/dts/dspic/p33ak128mc106.dtsi @@ -1,4 +1,4 @@ -/** +/* * Copyright (c) 2025, Microchip Technology Inc. * SPDX-License-Identifier: Apache-2.0 */ @@ -35,26 +35,47 @@ soc: soc { - compatible = "microchip,p33ak128mc106-soc"; + compatible = "microchip,p33ak128mc106-soc"; #address-cells = <1>; - #size-cells = <0>; + #size-cells = <1>; - flash0: flash@800004 { + flash0: flash@800000 { compatible = "zephyr,flash"; - reg = <0x800004 0x1FFFC>; + reg = <0x800000 0x20000>; label = "FLASH"; }; sram0: memory@4000 { compatible = "zephyr,memory"; - reg = <0x4000 0x4000>; + reg = <0x4000 0x20000>; label = "SRAM"; }; + intc0: interrupt-controller@0 { + compatible = "microchip,dspic33-intc"; + reg = <0x0 0x1>; + interrupt-controller; + #address-cells = <0>; + #interrupt-cells = <2>; + }; + timer1: timer@1E00 { compatible = "microchip,dspic33-timer"; - reg = <0x1E00 0x10>; + reg = <0x1E00 0xC>; + clock-frequency = <4000000>; + prescalar = <8>; + interrupt-parent = <&intc0>; + interrupts = <48 1>; label = "TIMER_1"; + status = "okay"; + }; + + uart1: uart@1700 { + compatible = "microchip,dspic33-uart"; + reg = <0x1700 0x28>; + clock-frequency = <4000000>; + current-speed = <115200>; + status = "okay"; }; }; }; diff --git a/include/zephyr/arch/dspic/arch.h b/include/zephyr/arch/dspic/arch.h index 062ba8164e409..0d01867f5bdc0 100644 --- a/include/zephyr/arch/dspic/arch.h +++ b/include/zephyr/arch/dspic/arch.h @@ -19,10 +19,15 @@ #define ARCH_STACK_PTR_ALIGN 4 -#define DSPIC_STATUS_DEFAULT 0 +#define IRQ_KEY_ILR_IRQ_MASK 0x7 +#define DSPIC_STATUS_DEFAULT 0 +#define DSPIC_PRIORITY_BITS 3u +#define DSPIC_PRIORITY_WIDTH DSPIC_PRIORITY_BITS + 1u +#define DSPIC_IRQ_PER_REG 8u +#define DSPIC_PRIORITY_MASK ((1u << DSPIC_PRIORITY_BITS) - 1u) #ifndef _ASMLANGUAGE - +#include #ifdef __cplusplus extern "C" { #endif @@ -32,6 +37,9 @@ void arch_irq_disable(unsigned int irq); int arch_irq_is_enabled(unsigned int irq); void z_irq_spurious(const void *unused); +/* dsPIC has no MMU, so device_map() is replaced with a direct assignment */ +#define device_map(virt, phys, size, flags) *(virt) = (phys) + /** * Configure a static interrupt. * @@ -51,9 +59,9 @@ void z_irq_spurious(const void *unused); z_dspic_irq_priority_set(irq_p, priority_p, flags_p); \ } -#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, isr_param_p, flags_p) \ +#define ARCH_IRQ_DIRECT_CONNECT(irq_p, priority_p, isr_p, flags_p) \ { \ - Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p, isr_param_p); \ + Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_p); \ z_dspic_irq_priority_set(irq_p, priority_p, flags_p); \ } @@ -61,25 +69,37 @@ void z_irq_spurious(const void *unused); static ALWAYS_INLINE void z_dspic_irq_priority_set(unsigned int irq, unsigned int prio, uint32_t flags) { + ARG_UNUSED(flags); + volatile unsigned int reg_index = irq / DSPIC_IRQ_PER_REG; + volatile unsigned int bit_pos = (irq % DSPIC_IRQ_PER_REG) * (DSPIC_PRIORITY_WIDTH); + volatile uint32_t *prior_reg = (volatile uint32_t *)(&IPC0 + reg_index); + *prior_reg &= ~(DSPIC_PRIORITY_MASK << bit_pos); + *prior_reg |= (prio & DSPIC_PRIORITY_MASK) << bit_pos; } static ALWAYS_INLINE void arch_irq_unlock(unsigned int key) { + __builtin_write_DISICTL(key & IRQ_KEY_ILR_IRQ_MASK); + __builtin_enable_interrupts(); } static ALWAYS_INLINE bool arch_irq_unlocked(unsigned int key) { - return 0; + return ((key & IRQ_KEY_ILR_IRQ_MASK) == IRQ_KEY_ILR_IRQ_MASK) ? false : true; } static ALWAYS_INLINE unsigned int arch_irq_lock(void) { - return 0; + volatile unsigned int key; + + key = __builtin_write_DISICTL(IRQ_KEY_ILR_IRQ_MASK); + __builtin_disable_interrupts(); + return key; } static ALWAYS_INLINE bool arch_is_in_isr(void) { - return 0; + return ((INTTREGbits.VECNUM) ? (true) : (false)); } static ALWAYS_INLINE void arch_nop(void) @@ -91,11 +111,7 @@ extern uint32_t sys_clock_cycle_get_32(void); static inline uint32_t arch_k_cycle_get_32(void) { -#ifdef TO_BE_IMPLEMENTED_LATER return sys_clock_cycle_get_32(); -#else - return 0; -#endif } extern uint64_t sys_clock_cycle_get_64(void); diff --git a/include/zephyr/arch/dspic/exception.h b/include/zephyr/arch/dspic/exception.h index 6723c67e312fa..f77c1e76f86c4 100644 --- a/include/zephyr/arch/dspic/exception.h +++ b/include/zephyr/arch/dspic/exception.h @@ -16,18 +16,18 @@ extern "C" { struct arch_esf { uint32_t PC; /* Program counter*/ - uint32_t FRAME; /* Previous frame pointer*/ uint32_t RCOUNT; /* repeat count register*/ uint32_t FSR; /* Floating point status register */ uint32_t FCR; /* Floating point control register*/ uint32_t W0; /* working register W0 */ - uint32_t W1; /* working register W0 */ - uint32_t W2; /* working register W0 */ - uint32_t W3; /* working register W0 */ - uint32_t W4; /* working register W0 */ - uint32_t W5; /* working register W0 */ - uint32_t W6; /* working register W0 */ - uint32_t W7; /* working register W0 */ + uint32_t W1; /* working register W1 */ + uint32_t W2; /* working register W2 */ + uint32_t W3; /* working register W3 */ + uint32_t W4; /* working register W4 */ + uint32_t W5; /* working register W5 */ + uint32_t W6; /* working register W6 */ + uint32_t W7; /* working register W7 */ + uint32_t W8; /* working register W8 */ uint32_t F0; /* Floating point register F0 */ uint32_t F1; /* Floating point register F1 */ uint32_t F2; /* Floating point register F2 */ @@ -36,6 +36,7 @@ struct arch_esf { uint32_t F5; /* Floating point register F5 */ uint32_t F6; /* Floating point register F6 */ uint32_t F7; /* Floating point register F7 */ + uint32_t FRAME; /* Previous frame pointer*/ }; typedef struct arch_esf arch_esf_t; diff --git a/include/zephyr/arch/dspic/linker.ld b/include/zephyr/arch/dspic/linker.ld index dc3065209dc16..99c689d432402 100644 --- a/include/zephyr/arch/dspic/linker.ld +++ b/include/zephyr/arch/dspic/linker.ld @@ -1,12 +1,10 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + /* * Generic Zephyr Linker Script - *. - * Note: For some of the input sections such as init levels and - * data sections and kernel objects needs to be added via - * linker script fragment files, At this point, only have added those - * input sections required and kept minimal because when adding - * linker script linker fragment files, it affects the syntax of - * XC-DSC Linker. */ #include @@ -27,20 +25,18 @@ #define ROMABLE_REGION program #define RAMABLE_REGION data -OUTPUT_ARCH("33AK128MC106") + CRT0_STARTUP(reset0.S.obj) CRT1_STARTUP(reset1.S.obj) CRT_STARTMODE(crt_start_mode_normal) - MEMORY { /* Memory map from the original target-specific script */ program (xr) : ORIGIN = FLASH_BASE_ADDRESS, LENGTH = (FLASH_SIZE * 1K) data (a!xr) : ORIGIN = SRAM_BASE_ADDRESS, LENGTH = (SRAM_SIZE * 1K) /* Used by and documented in include/linker/intlist.ld */ - IDT_LIST (wx) : ORIGIN = 0xFFFFFFFF, LENGTH = 0 + IDT_LIST (wx) : ORIGIN = 0xFFFFF7FF, LENGTH = 2K } - SECTIONS { /* Start of the ROM-based sections */ @@ -55,7 +51,6 @@ SECTIONS * table and debug information. */ #include - } GROUP_LINK_IN(ROMABLE_REGION) /* @@ -67,6 +62,7 @@ SECTIONS SECTION_PROLOGUE(._TEXT_SECTION_NAME,,) { __text_region_start = .; + #include *(.init); *(.text); *(.text*); @@ -74,18 +70,33 @@ SECTIONS KEEP (*(.handle)); KEEP (*(.isr*)); *(.lib*); - ___rodata_region_start = .; - *(.rodata) *(.rodata.*) - ___rodata_region_end = .; - *(.rodata) /* Read-Only Data */ - ___static_thread_data_list_start = .; - KEEP(*(SORT(.static_thread_data*))) - ___static_thread_data_list_end = .; + __text_region_end = .; . = ALIGN(4); } GROUP_LINK_IN(ROMABLE_REGION) - __text_region_end = .; - ITERABLE_SECTION_ROM_NUMERIC(service, Z_LINK_ITERABLE_SUBALIGN) + + ___rodata_region_start = .; + #include + + /* Located in generated directory. This file is populated by calling + * zephyr_linker_sources(ROM_SECTIONS ...). Useful for grouping iterable RO structs. + */ + #include + #include + + SECTION_PROLOGUE(.rodata,,) + { + *(.rodata) + *(.rodata.*) + /* Located in generated directory. This file is populated by the + * zephyr_linker_sources() Cmake function. + */ + #include + #include + } GROUP_LINK_IN(ROMABLE_REGION) + . = ALIGN(4); + ___rodata_region_end = .; + #include GROUP_END(ROMABLE_REGION) /* Start of the RAM-based sections */ @@ -108,27 +119,32 @@ SECTIONS __data_region_start = .; *(.data) *(".data.*") - __device_list_start = .; - KEEP(*(SORT(.z_device*))) - __device_list_end = .; - /* Initialization levels: Early -> Application */ - ___init_EARLY_start = .; - KEEP(*(SORT(.init_EARLY*))) - ___init_PRE_KERNEL_1_start = .; - KEEP(*(SORT(.init_PRE_KERNEL_1*))) - ___init_PRE_KERNEL_2_start = .; - KEEP(*(SORT(.init_PRE_KERNEL_2*))) - ___init_POST_KERNEL_start = .; - KEEP(*(SORT(.init_POST_KERNEL*))) - ___init_APPLICATION_start = .; - KEEP(*(SORT(.init_APPLICATION*))) - ___init_SMP_start = .; - KEEP(*(SORT(.init_SMP*))) - ___init_end = .; - __data_region_start = .; + *(".kernel.*") + /* Located in generated directory. This file is populated by the + * zephyr_linker_sources() Cmake function. + */ + #include + __data_region_end = .; } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) + #include + + #include + + #include + + /* Located in generated directory. This file is populated by the + * zephyr_linker_sources() Cmake function. + */ + #include + + /* Located in generated directory. This file is populated by the + * zephyr_linker_sources() Cmake function. + */ + #include + + #include /* * This section handles uninitialized data (BSS). It occupies space @@ -145,7 +161,9 @@ SECTIONS ___bss_end = .; } GROUP_LINK_IN(RAMABLE_REGION) + GROUP_END(RAMABLE_REGION) + } /* diff --git a/include/zephyr/kernel.h b/include/zephyr/kernel.h index f1a9661d64b0e..614b2eab1b9b8 100644 --- a/include/zephyr/kernel.h +++ b/include/zephyr/kernel.h @@ -6347,9 +6347,7 @@ __syscall int k_poll_signal_raise(struct k_poll_signal *sig, int result); */ static inline void k_cpu_idle(void) { -#ifdef TO_BE_IMPLEMENTED_LATER arch_cpu_idle(); -#endif } /** diff --git a/include/zephyr/linker/common-ram.ld b/include/zephyr/linker/common-ram.ld index 78016f9572f4a..9b84c1d15005c 100644 --- a/include/zephyr/linker/common-ram.ld +++ b/include/zephyr/linker/common-ram.ld @@ -61,6 +61,7 @@ ITERABLE_SECTION_RAM(scmi_protocol, Z_LINK_ITERABLE_SUBALIGN) } GROUP_DATA_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) #endif /* CONFIG_DEVICE_DEPS_DYNAMIC */ + ITERABLE_SECTION_RAM_GC_ALLOWED(log_mpsc_pbuf, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(log_msg_ptr, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(log_dynamic, Z_LINK_ITERABLE_SUBALIGN) @@ -90,8 +91,12 @@ ITERABLE_SECTION_RAM(scmi_protocol, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM_GC_ALLOWED(k_fifo, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM_GC_ALLOWED(k_lifo, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM_GC_ALLOWED(k_condvar, Z_LINK_ITERABLE_SUBALIGN) - ITERABLE_SECTION_RAM_GC_ALLOWED(sys_mem_blocks_ptr, Z_LINK_ITERABLE_SUBALIGN) + /* For placing kernel objects section and "sys_mem_blocks_ptr" section using + * same MACRO. Dummy instances were created for all kernel objects in application + * but not for the below section. + */ + ITERABLE_SECTION_RAM_GC_ALLOWED(sys_mem_blocks_ptr, Z_LINK_ITERABLE_SUBALIGN) ITERABLE_SECTION_RAM(net_buf_pool, Z_LINK_ITERABLE_SUBALIGN) #if defined(CONFIG_NETWORKING) diff --git a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld index 2bb7d2c509ce2..448b37d53020f 100644 --- a/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld +++ b/include/zephyr/linker/common-rom/common-rom-kernel-devices.ld @@ -88,7 +88,6 @@ } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) ITERABLE_SECTION_ROM(k_p4wq_initparam, Z_LINK_ITERABLE_SUBALIGN) - ITERABLE_SECTION_ROM(_static_thread_data, Z_LINK_ITERABLE_SUBALIGN) #if defined(CONFIG_PCIE) @@ -101,5 +100,4 @@ #include } GROUP_ROM_LINK_IN(RAMABLE_REGION, ROMABLE_REGION) #endif /* !CONFIG_DEVICE_DEPS_DYNAMIC */ - #include diff --git a/include/zephyr/linker/iterable_sections.h b/include/zephyr/linker/iterable_sections.h index 1aa3003d4a9b7..712c1be0b1e09 100644 --- a/include/zephyr/linker/iterable_sections.h +++ b/include/zephyr/linker/iterable_sections.h @@ -13,6 +13,8 @@ */ /* clang-format off */ + + #define Z_LINK_ITERABLE(struct_type) \ PLACE_SYMBOL_HERE(_CONCAT(_##struct_type, _list_start)); \ KEEP(*(SORT_BY_NAME(._##struct_type.static.*))); \ @@ -36,6 +38,7 @@ PLACE_SYMBOL_HERE(_CONCAT(_##struct_type, _list_start)); \ *(SORT_BY_NAME(._##struct_type.static.*)); \ PLACE_SYMBOL_HERE(_CONCAT(_##struct_type, _list_end)); + /* clang-format on */ #define Z_LINK_ITERABLE_SUBALIGN CONFIG_LINKER_ITERABLE_SUBALIGN diff --git a/include/zephyr/linker/linker-tool-xcdsc.h b/include/zephyr/linker/linker-tool-xcdsc.h index a68523d4a3f72..529027be45035 100644 --- a/include/zephyr/linker/linker-tool-xcdsc.h +++ b/include/zephyr/linker/linker-tool-xcdsc.h @@ -1,12 +1,11 @@ /* - * Copyright (c) 2023, Google, Inc. - * + * Copyright (c) 2025, Microchip Technology Inc. * SPDX-License-Identifier: Apache-2.0 */ /** * @file - * @brief LLVM LLD linker defs + * @brief XCDSC LD linker defs * * This header file defines the necessary macros used by the linker script for * use with the XCDSC Linker. @@ -14,8 +13,54 @@ #ifndef ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ #define ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ +#include + +OUTPUT_FORMAT("elf32-pic30") +OUTPUT_ARCH("33AK128MC106") -#include +/* + * The GROUP_START() and GROUP_END() macros are used to define a group + * of sections located in one memory area, such as RAM, ROM, etc. + * The parameter is the name of the memory area. + */ +#define GROUP_START(where) +#define GROUP_END(where) + +/** + * @def GROUP_LINK_IN + * + * Route memory to a specified memory area + * + * The GROUP_LINK_IN() macro is located at the end of the section + * description and tells the linker that this section is located in + * the memory area specified by 'where' argument. + * + * This macro is intentionally undefined for CONFIG_MMU systems when + * CONFIG_KERNEL_VM_BASE is not the same as CONFIG_SRAM_BASE_ADDRESS, + * as both the LMA and VMA destinations must be known for all sections + * as this corresponds to physical vs. virtual location. + * + * @param where Destination memory area + */ +#define GROUP_LINK_IN(where) > where + +/** + * @def GROUP_DATA_LINK_IN + * + * Route memory for read-write sections that are loaded. + * + * Used for initialized data sections that on XIP platforms must be copied at + * startup. + * + * @param vregion Output VMA + * @param lregion Output LMA (only used if CONFIG_MMU if VMA != LMA, + * or CONFIG_XIP) + */ +#define GROUP_DATA_LINK_IN(vregion, lregion) > vregion +/* + * xcdsc linker doesn't have the following directives + */ +#define SUBALIGN(x) ALIGN(x) /** * @def SECTION_PROLOGUE @@ -56,4 +101,25 @@ #undef SECTION_DATA_PROLOGUE #define SECTION_DATA_PROLOGUE(name, options, align) SECTION_PROLOGUE(name, options, align) +/** + * @def GROUP_ROM_LINK_IN + * + * Route memory for a read-only section + * + * The GROUP_ROM_LINK_IN() macro is located at the end of the section + * description and tells the linker that this a read-only section + * that is physically placed at the 'lregion` argument. + * + * If CONFIG_XIP is active, the 'lregion' area is flash memory. + * + * If CONFIG_MMU is active, the vregion argument will be used to + * determine where this is located in the virtual memory map, otherwise + * it is ignored. + * + * @param vregion Output VMA (only used if CONFIG_MMU where LMA != VMA) + * @param lregion Output LMA + */ +#undef GROUP_ROM_LINK_IN +#define GROUP_ROM_LINK_IN(vregion, lregion) > vregion + #endif /* ZEPHYR_INCLUDE_LINKER_LINKER_TOOL_XCDSC_H_ */ diff --git a/include/zephyr/linker/section_tags.h b/include/zephyr/linker/section_tags.h index ab73c0445016f..0188e6f918eeb 100644 --- a/include/zephyr/linker/section_tags.h +++ b/include/zephyr/linker/section_tags.h @@ -17,7 +17,16 @@ #define __noinit __in_section_unique(_NOINIT_SECTION_NAME) #define __noinit_named(name) __in_section_unique_named(_NOINIT_SECTION_NAME, name) -#define __irq_vector_table Z_GENERIC_SECTION(_IRQ_VECTOR_TABLE_SECTION_NAME) +/* The XC-DSC linker mandates that the input and output sections in the linker script must + * have matching attributes. To resolve this, the prog attribute is explicitly + * added to the isr_vector_table section. + */ +#ifdef CONFIG_DSPIC +#define __irq_vector_table \ + Z_GENERIC_SECTION(_IRQ_VECTOR_TABLE_SECTION_NAME) __attribute__((space(prog))) +#else +#define __irq_vector_table Z_GENERIC_SECTION(_IRQ_VECTOR_TABLE_SECTION_NAME) +#endif #define __sw_isr_table Z_GENERIC_SECTION(_SW_ISR_TABLE_SECTION_NAME) #ifdef CONFIG_SHARED_INTERRUPTS diff --git a/include/zephyr/toolchain/xcdsc.h b/include/zephyr/toolchain/xcdsc.h index 67e59535f1c63..a496d1c633a7f 100644 --- a/include/zephyr/toolchain/xcdsc.h +++ b/include/zephyr/toolchain/xcdsc.h @@ -6,6 +6,13 @@ #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_XCDSC_H_ #define ZEPHYR_INCLUDE_TOOLCHAIN_XCDSC_H_ +#ifndef __COUNTER__ +/* XCC (GCC-based compiler) doesn't support __COUNTER__ + * but this should be good enough + */ +#define __COUNTER__ __LINE__ +#endif + #ifndef ZEPHYR_INCLUDE_TOOLCHAIN_H_ #error Please do not include toolchain-specific headers directly, use instead #endif @@ -19,6 +26,11 @@ /* Double indirection to ensure section names are expanded before * stringification */ +#define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment)))) +#define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment) + +#define __GENERIC_DOT_SECTION(segment) __attribute__((section("." STRINGIFY(segment)))) +#define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment) /* * XC-DSC does not support using deprecated attribute in enum, * so just nullify it here to avoid compilation errors. @@ -34,7 +46,6 @@ __attribute__((section("." STRINGIFY(seg) "." STRINGIFY(__COUNTER__) "." STRINGIFY(name)))) #define CODE_UNREACHABLE __builtin_unreachable() -#define __used __attribute__((__used__)) #define __unused __attribute__((__unused__)) #define __maybe_unused __attribute__((__unused__)) @@ -216,4 +227,23 @@ static inline int popcount(unsigned int x) */ #define ZRESTRICT restrict + +/* Double indirection to ensure section names are expanded before + * stringification + */ +#define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment)))) +#define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment) + +#define __GENERIC_DOT_SECTION(segment) __attribute__((section("." STRINGIFY(segment)))) +#define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment) + #endif /* ZEPHYR_INCLUDE_TOOLCHAIN_XSDSC_H_ */ + +/* Double indirection to ensure section names are expanded before + * stringification + */ +#define __GENERIC_SECTION(segment) __attribute__((section(STRINGIFY(segment)))) +#define Z_GENERIC_SECTION(segment) __GENERIC_SECTION(segment) + +#define __GENERIC_DOT_SECTION(segment) __attribute__((section("." STRINGIFY(segment)))) +#define Z_GENERIC_DOT_SECTION(segment) __GENERIC_DOT_SECTION(segment) diff --git a/kernel/init.c b/kernel/init.c index 180a93c7dc5b7..6cac1779cce3f 100644 --- a/kernel/init.c +++ b/kernel/init.c @@ -806,12 +806,12 @@ FUNC_NORETURN void z_cstart(void) z_device_state_init(); #if CONFIG_SOC_EARLY_INIT_HOOK -#ifdef TO_BE_IMPLEMENTED_LATER +#ifndef CONFIG_DSPIC soc_early_init_hook(); #endif #endif #if CONFIG_BOARD_EARLY_INIT_HOOK -#ifdef TO_BE_IMPLEMENTED_LATER +#ifndef CONFIG_DSPIC board_early_init_hook(); #endif #endif diff --git a/kernel/timeout.c b/kernel/timeout.c index 77f063297983d..f698a0779e5a7 100644 --- a/kernel/timeout.c +++ b/kernel/timeout.c @@ -81,11 +81,7 @@ static int32_t elapsed(void) * will be non-zero while sys_clock_announce() is executing and zero * otherwise. */ -#ifdef TO_BE_IMPLEMENTED_LATER return announce_remaining == 0 ? sys_clock_elapsed() : 0U; -#else - return 0; -#endif } static int32_t next_timeout(int32_t ticks_elapsed) diff --git a/samples/hello_world/src/main.c b/samples/hello_world/src/main.c index c550ab461cb35..a09875b896f3a 100644 --- a/samples/hello_world/src/main.c +++ b/samples/hello_world/src/main.c @@ -5,10 +5,10 @@ */ #include +#include int main(void) { printf("Hello World! %s\n", CONFIG_BOARD_TARGET); - return 0; } diff --git a/scripts/schemas/twister/platform-schema.yaml b/scripts/schemas/twister/platform-schema.yaml index a4c0f673e46c7..ebbfa40806b8e 100644 --- a/scripts/schemas/twister/platform-schema.yaml +++ b/scripts/schemas/twister/platform-schema.yaml @@ -60,6 +60,7 @@ schema;platform-schema: "arc", "arm", "arm64", + "dspic", "mips", "nios2", "posix", diff --git a/scripts/west_commands/runners/__init__.py b/scripts/west_commands/runners/__init__.py index fc318e3d6cc7e..4494925cb150e 100644 --- a/scripts/west_commands/runners/__init__.py +++ b/scripts/west_commands/runners/__init__.py @@ -39,6 +39,7 @@ def _import_runner_module(runner_name): 'hifive1', 'intel_adsp', 'intel_cyclonev', + 'ipecmd', 'jlink', 'linkserver', 'mdb', diff --git a/scripts/west_commands/runners/ipecmd.py b/scripts/west_commands/runners/ipecmd.py new file mode 100644 index 0000000000000..dc7afada6d7eb --- /dev/null +++ b/scripts/west_commands/runners/ipecmd.py @@ -0,0 +1,126 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# +# SPDX-License-Identifier: Apache-2.0 + +'''Runner for flashing PIC devices with ipecmd.''' + +import os +import platform +import sys +from pathlib import Path + +from runners.core import RunnerCaps, ZephyrBinaryRunner + +COMMON_LOCATIONS = ["/opt", "/usr/local", "/home", "C:\\Program Files"] + + +class IpecmdBinaryRunner(ZephyrBinaryRunner): + '''Runner front-end for Microchip's dspic33a_curiosity.''' + + def __init__(self, cfg, device, flash_tool): + super().__init__(cfg) + self.elf = cfg.elf_file + self.ipecmd_cmd = None + self.mplabx_base = None + self.java_bin = None + self.ipecmd_jar = None + if platform.system() == 'Linux' or platform.system() == 'Windows': + self.mplabx_base = self.find_mplabx_base() + if not self.mplabx_base: + print("Error: Could not locate mplabx base directory") + sys.exit(1) + + version_path = self.find_latest_version_dir(self.mplabx_base) + if not version_path: + print("Error: No MPLAB X version directories found") + sys.exit(1) + + self.java_bin = self.find_java_bin(version_path) + if not self.java_bin or not os.access(self.java_bin, os.X_OK): + print("Error: Java executable not found or not executable") + sys.exit(1) + + self.ipecmd_jar = self.find_ipecmd_jar(version_path) + if not self.ipecmd_jar: + print(f"Error: ipecmd.jar not found in {version_path}/mplab_platform/mplab_ipe/") + sys.exit(1) + else: + print(f'ipecmd: {self.ipecmd_jar}') + self.app_bin = cfg.bin_file + print(f'bin file: {cfg.bin_file}') + self.hex_file = cfg.hex_file + print(f'hex file: {cfg.hex_file}') + self.device = device + self.flash_tool = flash_tool + + @classmethod + def name(cls): + return 'ipecmd' + + @classmethod + def capabilities(cls): + return RunnerCaps(commands={'flash'}, erase=True, reset=True) + + @classmethod + def do_add_parser(cls, parser): + # Required + parser.add_argument('--device', required=True, help='soc') + parser.add_argument('--flash-tool', required=True, help='hardware tool to program') + + parser.set_defaults(reset=True) + + @classmethod + def do_create(cls, cfg, args): + return IpecmdBinaryRunner(cfg, args.device, args.flash_tool) + + def do_run(self, command, **kwargs): + print("***************Flashing*************") + self.ensure_output('hex') + + self.logger.info(f'Flashing file: {self.hex_file}') + if self.hex_file is not None: + self.logger.info(f'flash tool: {self.flash_tool}, Device: {self.device}') + self.logger.info(f'flash cmd: {self.ipecmd_jar}') + cmd = [ + str(self.java_bin), + '-jar', + str(self.ipecmd_jar), + '-TP' + self.flash_tool, + '-P' + self.device, + '-M', + '-F' + self.hex_file, + '-OL', + ] + self.require(cmd[0]) + self.check_call(cmd) + else: + print("E: No HEX file found") + + def find_mplabx_base(self): + for base in COMMON_LOCATIONS: + for root, dirs, _ in os.walk(base): + for d in dirs: + if d.startswith("mplabx") or d.startswith("MPLABX"): + return Path(root) / d + return None + + def find_latest_version_dir(self, mplabx_base): + versions = sorted([p for p in mplabx_base.glob("v*/") if p.is_dir()]) + return versions[-1] if versions else None + + def find_java_bin(self, version_path): + if platform.system() == 'Linux': + java_dirs = list(version_path.glob("sys/java/*/bin/java")) + elif platform.system() == 'Windows': + java_dirs = list(version_path.glob("sys/java/*/bin/java.exe")) + else: + self.logger.error("Platform not supported") + sys.exit(1) + return java_dirs[0] if java_dirs else None + + def find_ipecmd_jar(self, version_path): + ipe_dir = version_path / "mplab_platform/mplab_ipe" + for root, _, files in os.walk(ipe_dir): + if "ipecmd.jar" in files: + return Path(root) / "ipecmd.jar" + return None diff --git a/snippets/ram-console/boards/dspic33a_curiosity_p33ak128mc106.overlay b/snippets/ram-console/boards/dspic33a_curiosity_p33ak128mc106.overlay new file mode 100644 index 0000000000000..c291e1b38e787 --- /dev/null +++ b/snippets/ram-console/boards/dspic33a_curiosity_p33ak128mc106.overlay @@ -0,0 +1,14 @@ +/ { + chosen { + zephyr,ram-console = &snippet_ram_console; + }; + + #address-cells = <1>; + #size-cells = <1>; + + snippet_ram_console: memory@5000 { + compatible = "zephyr,memory-region"; + reg = <0x5000 0x400>; + zephyr,memory-region = "RAM_CONSOLE"; + }; +}; diff --git a/snippets/ram-console/snippet.yml b/snippets/ram-console/snippet.yml index 47e154a9c7640..c74988b06310e 100644 --- a/snippets/ram-console/snippet.yml +++ b/snippets/ram-console/snippet.yml @@ -30,3 +30,6 @@ boards: imx93_evk/mimx9352/a55: append: EXTRA_DTC_OVERLAY_FILE: boards/imx93_evk_mimx9352_a55.overlay + dspic33a_curiosity/p33ak128mc106: + append: + EXTRA_DTC_OVERLAY_FILE: boards/dspic33a_curiosity_p33ak128mc106.overlay diff --git a/soc/microchip/dspic33/Kconfig.soc b/soc/microchip/dspic33/Kconfig.soc index 9f99de815576f..cc184da1d333b 100644 --- a/soc/microchip/dspic33/Kconfig.soc +++ b/soc/microchip/dspic33/Kconfig.soc @@ -4,6 +4,10 @@ config SOC_FAMILY_MICROCHIP_DSPIC33 bool +config BUILD_OUTPUT_HEX + bool + default y + config SOC_FAMILY default "microchip_dspic33" if SOC_FAMILY_MICROCHIP_DSPIC33 diff --git a/soc/microchip/dspic33/dspic33a/CMakeLists.txt b/soc/microchip/dspic33/dspic33a/CMakeLists.txt index f12efdf7c8b82..fc4b7df67049a 100644 --- a/soc/microchip/dspic33/dspic33a/CMakeLists.txt +++ b/soc/microchip/dspic33/dspic33a/CMakeLists.txt @@ -1,4 +1,5 @@ zephyr_include_directories(.) +zephyr_include_directories(${XCDSC_TOOLCHAIN_PATH}/support/generic/h) zephyr_sources_ifdef(CONFIG_PM power.c ) set(SOC_LINKER_SCRIPT diff --git a/soc/microchip/dspic33/dspic33a/Kconfig b/soc/microchip/dspic33/dspic33a/Kconfig index a46ff9baa903c..a51dc3592dced 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig +++ b/soc/microchip/dspic33/dspic33a/Kconfig @@ -8,8 +8,8 @@ config SOC_SERIES_DSPIC33A select FPU select SOC_EARLY_INIT_HOOK select BOARD_EARLY_INIT_HOOK - # select GEN_ISR_TABLES - # select GEN_IRQ_VECTOR_TABLE - # select GEN_SW_ISR_TABLE + select GEN_ISR_TABLES + select GEN_IRQ_VECTOR_TABLE + select GEN_SW_ISR_TABLE select HAS_PM select PM diff --git a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 index 9c509d888257d..0ff17992b7a19 100644 --- a/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 @@ -3,20 +3,17 @@ if SOC_P33AK128MC106 -config UART_CONSOLE - default n +config SRAM_SIZE + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_SRAM),0,K) + +config SRAM_BASE_ADDRESS + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_SRAM)) config FLASH_SIZE - default 128 + default $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) config FLASH_BASE_ADDRESS - default 0x00800000 - -config SRAM_SIZE - default 80 - -config SRAM_BASE_ADDRESS - default 0x010000 + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) config MAIN_STACK_SIZE default 128 diff --git a/soc/microchip/dspic33/dspic33a/power.c b/soc/microchip/dspic33/dspic33a/power.c index e0dbf0b32f3ad..576ef472b6e41 100644 --- a/soc/microchip/dspic33/dspic33a/power.c +++ b/soc/microchip/dspic33/dspic33a/power.c @@ -6,12 +6,15 @@ #include #include #include +#include void pm_state_set(enum pm_state state, uint8_t substate_id) { ARG_UNUSED(substate_id); switch (state) { case PM_STATE_SUSPEND_TO_IDLE: + __builtin_disable_interrupts(); + Idle(); break; default: break; @@ -23,6 +26,7 @@ void pm_state_exit_post_ops(enum pm_state state, uint8_t substate_id) ARG_UNUSED(substate_id); switch (state) { case PM_STATE_SUSPEND_TO_IDLE: + __builtin_enable_interrupts(); break; default: break; From e4c00e1bcf8e967d89cc37a3b26a68fae51214be Mon Sep 17 00:00:00 2001 From: Adhil Xavier Date: Mon, 25 Aug 2025 12:44:14 +0530 Subject: [PATCH 5/6] dspic: Windows host fixes for west commands (#38) dspic: Windows host fixes for west flash West flash tool was failing, modified flash tool script In windows build was failing with Path name with spaces, using modified cmake script. Signed-off-by: Adhil Xavier --- cmake/toolchain/xcdsc/generic.cmake | 85 +++++++++++++++++++++++++ scripts/west_commands/runners/ipecmd.py | 68 ++++++++++++-------- 2 files changed, 128 insertions(+), 25 deletions(-) diff --git a/cmake/toolchain/xcdsc/generic.cmake b/cmake/toolchain/xcdsc/generic.cmake index faa9174c61b5f..fcab28bace128 100644 --- a/cmake/toolchain/xcdsc/generic.cmake +++ b/cmake/toolchain/xcdsc/generic.cmake @@ -1,4 +1,88 @@ zephyr_get(XCDSC_TOOLCHAIN_PATH) + +if(WIN32) + # Detect invoking shell. + set(_CURRENT_SHELL "cmd") + if(DEFINED ENV{PSModulePath}) + set(_CURRENT_SHELL "powershell") + endif() + message(STATUS "Detected Windows shell: ${_CURRENT_SHELL}") + + # Buffer toolchain path from environment variable + set(_XCDSC_REAL "$ENV{XCDSC_TOOLCHAIN_PATH}") + if(NOT _XCDSC_REAL) + message(FATAL_ERROR "XCDSC_TOOLCHAIN_PATH is not set in the environment.") + endif() + + # Fixed junction path under %TEMP% + set(_XCDSC_LINK "$ENV{TEMP}\\xcdsc") + # Native path for cmd.exe commands + file(TO_NATIVE_PATH "${_XCDSC_LINK}" _XCDSC_LINK_WIN) + file(TO_NATIVE_PATH "${_XCDSC_REAL}" _XCDSC_REAL_WIN) + + # Ensures %TEMP%\xcdsc is a symlink/junction pointing to XCDSC_TOOLCHAIN_PATH, + # creating or replacing it as needed (shell chosen via _CURRENT_SHELL). + if(_CURRENT_SHELL STREQUAL "powershell") + message(STATUS "Ensuring junction via PowerShell") + execute_process( + COMMAND powershell -NoProfile -ExecutionPolicy Bypass -Command + "\$ErrorActionPreference='Stop'; \$ConfirmPreference='None';" + "\$p = Join-Path \$env:TEMP 'xcdsc';" + "\$t = '${_XCDSC_REAL}';" + "if (Test-Path -LiteralPath \$p) {" + " \$it = Get-Item -LiteralPath \$p -Force;" + " if (-not (\$it.Attributes -band [IO.FileAttributes]::ReparsePoint)) {" + " if (\$it.PSIsContainer) {" + " Remove-Item -LiteralPath \$p -Recurse -Force -Confirm:\$false" + " } else {" + " Remove-Item -LiteralPath \$p -Force -Confirm:\$false" + " }" + " New-Item -ItemType Junction -Path \$p -Target \$t | Out-Null" + " }" + "} else {" + " New-Item -ItemType Junction -Path \$p -Target \$t | Out-Null" + "}" + RESULT_VARIABLE _ps_rv + OUTPUT_VARIABLE _ps_out + ERROR_VARIABLE _ps_err + ) + if(NOT _ps_rv EQUAL 0) + message(FATAL_ERROR "Failed to ensure %TEMP%\\xcdsc junction (PowerShell).\n${_ps_err}") + endif() + else() + message(STATUS "Ensuring junction via Command Prompt") + # Ensures %TEMP%\xcdsc is a symlink/junction to XCDSC_TOOLCHAIN_PATH via cmd, + # creating or replacing it as needed. + execute_process( + COMMAND cmd.exe /C + "if exist \"${_XCDSC_LINK_WIN}\" ( " + " fsutil reparsepoint query \"${_XCDSC_LINK_WIN}\" >nul 2>&1 && ( ver >nul ) " + " || ( " + " if exist \"${_XCDSC_LINK_WIN}\\*\" ( " + " rmdir /S /Q \"${_XCDSC_LINK_WIN}\" " + " ) else ( " + " del /Q /F \"${_XCDSC_LINK_WIN}\" 2>nul " + " ) & " + " mklink /J \"${_XCDSC_LINK_WIN}\" \"${_XCDSC_REAL_WIN}\" " + " ) " + ") else ( " + " mklink /J \"${_XCDSC_LINK_WIN}\" \"${_XCDSC_REAL_WIN}\" " + ")" + RESULT_VARIABLE _cmd_rv + OUTPUT_VARIABLE _cmd_out + ERROR_VARIABLE _cmd_err + ) + if(NOT _cmd_rv EQUAL 0) + message(FATAL_ERROR "Failed to ensure %TEMP%\\xcdsc junction (cmd).\n${_cmd_err}") + endif() + endif() + + # Use the junction for the toolchain + set(XCDSC_TOOLCHAIN_PATH "${_XCDSC_LINK}") + message(STATUS "XCDSC toolchain (real): ${_XCDSC_REAL}") + message(STATUS "XCDSC toolchain (via junction): ${XCDSC_TOOLCHAIN_PATH}") +endif() + # Set toolchain module name to xcdsc set(COMPILER xcdsc) set(LINKER xcdsc) @@ -17,3 +101,4 @@ else() # Support for picolibc is indicated by the presence of 'picolibc.h' in th set(TOOLCHAIN_HAS_PICOLIBC ON CACHE BOOL "True if toolchain supports picolibc") endif() endif() + \ No newline at end of file diff --git a/scripts/west_commands/runners/ipecmd.py b/scripts/west_commands/runners/ipecmd.py index dc7afada6d7eb..91803e549e8d4 100644 --- a/scripts/west_commands/runners/ipecmd.py +++ b/scripts/west_commands/runners/ipecmd.py @@ -24,28 +24,35 @@ def __init__(self, cfg, device, flash_tool): self.mplabx_base = None self.java_bin = None self.ipecmd_jar = None - if platform.system() == 'Linux' or platform.system() == 'Windows': - self.mplabx_base = self.find_mplabx_base() - if not self.mplabx_base: - print("Error: Could not locate mplabx base directory") - sys.exit(1) - version_path = self.find_latest_version_dir(self.mplabx_base) - if not version_path: - print("Error: No MPLAB X version directories found") - sys.exit(1) + self.mplabx_base = self.find_mplabx_base() + if not self.mplabx_base: + print("Error: Could not locate mplabx base directory") + sys.exit(1) + version_path = self.find_latest_version_dir(self.mplabx_base) + if not version_path: + print("Error: No MPLAB X version directories found") + sys.exit(1) + if platform.system() == 'Linux': self.java_bin = self.find_java_bin(version_path) if not self.java_bin or not os.access(self.java_bin, os.X_OK): print("Error: Java executable not found or not executable") sys.exit(1) - self.ipecmd_jar = self.find_ipecmd_jar(version_path) + self.ipecmd_jar = self.find_ipecmd(version_path, "ipecmd.jar") if not self.ipecmd_jar: print(f"Error: ipecmd.jar not found in {version_path}/mplab_platform/mplab_ipe/") sys.exit(1) else: print(f'ipecmd: {self.ipecmd_jar}') + elif platform.system() == 'Windows': + self.ipecmd_exe = self.find_ipecmd(version_path, "ipecmd.exe") + if not self.ipecmd_exe: + print(f"Error: ipecmd.exe not found in {version_path}/mplab_platform/mplab_ipe/") + sys.exit(1) + else: + print(f'ipecmd: {self.ipecmd_exe}') self.app_bin = cfg.bin_file print(f'bin file: {cfg.bin_file}') self.hex_file = cfg.hex_file @@ -78,19 +85,30 @@ def do_run(self, command, **kwargs): self.ensure_output('hex') self.logger.info(f'Flashing file: {self.hex_file}') + self.logger.info(f'flash tool: {self.flash_tool}, Device: {self.device}') if self.hex_file is not None: - self.logger.info(f'flash tool: {self.flash_tool}, Device: {self.device}') - self.logger.info(f'flash cmd: {self.ipecmd_jar}') - cmd = [ - str(self.java_bin), - '-jar', - str(self.ipecmd_jar), - '-TP' + self.flash_tool, - '-P' + self.device, - '-M', - '-F' + self.hex_file, - '-OL', - ] + if platform.system() == 'Linux': + self.logger.info(f'flash cmd: {self.ipecmd_jar}') + cmd = [ + str(self.java_bin), + '-jar', + str(self.ipecmd_jar), + '-TP' + self.flash_tool, + '-P' + self.device, + '-M', + '-F' + self.hex_file, + '-OL', + ] + elif platform.system() == 'Windows': + self.logger.info(f'flash cmd: {self.ipecmd_exe}') + cmd = [ + str(self.ipecmd_exe), + '-TP' + self.flash_tool, + '-P' + self.device, + '-M', + '-F' + self.hex_file, + '-OL', + ] self.require(cmd[0]) self.check_call(cmd) else: @@ -118,9 +136,9 @@ def find_java_bin(self, version_path): sys.exit(1) return java_dirs[0] if java_dirs else None - def find_ipecmd_jar(self, version_path): + def find_ipecmd(self, version_path, tool): ipe_dir = version_path / "mplab_platform/mplab_ipe" for root, _, files in os.walk(ipe_dir): - if "ipecmd.jar" in files: - return Path(root) / "ipecmd.jar" + if tool in files: + return Path(root) / tool return None From c0b81b13d669038b88619633ad9f014885b15773 Mon Sep 17 00:00:00 2001 From: Adhil Xavier Date: Wed, 3 Sep 2025 09:46:12 +0530 Subject: [PATCH 6/6] cmake: cmake toolchain path fixes are added Setting CXX compiler evironment variable to xc-dsc-gcc Toolchain path issues fixed. Signed-off-by: Adhil Xavier --- cmake/compiler/xcdsc/target.cmake | 2 +- cmake/toolchain/xcdsc/generic.cmake | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/compiler/xcdsc/target.cmake b/cmake/compiler/xcdsc/target.cmake index 670bd84a7bae5..fbc7abedbaf9e 100644 --- a/cmake/compiler/xcdsc/target.cmake +++ b/cmake/compiler/xcdsc/target.cmake @@ -1,7 +1,7 @@ # Set default C compiler if not already set find_program(CMAKE_C_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH ) # XC-DSC toolchain does not support C++, so set CXX to fallback to gcc (or a dummy) # This prevents CMake errors if C++ is requested (even if unused) -find_program(CMAKE_CXX_COMPILER gcc) +find_program(CMAKE_CXX_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH ) # Set assembler explicitly find_program(CMAKE_ASM_COMPILER xc-dsc-gcc PATHS ${XCDSC_TOOLCHAIN_PATH}/bin/ NO_DEFAULT_PATH ) # Target CPU (must match user platform) diff --git a/cmake/toolchain/xcdsc/generic.cmake b/cmake/toolchain/xcdsc/generic.cmake index fcab28bace128..54f09c10258b5 100644 --- a/cmake/toolchain/xcdsc/generic.cmake +++ b/cmake/toolchain/xcdsc/generic.cmake @@ -9,7 +9,7 @@ if(WIN32) message(STATUS "Detected Windows shell: ${_CURRENT_SHELL}") # Buffer toolchain path from environment variable - set(_XCDSC_REAL "$ENV{XCDSC_TOOLCHAIN_PATH}") + set(_XCDSC_REAL "${XCDSC_TOOLCHAIN_PATH}") if(NOT _XCDSC_REAL) message(FATAL_ERROR "XCDSC_TOOLCHAIN_PATH is not set in the environment.") endif()