From 60f17b69f6a81bdc1dd1019deaac38dd8616b2a2 Mon Sep 17 00:00:00 2001 From: liuguang <1004383796@qq.com> Date: Mon, 19 Mar 2018 21:32:32 +0800 Subject: [PATCH] =?UTF-8?q?[BSP]=20fix=20pin=20drive=20bug=20and=20add=20i?= =?UTF-8?q?nterrupt=20mode.=20|=20=E4=BF=AE=E5=A4=8DPIN=E9=A9=B1=E5=8A=A8B?= =?UTF-8?q?UG=E5=B9=B6=E6=B7=BB=E5=8A=A0=E4=B8=AD=E6=96=AD=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 更新如下: 1. 修复GPIO5_0~2管脚复用调用错误(错误情况会影响SDRAM正常工作)。 2. 添加中断模式,支持上升沿、下降沿、双边沿、高电平、低电平触发中断模式。 3. 移除C99特性。 --- bsp/imxrt1052-evk/drivers/drv_pin.c | 461 +++++++++++++++++++++++++++- bsp/imxrt1052-evk/drivers/drv_pin.h | 1 + 2 files changed, 450 insertions(+), 12 deletions(-) diff --git a/bsp/imxrt1052-evk/drivers/drv_pin.c b/bsp/imxrt1052-evk/drivers/drv_pin.c index 84e3733039..3715371cde 100644 --- a/bsp/imxrt1052-evk/drivers/drv_pin.c +++ b/bsp/imxrt1052-evk/drivers/drv_pin.c @@ -9,7 +9,8 @@ * * Change Logs: * Date Author Notes - * 2018-03-13 Liuguang the first version. + * 2018-03-13 Liuguang the first version. + * 2018-03-19 Liuguang add GPIO interrupt mode support. */ #include "drv_pin.h" @@ -19,12 +20,10 @@ #ifdef RT_USING_PIN -/* GPIOʱӻGPIO_PinInitԶ, º򲻻Զ */ #if defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL #error "Please don't define 'FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL'!" #endif -/* RT1052 PINṹ */ struct rt1052_pin { rt_uint16_t pin; @@ -32,10 +31,18 @@ struct rt1052_pin rt_uint32_t gpio_pin; }; +struct rt1052_irq +{ + rt_uint16_t enable; + struct rt_pin_irq_hdr irq_info; +}; + #define __ARRAY_LEN(array) (sizeof(array)/sizeof(array[0])) #define __RT1052_PIN_DEFAULT {0, 0, 0} #define __RT1052_PIN(INDEX, PORT, PIN) {INDEX, PORT, PIN} +static struct rt_pin_ops rt1052_pin_ops; + static struct rt1052_pin rt1052_pin_map[] = { __RT1052_PIN_DEFAULT, @@ -179,6 +186,279 @@ static struct rt1052_pin rt1052_pin_map[] = __RT1052_PIN(127, GPIO5, 2) /* PMIC_STBY_REQ */ }; +static struct rt1052_irq rt1052_irq_map[] = +{ + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} }, + {PIN_IRQ_DISABLE, {PIN_IRQ_PIN_NONE, PIN_IRQ_MODE_RISING, RT_NULL, RT_NULL} } +}; + +void gpio_isr(GPIO_Type* base, rt_uint32_t gpio_pin) +{ + if((GPIO_PortGetInterruptFlags(base) & (1 << gpio_pin)) != 0) + { + GPIO_PortClearInterruptFlags(base, gpio_pin); + + if(rt1052_irq_map[gpio_pin].irq_info.hdr != RT_NULL) + { + rt1052_irq_map[gpio_pin].irq_info.hdr(rt1052_irq_map[gpio_pin].irq_info.args); + } + } +} + +void GPIO1_Combined_0_15_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 0; gpio_pin <= 15; gpio_pin++) + { + gpio_isr(GPIO1, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO1_Combined_16_31_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 16; gpio_pin <= 31; gpio_pin++) + { + gpio_isr(GPIO1, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO2_Combined_0_15_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 0; gpio_pin <= 15; gpio_pin++) + { + gpio_isr(GPIO2, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO2_Combined_16_31_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 16; gpio_pin <= 31; gpio_pin++) + { + gpio_isr(GPIO2, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO3_Combined_0_15_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 0; gpio_pin <= 15; gpio_pin++) + { + gpio_isr(GPIO3, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO3_Combined_16_31_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 16; gpio_pin <= 31; gpio_pin++) + { + gpio_isr(GPIO3, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO4_Combined_0_15_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 0; gpio_pin <= 15; gpio_pin++) + { + gpio_isr(GPIO4, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} +void GPIO4_Combined_16_31_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 16; gpio_pin <= 31; gpio_pin++) + { + gpio_isr(GPIO4, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +void GPIO5_Combined_0_15_IRQHandler(void) +{ + rt_uint8_t gpio_pin; + + rt_interrupt_enter(); + + for(gpio_pin = 0; gpio_pin <= 2; gpio_pin++) + { + gpio_isr(GPIO5, gpio_pin); + } + +#if defined __CORTEX_M && (__CORTEX_M == 4U) + __DSB(); +#endif + + rt_interrupt_leave(); +} + +static IRQn_Type rt1052_get_irqnum(GPIO_Type *gpio, rt_uint32_t gpio_pin) +{ + IRQn_Type irq_num; + + if(gpio == GPIO1) + { + if(gpio_pin <= 15) + { + irq_num = GPIO1_Combined_0_15_IRQn; + } + else + { + irq_num = GPIO1_Combined_16_31_IRQn; + } + } + else if(gpio == GPIO2) + { + if(gpio_pin <= 15) + { + irq_num = GPIO2_Combined_0_15_IRQn; + } + else + { + irq_num = GPIO2_Combined_16_31_IRQn; + } + } + else if(gpio == GPIO3) + { + if(gpio_pin <= 15) + { + irq_num = GPIO3_Combined_0_15_IRQn; + } + else + { + irq_num = GPIO3_Combined_16_31_IRQn; + } + } + else if(gpio == GPIO4) + { + if(gpio_pin <= 15) + { + irq_num = GPIO4_Combined_0_15_IRQn; + } + else + { + irq_num = GPIO4_Combined_16_31_IRQn; + } + } + else if(gpio == GPIO5) + { + if(gpio_pin <= 15) + { + irq_num = GPIO5_Combined_0_15_IRQn; + } + else + { + irq_num = GPIO5_Combined_16_31_IRQn; + } + } + + return irq_num; +} + static void rt1052_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) { gpio_pin_config_t gpio; @@ -193,15 +473,15 @@ static void rt1052_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) { CLOCK_EnableClock(kCLOCK_Iomuxc); + IOMUXC_SetPinMux(0x401F8010U + pin*4, 0x5U, 0, 0, 0, 0); } else { CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + + IOMUXC_SetPinMux(0x401F8000U + (pin-125)*4, 0x5U, 0, 0, 0, 0); } - /* IOMUXC: IOΪGPIO */ - IOMUXC_SetPinMux(0x401F8010U + pin*4, 0x5U, 0, 0, 0, 0); - gpio.outputLogic = 0; gpio.interruptMode = kGPIO_NoIntmode; @@ -243,7 +523,6 @@ static void rt1052_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode) break; } - /* GPIOģʽ: ģʽ, ©ģ, IOתٶ(50MHz) */ IOMUXC_SetPinConfig(0, 0, 0, 0, 0x401F8200U + pin*4, config_value); GPIO_PinInit(rt1052_pin_map[pin].gpio, rt1052_pin_map[pin].gpio_pin, &gpio); @@ -259,17 +538,175 @@ static void rt1052_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value) GPIO_PinWrite(rt1052_pin_map[pin].gpio, rt1052_pin_map[pin].gpio_pin, value); } -static struct rt_pin_ops rt1052_pin_ops = +static rt_err_t rt1052_pin_attach_irq(struct rt_device *device, rt_int32_t pin, + rt_uint32_t mode, void (*hdr)(void *args), void *args) { - .pin_mode = rt1052_pin_mode, - .pin_read = rt1052_pin_read, - .pin_write = rt1052_pin_write -}; + struct rt1052_pin* pin_map = RT_NULL; + struct rt1052_irq* irq_map = RT_NULL; + + pin_map = &rt1052_pin_map[pin]; + irq_map = &rt1052_irq_map[rt1052_pin_map[pin].gpio_pin]; + + if(pin_map == RT_NULL || irq_map == RT_NULL) + { + return RT_ENOSYS; + } + + if(irq_map->enable == PIN_IRQ_ENABLE) + { + return RT_EBUSY; + } + + irq_map->irq_info.pin = pin; + irq_map->irq_info.hdr = hdr; + irq_map->irq_info.mode = mode; + irq_map->irq_info.args = args; + + return RT_EOK; +} + +static rt_err_t rt1052_pin_dettach_irq(struct rt_device *device, rt_int32_t pin) +{ + struct rt1052_pin* pin_map = RT_NULL; + struct rt1052_irq* irq_map = RT_NULL; + + pin_map = &rt1052_pin_map[pin]; + irq_map = &rt1052_irq_map[rt1052_pin_map[pin].gpio_pin]; + + if(pin_map == RT_NULL || irq_map == RT_NULL) + { + return RT_ENOSYS; + } + + if(irq_map->enable == PIN_IRQ_DISABLE) + { + return RT_EOK; + } + + irq_map->irq_info.pin = PIN_IRQ_PIN_NONE; + irq_map->irq_info.hdr = RT_NULL; + irq_map->irq_info.mode = PIN_IRQ_MODE_RISING; + irq_map->irq_info.args = RT_NULL; + + return RT_EOK; +} + +static rt_err_t rt1052_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) +{ + gpio_pin_config_t gpio; + IRQn_Type irq_num; + + struct rt1052_pin* pin_map = RT_NULL; + struct rt1052_irq* irq_map = RT_NULL; + + pin_map = &rt1052_pin_map[pin]; + irq_map = &rt1052_irq_map[rt1052_pin_map[pin].gpio_pin]; + + if(pin_map == RT_NULL || irq_map == RT_NULL) + { + return RT_ENOSYS; + } + + if(enabled == PIN_IRQ_ENABLE) + { + if(irq_map->enable == PIN_IRQ_ENABLE) + { + return RT_EBUSY; + } + + if(irq_map->irq_info.pin != pin) + { + return RT_EIO; + } + + irq_map->enable = PIN_IRQ_ENABLE; + + if(rt1052_pin_map[pin].gpio != GPIO5) + { + CLOCK_EnableClock(kCLOCK_Iomuxc); + IOMUXC_SetPinMux(0x401F8010U + pin*4, 0x5U, 0, 0, 0, 0); + } + else + { + CLOCK_EnableClock(kCLOCK_IomuxcSnvs); + IOMUXC_SetPinMux(0x401F8000U + (pin-125)*4, 0x5U, 0, 0, 0, 0); + } + + gpio.direction = kGPIO_DigitalInput; + gpio.outputLogic = 0; + + switch(irq_map->irq_info.mode) + { + case PIN_IRQ_MODE_RISING: + { + gpio.interruptMode = kGPIO_IntRisingEdge; + } + break; + + case PIN_IRQ_MODE_FALLING: + { + gpio.interruptMode = kGPIO_IntFallingEdge; + } + break; + + case PIN_IRQ_MODE_RISING_FALLING: + { + gpio.interruptMode = kGPIO_IntRisingOrFallingEdge; + } + break; + + case PIN_IRQ_MODE_HIGH_LEVEL: + { + gpio.interruptMode = kGPIO_IntHighLevel; + } + break; + + case PIN_IRQ_MODE_LOW_LEVEL: + { + gpio.interruptMode = kGPIO_IntLowLevel; + } + break; + } + + irq_num = rt1052_get_irqnum(rt1052_pin_map[pin].gpio, rt1052_pin_map[pin].gpio_pin); + + NVIC_SetPriority(irq_num, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 5, 0)); + EnableIRQ(irq_num); + + GPIO_PinInit(rt1052_pin_map[pin].gpio, rt1052_pin_map[pin].gpio_pin, &gpio); + GPIO_PortEnableInterrupts(rt1052_pin_map[pin].gpio, 1U << rt1052_pin_map[pin].gpio_pin); + } + else if(enabled == PIN_IRQ_DISABLE) + { + if(irq_map->enable == PIN_IRQ_DISABLE) + { + return RT_EOK; + } + + irq_map->enable = PIN_IRQ_DISABLE; + irq_num = rt1052_get_irqnum(rt1052_pin_map[pin].gpio, rt1052_pin_map[pin].gpio_pin); + + NVIC_DisableIRQ(irq_num); + } + else + { + return RT_EINVAL; + } + + return RT_EOK; +} int rt_hw_pin_init(void) { int ret = RT_EOK; + rt1052_pin_ops.pin_mode = rt1052_pin_mode; + rt1052_pin_ops.pin_read = rt1052_pin_read; + rt1052_pin_ops.pin_write = rt1052_pin_write; + rt1052_pin_ops.pin_attach_irq = rt1052_pin_attach_irq; + rt1052_pin_ops.pin_dettach_irq = rt1052_pin_dettach_irq; + rt1052_pin_ops.pin_irq_enable = rt1052_pin_irq_enable; + ret = rt_device_pin_register("pin", &rt1052_pin_ops, RT_NULL); return ret; diff --git a/bsp/imxrt1052-evk/drivers/drv_pin.h b/bsp/imxrt1052-evk/drivers/drv_pin.h index f1de4fbea7..6c0574ec0f 100644 --- a/bsp/imxrt1052-evk/drivers/drv_pin.h +++ b/bsp/imxrt1052-evk/drivers/drv_pin.h @@ -10,6 +10,7 @@ * Change Logs: * Date Author Notes * 2018-03-13 Liuguang the first version. + * 2018-03-19 Liuguang add GPIO interrupt mode support. */ #ifndef __DRV_PIN_H__