Просмотр исходного кода

[update] The example Adapts to RT-Thread and Fix the bug. | 例子适配RT-Thread并修复bug.

liu2guang 8 лет назад
Родитель
Сommit
c901eaa1ff
5 измененных файлов с 285 добавлено и 156 удалено
  1. 6 0
      SConscript
  2. 72 42
      examples/event_async.c
  3. 64 22
      examples/event_inquire.c
  4. 119 62
      multi_button.c
  5. 24 30
      multi_button.h

+ 6 - 0
SConscript

@@ -13,6 +13,12 @@ inc = inc + [cwd]
 # add MultiButton basic code
 src = src + ['./multi_button.c']
 
+# add MultiButton Test code
+if GetDepend('MULTIBUTTON_USING_EXAMPLE_ASYNC'):
+    src = src + ['./examples/event_async.c']
+if GetDepend('MULTIBUTTON_USING_EXAMPLE_INQUIRE'):
+    src = src + ['./examples/event_inquire.c']
+
 # add group to IDE project
 group = DefineGroup('MultiButton', src, depend = ['PKG_USING_MULTIBUTTON'], CPPPATH = inc)
 

+ 72 - 42
examples/event_async.c

@@ -1,58 +1,88 @@
+#include <rtthread.h> 
+#include <rtdevice.h> 
 #include "multi_button.h"
 
-struct Button btn1;
-struct Button btn2;
+static struct button btn;
 
-int read_button1_GPIO()
-{
-    return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
-}
+#define BUTTON_PIN (10)
 
-int read_button2_GPIO()
+static uint8_t button_read_pin(void) 
 {
-    return HAL_GPIO_ReadPin(B2_GPIO_Port, B2_Pin);
+    return rt_pin_read(BUTTON_PIN); 
 }
 
-int main()
+void button_callback(void *btn)
 {
-    button_init(&btn1, read_button1_GPIO, 0);
-    button_init(&btn2, read_button2_GPIO, 0);
-
-    button_attach(&btn1, PRESS_DOWN,       BTN1_PRESS_DOWN_Handler);
-    button_attach(&btn1, PRESS_UP,         BTN1_PRESS_UP_Handler);
-    button_attach(&btn1, PRESS_REPEAT,     BTN1_PRESS_REPEAT_Handler);
-    button_attach(&btn1, SINGLE_CLICK,     BTN1_SINGLE_Click_Handler);
-    button_attach(&btn1, DOUBLE_CLICK,     BTN1_DOUBLE_Click_Handler);
-    button_attach(&btn1, LONG_RRESS_START, BTN1_LONG_RRESS_START_Handler);
-    button_attach(&btn2, LONG_PRESS_HOLD,  BTN1_LONG_PRESS_HOLD_Handler);
-
-    button_attach(&btn2, PRESS_DOWN,       BTN2_PRESS_DOWN_Handler);
-    button_attach(&btn2, PRESS_UP,         BTN2_PRESS_UP_Handler);
-    button_attach(&btn2, PRESS_REPEAT,     BTN2_PRESS_REPEAT_Handler);
-    button_attach(&btn2, SINGLE_CLICK,     BTN2_SINGLE_Click_Handler);
-    button_attach(&btn2, DOUBLE_CLICK,     BTN2_DOUBLE_Click_Handler);
-    button_attach(&btn2, LONG_RRESS_START, BTN2_LONG_RRESS_START_Handler);
-    button_attach(&btn2, LONG_PRESS_HOLD,  BTN2_LONG_PRESS_HOLD_Handler);
-
-    button_start(&btn1);
-    button_start(&btn2);
-
-    //make the timer invoking the button_ticks() interval 5ms.
-    //This function is implemented by yourself.
-    __timer_start(button_ticks, 0, 5);
+    uint32_t btn_event_val; 
+    
+    btn_event_val = get_button_event((struct button *)btn); 
+    
+    switch(btn_event_val)
+    {
+    case PRESS_DOWN:
+        rt_kprintf("button press down\n"); 
+    break; 
 
-    while(1)
-    {}
+    case PRESS_UP: 
+        rt_kprintf("button press up\n");
+    break; 
+
+    case PRESS_REPEAT: 
+        rt_kprintf("button press repeat\n");
+    break; 
+
+    case SINGLE_CLICK: 
+        rt_kprintf("button single click\n");
+    break; 
+
+    case DOUBLE_CLICK: 
+        rt_kprintf("button double click\n");
+    break; 
+
+    case LONG_RRESS_START: 
+        rt_kprintf("button long press start\n");
+    break; 
+
+    case LONG_PRESS_HOLD: 
+        rt_kprintf("button long press hold\n");
+    break; 
+    }
 }
 
-void BTN1_PRESS_DOWN_Handler(void* btn)
+void btn_thread_entry(void* p)
 {
-    //do something...
+    while(1)
+    {
+        /* 5ms */
+        rt_thread_delay(RT_TICK_PER_SECOND/200); 
+        button_ticks(); 
+    }
 }
 
-void BTN1_PRESS_UP_Handler(void* btn)
+int multi_button_test(void)
 {
-    //do something...
-}
+    rt_thread_t thread = RT_NULL;
+    
+    /* Create background ticks thread */
+    thread = rt_thread_create("btn", btn_thread_entry, RT_NULL, 1024, 10, 10);
+    if(thread == RT_NULL)
+    {
+        return RT_ERROR; 
+    }
+    rt_thread_startup(thread);
+
+    /* low level drive */
+    rt_pin_mode  (BUTTON_PIN, PIN_MODE_INPUT); 
+    button_init  (&btn, button_read_pin, PIN_LOW);
+    button_attach(&btn, PRESS_DOWN,       button_callback);
+    button_attach(&btn, PRESS_UP,         button_callback);
+    button_attach(&btn, PRESS_REPEAT,     button_callback);
+    button_attach(&btn, SINGLE_CLICK,     button_callback);
+    button_attach(&btn, DOUBLE_CLICK,     button_callback);
+    button_attach(&btn, LONG_RRESS_START, button_callback);
+    button_attach(&btn, LONG_PRESS_HOLD,  button_callback);
+    button_start (&btn);
 
-...
+    return RT_EOK; 
+}
+INIT_APP_EXPORT(multi_button_test); 

+ 64 - 22
examples/event_inquire.c

@@ -1,37 +1,79 @@
+#include <rtthread.h> 
+#include <rtdevice.h> 
 #include "multi_button.h"
 
-struct Button btn1;
+static struct button btn;
 
-int read_button1_GPIO()
+#define BUTTON_PIN (10)
+
+static uint8_t button_read_pin(void) 
 {
-    return HAL_GPIO_ReadPin(B1_GPIO_Port, B1_Pin);
+    return rt_pin_read(BUTTON_PIN); 
 }
 
-
-int main()
+void btn_test_thread_entry(void *p)
 {
-    static uint8_t btn1_event_val;
+    uint32_t btn_event_val; 
+    
+    while(1)
+    {
+        if(btn_event_val != get_button_event(&btn)) 
+        {
+            btn_event_val = get_button_event(&btn);
 
-    button_init(&btn1, read_button1_GPIO, 0);
-    button_start(&btn1);
+            switch(btn_event_val)
+            {
+            case PRESS_DOWN:
+                rt_kprintf("button press down\n"); 
+            break; 
 
-    //make the timer invoking the button_ticks() interval 5ms.
-    //This function is implemented by yourself.
-    __timer_start(button_ticks, 0, 5);
+            case PRESS_UP: 
+                rt_kprintf("button press up\n");
+            break; 
 
-    while(1)
-    {
-        if(btn1_event_val != get_button_event(&btn1)) {
-            btn1_event_val = get_button_event(&btn1);
-
-            if(btn1_event_val == PRESS_DOWN) {
-                //do something
-            } else if(btn1_event_val == PRESS_UP) {
-                //do something
-            } else if(btn1_event_val == LONG_PRESS_HOLD) {
-                //do something
+            case PRESS_REPEAT: 
+                rt_kprintf("button press repeat\n");
+            break; 
+
+            case SINGLE_CLICK: 
+                rt_kprintf("button single click\n");
+            break; 
+
+            case DOUBLE_CLICK: 
+                rt_kprintf("button double click\n");
+            break; 
+
+            case LONG_RRESS_START: 
+                rt_kprintf("button long press start\n");
+            break; 
+
+            case LONG_PRESS_HOLD: 
+                rt_kprintf("button long press hold\n");
+            break; 
             }
         }
+        
+        button_ticks(); 
+        rt_thread_delay(RT_TICK_PER_SECOND/200); 
     }
 }
 
+int multi_button_test(void)
+{
+    rt_thread_t thread = RT_NULL;
+
+    thread = rt_thread_create("btn_test", btn_test_thread_entry, RT_NULL, 1024, 15, 10);
+    if(thread == RT_NULL)
+    {
+        return RT_ERROR; 
+    }
+    rt_thread_startup(thread);
+
+    /* low level drive */
+    rt_pin_mode (BUTTON_PIN, PIN_MODE_INPUT); 
+    button_init (&btn, button_read_pin, PIN_LOW);
+    button_start(&btn);
+
+    return RT_EOK; 
+}
+INIT_APP_EXPORT(multi_button_test); 

+ 119 - 62
multi_button.c

@@ -1,25 +1,37 @@
 /*
- * Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
- * All rights reserved
- */
+ * @File:    multi_button.c
+ * @Author:  Zibin Zheng
+ * @Date:    2018-01-23 20:36:01 
+ * 
+ * @LICENSE: Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
+ *           All rights reserved. 
+ * 
+ * @NOTE:    The original author of MultiButton is Zibin Zheng.
+ *           Please contact the original author for authorization 
+ *           before use.I(liu2guang) only adapt the library to 
+ *           rt-thread and fix some bugs. I(liu2guang) am not 
+ *           responsible for the authorization of the library.
+ *
+ * Change Logs: 
+ * Date           Author       Notes 
+ * 2018-01-23     liu2guang    Adapter rtthread and Fix the bug. 
+ */ 
+#include "multi_button.h" 
 
-#include "multi_button.h"
-
-#define EVENT_CB(ev)   if(handle->cb[ev])handle->cb[ev]((Button*)handle)
-
-//button handle list head.
-static struct Button* head_handle = NULL;
+#define EVENT_CB(ev) if(handle->cb[ev]) handle->cb[ev]((button*)handle)
+    
+static struct button* head_handle = NULL;
 
 /**
   * @brief  Initializes the button struct handle.
   * @param  handle: the button handle strcut.
-  * @param  pin_level: read the HAL GPIO of the connet button level.
-  * @param  active_level: pressed GPIO level.
+  * @param  pin_level: read the pin of the connet button level.
+  * @param  active_level: pin pressed level.
   * @retval None
   */
-void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level)
+void button_init(struct button* handle, uint8_t(*pin_level)(void), uint8_t active_level)
 {
-    memset(handle, sizeof(struct Button), 0);
+    memset(handle, sizeof(struct button), 0);
     handle->event = (uint8_t)NONE_PRESS;
     handle->hal_button_Level = pin_level;
     handle->button_level = handle->hal_button_Level();
@@ -33,7 +45,7 @@ void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_le
   * @param  cb: callback function.
   * @retval None
   */
-void button_attach(struct Button* handle, PressEvent event, BtnCallback cb)
+void button_attach(struct button* handle, PressEvent event, BtnCallback cb)
 {
     handle->cb[event] = cb;
 }
@@ -43,107 +55,137 @@ void button_attach(struct Button* handle, PressEvent event, BtnCallback cb)
   * @param  handle: the button handle strcut.
   * @retval button event.
   */
-PressEvent get_button_event(struct Button* handle)
+PressEvent get_button_event(struct button* handle)
 {
     return (PressEvent)(handle->event);
 }
 
 /**
-  * @brief  Button driver core function, driver state machine.
+  * @brief  button driver core function, driver state machine.
   * @param  handle: the button handle strcut.
   * @retval None
   */
-void button_handler(struct Button* handle)
+void button_handler(struct button* handle)
 {
     uint8_t read_gpio_level = handle->hal_button_Level();
 
     //ticks counter working..
-    if((handle->state) > 0) handle->ticks++;
+    if((handle->state) > 0) 
+    {
+        handle->ticks++;
+    }
 
     /*------------button debounce handle---------------*/
-    if(read_gpio_level != handle->button_level) { //not equal to prev one
+    if(read_gpio_level != handle->button_level)
+    { 
+        //not equal to prev one
         //continue read 3 times same new level change
-        if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) {
+        if(++(handle->debounce_cnt) >= DEBOUNCE_TICKS) 
+        {
             handle->button_level = read_gpio_level;
             handle->debounce_cnt = 0;
         }
-    } else { //leved not change ,counter reset.
+    } 
+    else 
+    { 
+        // leved not change ,counter reset.
         handle->debounce_cnt = 0;
     }
 
     /*-----------------State machine-------------------*/
-    switch (handle->state) {
+    switch (handle->state) 
+    {
     case 0:
-        if(handle->button_level == handle->active_level) {	//start press down
+        if(handle->button_level == handle->active_level) 
+        { 
             handle->event = (uint8_t)PRESS_DOWN;
             EVENT_CB(PRESS_DOWN);
-            handle->ticks = 0;
+            handle->ticks  = 0;
             handle->repeat = 1;
-            handle->state = 1;
-        } else {
+            handle->state  = 1; 
+        } 
+        else 
+        {
             handle->event = (uint8_t)NONE_PRESS;
         }
         break;
 
     case 1:
-        if(handle->button_level != handle->active_level) { //released press up
+        if(handle->button_level != handle->active_level)
+        { 
             handle->event = (uint8_t)PRESS_UP;
             EVENT_CB(PRESS_UP);
             handle->ticks = 0;
-            handle->state = 2;
+            handle->state = 2; 
 
-        } else if(handle->ticks > LONG_TICKS) {
+        } 
+        else if(handle->ticks > LONG_TICKS)
+        {
             handle->event = (uint8_t)LONG_RRESS_START;
             EVENT_CB(LONG_RRESS_START);
-            handle->state = 5;
+            handle->state = 5; 
         }
         break;
 
     case 2:
-        if(handle->button_level == handle->active_level) { //press down again
+        if(handle->button_level == handle->active_level) 
+        { 
             handle->event = (uint8_t)PRESS_DOWN;
             EVENT_CB(PRESS_DOWN);
             handle->repeat++;
-            if(handle->repeat == 2) {
-                EVENT_CB(DOUBLE_CLICK); // repeat hit
-            }
-            EVENT_CB(PRESS_REPEAT); // repeat hit
+            
+            handle->event = (uint8_t)PRESS_REPEAT;
+            EVENT_CB(PRESS_REPEAT);
             handle->ticks = 0;
             handle->state = 3;
-        } else if(handle->ticks > SHORT_TICKS) { //released timeout
-            if(handle->repeat == 1) {
+            
+        } 
+        else if(handle->ticks > SHORT_TICKS) 
+        { 
+            if(handle->repeat == 1) 
+            {
                 handle->event = (uint8_t)SINGLE_CLICK;
                 EVENT_CB(SINGLE_CLICK);
-            } else if(handle->repeat == 2) {
+            } 
+            else if(handle->repeat == 2) 
+            {
                 handle->event = (uint8_t)DOUBLE_CLICK;
+                EVENT_CB(DOUBLE_CLICK); 
             }
             handle->state = 0;
         }
         break;
 
     case 3:
-        if(handle->button_level != handle->active_level) { //released press up
+        if(handle->button_level != handle->active_level) 
+        {
             handle->event = (uint8_t)PRESS_UP;
             EVENT_CB(PRESS_UP);
-            if(handle->ticks < SHORT_TICKS) {
+            
+            if(handle->ticks < SHORT_TICKS) 
+            {
                 handle->ticks = 0;
-                handle->state = 2; //repeat press
-            } else {
+                handle->state = 2; 
+            } 
+            else 
+            {
                 handle->state = 0;
             }
         }
         break;
 
     case 5:
-        if(handle->button_level == handle->active_level) {
-            //continue hold trigger
+        if(handle->button_level == handle->active_level) 
+        {
             handle->event = (uint8_t)LONG_PRESS_HOLD;
             EVENT_CB(LONG_PRESS_HOLD);
-
-        } else { //releasd
+        } 
+        else 
+        {
             handle->event = (uint8_t)PRESS_UP;
             EVENT_CB(PRESS_UP);
-            handle->state = 0; //reset
+            
+            handle->state = 0; 
         }
         break;
     }
@@ -154,15 +196,23 @@ void button_handler(struct Button* handle)
   * @param  handle: target handle strcut.
   * @retval 0: succeed. -1: already exist.
   */
-int button_start(struct Button* handle)
+int button_start(struct button* handle)
 {
-    struct Button* target = head_handle;
-    while(target) {
-        if(target == handle) return -1;	//already exist.
+    struct button* target = head_handle;
+    
+    while(target) 
+    {
+        if(target == handle) 
+        {
+            return -1;  //already exist.
+        }
+        
         target = target->next;
     }
+    
     handle->next = head_handle;
     head_handle = handle;
+    
     return 0;
 }
 
@@ -171,16 +221,22 @@ int button_start(struct Button* handle)
   * @param  handle: target handle strcut.
   * @retval None
   */
-void button_stop(struct Button* handle)
+void button_stop(struct button* handle)
 {
-    struct Button** curr;
-    for(curr = &head_handle; *curr; ) {
-        struct Button* entry = *curr;
-        if (entry == handle) {
+    struct button** curr;
+    
+    for(curr = &head_handle; *curr;) 
+    {
+        struct button* entry = *curr;
+        
+        if (entry == handle) 
+        {
             *curr = entry->next;
-//			free(entry);
-        } else
+        } 
+        else
+        {
             curr = &entry->next;
+        }
     }
 }
 
@@ -189,11 +245,12 @@ void button_stop(struct Button* handle)
   * @param  None.
   * @retval None
   */
-void button_ticks()
+void button_ticks(void)
 {
-    struct Button* target;
-    for(target=head_handle; target; target=target->next) {
+    struct button* target;
+    
+    for(target = head_handle; target != NULL; target = target->next)
+    {
         button_handler(target);
     }
 }
-

+ 24 - 30
multi_button.h

@@ -1,20 +1,14 @@
-/*
- * Copyright (c) 2016 Zibin Zheng <znbin@qq.com>
- * All rights reserved
- */
-
-#ifndef _MULTI_BUTTON_H_
-#define _MULTI_BUTTON_H_
+#ifndef __MULTI_BUTTON_H_
+#define __MULTI_BUTTON_H_
 
 #include "stdint.h"
 #include "string.h"
 
 //According to your need to modify the constants.
-#define TICKS_INTERVAL    5	//ms
-#define DEBOUNCE_TICKS    3	//MAX 8
-#define SHORT_TICKS       (300 /TICKS_INTERVAL)
-#define LONG_TICKS        (1000 /TICKS_INTERVAL)
-
+#define TICKS_INTERVAL    5 //ms
+#define DEBOUNCE_TICKS    3 //MAX 8
+#define SHORT_TICKS       (300  / TICKS_INTERVAL)
+#define LONG_TICKS        (1000 / TICKS_INTERVAL)
 
 typedef void (*BtnCallback)(void*);
 
@@ -30,32 +24,32 @@ typedef enum {
     NONE_PRESS
 }PressEvent;
 
-typedef struct Button {
+typedef struct button {
     uint16_t ticks;
-    uint8_t  repeat : 4;
-    uint8_t  event : 4;
-    uint8_t  state : 3;
-    uint8_t  debounce_cnt : 3;
+    uint8_t  repeat       : 4;
+    uint8_t  event        : 4;
+    uint8_t  state        : 3;
+    uint8_t  debounce_cnt : 3; 
     uint8_t  active_level : 1;
     uint8_t  button_level : 1;
     uint8_t  (*hal_button_Level)(void);
     BtnCallback  cb[number_of_event];
-    struct Button* next;
-}Button;
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-void button_init(struct Button* handle, uint8_t(*pin_level)(), uint8_t active_level);
-void button_attach(struct Button* handle, PressEvent event, BtnCallback cb);
-PressEvent get_button_event(struct Button* handle);
-int  button_start(struct Button* handle);
-void button_stop(struct Button* handle);
+    struct button* next;
+}button;
+
+#ifdef __cplusplus  
+extern "C" {  
+#endif  
+
+void button_init(struct button* handle, uint8_t(*pin_level)(void), uint8_t active_level);
+void button_attach(struct button* handle, PressEvent event, BtnCallback cb);
+PressEvent get_button_event(struct button* handle);
+int  button_start(struct button* handle);
+void button_stop(struct button* handle);
 void button_ticks(void);
 
 #ifdef __cplusplus
-}
+} 
 #endif
 
 #endif