META实现出货检测卡托是否插入功能
一、 背景描述
出货的手机有时会存在卡托漏装的情况,传统只通过人工来检查。但这种做法不能保证不会出错。因而需要一种自动化的可靠的检测方式。
二、设计思路
实现一种自动化检测方式:
工具端在出货前的datacheck站位检查卡托是否插入,插入判断PASS,未插入判断FAIL
三、软件端实现:
3.1 带有卡托的手机有专用的中断脚用来检测卡托的状态。软件端通过获取中断脚的电平高低来判断是否有卡托插入。软件上报给工具的只有0和1, 0代表未插入卡托,1代表插入卡托。
3.2 工具与手机通过META方式发送与接受命令。定义:
FT_CUSTOMER_CMD_SIM_TRAY = 5,//检查SIM卡托是否插入命令
FT_CUSTOMER_CMD_TCARD_TRAY = 6,//检查T卡托是否插入命令
3.3 获取中断脚状态通过读取mtgpio文件得到,定义:
在vendor\mediatek\proprietary\custom\projectname\cgen\inc\sd_sim_card_tray_detect.h
#ifndef __TRAN_FT_SIM_SD_TRAY_DETECT_H
#define __TRAN_FT_SIM_SD_TRAY_DETECT_H
#define PIN_VOLT_HIGH 1
#define PIN_VOLT_LOW 0
#define SIM_DETECT_PIN_NUM 47 //PD_GPIO47[A1]
#define SIM_DETECT_PIN_ACTIVE PIN_VOLT_HIGH
#define SD_DETECT_PIN_NUM 0 //PD_GPIO0
#define SD_DETECT_PIN_ACTIVE PIN_VOLT_HIGH
#define SYS_DEV_GPIO_PATH “/sys/bus/platform/drivers/mediatek-mt6761-pinctrl/1000b000.pinctrl/mt_gpio”[A2]
#endif
(注:如上宏的值根据不同项目适配)
3.4 代码实现
n 修改ProjectConfig.mk:
定义功能宏TRAN_FT_SIM_SD_TRAY_DETECT控制是否生效
在tran_projects\projectname \device\transsion\projectname \ProjectConfig_BSP.mk添加:
#add start
TRAN_FT_SIM_SD_TRAY_DETECT = yes
#add end
n 修改vendor\mediatek\proprietary\hardware\meta\common\Android.mk
添加:
#add start
ifeq ($(strip $(TRAN_FT_SIM_SD_TRAY_DETECT)),yes)
LOCAL_CFLAGS += -DTRAN_FT_SIM_SD_TRAY_DETECT
endif
#add end
n 修改vendor\mediatek\proprietary\hardware\meta\common\src\ FtModule.cpp
typedef enum FT_CUSTOMER_CMD {
FT_CUSTOMER_CMD_NONE = 0,
//……………//省略
#if defined(TRAN_FT_SIM_SD_TRAY_DETECT)
FT_CUSTOMER_CMD_SIM_TRAY = 5,
FT_CUSTOMER_CMD_TCARD_TRAY = 6,
#endif
//……………//省略
FT_CUSTOMER_CMD_MAX,
} FtCustomerCmd;
#if defined(TRAN_FT_SIM_SD_TRAY_DETECT)
//token not include (R1 R0) for what won’t work using this code
int get_gpio_for_token(int gpio, const char *token)
{
FILE *fp;
char *line = NULL;
size_t len = 0;
ssize_t ret;
const char *delim_line = ":";
const char *delim_header = ")";[A3]
char *saveptr1, *saveptr2;
char *tok, *tok1, *tok2;
int index = -1;
int found = 0;
int count = 0;
int i;
char array[9][9] = {{0}};
char *ptr = NULL;
char *temp_ptr = NULL;
int result = INT_MAX;
char gpiostr[8];
sprintf(gpiostr, "%d", gpio);
ALOGD(TAG"gpio=%s\n", gpiostr);
fp = fopen(SYS_DEV_GPIO_PATH, "r");
if (fp == NULL)
return result;
while ((ret = getline(&line, &len, fp)) != -1) {
tok = strtok_r(line, delim_line, &saveptr1);
if (tok == NULL)
continue;
//skip leading '0'
while ((strlen(tok) > 1) && (*tok == '0')) tok++;
if (!strncmp(tok, "PIN", strlen("PIN"))) {
tok1 = strtok_r(NULL, delim_line, &saveptr1);
if (tok1 == NULL)
continue;
while (*tok1 == ' ' || *tok1 == '\t') ++tok1;
tok2 = strtok_r(tok1, delim_header, &saveptr2);
while (tok2 != NULL) {
index++;
//ALOGD(TAG"index=%d, tok2=%s\n", index, tok2+1);
if (strstr(tok2, token)) {
ALOGD(TAG"index=%d, tok2=%s\n", index, tok2+1);
found = 1;
break;
}
tok2 = strtok_r(NULL, delim_header, &saveptr2);
}
} else if (!strncmp(tok, gpiostr, strlen(gpiostr))) {
tok1 = strtok_r(NULL, delim_line, &saveptr1);
if (tok1 == NULL) {
fclose(fp);
return result;
}
ALOGD(TAG"tok1=%s\n", tok1);
while (*(ptr = tok1++) != '\0' && count < 9) {
if (*ptr == ' ' || *ptr == '\t' || *ptr == '\n' || *ptr == '(' || *ptr == ')') {
continue;
}
if (*ptr == '-' || *ptr == '+') {
temp_ptr = ptr;
continue;
}
if (temp_ptr != NULL) {
memcpy(array[count], temp_ptr, ptr-temp_ptr+1);
array[count][ptr-temp_ptr+1] = '\0';
temp_ptr = NULL;
} else {
array[count][0] = *ptr;
array[count][1] = '\0';
}
count++;
}
//ALOGD(TAG"count=%d\n", count);
//for (i = 0;i < count;i++)
//ALOGD(TAG"array[%d]=%s\n", i, array[i]);
if (found && index < count)
result = atoi(array[index]);
ALOGD(TAG"result=%d\n", result);
fclose(fp);
return result;
}
}
fclose(fp);
return result;
}
int is_eint_detected(int gpio, int active)
{
int status;
const char *din = “DIN”;
status = get_gpio_for_token(gpio, din);
if (status == INT_MAX)
return 0;
if (status == active)
return 1;
else
return 0;
}
#endif
在FtModCustomer中
void FtModCustomer::exec(Frame *pFrm)
{
//………………//省略
#if defined(TRAN_FT_SIM_SD_TRAY_DETECT)
case FT_CUSTOMER_CMD_SIM_TRAY:
{
char out_buf[1] = {0};
ft_cnf.result.m_u1Dummy = FT_CUSTOMER_FAILED;
META_LOG(TAG “new sim eint check start\n”);
if (is_eint_detected(SIM_DETECT_PIN_NUM, SIM_DETECT_PIN_ACTIVE)) {
ft_cnf.result.m_u1Dummy = FT_CUSTOMER_SUCCESS;
ft_cnf.status = META_SUCCESS;
out_buf[0] = 1;
META_LOG(“process sim tray detect pin sucess”);
} else {
out_buf[0] = 0;
META_LOG(“process sim tray detect pin failed”);
}
WriteDataToPC(&ft_cnf, sizeof(ft_cnf), out_buf, sizeof(out_buf));
break;
}
case FT_CUSTOMER_CMD_TCARD_TRAY:
{
char out_buf[1] = {0};
ft_cnf.result.m_u1Dummy = FT_CUSTOMER_FAILED;
META_LOG(TAG “new sd eint check start\n”);
if (is_eint_detected(SD_DETECT_PIN_NUM, SD_DETECT_PIN_ACTIVE)) {
ft_cnf.result.m_u1Dummy = FT_CUSTOMER_SUCCESS;
ft_cnf.status = META_SUCCESS;
out_buf[0] = 1;
META_LOG(“process tcard tray detect pin sucess”);
} else {
out_buf[0] = 0;
META_LOG(“process tcard tray detect pin failed”);
}
WriteDataToPC(&ft_cnf, sizeof(ft_cnf), out_buf, sizeof(out_buf));
break;
}
#endif
//………………//省略
free(peer_buf);
}
四、 提交链接:
http://192.168.10.48/#/c/MTK_CODE/alps/vendor/mediatek/proprietary/hardware/meta/+/13721/
http://192.168.10.48/#/c/MTK_CODE/alps/vendor/mediatek/proprietary/custom/+/17634/
http://192.168.10.48/#/c/tran_projects/+/13718/
五、测试方法
5.1 运行TPStester,选择有Query_SIMTray_Status 和Query_TCARDTray_Status测试项的脚本(datacheck脚本)
5.2 开始测试,手机关机状态USB连接电脑。
5.3 测试结束能够获取插卡与未插卡的结果且显示PASS
[A1]不同主板GPIO口,注意
[A2]不同项目路径不同,注意检查适配
[A3]项目平台不同,分隔符可能不同,如果检查不到GPIO值变化可以检查一下分隔符知否正确,一些老平台项目是“]”