Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions arch/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ config DSPIC
select STACK_SENTINAL
select ATOMIC_OPERATIONS_C
select ARCH_HAS_VECTOR_TABLE_RELOCATION
select CPU_HAS_ICACHE
select CACHE_MANAGEMENT
select ARCH_HAS_STACK_PROTECTION
select TICKLESS_CAPABLE
select ARCH_HAS_CUSTOM_BUSY_WAIT
help
dspic architecture

Expand Down
2 changes: 1 addition & 1 deletion arch/dspic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@ if(CONFIG_BIG_ENDIAN)
else()
set_property(GLOBAL PROPERTY PROPERTY_OUTPUT_FORMAT elf32-little)
endif()
zephyr_include_directories(${XCDSC_TOOLCHAIN_PATH}/support/generic/h/)
zephyr_include_directories(${DFP_ROOT}/support/generic/h/)
zephyr_include_directories(include)
add_subdirectory(core)
20 changes: 17 additions & 3 deletions arch/dspic/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,24 @@ config GEN_ISR_TABLES
config DYNAMIC_INTERRUPTS
default n

config NUM_IRQS
default 279

config GEN_IRQ_START_VECTOR
default 0

config DSPIC33_IRQ_OFFLOAD_IRQ
int "IRQ number for irq_offload()"
default 34
help
Select the interrupt number used by irq_offload().
This must be a valid, software-triggerable interrupt on the dsPIC33.

config DSPIC_STACK_PROTECTION
bool
default y if HW_STACK_PROTECTION
select THREAD_STACK_INFO
help
Enable stack overflow detection
Will cause a fatal exception on stack overflow

config TEST_EXTRA_STACK_SIZE
default 512
endmenu
3 changes: 2 additions & 1 deletion arch/dspic/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ zephyr_library_sources(
cpu_idle.c
fatal.c
irq_manage.c
isr_wrapper.c
isr_wrapper.S
prep_c.c
thread.c
swap.c
Expand All @@ -13,6 +13,7 @@ zephyr_library_sources(
init.S
vector_table.S
reset1.S
irq_offload.c
)

zephyr_linker_sources(ROM_START SORT_KEY 0x00 vector_table.ld)
2 changes: 1 addition & 1 deletion arch/dspic/core/fatal.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ LOG_MODULE_REGISTER(dspic, 4);

volatile uint32_t reason, address;

#define EXCEPTION_HANDLER __attribute__((interrupt, no_auto_psv, weak))
#define EXCEPTION_HANDLER __attribute__((interrupt, no_auto_psv, weak, naked))
#define BUS_ERROR_MASK 0xF
#define MATH_ERROR_MASK 0x1F
#define GENERAL_TRAP_MASK 0x8000000Fu
Expand Down
43 changes: 29 additions & 14 deletions arch/dspic/core/irq_manage.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,46 +18,61 @@
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};
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);

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_enable_reg[reg_index] |= (uint32_t)(1u << bit_pos);
}

int arch_irq_is_enabled(unsigned int irq)
{
volatile uint32_t *int_enable_reg[] = {&IEC0, &IEC1, &IEC2, &IEC3, &IEC4,
&IEC5, &IEC6, &IEC7, &IEC8};
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);

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);
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};
volatile uint32_t *int_enable_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), ie_offset);

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));
int_enable_reg[reg_index] &= (uint32_t)(~(1u << bit_pos));
}

bool arch_dspic_irq_isset(unsigned int irq)
{
volatile uint32_t *int_ifs_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), if_offset);
volatile int ret_ifs = false;
unsigned int reg_index = irq / (sizeof(uint32_t) << 3);
unsigned int bit_pos = irq % (sizeof(uint32_t) << 3);

return;
if ( (int_ifs_reg[reg_index] & (1u << bit_pos)) != 0u ) {

Check failure on line 61 in arch/dspic/core/irq_manage.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACING

arch/dspic/core/irq_manage.c:61 space prohibited before that close parenthesis ')'

Check failure on line 61 in arch/dspic/core/irq_manage.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACING

arch/dspic/core/irq_manage.c:61 space prohibited after that open parenthesis '('
ret_ifs = true;
}
return ret_ifs;
}

void z_dspic_enter_irq(int irq)
{
volatile uint32_t *int_ifs_reg = (uint32_t *)DT_PROP(DT_NODELABEL(intc0), if_offset);

unsigned int reg_index = (unsigned int)irq / (sizeof(uint32_t) << 3);
unsigned int bit_pos = (unsigned int)irq % (sizeof(uint32_t) << 3);

/* Enable the interrupt by setting it's bit in interrupt enable register*/
int_ifs_reg[reg_index] |= (uint32_t)(1u << bit_pos);
}

#ifdef __cplusplus
Expand Down
48 changes: 48 additions & 0 deletions arch/dspic/core/irq_offload.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
/*
* Copyright (c) 2025, Microchip Technology Inc.
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/kernel.h>
#include <zephyr/kernel_structs.h>
#include <kernel_internal.h>
#include <zephyr/irq.h>
#include <zephyr/irq_offload.h>
#include <xc.h>

static irq_offload_routine_t _offload_routine;
static const void *offload_param;

void z_irq_do_offload(void)
{
irq_offload_routine_t tmp;

if (_offload_routine != NULL) {

tmp = _offload_routine;
_offload_routine = NULL;

tmp((const void *)offload_param);
}
}

void handler(void)
{
z_irq_do_offload();
}

void arch_irq_offload_init(void)
{
IRQ_CONNECT(CONFIG_DSPIC33_IRQ_OFFLOAD_IRQ, 1, handler, NULL, 0);
}

void arch_irq_offload(irq_offload_routine_t routine, const void *parameter)
{
uint32_t key = irq_lock();

_offload_routine = routine;
offload_param = parameter;
irq_enable(CONFIG_DSPIC33_IRQ_OFFLOAD_IRQ);
z_dspic_enter_irq(CONFIG_DSPIC33_IRQ_OFFLOAD_IRQ);
irq_unlock(key);
}
Loading
Loading