5#include "hpm_interrupt.h"
6#include "hpm_ioc_regs.h"
23std::atomic_flag g_hpm_gpio_irq_route_lock = ATOMIC_FLAG_INIT;
25bool HPM_GPIO_IsFastController(GPIO_Type* gpio)
28 return gpio == HPM_FGPIO;
35class HPMGPIOIrqRouteGuard
38 HPMGPIOIrqRouteGuard()
39 : irq_state_(disable_global_irq(CSR_MSTATUS_MIE_MASK) & CSR_MSTATUS_MIE_MASK)
41 while (g_hpm_gpio_irq_route_lock.test_and_set(std::memory_order_acquire))
46 ~HPMGPIOIrqRouteGuard()
48 g_hpm_gpio_irq_route_lock.clear(std::memory_order_release);
49 restore_global_irq(irq_state_);
52 HPMGPIOIrqRouteGuard(
const HPMGPIOIrqRouteGuard&) =
delete;
53 HPMGPIOIrqRouteGuard& operator=(
const HPMGPIOIrqRouteGuard&) =
delete;
70static inline void HPM_GPIO_ConfigMuxToGPIO(GPIO_Type* gpio, uint32_t port,
72 bool enable_loopback =
true)
74 uint32_t func_ctl = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(0);
77 func_ctl |= IOC_PAD_FUNC_CTL_LOOP_BACK_MASK;
79 HPM_IOC->PAD[pad_index].FUNC_CTL = func_ctl;
82#if defined(GPIO_DI_GPIOY) && defined(HPM_PIOC)
83 if (port == GPIO_DI_GPIOY && (gpio == HPM_GPIO0 || HPM_GPIO_IsFastController(gpio)))
85 HPM_PIOC->PAD[pad_index].FUNC_CTL = IOC_PAD_FUNC_CTL_ALT_SELECT_SET(3);
103 pad_index_(pad_index == INVALID_PAD_INDEX ? ResolvePadIndex(gpio, port, pin)
109 if (port_controller_map[
port_] ==
nullptr)
135 if (HPM_GPIO_IsFastController(
gpio_))
140 HPMGPIOIrqRouteGuard guard;
147 const bool needs_port_irq_enable = (route.enabled_pin_count == 0u);
148 if (!needs_port_irq_enable && (route.controller !=
gpio_ || route.irq !=
irq_))
155 if (needs_port_irq_enable)
157 route.controller =
gpio_;
159 intc_m_enable_irq_with_priority(
irq_, 1);
162 ++route.enabled_pin_count;
184 if (HPM_GPIO_IsFastController(
gpio_))
189 HPMGPIOIrqRouteGuard guard;
198 if (route.enabled_pin_count == 0u)
205 if (route.controller !=
gpio_ || route.irq !=
irq_)
211 --route.enabled_pin_count;
212 if (route.enabled_pin_count == 0u)
214 const uint32_t route_irq = route.irq;
216 intc_m_disable_irq(route_irq);
251 const bool is_interrupt_direction =
255 if (is_interrupt_direction && HPM_GPIO_IsFastController(
gpio_))
261#if !defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) || (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT != 1)
284 gpio_config_pin_interrupt(
gpio_,
port_,
pin_, gpio_interrupt_trigger_edge_falling);
288 gpio_config_pin_interrupt(
gpio_,
port_,
pin_, gpio_interrupt_trigger_edge_rising);
291#if defined(GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT) && (GPIO_SOC_HAS_EDGE_BOTH_INTERRUPT == 1)
293 gpio_config_pin_interrupt(
gpio_,
port_,
pin_, gpio_interrupt_trigger_edge_both);
304 uint32_t pad_ctl = HPM_IOC->PAD[
pad_index_].PAD_CTL;
308 ~(IOC_PAD_PAD_CTL_PE_MASK | IOC_PAD_PAD_CTL_PS_MASK | IOC_PAD_PAD_CTL_OD_MASK);
315 pad_ctl |= IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(1);
318 pad_ctl |= IOC_PAD_PAD_CTL_PE_SET(1) | IOC_PAD_PAD_CTL_PS_SET(0);
324 pad_ctl |= IOC_PAD_PAD_CTL_OD_SET(1);
370 HPM_IOC->PAD[
pad_index_].FUNC_CTL = IOC_PAD_FUNC_CTL_ANALOG_MASK;
372 uint32_t pad_ctl = HPM_IOC->PAD[
pad_index_].PAD_CTL;
373 pad_ctl &= ~(IOC_PAD_PAD_CTL_PE_MASK | IOC_PAD_PAD_CTL_OD_MASK);
400 GPIO_Type* controller = port_controller_map[port];
401 if (controller ==
nullptr)
406 const uint32_t flags = gpio_get_port_interrupt_flags(controller, port);
412 for (uint8_t pin = 0; pin <
PIN_COUNT; ++pin)
414 if ((flags & (1u << pin)) == 0u)
419 gpio_clear_pin_interrupt_flag(controller, port, pin);
422 gpio->callback_.Run(
true);
432 if (gpio != HPM_GPIO0 && !HPM_GPIO_IsFastController(gpio))
439#if defined(GPIO_DI_GPIOA) && defined(IOC_PAD_PA00)
441 return static_cast<uint16_t
>(IOC_PAD_PA00 + pin);
443#if defined(GPIO_DI_GPIOB) && defined(IOC_PAD_PB00)
445 return static_cast<uint16_t
>(IOC_PAD_PB00 + pin);
447#if defined(GPIO_DI_GPIOX) && defined(IOC_PAD_PX00)
451#if defined(GPIO_DI_GPIOY) && defined(IOC_PAD_PY00)
464extern "C" void libxr_hpm_gpio_check_interrupt(uint32_t port)
@ OUTPUT_PUSH_PULL
推挽输出模式。Push-pull output mode.
@ RISING_INTERRUPT
上升沿中断模式。Rising edge interrupt mode.
@ FALL_RISING_INTERRUPT
双沿触发中断模式。Both edge interrupt mode.
@ OUTPUT_OPEN_DRAIN
开漏输出模式。Open-drain output mode.
@ FALL_INTERRUPT
下降沿中断模式。Falling edge interrupt mode.
@ NONE
无上拉或下拉。No pull-up or pull-down.
@ DOWN
下拉模式。Pull-down mode.
HPM 平台 GPIO 驱动实现 / GPIO driver implementation for HPM platform.
GPIO_Type * gpio_
GPIO 控制器实例 / GPIO controller instance.
ErrorCode EnableInterrupt() override
使能当前引脚中断 / Enable GPIO interrupt for current pin.
static constexpr uint32_t INVALID_IRQ
无效 IRQ 标记 / Invalid IRQ marker.
static constexpr uint32_t PORT_COUNT
支持的端口数量 / Supported port count.
static constexpr uint16_t INVALID_PAD_INDEX
无效 PAD 标记 / Invalid PAD marker.
ErrorCode SetAnalogHighImpedance()
将当前 PAD 配置为模拟高阻 / Configure current pad to analog high-impedance.
static uint16_t ResolvePadIndex(GPIO_Type *gpio, uint32_t port, uint8_t pin)
根据控制器与端口引脚推导 IOC PAD 编号 / Resolve IOC PAD index from controller/port/pin tuple.
bool interrupt_enabled_
当前 pin IRQ 使能状态 / Per-instance IRQ enabled flag.
ErrorCode SetConfig(Configuration config) override
配置当前引脚模式 / Configure GPIO mode for current pin.
uint16_t pad_index_
IOC PAD 编号 / IOC PAD index.
static void CheckInterrupt(uint32_t port)
分发某一端口的 GPIO 中断回调 / Dispatch GPIO interrupt callbacks for one port.
uint32_t irq_
当前 port 对应 IRQ 号 / IRQ number for the current port.
ErrorCode DisableInterrupt() override
失能当前引脚中断 / Disable GPIO interrupt for current pin.
static constexpr uint32_t PIN_COUNT
每个端口引脚数 / Pins per port.
HPMGPIO(GPIO_Type *gpio, uint32_t port, uint8_t pin, uint32_t irq=INVALID_IRQ, uint16_t pad_index=INVALID_PAD_INDEX)
构造 HPM GPIO 对象 / Construct an HPM GPIO object.
uint8_t pin_
GPIO 引脚号 / GPIO pin index.
uint32_t port_
GPIO 端口号 / GPIO port index.
static HPMGPIO * map[PORT_COUNT][PIN_COUNT]
GPIO 对象映射表 / GPIO object dispatch map.
HPM GPIO 驱动适配头文件 / Adapter header for the HPM GPIO driver.
@ STATE_ERR
状态错误 | State error
@ NOT_SUPPORT
不支持 | Not supported
@ OK
操作成功 | Operation successful
@ ARG_ERR
参数错误 | Argument error
存储 GPIO 配置参数的结构体。Structure storing GPIO configuration parameters.
Pull pull
GPIO 上拉/下拉配置。GPIO pull-up/pull-down configuration.
Direction direction
GPIO 引脚方向。GPIO pin direction.
端口级 IRQ 路由状态 / Shared port-level IRQ routing state.