Quellcode durchsuchen

[Components] Drivers: pin add irq apis

Aubr.Cool vor 8 Jahren
Ursprung
Commit
320b116b5f
3 geänderte Dateien mit 399 neuen und 4 gelöschten Zeilen
  1. 334 0
      bsp/stm32f10x/drivers/gpio.c
  2. 25 1
      components/drivers/include/drivers/pin.h
  3. 40 3
      components/drivers/misc/pin.c

+ 334 - 0
bsp/stm32f10x/drivers/gpio.c

@@ -17,6 +17,7 @@
 #include <rtdevice.h>
 #include <board.h>
 #include <gpio.h>
+#include <stm32f10x_exti.h>
 
 #ifdef RT_USING_PIN
 
@@ -408,6 +409,50 @@ static const struct pin_index pins[] =
 #endif
 };
 
+struct pin_irq_map
+{
+    rt_uint16_t            pinbit;
+    rt_uint32_t            irqbit;
+    enum IRQn              irqno;
+};
+static const  struct pin_irq_map pin_irq_map[] =
+{
+   {GPIO_Pin_0,  EXTI_Line0,  EXTI0_IRQn    },
+   {GPIO_Pin_1,  EXTI_Line1,  EXTI1_IRQn    },
+   {GPIO_Pin_2,  EXTI_Line2,  EXTI2_IRQn    },
+   {GPIO_Pin_3,  EXTI_Line3,  EXTI3_IRQn    },
+   {GPIO_Pin_4,  EXTI_Line4,  EXTI4_IRQn    },
+   {GPIO_Pin_5,  EXTI_Line5,  EXTI9_5_IRQn  },
+   {GPIO_Pin_6,  EXTI_Line6,  EXTI9_5_IRQn  },
+   {GPIO_Pin_7,  EXTI_Line7,  EXTI9_5_IRQn  },
+   {GPIO_Pin_8,  EXTI_Line8,  EXTI9_5_IRQn  },
+   {GPIO_Pin_9,  EXTI_Line9,  EXTI9_5_IRQn  },
+   {GPIO_Pin_10, EXTI_Line10, EXTI15_10_IRQn},
+   {GPIO_Pin_11, EXTI_Line11, EXTI15_10_IRQn},
+   {GPIO_Pin_12, EXTI_Line12, EXTI15_10_IRQn},
+   {GPIO_Pin_13, EXTI_Line13, EXTI15_10_IRQn},
+   {GPIO_Pin_14, EXTI_Line14, EXTI15_10_IRQn},
+   {GPIO_Pin_15, EXTI_Line15, EXTI15_10_IRQn},
+};
+struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
+{
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},
+    {-1, 0, RT_NULL, RT_NULL},                  
+};
 
 #define ITEM_NUM(items) sizeof(items)/sizeof(items[0])
 const struct pin_index *get_pin(uint8_t pin)
@@ -515,11 +560,193 @@ void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
     GPIO_Init(index->gpio, &GPIO_InitStructure);
 }
 
+rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
+{
+    int i;
+    for(i = 0; i < 32; i++)
+    {
+        if((0x01 << i) == bit)
+        {
+            return i;
+        }
+    }
+    return -1;
+}
+rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
+{
+    rt_int32_t mapindex = bit2bitno(pinbit);
+    if(mapindex < 0 || mapindex >= ITEM_NUM(pin_irq_map))
+    {
+        return RT_NULL;
+    }
+    return &pin_irq_map[mapindex];
+};
+rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
+                  rt_uint32_t mode, void (*hdr)(void *args), void *args)
+{
+    const struct pin_index *index;
+    rt_base_t level;
+    rt_int32_t irqindex = -1;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_ENOSYS;
+    }
+    irqindex = bit2bitno(index->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   &&
+       pin_irq_hdr_tab[irqindex].hdr == hdr   &&
+       pin_irq_hdr_tab[irqindex].mode == mode &&
+       pin_irq_hdr_tab[irqindex].args == args
+    )
+    {
+        rt_hw_interrupt_enable(level);
+        return RT_EOK;
+    }
+    if(pin_irq_hdr_tab[irqindex].pin != -1)
+    {
+        rt_hw_interrupt_enable(level);
+        return RT_EBUSY;
+    }
+    pin_irq_hdr_tab[irqindex].pin = pin;
+    pin_irq_hdr_tab[irqindex].hdr = hdr;
+    pin_irq_hdr_tab[irqindex].mode = mode;
+    pin_irq_hdr_tab[irqindex].args = args;
+    rt_hw_interrupt_enable(level);
+ 
+    return RT_EOK;
+}
+rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
+{
+    const struct pin_index *index;
+    rt_base_t level;
+    rt_int32_t irqindex = -1;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_ENOSYS;
+    }
+    irqindex = bit2bitno(index->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;
+}
+rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin)
+{
+    const struct pin_index *index;
+    const struct pin_irq_map *irqmap;
+    rt_base_t level;
+    rt_int32_t irqindex = -1;
+    GPIO_InitTypeDef  GPIO_InitStructure;
+    NVIC_InitTypeDef  NVIC_InitStructure;
+    EXTI_InitTypeDef EXTI_InitStructure;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_ENOSYS;
+    }
+    irqindex = bit2bitno(index->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;
+    }
+    irqmap = &pin_irq_map[irqindex];
+    /* GPIO Periph clock enable */
+    RCC_APB2PeriphClockCmd(index->rcc, ENABLE);
+    /* Configure GPIO_InitStructure */
+    GPIO_InitStructure.GPIO_Pin     = index->pin;
+    GPIO_InitStructure.GPIO_Mode  = GPIO_Mode_IPU;
+    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
+    GPIO_Init(index->gpio, &GPIO_InitStructure);
+
+    NVIC_InitStructure.NVIC_IRQChannel= irqmap->irqno;
+    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority= 2;  
+    NVIC_InitStructure.NVIC_IRQChannelSubPriority= 2; 
+    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
+    NVIC_Init(&NVIC_InitStructure);
+
+    EXTI_InitStructure.EXTI_Line = irqmap->irqbit;  
+    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+    switch(pin_irq_hdr_tab[irqindex].mode)
+    {
+    case PIN_IRQ_MODE_RISING:
+      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+      break;
+    case PIN_IRQ_MODE_FALLING:
+      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Falling;
+      break;
+    case PIN_IRQ_MODE_RISING_FALLING:
+      EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising_Falling;
+      break;
+    }
+    EXTI_InitStructure.EXTI_LineCmd = ENABLE;  
+    EXTI_Init(&EXTI_InitStructure);
+    rt_hw_interrupt_enable(level);
+
+    return RT_EOK;
+}
+rt_err_t stm32_pin_irq_disable(struct rt_device *device, rt_base_t pin)
+{
+    const struct pin_index *index;
+    const struct pin_irq_map *irqmap;
+    EXTI_InitTypeDef EXTI_InitStructure;
+
+    index = get_pin(pin);
+    if (index == RT_NULL)
+    {
+        return RT_ENOSYS;
+    }
+    irqmap = get_pin_irq_map(index->pin);
+    if(irqmap == RT_NULL)
+    {
+        return RT_ENOSYS;
+    }
+    EXTI_InitStructure.EXTI_Line = irqmap->irqbit;  
+    EXTI_InitStructure.EXTI_Mode = EXTI_Mode_Interrupt;
+    EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
+    EXTI_InitStructure.EXTI_LineCmd = DISABLE;  
+    EXTI_Init(&EXTI_InitStructure);
+    return RT_EOK;
+}
 const static struct rt_pin_ops _stm32_pin_ops =
 {
     stm32_pin_mode,
     stm32_pin_write,
     stm32_pin_read,
+    stm32_pin_attach_irq,
+    stm32_pin_dettach_irq,
+    stm32_pin_irq_enable,
+    stm32_pin_irq_disable
 };
 
 int stm32_hw_pin_init(void)
@@ -531,4 +758,111 @@ int stm32_hw_pin_init(void)
 }
 INIT_BOARD_EXPORT(stm32_hw_pin_init);
 
+rt_inline void pin_irq_hdr(int irqno)
+{
+    EXTI_ClearITPendingBit(pin_irq_map[irqno].irqno);
+    if(pin_irq_hdr_tab[irqno].hdr)
+    {
+       pin_irq_hdr_tab[irqno].hdr(pin_irq_hdr_tab[irqno].args);
+    }
+}
+void EXTI0_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    pin_irq_hdr(0);
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI1_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    pin_irq_hdr(1);
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI2_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    pin_irq_hdr(2);
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI3_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    pin_irq_hdr(3);
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI4_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    pin_irq_hdr(4);
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI9_5_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    if(EXTI_GetITStatus(EXTI_Line5) != RESET)
+    {
+        pin_irq_hdr(5);
+    }
+    if(EXTI_GetITStatus(EXTI_Line6) != RESET)
+    {
+        pin_irq_hdr(6);
+    }
+    if(EXTI_GetITStatus(EXTI_Line7) != RESET)
+    {
+        pin_irq_hdr(7);
+    }
+    if(EXTI_GetITStatus(EXTI_Line8) != RESET)
+    {
+        pin_irq_hdr(8);
+    }
+    if(EXTI_GetITStatus(EXTI_Line9) != RESET)
+    {
+        pin_irq_hdr(9);
+    }
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+void EXTI15_10_IRQHandler(void)
+{
+     /* enter interrupt */
+    rt_interrupt_enter();
+    if(EXTI_GetITStatus(EXTI_Line10) != RESET)
+    {
+        pin_irq_hdr(10);
+    }
+    if(EXTI_GetITStatus(EXTI_Line11) != RESET)
+    {
+        pin_irq_hdr(11);
+    }
+    if(EXTI_GetITStatus(EXTI_Line12) != RESET)
+    {
+        pin_irq_hdr(12);
+    }
+    if(EXTI_GetITStatus(EXTI_Line13) != RESET)
+    {
+        pin_irq_hdr(13);
+    }
+    if(EXTI_GetITStatus(EXTI_Line14) != RESET)
+    {
+        pin_irq_hdr(14);
+    }
+    if(EXTI_GetITStatus(EXTI_Line15) != RESET)
+    {
+        pin_irq_hdr(15);
+    }
+    /* leave interrupt */
+    rt_interrupt_leave();
+}
+
 #endif

+ 25 - 1
components/drivers/include/drivers/pin.h

@@ -46,6 +46,12 @@ struct rt_device_pin
 #define PIN_MODE_INPUT          0x01
 #define PIN_MODE_INPUT_PULLUP   0x02
 
+#define PIN_IRQ_MODE_RISING             0x00
+#define PIN_IRQ_MODE_FALLING            0x01
+#define PIN_IRQ_MODE_RISING_FALLING     0x02
+
+#define PIN_IRQ_PIN_NONE                -1
+
 struct rt_device_pin_mode
 {
     rt_uint16_t pin;
@@ -56,7 +62,13 @@ struct rt_device_pin_status
     rt_uint16_t pin;
     rt_uint16_t status;
 };
-
+struct rt_pin_irq_hdr
+{
+    rt_int32_t        pin;
+    rt_uint32_t       mode;
+    void (*hdr)(void *args);
+    void             *args;
+};
 struct rt_pin_ops
 {
     void (*pin_mode)(struct rt_device *device, rt_base_t pin, rt_base_t mode);
@@ -64,6 +76,11 @@ struct rt_pin_ops
     int (*pin_read)(struct rt_device *device, rt_base_t pin);
 
     /* TODO: add GPIO interrupt */
+    rt_err_t (*pin_attach_irq)(struct rt_device *device, rt_int32_t pin,
+                      rt_uint32_t mode, void (*hdr)(void *args), void *args);
+    rt_err_t (*pin_dettach_irq)(struct rt_device *device, rt_int32_t pin);
+    rt_err_t (*pin_irq_enable)(struct rt_device *device, rt_base_t pin);
+    rt_err_t (*pin_irq_disable)(struct rt_device *device, rt_base_t pin);
 };
 
 int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void *user_data);
@@ -71,7 +88,14 @@ int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void
 void rt_pin_mode(rt_base_t pin, rt_base_t mode);
 void rt_pin_write(rt_base_t pin, rt_base_t value);
 int  rt_pin_read(rt_base_t pin);
+rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
+                             void (*hdr)(void *args), void  *args);
+rt_err_t rt_pin_dettach_irq(rt_int32_t pin);
+rt_err_t pin_irq_enable(rt_base_t pin);
+rt_err_t pin_irq_disable(rt_base_t pin);
 
+int rt_device_pin_irq_register(const char *name, const struct rt_pin_ops *ops,
+                                                              void *user_data);
 #ifdef __cplusplus
 }
 #endif

+ 40 - 3
components/drivers/misc/pin.c

@@ -98,24 +98,61 @@ int rt_device_pin_register(const char *name, const struct rt_pin_ops *ops, void
     return 0;
 }
 
+rt_err_t rt_pin_attach_irq(rt_int32_t pin, rt_uint32_t mode,
+                             void (*hdr)(void *args), void  *args)
+{
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
+    if(_hw_pin.ops->pin_attach_irq)
+    {
+        return _hw_pin.ops->pin_attach_irq(&_hw_pin.parent, pin, mode, hdr, args);
+    }
+    return RT_ENOSYS;
+}
+rt_err_t rt_pin_dettach_irq(rt_int32_t pin)
+{
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
+    if(_hw_pin.ops->pin_dettach_irq)
+    {
+        return _hw_pin.ops->pin_dettach_irq(&_hw_pin.parent, pin);
+    }
+    return RT_ENOSYS;
+}
+rt_err_t pin_irq_enable(rt_base_t pin)
+{
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
+    if(_hw_pin.ops->pin_irq_enable)
+    {
+        return _hw_pin.ops->pin_irq_enable(&_hw_pin.parent, pin);
+    }
+    return RT_ENOSYS;
+}
+rt_err_t pin_irq_disable(rt_base_t pin)
+{
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
+    if(_hw_pin.ops->pin_irq_disable)
+    {
+        return _hw_pin.ops->pin_irq_disable(&_hw_pin.parent, pin);
+    }
+    return RT_ENOSYS;
+}
 /* RT-Thread Hardware PIN APIs */
 void rt_pin_mode(rt_base_t pin, rt_base_t mode)
 {
-	RT_ASSERT(_hw_pin.ops != RT_NULL);
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
     _hw_pin.ops->pin_mode(&_hw_pin.parent, pin, mode);
 }
 FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_mode, pinMode, set hardware pin mode);
 
 void rt_pin_write(rt_base_t pin, rt_base_t value)
 {
-	RT_ASSERT(_hw_pin.ops != RT_NULL);
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
     _hw_pin.ops->pin_write(&_hw_pin.parent, pin, value);
 }
 FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_write, pinWrite, write value to hardware pin);
 
 int  rt_pin_read(rt_base_t pin)
 {
-	RT_ASSERT(_hw_pin.ops != RT_NULL);
+    RT_ASSERT(_hw_pin.ops != RT_NULL);
     return _hw_pin.ops->pin_read(&_hw_pin.parent, pin);
 }
 FINSH_FUNCTION_EXPORT_ALIAS(rt_pin_read, pinRead, read status from hardware pin);