gustavonihei commented on a change in pull request #2838: URL: https://github.com/apache/incubator-nuttx/pull/2838#discussion_r577560175
########## File path: arch/risc-v/src/esp32c3/esp32c3_irq.c ########## @@ -0,0 +1,372 @@ +/**************************************************************************** + * arch/risc-v/src/esp32c3/esp32c3_irq.c + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include <nuttx/config.h> + +#include <sys/errno.h> +#include <debug.h> + +#include <nuttx/irq.h> +#include <nuttx/arch.h> +#include <nuttx/board.h> +#include <arch/board/board.h> + +#include <arch/irq.h> +#include <arch/rv32im/mcause.h> + +#include "riscv_internal.h" +#include "hardware/esp32c3_interrupt.h" + +#include "esp32c3.h" +#include "esp32c3_attr.h" + +#include "esp32c3_irq.h" + +/**************************************************************************** + * Pre-processor Definitions + ****************************************************************************/ + +#define ESP32C3_DEFAULT_INT_THRESHOLD 1 + +/* No peripheral assigned to this CPU interrupt */ + +#define CPUINT_UNASSIGNED 0xff + +/**************************************************************************** + * Public Data + ****************************************************************************/ + +volatile uint32_t *g_current_regs; + +/**************************************************************************** + * Private Data + ****************************************************************************/ + +uint8_t g_cpuint_map[ESP32C3_CPUINT_MAX]; + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: up_irqinitialize + ****************************************************************************/ + +void up_irqinitialize(void) +{ + int periphid; + + /* Indicate that no peripheral interrupts are assigned to CPU interrupts */ + + memset(g_cpuint_map, CPUINT_UNASSIGNED, ESP32C3_CPUINT_MAX); + + /* Clear all peripheral interrupts from "bootloader" */ + + for (periphid = 0; periphid < ESP32C3_NPERIPHERALS; periphid++) + { + putreg32(0, DR_REG_INTERRUPT_BASE + periphid * 4); + } + + /* Set CPU interrupt threshold level */ + + putreg32(ESP32C3_DEFAULT_INT_THRESHOLD, INTERRUPT_CPU_INT_THRESH_REG); + + /* Attach the ECALL interrupt. */ + + irq_attach(ESP32C3_IRQ_ECALL_M, up_swint, NULL); + +#ifndef CONFIG_SUPPRESS_INTERRUPTS + + /* And finally, enable interrupts */ + + up_irq_enable(); +#endif +} + +/**************************************************************************** + * Name: up_get_newintctx + * + * Description: + * Return initial mstatus when a task is created. + * + ****************************************************************************/ + +uint32_t up_get_newintctx(void) +{ + /* Set machine previous privilege mode to machine mode. + * Also set machine previous interrupt enable + */ + + return (MSTATUS_MPPM | MSTATUS_MPIE); +} + +/**************************************************************************** + * Name: up_enable_irq + * + * Description: + * Enable the CPU interrupt specified by 'cpuint' + * + ****************************************************************************/ + +void up_enable_irq(int cpuint) +{ + irqstate_t irqstate; + + DEBUGASSERT(cpuint >= ESP32C3_CPUINT_MIN && cpuint <= ESP32C3_CPUINT_MAX); + + irqstate = enter_critical_section(); + setbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG); + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: up_disable_irq + * + * Description: + * Disable the CPU interrupt specified by 'cpuint' + * + ****************************************************************************/ + +void up_disable_irq(int cpuint) +{ + irqstate_t irqstate; + + DEBUGASSERT(cpuint >= ESP32C3_CPUINT_MIN && cpuint <= ESP32C3_CPUINT_MAX); + + irqstate = enter_critical_section(); + resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG); + leave_critical_section(irqstate); +} + +/**************************************************************************** + * Name: esp32c3_request_irq + * + * Description: + * Request IRQ and resource with given parameters. + * + * Input Parameters: + * periphid - Peripheral ID + * prio - Interrupt priority + * flags - Interrupt flags + * + * Returned Value: + * Allocated CPU interrupt on success, a negated error on failure. + * + ****************************************************************************/ + +int esp32c3_request_irq(uint8_t periphid, uint8_t prio, uint32_t flags) +{ + int ret; + uint32_t regval; + int cpuint; + irqstate_t irqstate; + + DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS); + DEBUGASSERT((prio >= ESP32C3_INT_PRIO_MIN) && + (prio <= ESP32C3_INT_PRIO_MAX)); + + irqstate = enter_critical_section(); + + /* Skip over enabled interrupts. NOTE: bit 0 is reserved. */ + + regval = getreg32(INTERRUPT_CPU_INT_ENABLE_REG); + for (cpuint = 1; cpuint <= ESP32C3_CPUINT_MAX; cpuint++) + { + if (!(regval & (1 << cpuint))) + { + break; + } + } + + irqinfo("INFO: cpuint=%d\n", cpuint); + + if (cpuint <= ESP32C3_CPUINT_MAX) + { + DEBUGASSERT(g_cpuint_map[cpuint] == CPUINT_UNASSIGNED); + + /* We have a free CPU interrupt. We can continue with mapping the + * peripheral. + */ + + /* Save the CPU interrupt ID. We will return this value. */ + + ret = cpuint; + + /* Update our CPU interrupt to Peripheral map. */ + + g_cpuint_map[cpuint] = periphid; + + /* Set the interrupt priority. */ + + putreg32(prio, INTERRUPT_CPU_INT_PRI_0_REG + cpuint * 4); + + /* Set the interrupt type (Edge or Level). */ + + if (flags & ESP32C3_INT_EDGE) + { + setbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG); + } + else + { + resetbits(1 << cpuint, INTERRUPT_CPU_INT_TYPE_REG); + } + + /* Map the CPU interrupt ID to the peripheral. */ + + putreg32(cpuint, DR_REG_INTERRUPT_BASE + periphid * 4); + + /* Disable the CPU interrupt. */ + + resetbits(1 << cpuint, INTERRUPT_CPU_INT_ENABLE_REG); + } + else + { + /* We couldn't find a free CPU interrupt. */ + + ret = -ENOMEM; + } + + leave_critical_section(irqstate); + + return ret; +} + +/**************************************************************************** + * Name: esp32c3_free_cpuint + * + * Description: + * Free CPU interrupt. + * + * Input Parameters: + * periphid - Peripheral ID. + * + * Returned Value: + * None. + * + ****************************************************************************/ + +void esp32c3_free_cpuint(uint8_t periphid) +{ + irqstate_t irqstate; + uint32_t cpuint; + + DEBUGASSERT(periphid < ESP32C3_NPERIPHERALS); + + irqstate = enter_critical_section(); + + /* Get the CPU interrupt ID mapped to this peripheral. */ + + cpuint = getreg32(DR_REG_INTERRUPT_BASE + periphid * 4) & 0x1f; + irqinfo("INFO: irq[%d]=%08lx\n", periphid, cpuint); + + if (cpuint) + { + /* Undo the alloaction process: Review comment: ```suggestion /* Undo the allocation process: ``` ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: us...@infra.apache.org