341 lines
9.2 KiB
C
341 lines
9.2 KiB
C
/** ##########################################################################
|
||
** Filename : keyboard_drive.c
|
||
** Project : RGB LED
|
||
** Module :
|
||
** Processor : Cypress CY8C4125LQE-S433
|
||
** Version : V1.0
|
||
** Compiler : PSoC Creator 4.2
|
||
** Date/Time : 2020/02/26
|
||
** Abstract :
|
||
**
|
||
** Contents :
|
||
**
|
||
**
|
||
** (c) Copyright dmdz Co.,Ltd
|
||
** --------------------------------------------------------------------------
|
||
** R E V I S I O N H I S T O R Y
|
||
** --------------------------------------------------------------------------
|
||
** Date Ver Author Description
|
||
|
||
** --------- ---- ----------------- --------------------------------------
|
||
** #########################################################################*/
|
||
#include "key_adc_driver.h"
|
||
#include "adc.h"
|
||
|
||
#include "common_memory.h"
|
||
|
||
/*****************************************************************************
|
||
* I N C L U D E F I L E S
|
||
*****************************************************************************/
|
||
void key_adc_driver_check_channel(u16 adc_value,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg);
|
||
static u8 key_adc_driver_check_state(u8 count,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg);
|
||
static void key_adc_driver_check_channel_op(u8 result1,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg);
|
||
|
||
/*****************************************************************************
|
||
* D E F I N E S
|
||
*****************************************************************************/
|
||
static key_adc_driver_s g_key_adc_driver[KEY_ADC_CHANNEL_TOTALS];
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_drive_init(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : None
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description : cycle task
|
||
*****************************************************************************/
|
||
void key_adc_driver_init(void)
|
||
{
|
||
common_memory_clear((u8*)&g_key_adc_driver,(u16)sizeof(g_key_adc_driver));
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_drive_task(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : None
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description : cycle task
|
||
*****************************************************************************/
|
||
void key_adc_driver_task(void)
|
||
{
|
||
u8 i;
|
||
adc_result_t l_adc_value[KEY_ADC_CHANNEL_TOTALS];
|
||
key_adc_driver_cfg_get_value(KEY_ADC_CHANNEL_TOTALS,&l_adc_value[0]);
|
||
for(i=0u;i<KEY_ADC_CHANNEL_TOTALS;i++)
|
||
{
|
||
#ifdef KEY_ADC_DEBUG_EN
|
||
g_key_adc_driver[i].adc_org = l_adc_value[i];
|
||
#endif
|
||
key_adc_driver_check_channel(l_adc_value[i],&g_key_adc_driver[i],&g_key_adc_range_cfg[i][0]);
|
||
}
|
||
}
|
||
|
||
static u8 key_adc_driver_check_state(u8 count,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg)
|
||
{
|
||
u8 j=count;
|
||
u8 l_result=0xffu;
|
||
switch(p_key_sm->jude_line[j])
|
||
{
|
||
case KEY_ADC_RESULT_IDLE:
|
||
if(p_key_cfg[j].valid == 0x80u)
|
||
{
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=g_key_cfg_times[KEY_ADC_FAULT_TIME_ID]) /* p_key_cfg[j].debounce */
|
||
{
|
||
p_key_sm->count =0;
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_PRESSS;
|
||
l_result = j;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=g_key_cfg_times[KEY_ADC_DEBOUNCE_TIME_ID]) /*p_key_cfg[j].debounce*/
|
||
{
|
||
p_key_sm->count =0;
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_PRESSS;
|
||
l_result = j;
|
||
}
|
||
}
|
||
break;
|
||
#if 0
|
||
case KEY_ADC_RESULT_PRESSS:
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=p_key_cfg[j].long_press)
|
||
{
|
||
/*p_key_sm->count =0;*/
|
||
p_key_sm->jude_line[j] = KEY_RESULT_LONG;
|
||
}
|
||
break;
|
||
case KEY_RESULT_LONG:
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=p_key_cfg[j].stick_press)
|
||
{
|
||
/*p_key_sm->count =0;*/
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_STICK;
|
||
}
|
||
break;
|
||
#else
|
||
case KEY_ADC_RESULT_PRESSS:
|
||
l_result = j;
|
||
p_key_sm->count=0u;
|
||
break;
|
||
#endif
|
||
default:
|
||
/*code*/
|
||
break;
|
||
}
|
||
return l_result;
|
||
}
|
||
|
||
static void key_adc_driver_check_channel_op(u8 result1,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg)
|
||
{
|
||
u8 j;
|
||
u8 l_result = result1;
|
||
/*如果是沒有任何按鍵有效*/
|
||
if(l_result == 0xffu)
|
||
{
|
||
#if 0
|
||
for(j=0;j<KEY_ADC_1CHANNEL_JUDGE_TOTALS;j++)
|
||
{
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
for(j=0;j<KEY_ADC_1CHANNEL_PHY_TOTALS;j++)
|
||
{
|
||
p_key_sm->result[j] = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
#endif
|
||
}
|
||
else
|
||
{
|
||
for(j=0;j<KEY_ADC_1CHANNEL_PHY_TOTALS;j++)
|
||
{
|
||
if( (p_key_cfg[l_result].valid & (u8)((u8)0x01<<j) ) != 0u) /*PRQA S 4571*/
|
||
{
|
||
//该判断句,是为了,在fault时,不能直接置成功
|
||
//if( (p_key_sm->result[j]!=KEY_ADC_RESULT_FAULT) )// && (p_key_sm->pre_state!=KEY_ADC_STATE_FAULT) )
|
||
{
|
||
p_key_sm->result[j] = KEY_ADC_RESULT_PRESSS;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
//第一个判断句,是为了保持上次fault,第二个判断句,是为了弹起时,才清除状态
|
||
//if( (p_key_sm->result[j] != KEY_ADC_RESULT_FAULT) || (p_key_sm->state==KEY_ADC_STATE_IDLE) )
|
||
{
|
||
p_key_sm->result[j] =KEY_ADC_RESULT_IDLE;
|
||
}
|
||
}
|
||
/*机械故障*/
|
||
if(p_key_cfg[l_result].valid == 0x80u)
|
||
{
|
||
p_key_sm->result[j] =KEY_ADC_RESULT_FAULT;
|
||
p_key_sm->state = KEY_ADC_STATE_FAULT; //在错误的范围
|
||
}
|
||
}
|
||
//
|
||
}
|
||
}
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_drive_task(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : None
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description : cycle task
|
||
*****************************************************************************/
|
||
void key_adc_driver_check_channel(u16 adc_value,key_adc_driver_s *p_key_sm,const key_adc_range_cfg_s *p_key_cfg)
|
||
{
|
||
u8 j,k;
|
||
u8 l_result = 0xffu;
|
||
u8 l_breakout =0u;
|
||
for(j=0;j<KEY_ADC_1CHANNEL_JUDGE_TOTALS;j++)
|
||
{
|
||
if( (adc_value>= p_key_cfg[j].min) && (adc_value <= p_key_cfg[j].max) ) /*&& (p_key_cfg[j].valid!=0u) )*/
|
||
{
|
||
p_key_sm->state = (key_adc_state_e)j;
|
||
if(p_key_sm->pre_state != p_key_sm->state)
|
||
{
|
||
p_key_sm->count =0;
|
||
for(k=0;k<KEY_ADC_1CHANNEL_JUDGE_TOTALS;k++)
|
||
{
|
||
p_key_sm->jude_line[k] = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
/*code*/
|
||
}
|
||
l_result = key_adc_driver_check_state(j,p_key_sm,p_key_cfg);
|
||
l_breakout=1u;
|
||
/*break;*/
|
||
}
|
||
else
|
||
{
|
||
/*p_key_sm->jude_line[j] = KEY_ADC_RESULT_IDLE;*/
|
||
if(p_key_sm->jude_line[j] != KEY_ADC_RESULT_IDLE)
|
||
{
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=p_key_cfg[j].debounce)
|
||
{
|
||
p_key_sm->count =0;
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_IDLE;
|
||
l_result = 0xffu;
|
||
l_breakout=1u;
|
||
/*break;*/
|
||
}
|
||
}
|
||
}
|
||
if(l_breakout==1u)
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
|
||
//不在任何范围内
|
||
if(l_breakout==0u)
|
||
{
|
||
//消抖的时间,要更久一点,达到秒级
|
||
p_key_sm->count++;
|
||
if(p_key_sm->count>=g_key_cfg_times[KEY_ADC_OTHER_FAULT_TIME_ID])
|
||
{
|
||
p_key_sm->count =0;
|
||
l_result = 0xffu;
|
||
|
||
for(j=0;j<KEY_ADC_1CHANNEL_JUDGE_TOTALS;j++)
|
||
{
|
||
p_key_sm->jude_line[j] = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
for(j=0;j<KEY_ADC_1CHANNEL_PHY_TOTALS;j++)
|
||
{
|
||
p_key_sm->result[j] = KEY_ADC_RESULT_FAULT;
|
||
}
|
||
p_key_sm->state = KEY_ADC_STATE_FAULT; //不在任何判斷範圍
|
||
}
|
||
}
|
||
|
||
key_adc_driver_check_channel_op(l_result,p_key_sm,p_key_cfg);
|
||
|
||
p_key_sm->pre_state = p_key_sm->state;
|
||
}
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_driver_get_result(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : channel AD邏輯通道 sub_id 內部的key排序
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description :
|
||
*****************************************************************************/
|
||
key_adc_result_e key_adc_driver_get_result(u8 channel,u8 sub_id)
|
||
{
|
||
key_adc_result_e l_result=KEY_ADC_RESULT_IDLE;
|
||
if(channel<=KEY_ADC_CHANNEL_TOTALS)
|
||
{
|
||
if(sub_id<=KEY_ADC_1CHANNEL_PHY_TOTALS)
|
||
{
|
||
if(g_key_adc_driver[channel].result[sub_id] != KEY_ADC_RESULT_IDLE)
|
||
{
|
||
l_result = g_key_adc_driver[channel].result[sub_id];
|
||
}
|
||
else
|
||
{
|
||
l_result = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
}
|
||
}
|
||
return l_result;
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_goto_sleep(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : None
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description : cycle task
|
||
*****************************************************************************/
|
||
/* software detailed design ID : */
|
||
void key_adc_goto_sleep(void)
|
||
{
|
||
#if 1
|
||
common_memory_clear((u8*)&g_key_adc_driver,(u16)sizeof(g_key_adc_driver));
|
||
#else
|
||
u8 i;
|
||
for(i=0u;i<KEY_ADC_CHANNEL_TOTALS;i++)
|
||
{
|
||
g_key_adc_driver[i].result[i] = KEY_ADC_RESULT_IDLE;
|
||
}
|
||
#endif
|
||
}
|
||
|
||
|
||
/*****************************************************************************
|
||
|Prototype : void key_adc_goto_sleep(void)
|
||
|Called by : None
|
||
|Preconditions : None
|
||
|Input parameters : None
|
||
|Output parameters : None
|
||
|Return value : None
|
||
|Description : cycle task
|
||
*****************************************************************************/
|
||
/* software detailed design ID : */
|
||
void key_adc_goto_wakeup(void)
|
||
{
|
||
|
||
|
||
}
|
||
|
||
|
||
|
||
/* [] END OF FILE */
|