diff options
Diffstat (limited to 'FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c')
-rw-r--r-- | FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c | 151 |
1 files changed, 151 insertions, 0 deletions
diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c new file mode 100644 index 000000000..1c34ca447 --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_local-external-interrupts0.c @@ -0,0 +1,151 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include <metal/machine/platform.h> + +#ifdef METAL_SIFIVE_LOCAL_EXTERNAL_INTERRUPTS0 + +#include <metal/io.h> +#include <metal/drivers/sifive_local-external-interrupts0.h> +#include <metal/machine.h> + +void __metal_driver_sifive_local_external_interrupt_init(struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_local_external_interrupts0 *local0; + + local0 = (struct __metal_driver_sifive_local_external_interrupts0 *)(controller); + if ( !local0->init_done ) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + if (intc) { + /* Register its interruptswith with parent controller, aka all external to default isr */ + for (int i = 0; + i < __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); + i++) { + intc->vtable->interrupt_register(intc, + __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, i), + NULL, controller); + } + local0->init_done = 1; + } + } +} + +int __metal_driver_sifive_local_external_interrupt_register(struct metal_interrupt *controller, + int id, metal_interrupt_handler_t isr, + void *priv) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_register(intc, id, isr, priv); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_enable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_enable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_disable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_local_external_interrupts0_interrupt_parent(controller); + + /* Enable its interrupts with parent controller */ + if (intc) { + rc = intc->vtable->interrupt_disable(intc, id); + } + } + return rc; +} + +int __metal_driver_sifive_local_external_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int threshold) +{ + /* Core controller does not support threshold configuration */ + return -1; +} + +unsigned int __metal_driver_sifive_local_external_interrupt_get_threshold(struct metal_interrupt *controller) +{ + /* Core controller does not support threshold configuration */ + return 0; +} + + +int __metal_driver_sifive_local_external_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) +{ + /* Core controller does not support priority configuration */ + return -1; +} + +unsigned int __metal_driver_sifive_local_external_interrupt_get_priority(struct metal_interrupt *controller, int id) +{ + /* Core controller does not support priority configuration */ + return 0; +} + +int __metal_driver_sifive_local_external_command_request (struct metal_interrupt *controller, + int command, void *data) +{ + int idx; + int rc = -1; + + switch (command) { + case METAL_MAX_INTERRUPT_GET: + rc = __metal_driver_sifive_local_external_interrupts0_num_interrupts(controller); + break; + case METAL_INDEX_INTERRUPT_GET: + rc = 0; + if (data) { + idx = *(int *)data; + rc = __metal_driver_sifive_local_external_interrupts0_interrupt_lines(controller, idx); + } + break; + default: + break; + } + + return rc; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_local_external_interrupts0) = { + .local0_vtable.interrupt_init = __metal_driver_sifive_local_external_interrupt_init, + .local0_vtable.interrupt_register = __metal_driver_sifive_local_external_interrupt_register, + .local0_vtable.interrupt_enable = __metal_driver_sifive_local_external_interrupt_enable, + .local0_vtable.interrupt_disable = __metal_driver_sifive_local_external_interrupt_disable, + .local0_vtable.interrupt_get_threshold = __metal_driver_sifive_local_external_interrupt_get_threshold, + .local0_vtable.interrupt_set_threshold = __metal_driver_sifive_local_external_interrupt_set_threshold, + .local0_vtable.interrupt_get_priority = __metal_driver_sifive_local_external_interrupt_get_priority, + .local0_vtable.interrupt_set_priority = __metal_driver_sifive_local_external_interrupt_set_priority, + .local0_vtable.command_request = __metal_driver_sifive_local_external_command_request, +}; + +#endif + +typedef int no_empty_translation_units; + |