X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=FreeRTOS%2FDemo%2FRISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio%2Ffreedom-metal%2Fsrc%2Fdrivers%2Fsifive_global-external-interrupts0.c;fp=FreeRTOS%2FDemo%2FRISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio%2Ffreedom-metal%2Fsrc%2Fdrivers%2Fsifive_global-external-interrupts0.c;h=0d56bafeffaa6d6de7a0c1d9b4691a362d2e54d3;hb=d38142e468c2f407c9cbbb271f487fc35879bdef;hp=0000000000000000000000000000000000000000;hpb=3bcd0c8a9d1b399c59475115322cbb93484e66d2;p=freertos diff --git a/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c new file mode 100644 index 000000000..0d56bafef --- /dev/null +++ b/FreeRTOS/Demo/RISC-V_RV32_SiFive_HiFive1-RevB_FreedomStudio/freedom-metal/src/drivers/sifive_global-external-interrupts0.c @@ -0,0 +1,169 @@ +/* Copyright 2018 SiFive, Inc */ +/* SPDX-License-Identifier: Apache-2.0 */ + +#include + +#ifdef METAL_SIFIVE_GLOBAL_EXTERNAL_INTERRUPTS0 + +#include +#include +#include +#include + +void __metal_driver_sifive_global_external_interrupt_init(struct metal_interrupt *controller) +{ + struct __metal_driver_sifive_global_external_interrupts0 *global0; + + global0 = (struct __metal_driver_sifive_global_external_interrupts0 *)(controller); + if ( !global0->init_done ) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + intc->vtable->interrupt_init(intc); + /* Register its interrupts with with parent controller */ + for (int i = 0; + i < __metal_driver_sifive_global_external_interrupts0_num_interrupts(controller); + i++) { + intc->vtable->interrupt_register(intc, + __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, i), + NULL, controller); + } + global0->init_done = 1; + } + } +} + +int __metal_driver_sifive_global_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_global_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_global_external_interrupt_enable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_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_global_external_interrupt_disable(struct metal_interrupt *controller, int id) +{ + int rc = -1; + + if (id != 0) { + struct metal_interrupt *intc = + __metal_driver_sifive_global_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_global_external_interrupt_set_threshold(struct metal_interrupt *controller, + unsigned int threshold) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + if (intc) { + return intc->vtable->interrupt_set_threshold(intc, threshold); + } + return -1; +} + +unsigned int __metal_driver_sifive_global_external_interrupt_get_threshold(struct metal_interrupt *controller) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + return intc->vtable->interrupt_get_threshold(intc); + } + return 0; +} + +int __metal_driver_sifive_global_external_interrupt_set_priority(struct metal_interrupt *controller, + int id, unsigned int priority) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + if (intc) { + return intc->vtable->interrupt_set_priority(intc, id, priority); + } + return -1; +} + +unsigned int __metal_driver_sifive_global_external_interrupt_get_priority(struct metal_interrupt *controller, int id) +{ + struct metal_interrupt *intc = + __metal_driver_sifive_global_external_interrupts0_interrupt_parent(controller); + + if (intc) { + return intc->vtable->interrupt_get_priority(intc, id); + } + return 0; +} + +int __metal_driver_sifive_global_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_global_external_interrupts0_num_interrupts(controller); + break; + case METAL_INDEX_INTERRUPT_GET: + rc = 0; + if (data) { + idx = *(int *)data; + rc = __metal_driver_sifive_global_external_interrupts0_interrupt_lines(controller, idx); + } + break; + default: + break; + } + + return rc; +} + +__METAL_DEFINE_VTABLE(__metal_driver_vtable_sifive_global_external_interrupts0) = { + .global0_vtable.interrupt_init = __metal_driver_sifive_global_external_interrupt_init, + .global0_vtable.interrupt_register = __metal_driver_sifive_global_external_interrupt_register, + .global0_vtable.interrupt_enable = __metal_driver_sifive_global_external_interrupt_enable, + .global0_vtable.interrupt_disable = __metal_driver_sifive_global_external_interrupt_disable, + .global0_vtable.interrupt_get_threshold = __metal_driver_sifive_global_external_interrupt_get_threshold, + .global0_vtable.interrupt_set_threshold = __metal_driver_sifive_global_external_interrupt_set_threshold, + .global0_vtable.interrupt_get_priority = __metal_driver_sifive_global_external_interrupt_get_priority, + .global0_vtable.interrupt_set_priority = __metal_driver_sifive_global_external_interrupt_set_priority, + .global0_vtable.command_request = __metal_driver_sifive_global_external_command_request, +}; + +#endif + +typedef int no_empty_translation_units;