rk3399_arm_lvds/i2c_key/ch455_key.cpp

331 lines
8.8 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <iostream>
#include <iomanip>
#include <memory>
#include <thread>
#include <chrono>
#include <functional>
#include <fcntl.h>
#include <poll.h>
#include <unistd.h>
#define I2C_SDA 43 // GPIO1_B3
#define I2C_SCL 44 // GPIO1_B4
#define I2C_INT 52
typedef unsigned char UINT8;
typedef unsigned short UINT16;
#define STATUS_SUCCESS 0
#define STATUS_FAILURE -1
#define CH455_GET_KEY 0x0700 // 获取按键,返回按键代码
#define CH455_SYSOFF 0x0400 // 关闭显示、关闭键盘
#define CH455_I2C_ADDR 0x40 // CH455的地址
#define CH455_I2C_MASK 0x3E // CH455的高字节命令掩码
#define CH455_BIT_ENABLE 0x01
// #define CH455_BIT_ENABLE 0x03 // 开启/关闭位
#define CH455_BIT_SLEEP 0x04 // 睡眠控制位
#define CH455_SYSON (CH455_SYSOFF | CH455_BIT_ENABLE)
#define CH455_SLEEPOFF CH455_SYSOFF // 关闭睡眠
#define CH455_SLEEPON (CH455_SYSOFF | CH455_BIT_SLEEP) // 开启睡眠
static unsigned char TxBuf[24] = {0};
static unsigned char RxBuf[24] = {0};
void CH455_I2c_Stop(void);
void CH455_I2C_WrByte(unsigned char IIC_Byte);
void delay_us(int i)
{
int j, k;
for (j = 0; j < i; j++)
for (k = 0; k < 10; k++)
;
}
void initGpio(int addr)
{
// printf("开始创建GPIO%d节点\n", addr);
FILE *fp = fopen("/sys/class/gpio/export", "w");
if (fp == NULL)
perror("export open filed");
else
fprintf(fp, "%d", addr);
fclose(fp);
// printf("结束创建GPIO%d节点\n", addr);
}
// 设置为gpio方向
void setGpioDirection(int addr, char *direction)
{
// printf("设置第GPIO%d为out模式\n",addr);
char path[100] = {0};
sprintf(path, "/sys/class/gpio/gpio%d/direction", addr);
FILE *fp = fopen(path, "w");
if (fp == NULL)
perror("direction open filed");
else
fprintf(fp, "%s", direction);
fclose(fp);
// printf("结束设置第GPIO%d为out模式\n",addr);
}
// 设置gpio的电平
void set_gpioValue(int addr, int value)
{
// printf("设置GPIO%d为%d\n", addr, value);
char path[64];
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr);
FILE *fp = fopen(path, "w");
if (fp == NULL)
perror("direction open filed");
else
fprintf(fp, "%d", value);
fclose(fp);
// printf("结束设置GPIO%d位置为%d\n", addr, value);
}
void IOWR_OUT(int addr, int val)
{
initGpio(addr);
setGpioDirection(addr, "out");
set_gpioValue(addr, val);
}
void IOWR_IN(int addr, int val)
{
initGpio(addr);
setGpioDirection(addr, "in");
set_gpioValue(addr, val);
}
// 读gpio节点状态
int IORD(int addr)
{
char path[64];
char value_str[3];
snprintf(path, sizeof(path), "/sys/class/gpio/gpio%d/value", addr);
// printf("/sys/class/gpio/gpio%d/value", addr);
FILE *fp = fopen(path, "r");
// fd = open(path, O_RDONLY);
if (fp == NULL)
{
printf("Failed to open gpio value for reading!");
return -1;
}
if (fread(value_str, sizeof(char), 3, fp) < 0)
{
perror("Failed to read value!");
return -1;
}
fclose(fp);
// printf("读取GPIO状态结束\n");
return (atoi(value_str));
}
// 开始位
void CH455_I2c_Start(void)
{
IOWR_OUT(I2C_SDA, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
IOWR_OUT(I2C_SDA, 0);
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
}
// 结束位
void CH455_I2c_Stop(void)
{
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
IOWR_OUT(I2C_SDA, 0);
delay_us(5);
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
IOWR_OUT(I2C_SDA, 1);
delay_us(5);
}
// 主控端写入一个字节到从机
void CH455_I2C_WrByte(unsigned char IIC_Byte)
{
unsigned char i;
for (i = 0; i < 8; i++)
{
// IOWR(I2C_SCL, 0); //钳住I2C总线准备发送数据
if (IIC_Byte & 0x80)
IOWR_OUT(I2C_SDA, 1);
else
IOWR_OUT(I2C_SDA, 0);
delay_us(5);
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
IIC_Byte <<= 1;
}
delay_us(5);
IOWR_OUT(I2C_SDA, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
}
// 主控端对从机读取一个字节
static unsigned char CH455_I2C_RdByte(void) // 读取一个字节数据
{
unsigned char i = 0;
unsigned char bytedata = 0;
delay_us(5);
// 将数据设置为输入模式
IOWR_IN(I2C_SDA, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
for (i = 0; i < 8; i++)
{
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
bytedata <<= 1;
delay_us(5);
bytedata = bytedata | (IORD(I2C_SDA));
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
}
IOWR_OUT(I2C_SDA, 1); // 数据线设置回输出模式
delay_us(5);
IOWR_OUT(I2C_SCL, 1);
delay_us(5);
IOWR_OUT(I2C_SCL, 0);
delay_us(5);
return (bytedata); // 返回数据
}
// 写命令
static unsigned char CH455_Write(UINT16 cmd)
{
printf("CH455_Write start...\n");
CH455_I2c_Start(); // 启动总线
printf("CH455_Write first byte= %02x\n", ((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR);
printf("CH455_Write second byte= %02x\n", (UINT8)cmd);
CH455_I2C_WrByte(((UINT8)(cmd >> 7) & CH455_I2C_MASK) | CH455_I2C_ADDR);
CH455_I2C_WrByte((UINT8)cmd); // 发送数据
CH455_I2c_Stop(); // 结束总线
printf("CH455_Write end...\n");
printf("\n");
return 1;
}
static unsigned char CH455_Read(void) // 读取按键值
{
printf("CH455_Read start...\n");
UINT8 keycode;
CH455_I2c_Start(); // 启动总线
printf("write byte= %02x\n", (UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR);
CH455_I2C_WrByte((UINT8)(CH455_GET_KEY >> 7) & CH455_I2C_MASK | 0x01 | CH455_I2C_ADDR);
keycode = CH455_I2C_RdByte(); // 读取数据
printf("read byte= %02x\n", keycode);
CH455_I2c_Stop(); // 结束总线
printf("CH455_Read end...\n");
printf("\n");
return keycode;
}
void key_Inter(void)
{
int ret;
int val = 0;
char buf[8];
int num;
UINT16 key_value;
pollfd pfd;
pfd.fd = -1;
pfd.fd = open("/sys/class/gpio/gpio52/value", O_RDONLY);
if (pfd.fd > 0)
printf("huagao::open sucess,fd = %d\n", pfd.fd);
else
printf("huagao::open failed,fd = %d\n", pfd.fd);
pfd.events = POLLPRI;
num = read(pfd.fd, buf, 8); // This is to clear the avaible read
for (int i = 0; i < 8; i++)
printf("huagao::buf[%d] = %d\n", i, buf[i]);
ret = CH455_Write(CH455_SYSON);
printf("CH455_SYSON = %02x\n", (CH455_SYSON));
printf("CH455_Read() = %02x\n", CH455_Read());
key_value = 0xff;
while (1)
{
ret = poll(&pfd, 1, 1000);
if (ret > 0)
{
printf("--------------------------------------------\n");
printf("huagao::poll get date.\n");
printf("huagao::poll ret = %d\n", ret);
/*
POLLIN: 有普通数据或者优先数据可读
POLLRDNORM: 有普通数据可读
POLLRDBAND: 有优先数据可读
POLLPRI: 有紧急数据可读
POLLOUT: 有普通数据可写
POLLWRNORM: 有普通数据可写
POLLWRBAND: 有紧急数据可写
POLLERR: 有错误发生
POLLHUP: 有描述符挂起事件发生
POLLNVAL: 描述符非法
*/
if (pfd.revents & POLLPRI)
{
lseek(pfd.fd, 0, SEEK_SET);
num = read(pfd.fd, buf, 8);
buf[num - 1] = '\0';
ret = atoi(buf);
for (int i = 0; i < 8; i++)
printf("huagao::buf[%d] = %d\n", i, buf[i]);
printf("huagao::atoi(buf) ret = %d\n", ret);
}
key_value = CH455_Read();
printf("CH455_Read() = %02x\n", key_value);
printf("--------------------------------------------\n");
printf("\n");
}
else if (ret == 0)
{
printf("--------------------------------------------\n");
printf("huagao::ret = %d\n", ret);
printf("huagao::poll time out.\n");
printf("--------------------------------------------\n");
printf("\n");
}
else
{
printf("--------------------------------------------\n");
printf("huagao::ret = %d\n", ret);
printf("huagao::poll err.\n");
printf("--------------------------------------------\n");
printf("\n");
}
}
}
int main(void)
{
system("echo 52 > /sys/class/gpio/export");
system("echo in > /sys/class/gpio/gpio52/direction");
system("echo falling > /sys/class/gpio/gpio52/edge");
key_Inter();
return 0;
}