From 850815db622e12c8df3a25f823078a24c9876cbe Mon Sep 17 00:00:00 2001 From: FuChao Date: Fri, 10 Sep 2021 11:21:47 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0GPIO=E4=B8=AD=E6=96=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bsp/Vango_V85xx/drivers/drv_gpio.c | 204 ++++++++++++++++++++++++++--- bsp/Vango_V85xx/drivers/drv_gpio.h | 5 +- 2 files changed, 191 insertions(+), 18 deletions(-) diff --git a/bsp/Vango_V85xx/drivers/drv_gpio.c b/bsp/Vango_V85xx/drivers/drv_gpio.c index 60a8b7e642..8c9f7bf6d3 100644 --- a/bsp/Vango_V85xx/drivers/drv_gpio.c +++ b/bsp/Vango_V85xx/drivers/drv_gpio.c @@ -8,7 +8,7 @@ * 2020-12-27 iysheng first version * 2021-01-01 iysheng support exti interrupt * 2021-09-07 FuC Suit for Vango V85xx - * 2021-09-09 ZhuXW Fixing GPIO interrupt ... + * 2021-09-09 ZhuXW Add GPIO interrupt */ #include @@ -33,7 +33,32 @@ #error Unsupported V85XX GPIO peripheral. #endif -#define PIN_GDPORT_MAX __V85XX_PORT_MAX +#define PIN_V85XXPORT_MAX __V85XX_PORT_MAX +#define PIN_V85XXPORT_A 0u + +static const struct pin_irq_map pin_irq_map[] = +{ +#if defined(SOC_SERIES_V85XX) + {GPIO_Pin_0, PMU_IRQn}, + {GPIO_Pin_1, PMU_IRQn}, + {GPIO_Pin_2, PMU_IRQn}, + {GPIO_Pin_3, PMU_IRQn}, + {GPIO_Pin_4, PMU_IRQn}, + {GPIO_Pin_5, PMU_IRQn}, + {GPIO_Pin_6, PMU_IRQn}, + {GPIO_Pin_7, PMU_IRQn}, + {GPIO_Pin_8, PMU_IRQn}, + {GPIO_Pin_9, PMU_IRQn}, + {GPIO_Pin_10, PMU_IRQn}, + {GPIO_Pin_11, PMU_IRQn}, + {GPIO_Pin_12, PMU_IRQn}, + {GPIO_Pin_13, PMU_IRQn}, + {GPIO_Pin_14, PMU_IRQn}, + {GPIO_Pin_15, PMU_IRQn}, +#else +#error "Unsupported soc series" +#endif +}; static struct rt_pin_irq_hdr pin_irq_hdr_tab[] = { @@ -100,12 +125,18 @@ static void v85xx_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) GPIO_TypeDef *gpio_port; uint16_t gpio_pin; - if (PIN_PORT(pin) < PIN_GDPORT_MAX) + if (PIN_PORT(pin) == PIN_V85XXPORT_A) { - gpio_port = PIN_GDPORT(pin); - gpio_pin = PIN_GDPIN(pin); + gpio_pin = PIN_V85XXPIN(pin); - GPIOBToF_WriteBit(gpio_port, gpio_pin, (BitState)value);//GPIOA ignored + GPIOA_WriteBit(GPIOA, gpio_pin, (BitState)value); + } + else if (PIN_PORT(pin) < PIN_V85XXPORT_MAX) + { + gpio_port = PIN_V85XXPORT(pin); + gpio_pin = PIN_V85XXPIN(pin); + + GPIOBToF_WriteBit(gpio_port, gpio_pin, (BitState)value); } } @@ -115,11 +146,16 @@ static int v85xx_pin_read(rt_device_t dev, rt_base_t pin) uint16_t gpio_pin; int value = PIN_LOW; - if (PIN_PORT(pin) < PIN_GDPORT_MAX) + if (PIN_PORT(pin) == PIN_V85XXPORT_A) { - gpio_port = PIN_GDPORT(pin); - gpio_pin = PIN_GDPIN(pin); - value = GPIOBToF_ReadInputDataBit(gpio_port, gpio_pin);//GPIOA ignored + gpio_pin = PIN_V85XXPIN(pin); + value = GPIOA_ReadInputDataBit(GPIOA, gpio_pin); + } + else if (PIN_PORT(pin) < PIN_V85XXPORT_MAX) + { + gpio_port = PIN_V85XXPORT(pin); + gpio_pin = PIN_V85XXPIN(pin); + value = GPIOBToF_ReadInputDataBit(gpio_port, gpio_pin); } return value; @@ -129,13 +165,13 @@ static void v85xx_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) { GPIO_InitType GPIO_InitStruct = {0}; - if (PIN_PORT(pin) >= PIN_GDPORT_MAX) + if (PIN_PORT(pin) >= PIN_V85XXPORT_MAX) { return; } /* Configure GPIO_InitStructure */ - GPIO_InitStruct.GPIO_Pin = PIN_GDPIN(pin); + GPIO_InitStruct.GPIO_Pin = PIN_V85XXPIN(pin); GPIO_InitStruct.GPIO_Mode = GPIO_Mode_INPUT; switch (mode) @@ -159,7 +195,14 @@ static void v85xx_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) break; } - GPIOBToF_Init(PIN_GDPORT(pin), &GPIO_InitStruct);//ignore GPIOA + if (PIN_PORT(pin) == PIN_V85XXPORT_A) + { + GPIOA_Init(GPIOA, &GPIO_InitStruct); + } + else if (PIN_PORT(pin) < PIN_V85XXPORT_MAX) + { + GPIOBToF_Init(PIN_V85XXPORT(pin), &GPIO_InitStruct); + } } rt_inline rt_int32_t bit2bitno(rt_uint32_t bit) @@ -182,12 +225,16 @@ static rt_err_t v85xx_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_base_t level; rt_int32_t irqindex = -1; - if (PIN_PORT(pin) >= PIN_GDPORT_MAX) + if (PIN_PORT(pin) > PIN_V85XXPORT_A) { return -RT_ENOSYS; } - irqindex = bit2bitno(PIN_GDPIN(pin)); + irqindex = bit2bitno(PIN_V85XXPIN(pin)); + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } level = rt_hw_interrupt_disable(); if (pin_irq_hdr_tab[irqindex].pin == pin && @@ -213,12 +260,112 @@ static rt_err_t v85xx_pin_attach_irq(struct rt_device *device, rt_int32_t pin, } static rt_err_t v85xx_pin_detach_irq(struct rt_device *device, rt_int32_t pin) { + rt_base_t level; + rt_int32_t irqindex = -1; + + if (PIN_PORT(pin) > PIN_V85XXPORT_A) + { + return -RT_ENOSYS; + } + + irqindex = bit2bitno(PIN_V85XXPIN(pin)); + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } + + level = rt_hw_interrupt_disable(); + if (pin_irq_hdr_tab[irqindex].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_EOK; + } + pin_irq_hdr_tab[irqindex].pin = -1; + pin_irq_hdr_tab[irqindex].hdr = RT_NULL; + pin_irq_hdr_tab[irqindex].mode = 0; + pin_irq_hdr_tab[irqindex].args = RT_NULL; + rt_hw_interrupt_enable(level); return RT_EOK; } static rt_err_t v85xx_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { + const struct pin_irq_map *irqmap; + rt_base_t level; + rt_int32_t irqindex = -1; + GPIO_InitType GPIO_InitStruct = {0}; + if (PIN_PORT(pin) > PIN_V85XXPORT_A) + { + return -RT_ENOSYS; + } + + GPIO_InitStruct.GPIO_Pin = PIN_V85XXPIN(pin); + if (enabled == PIN_IRQ_ENABLE) + { + irqindex = bit2bitno(PIN_V85XXPIN(pin)); + if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map)) + { + return RT_ENOSYS; + } + + level = rt_hw_interrupt_disable(); + + if (pin_irq_hdr_tab[irqindex].pin == -1) + { + rt_hw_interrupt_enable(level); + return RT_ENOSYS; + } + + GPIO_InitStruct.GPIO_Mode = GPIO_Mode_INPUT; + GPIO_InitStruct.GPIO_Pin = PIN_V85XXPIN(pin); + GPIOA_Init(GPIOA, &GPIO_InitStruct); + + irqmap = &pin_irq_map[irqindex]; + + switch (pin_irq_hdr_tab[irqindex].mode) + { + case PIN_IRQ_MODE_RISING: + PMU_WakeUpPinConfig(PIN_V85XXPIN(pin), IOA_RISING); + break; + case PIN_IRQ_MODE_FALLING: + PMU_WakeUpPinConfig(PIN_V85XXPIN(pin), IOA_FALLING); + break; + case PIN_IRQ_MODE_RISING_FALLING: + PMU_WakeUpPinConfig(PIN_V85XXPIN(pin), IOA_EDGEBOTH); + break; + case PIN_IRQ_MODE_HIGH_LEVEL: + PMU_WakeUpPinConfig(PIN_V85XXPIN(pin), IOA_HIGH); + break; + case PIN_IRQ_MODE_LOW_LEVEL: + PMU_WakeUpPinConfig(PIN_V85XXPIN(pin), IOA_LOW); + break; + default: + break; + } + PMU_INTConfig(PMU_INT_IOAEN, ENABLE); + + NVIC_SetPriority(irqmap->irqno, 0); + NVIC_EnableIRQ(irqmap->irqno); + pin_irq_enable_mask |= irqmap->pinbit; + + rt_hw_interrupt_enable(level); + } + else if (enabled == PIN_IRQ_DISABLE) + { + + level = rt_hw_interrupt_disable(); + + PMU_INTConfig(PMU_INT_IOAEN, DISABLE); + + NVIC_DisableIRQ(irqmap->irqno); + + rt_hw_interrupt_enable(level); + } + else + { + return -RT_ENOSYS; + } return RT_EOK; } @@ -243,6 +390,32 @@ rt_inline void pin_irq_hdr(int irqno) } } + +void v85xx_pin_exti_irqhandler() +{ + rt_base_t intsts=0; + int i=0; + + intsts = PMU_GetIOAAllINTStatus(); + for(i=0; i<16; i++) + { + if((1<> 4) & 0xFu)) #define PIN_NO(pin) ((uint8_t)((pin) & 0xFu)) -#define PIN_GDPORT(pin) ((GPIO_TypeDef *)(GPIOB_BASE + (0x400u * PIN_PORT(pin)))) -#define PIN_GDPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) +#define PIN_V85XXPORT(pin) ((GPIO_TypeDef *)(GPIOB_BASE + (0x400u * PIN_PORT(pin)))) +#define PIN_V85XXPIN(pin) ((uint16_t)(1u << PIN_NO(pin))) struct pin_irq_map {