1 Star 1 Fork 1

RT-Thread-Mirror / rtpkg_button

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
button.c 15.40 KB
一键复制 编辑 原始数据 按行查看 历史
ijiedev 提交于 2018-11-30 10:18 . update button.c
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552
/************************************************************
* @brief button_drive
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0.1
* @note button.c
***********************************************************/
#include "button.h"
#ifdef PKG_USING_BUTTON
/*******************************************************************
* Variable Declaration
*******************************************************************/
static struct button* Head_Button = RT_NULL;
/*******************************************************************
* Function Declaration
*******************************************************************/
static char *StrnCopy(char *dst, const char *src, rt_uint32_t n);
static void Print_Btn_Info(Button_t* btn);
static void Add_Button(Button_t* btn);
/************************************************************
* @brief Create a Button
* @param name:button name
* @param btn:button structure
* @param read_btn_level:Button trigger level reading function,
* Return the level of the rt_uint8_t type by yourself
* @param btn_trigger_level:Button trigger level
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Button_Create(const char *name,
Button_t *btn,
rt_uint8_t(*read_btn_level)(void),
rt_uint8_t btn_trigger_level)
{
if( btn == RT_NULL)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("struct button is RT_NULL!"));
}
memset(btn, 0, sizeof(struct button)); //Clear structure information
StrnCopy(btn->Name, name, BTN_NAME_MAX); //button name
btn->Button_State = NONE_TRIGGER; //Button status
btn->Button_Last_State = NONE_TRIGGER; //Button last status
btn->Button_Trigger_Event = NONE_TRIGGER; //Button trigger event
btn->Read_Button_Level = read_btn_level; //Button trigger level reading function
btn->Button_Trigger_Level = btn_trigger_level; //Button trigger level
btn->Button_Last_Level = btn->Read_Button_Level(); //Button current level
btn->Debounce_Time = 0;
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button create success!"));
Add_Button(btn); //Added to the singly linked list when button created
Print_Btn_Info(btn); //printf info
}
/************************************************************
* @brief burron trigger events are attach to callback function
* @param btn:button structure
* @param btn_event:button events
* @param btn_callback : Callback handler after the button is triggered.Need user implementation
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
void Button_Attach(Button_t *btn,Button_Event btn_event,Button_CallBack btn_callback)
{
if( btn == RT_NULL)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("struct button is RT_NULL!"));
}
if(BUTTON_ALL_RIGGER == btn_event)
{
for(rt_uint8_t i = 0 ; i < number_of_event-1 ; i++)
/*A callback function triggered by a button event ,Used to handle button events */
btn->CallBack_Function[i] = btn_callback;
}
else
{
btn->CallBack_Function[btn_event] = btn_callback;
}
}
/************************************************************
* @brief Delete an already created button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Button_Delete(Button_t *btn)
{
struct button** curr;
for(curr = &Head_Button; *curr;)
{
struct button* entry = *curr;
if (entry == btn)
{
*curr = entry->Next;
}
else
{
curr = &entry->Next;
}
}
}
/************************************************************
* @brief Get Button Event Info
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
void Get_Button_EventInfo(Button_t *btn)
{
for(rt_uint8_t i = 0 ; i < number_of_event-1 ; i++)
{
if(btn->CallBack_Function[i] != 0)
{
/* print */
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Button_Event:%d",i));
}
}
}
/************************************************************
* @brief Get Button Event
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
rt_uint8_t Get_Button_Event(Button_t *btn)
{
return (rt_uint8_t)(btn->Button_Trigger_Event);
}
/************************************************************
* @brief Get Button State
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
***********************************************************/
rt_uint8_t Get_Button_State(Button_t *btn)
{
return (rt_uint8_t)(btn->Button_State);
}
/************************************************************
* @brief button cycle processing function
* @param btn:button structure
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note This function must be called in a certain period. The recommended period is 20~50ms.
***********************************************************/
void Button_Cycle_Process(Button_t *btn)
{
/* Get the current button level */
rt_uint8_t current_level = (rt_uint8_t)btn->Read_Button_Level();
/* Button level changes, debounce */
if((current_level != btn->Button_Last_Level)&&(++(btn->Debounce_Time) >= BUTTON_DEBOUNCE_TIME))
{
/* Update current button level */
btn->Button_Last_Level = current_level;
/* button is pressed */
btn->Debounce_Time = 0;
/* If the button is not pressed, change the button state to press (first press / double trigger) */
if((btn->Button_State == NONE_TRIGGER)||(btn->Button_State == BUTTON_DOUBLE))
{
btn->Button_State = BUTTON_DOWM;
}
//free button
else if(btn->Button_State == BUTTON_DOWM)
{
btn->Button_State = BUTTON_UP;
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button release"));
}
}
switch(btn->Button_State)
{
/* button dowm */
case BUTTON_DOWM :
{
if(btn->Button_Last_Level == btn->Button_Trigger_Level)
{
/* Support continuous triggering */
#ifdef CONTINUOS_TRIGGER
if(++(btn->Button_Cycle) >= BUTTON_CONTINUOS_CYCLE)
{
btn->Button_Cycle = 0;
btn->Button_Trigger_Event = BUTTON_CONTINUOS;
/* continuous triggering */
TRIGGER_CB(BUTTON_CONTINUOS);
RT_DEBUG_LOG(RT_DEBUG_THREAD,("continuous triggering"));
}
#else
btn->Button_Trigger_Event = BUTTON_DOWM;
/* Update the trigger event before releasing the button as long press */
if(++(btn->Long_Time) >= BUTTON_LONG_TIME)
{
#ifdef LONG_FREE_TRIGGER
btn->Button_Trigger_Event = BUTTON_LONG;
#else
/* Continuous triggering of long press cycles */
if(++(btn->Button_Cycle) >= BUTTON_LONG_CYCLE)
{
btn->Button_Cycle = 0;
btn->Button_Trigger_Event = BUTTON_LONG;
/* long triggering */
TRIGGER_CB(BUTTON_LONG);
}
#endif
/* Update time overflow */
if(btn->Long_Time == 0xFF)
{
btn->Long_Time = BUTTON_LONG_TIME;
}
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Long press"));
}
#endif
}
break;
}
/* button up */
case BUTTON_UP :
{
/* Trigger click */
if(btn->Button_Trigger_Event == BUTTON_DOWM)
{
/* double click */
if((btn->Timer_Count <= BUTTON_DOUBLE_TIME)&&(btn->Button_Last_State == BUTTON_DOUBLE))
{
btn->Button_Trigger_Event = BUTTON_DOUBLE;
TRIGGER_CB(BUTTON_DOUBLE);
RT_DEBUG_LOG(RT_DEBUG_THREAD,("double click"));
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = NONE_TRIGGER;
}
else
{
btn->Timer_Count=0;
/* Detection long press failed, clear 0 */
btn->Long_Time = 0;
#ifndef SINGLE_AND_DOUBLE_TRIGGER
/* click */
TRIGGER_CB(BUTTON_DOWM);
#endif
btn->Button_State = BUTTON_DOUBLE;
btn->Button_Last_State = BUTTON_DOUBLE;
}
}
else if(btn->Button_Trigger_Event == BUTTON_LONG)
{
#ifdef LONG_FREE_TRIGGER
/* Long press */
TRIGGER_CB(BUTTON_LONG);
#else
/* Long press free */
TRIGGER_CB(BUTTON_LONG_FREE);
#endif
btn->Long_Time = 0;
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_LONG;
}
#ifdef CONTINUOS_TRIGGER
/* Press continuously */
else if(btn->Button_Trigger_Event == BUTTON_CONTINUOS)
{
btn->Long_Time = 0;
/* Press continuously free */
TRIGGER_CB(BUTTON_CONTINUOS_FREE);
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_CONTINUOS;
}
#endif
break;
}
case BUTTON_DOUBLE :
{
/* Update time */
btn->Timer_Count++;
if(btn->Timer_Count>=BUTTON_DOUBLE_TIME)
{
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = NONE_TRIGGER;
}
#ifdef SINGLE_AND_DOUBLE_TRIGGER
if((btn->Timer_Count>=BUTTON_DOUBLE_TIME)&&(btn->Button_Last_State != BUTTON_DOWM))
{
btn->Timer_Count=0;
TRIGGER_CB(BUTTON_DOWM);
btn->Button_State = NONE_TRIGGER;
btn->Button_Last_State = BUTTON_DOWM;
}
#endif
break;
}
default :
break;
}
}
/************************************************************
* @brief Traversing the way to scan the button without losing each button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note This function is called periodically, it is recommended to call 20-50ms once.
***********************************************************/
void Button_Process(void)
{
struct button* pass_btn;
for(pass_btn = Head_Button; pass_btn != RT_NULL; pass_btn = pass_btn->Next)
{
Button_Cycle_Process(pass_btn);
}
}
/************************************************************
* @brief Search Button
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
void Search_Button(void)
{
struct button* pass_btn;
for(pass_btn = Head_Button; pass_btn != RT_NULL; pass_btn = pass_btn->Next)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button node have %s",pass_btn->Name));
}
}
/************************************************************
* @brief Handle all button callback functions
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note Not implemented yet
***********************************************************/
void Button_Process_CallBack(void *btn)
{
rt_uint8_t btn_event = Get_Button_Event(btn);
switch(btn_event)
{
case BUTTON_DOWM:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your press trigger"));
break;
}
case BUTTON_UP:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your trigger release"));
break;
}
case BUTTON_DOUBLE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your double-click trigger"));
break;
}
case BUTTON_LONG:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your long press trigger"));
break;
}
case BUTTON_LONG_FREE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your long press trigger free"));
break;
}
case BUTTON_CONTINUOS:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add your continuous trigger processing logic"));
break;
}
case BUTTON_CONTINUOS_FREE:
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("Add processing logic for your continuous trigger release"));
break;
}
}
}
/**************************** The following is the internal call function ********************/
/************************************************************
* @brief Copy the specified length string
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static char *StrnCopy(char *dst, const char *src, rt_uint32_t n)
{
if (n != 0)
{
char *d = dst;
const char *s = src;
do
{
if ((*d++ = *s++) == 0)
{
while (--n != 0)
*d++ = 0;
break;
}
} while (--n != 0);
}
return (dst);
}
/************************************************************
* @brief Print button related information
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static void Print_Btn_Info(Button_t* btn)
{
RT_DEBUG_LOG(RT_DEBUG_THREAD,("button struct information:\n\
btn->Name:%s \n\
btn->Button_State:%d \n\
btn->Button_Trigger_Event:%d \n\
btn->Button_Trigger_Level:%d \n\
btn->Button_Last_Level:%d \n\
",
btn->Name,
btn->Button_State,
btn->Button_Trigger_Event,
btn->Button_Trigger_Level,
btn->Button_Last_Level));
Search_Button();
}
/************************************************************
* @brief Connect buttons with a single linked list
* @param RT_NULL
* @return RT_NULL
* @author jiejie
* @github https://github.com/jiejieTop
* @date 2018-xx-xx
* @version v1.0
* @note RT_NULL
***********************************************************/
static void Add_Button(Button_t* btn)
{
struct button *pass_btn = Head_Button;
while(pass_btn)
{
pass_btn = pass_btn->Next;
}
btn->Next = Head_Button;
Head_Button = btn;
}
#endif
1
https://gitee.com/RT-Thread-Mirror/rtpkg_button.git
git@gitee.com:RT-Thread-Mirror/rtpkg_button.git
RT-Thread-Mirror
rtpkg_button
rtpkg_button
master

搜索帮助