newtx/ui/keymonitor.cpp

206 lines
6.3 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 "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();
// printf("Key = %02x pin value = %d \n",value,pin);
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();
}