rk3399_arm_lvds/i2c_key/ch455_key.cpp

331 lines
8.8 KiB
C++
Raw Permalink Normal View History

2024-03-05 03:46:18 +00:00
#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;
}