diff --git a/arch/Kconfig b/arch/Kconfig index d29976d37a453..e07082c1d6f2e 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -167,6 +167,24 @@ config RX help Renesas RX architecture +config DSPIC + bool + select ARCH_IS_SET + select STACK_GROWS_UP + 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 CACHE_MANAGEMENT + select TICKLESS_CAPABLE + help + dspic architecture + config ARCH_IS_SET bool help @@ -376,6 +394,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..45ebe011c0ff7 --- /dev/null +++ b/arch/dspic/Kconfig @@ -0,0 +1,23 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +menu "DSPIC Options" + depends on DSPIC + +config ARCH + string + default "dspic" + +config GEN_ISR_TABLES + default y + +config DYNAMIC_INTERRUPTS + default n + +config NUM_IRQS + default 279 + +config GEN_IRQ_START_VECTOR + default 0 + +endmenu diff --git a/arch/dspic/core/CMakeLists.txt b/arch/dspic/core/CMakeLists.txt new file mode 100644 index 0000000000000..ecc7a0ea64868 --- /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 0x00 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..d3d984f5aa986 --- /dev/null +++ b/arch/dspic/core/cpu_idle.c @@ -0,0 +1,34 @@ +/** + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#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) +{ + __builtin_disable_interrupts(); + Idle(); + arch_irq_unlock(key); + __builtin_enable_interrupts(); +} +#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..c9b9e75185af6 --- /dev/null +++ b/arch/dspic/core/fatal.c @@ -0,0 +1,123 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#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, weak)) +#define BUS_ERROR_MASK 0xF +#define MATH_ERROR_MASK 0x1F +#define GENERAL_TRAP_MASK 0x8000000Fu + +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 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) +{ + /* 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) +{ + /* 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) +{ + 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) +{ + /* 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) +{ + INTCON1bits.STKERR = 0; + PCTRAP = 0; + TRAPS_halt_on_error(); +} + +/** Generic error.**/ +void EXCEPTION_HANDLER _GeneralTrap(void) +{ + 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(); +} + +#ifdef __cplusplus +} +#endif + +#endif /* _ASMLANGUAGE */ diff --git a/arch/dspic/core/init.S b/arch/dspic/core/init.S new file mode 100644 index 0000000000000..5477cb3e49ad8 --- /dev/null +++ b/arch/dspic/core/init.S @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +.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..51f9eb1328060 --- /dev/null +++ b/arch/dspic/core/irq_manage.c @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include + +#ifndef _ASMLANGUAGE +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void z_irq_spurious(const void *unused) +{ + ARG_UNUSED(unused); + while (1) { + } + return; +} + +void arch_irq_enable(unsigned int 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) +{ + 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) +{ + 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 new file mode 100644 index 0000000000000..6a083bc538f2b --- /dev/null +++ b/arch/dspic/core/isr_wrapper.c @@ -0,0 +1,48 @@ +/* + * 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 + */ +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)) _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/offsets/offsets.c b/arch/dspic/core/offsets/offsets.c new file mode 100644 index 0000000000000..c88caaf2ce939 --- /dev/null +++ b/arch/dspic/core/offsets/offsets.c @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * 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..b0126d5183f2e --- /dev/null +++ b/arch/dspic/core/reset0.S @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#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..c8db2021c28de --- /dev/null +++ b/arch/dspic/core/reset1.S @@ -0,0 +1,21 @@ +/* + * 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 + +.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..32f329c76df33 --- /dev/null +++ b/arch/dspic/core/swap.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include +#include +#include +#include +#include "kswap.h" + +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) { + 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 + */ + irq_unlock(key); + register int result __asm__("w0"); + return result; + + /* Context switch is performed here. Returning implies the + * thread has been context-switched-in again. + */ +} diff --git a/arch/dspic/core/thread.c b/arch/dspic/core/thread.c new file mode 100644 index 0000000000000..2ab6d2861b5d1 --- /dev/null +++ b/arch/dspic/core/thread.c @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#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); + +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; + /* 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 + * 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)thread->callee_saved.stack; + /*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..8014503095c56 --- /dev/null +++ b/arch/dspic/core/vector_table.S @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#include +#include +#include "vector_table.h" + +.global __ReservedTrap0 +.global __BusErrorTrap +.global __AddressErrorTrap +.global __IllegalInstructionTrap +.global __MathErrorTrap +.global __StackErrorTrap +.global __GeneralTrap +.global __ReservedTrap7 +.global _isr_wrapper + + +.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 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..28bcd17a875ce --- /dev/null +++ b/arch/dspic/include/kernel_arch_func.h @@ -0,0 +1,97 @@ +/* + * 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 + +extern uint32_t vector_start; + +/* 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; + + /** + * 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 */ +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/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/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/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/dspic33/dspic33a_curiosity/board.yml b/boards/microchip/dspic33/dspic33a_curiosity/board.yml new file mode 100644 index 0000000000000..561db73fdf4a9 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/board.yml @@ -0,0 +1,7 @@ +board: + name: dspic33a_curiosity + full_name: dsPIC33A Curiosity Platform Development Board + vendor: microchip + socs: + - name: p33ak128mc106 + - name: p33ak256mc506 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/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig new file mode 100644 index 0000000000000..cbfee96cec289 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc106_defconfig @@ -0,0 +1,38 @@ +# 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_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 + +# 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/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc506.dts b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_p33ak128mc506.dts new file mode 100644 index 0000000000000..9213a07beb6d8 --- /dev/null +++ b/boards/microchip/dspic33/dspic33a_curiosity/dspic33a_curiosity_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..7b5dd556de348 --- /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 ) +set(CMAKE_C_FLAGS -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..fbc7abedbaf9e --- /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 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) +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..0f152caabaaec --- /dev/null +++ b/cmake/linker/xcdsc/target.cmake @@ -0,0 +1,96 @@ +# 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(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) + 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_LINKER + -D_ASM_LANGUAGE + -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..923c90caf1c82 --- /dev/null +++ b/cmake/toolchain/xcdsc/Kconfig @@ -0,0 +1,19 @@ +# 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 + 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..54f09c10258b5 --- /dev/null +++ b/cmake/toolchain/xcdsc/generic.cmake @@ -0,0 +1,104 @@ +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 "${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) +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() + \ No newline at end of file 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..57bb6d5f51ec1 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); +#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 new file mode 100644 index 0000000000000..ad37b0c94029d --- /dev/null +++ b/dts/dspic/p33ak128mc106.dtsi @@ -0,0 +1,81 @@ +/* + * 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 = <1>; + + flash0: flash@800000 { + compatible = "zephyr,flash"; + reg = <0x800000 0x20000>; + label = "FLASH"; + }; + + sram0: memory@4000 { + compatible = "zephyr,memory"; + 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 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/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..0d01867f5bdc0 --- /dev/null +++ b/include/zephyr/arch/dspic/arch.h @@ -0,0 +1,130 @@ +/* + * 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 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 + +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); + +/* 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. + * + * 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, flags_p) \ + { \ + Z_ISR_DECLARE_DIRECT(irq_p, ISR_FLAG_DIRECT, isr_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) +{ + 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 ((key & IRQ_KEY_ILR_IRQ_MASK) == IRQ_KEY_ILR_IRQ_MASK) ? false : true; +} + +static ALWAYS_INLINE unsigned int arch_irq_lock(void) +{ + 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 ((INTTREGbits.VECNUM) ? (true) : (false)); +} + +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) +{ + return sys_clock_cycle_get_32(); +} + +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..f77c1e76f86c4 --- /dev/null +++ b/include/zephyr/arch/dspic/exception.h @@ -0,0 +1,49 @@ +/* + * 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 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 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 */ + 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 */ + uint32_t FRAME; /* Previous frame pointer*/ +}; +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..99c689d432402 --- /dev/null +++ b/include/zephyr/arch/dspic/linker.ld @@ -0,0 +1,2995 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/* + * Generic Zephyr Linker Script + */ + +#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 + + +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 = 0xFFFFF7FF, LENGTH = 2K +} +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 = .; + #include + *(.init); + *(.text); + *(.text*); + *(.user_init); + KEEP (*(.handle)); + KEEP (*(.isr*)); + *(.lib*); + __text_region_end = .; + . = ALIGN(4); + } GROUP_LINK_IN(ROMABLE_REGION) + + ___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 */ + 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.*") + *(".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 + * 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/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/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-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..e6f40d678c7d4 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 @@ -115,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 @@ -135,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 @@ -155,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 diff --git a/include/zephyr/linker/linker-tool-xcdsc.h b/include/zephyr/linker/linker-tool-xcdsc.h new file mode 100644 index 0000000000000..529027be45035 --- /dev/null +++ b/include/zephyr/linker/linker-tool-xcdsc.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @file + * @brief XCDSC LD 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 + +OUTPUT_FORMAT("elf32-pic30") +OUTPUT_ARCH("33AK128MC106") + +/* + * 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 + * + * 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) + +/** + * @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/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/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.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..a496d1c633a7f --- /dev/null +++ b/include/zephyr/toolchain/xcdsc.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#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 + +#include +#include + +#define Z_STRINGIFY(x) #x +#define STRINGIFY(s) Z_STRINGIFY(s) + +/* 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. + */ +#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 __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 + +/* 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 2ab9804c7cf0e..6cac1779cce3f 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 +#ifndef CONFIG_DSPIC soc_early_init_hook(); #endif +#endif #if CONFIG_BOARD_EARLY_INIT_HOOK +#ifndef CONFIG_DSPIC 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/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..91803e549e8d4 --- /dev/null +++ b/scripts/west_commands/runners/ipecmd.py @@ -0,0 +1,144 @@ +# 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 + + 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(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 + 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}') + self.logger.info(f'flash tool: {self.flash_tool}, Device: {self.device}') + if self.hex_file is not None: + 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: + 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(self, version_path, tool): + ipe_dir = version_path / "mplab_platform/mplab_ipe" + for root, _, files in os.walk(ipe_dir): + if tool in files: + return Path(root) / tool + 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/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..0c0e4f2fe05aa --- /dev/null +++ b/soc/microchip/dspic33/Kconfig @@ -0,0 +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 new file mode 100644 index 0000000000000..e6769d6f9e91d --- /dev/null +++ b/soc/microchip/dspic33/Kconfig.defconfig @@ -0,0 +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 new file mode 100644 index 0000000000000..cc184da1d333b --- /dev/null +++ b/soc/microchip/dspic33/Kconfig.soc @@ -0,0 +1,14 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +config SOC_FAMILY_MICROCHIP_DSPIC33 + bool + +config BUILD_OUTPUT_HEX + bool + default y + +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..fc4b7df67049a --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/CMakeLists.txt @@ -0,0 +1,8 @@ +zephyr_include_directories(.) +zephyr_include_directories(${XCDSC_TOOLCHAIN_PATH}/support/generic/h) +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..a51dc3592dced --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig @@ -0,0 +1,15 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +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..0ff17992b7a19 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.p33ak128mc106 @@ -0,0 +1,37 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +if SOC_P33AK128MC106 + +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 $(dt_chosen_reg_size_int,$(DT_CHOSEN_Z_FLASH),0,K) + +config FLASH_BASE_ADDRESS + default $(dt_chosen_reg_addr_hex,$(DT_CHOSEN_Z_FLASH)) + +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..72f99ab38fa01 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.defconfig.series @@ -0,0 +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 new file mode 100644 index 0000000000000..69cde09e0b3c1 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/Kconfig.soc @@ -0,0 +1,24 @@ +# Copyright (c) 2025, Microchip Technology Inc. +# SPDX-License-Identifier: Apache-2.0 + +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..576ef472b6e41 --- /dev/null +++ b/soc/microchip/dspic33/dspic33a/power.c @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025, Microchip Technology Inc. + * SPDX-License-Identifier: Apache-2.0 + */ + +#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; + } +} + +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; + } +} 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