newtx/ui/keymonitor.cpp

206 lines
6.3 KiB
C++
Raw Permalink Normal View History

2024-02-02 08:53:17 +00:00
#include "keymonitor.h"
#include <uart/Gpio.h>
#include <uart/PinMonitor.h>
#include <iostream>
#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) // 开启睡眠
KeyMonitor::KeyMonitor(std::function<void(int)> keycall) : m_keycall(keycall)
{
m_gpioi2c_SCL = std::make_shared<Gpio>(44); //I2C_SCL
m_gpioi2c_SCL->setDirection(Gpio::out);
m_gpioi2c_SDA = std::make_shared<Gpio>(43); //I2C_SDA
m_gpioi2c_SDA->setDirection(Gpio::out);
write_cmd(CH455_SYSON);
printf("read_key = %02x\n", read_key());
setled(HGLed::Led_All_close);
auto pincall=[&](int pin)
{
auto value= read_key();
2024-02-04 02:30:09 +00:00
// printf("Key = %02x pin value = %d \n",value,pin);
2024-02-02 08:53:17 +00:00
if(m_keycall)
m_keycall(value);
};
m_keymonitor = std::make_shared<PinMonitor>(52,pincall);
}
KeyMonitor::~KeyMonitor()
{
if(m_gpioi2c_SCL.get())
m_gpioi2c_SCL.reset();
if(m_gpioi2c_SDA.get())
m_gpioi2c_SDA.reset();
if(m_keymonitor.get())
m_keymonitor.reset();
}
void KeyMonitor::init()
{
}
void KeyMonitor::i2c_start()
{
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
void KeyMonitor::i2c_write(unsigned char cmd)
{
unsigned char i;
for(i=0; i<8; i++)
{
//IOWR(I2C_SCL, 0); //钳住I2C总线准备发送数据
if(cmd & 0x80)
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
else
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
cmd<<=1;
}
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
unsigned char KeyMonitor::i2c_read()
{
unsigned char bytedata = 0;
m_gpioi2c_SDA->setDirection(Gpio::in);//将数据设置为输入模式
//m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
for(int i=0; i<8; i++)
{
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
bytedata <<= 1;
bytedata = bytedata | (m_gpioi2c_SDA->getValue());
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
m_gpioi2c_SDA->setDirection(Gpio::out);
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);////数据线设置回输出模式
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
return bytedata;
}
void KeyMonitor::i2c_stop()
{
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::Low);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SCL->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
m_gpioi2c_SDA->setValue(Gpio::GpioLevel::High);
std::this_thread::sleep_for(std::chrono::microseconds(5));
}
void KeyMonitor::write_cmd(unsigned short cmd)
{
i2c_start();
i2c_write(((unsigned char)(cmd>>7)&CH455_I2C_MASK)|CH455_I2C_ADDR);
i2c_write(cmd);
i2c_stop();
}
unsigned char KeyMonitor::read_key()
{
unsigned char key=0;
i2c_start();
i2c_write((unsigned char)(CH455_GET_KEY>>7)&CH455_I2C_MASK|0x01|CH455_I2C_ADDR);
key = i2c_read();
i2c_stop();
return key;
}
std::uint8_t KeyMonitor::getledstate()
{
return m_ledstate;
}
void KeyMonitor::setled(HGLed value)
{
switch (value)
{
case HGLed::Led_All_close:
m_ledstate = 0;
break;
#ifdef G200
case HGLed::Led_All_open:
m_ledstate = 0xf8;
break;
case HGLed::Led_Count_close:
m_ledstate = m_ledstate & 0xef;
break;
case HGLed::Led_Count_open:
m_ledstate = m_ledstate | 0x10;
break;
case HGLed::Led_DoubleFeed_close:
m_ledstate = m_ledstate & 0xbf;
break;
case HGLed::Led_DoubleFeed_open:
m_ledstate = m_ledstate | 0x40;
break;
case HGLed::Led_Enter_close:
m_ledstate = m_ledstate & 0xf7;
break;
case HGLed::Led_Enter_open:
m_ledstate = m_ledstate | 0x8;
break;
case HGLed::Led_Handle_close:
m_ledstate = m_ledstate & 0xdf;
break;
case HGLed::Led_Handle_open:
m_ledstate = m_ledstate | 0x20;
break;
#endif
default:
break;
}
i2c_start();
i2c_write(0x6e);
i2c_write(m_ledstate);
i2c_stop();
}