335 lines
8.2 KiB
C++
335 lines
8.2 KiB
C++
|
#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;
|
|||
|
}
|
|||
|
|
|||
|
|