typedef enum {
APP_BUTTON,
APP_TOUCH,
+ APP_ENCODER,
} app_type;
typedef struct {
typedef enum {
APP_BUTTON,
APP_TOUCH,
+ APP_ENCODER,
} app_type;
typedef struct {
typedef enum {
APP_BUTTON,
APP_TOUCH,
+ APP_ENCODER,
} app_type;
typedef struct {
#endif
#include "sys/time.h"
#include "touch_screen_def.h"
+#include "rotary_encoder_def.h"
#include "time.h"
#include "tcxo.h"
#ifdef CONFIG_LOW_POWER_TEST
#endif
if ((g_pms_lcd_on_first_flag == false) && (g_pms_dpu_ready == false)) {
touch_screen_resume(); // open touch
+ rotary_encoder_resume();
}
#ifdef CONFIG_CLDO1PD_SUPPORT
pmu_control_cldo1_sleep_bypass(TURN_ON);
#endif
osDelay(100); // Wait 100ms for the uikit to complete display.
touch_screen_suspend(); // close touch
+ rotary_encoder_suspend();
ext_errno ret = drv_vau_suspend(NULL);
if (ret != 0) {
POWER_DISPLAY_PRINT_ERR(0, "drv vau suspend error ret=%x\r\n", ret);
if("ROTARYENCODER_HX3507" IN_LIST DEFINES)
set(SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c
- ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507_hal.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507_at_cmd.c
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507
)
set(PUBLIC_DEFINES
SUPPORT_AT_HX3507
)
else()
set(SOURCES
- ${CMAKE_CURRENT_SOURCE_DIR}/hx3507.c
- ${CMAKE_CURRENT_SOURCE_DIR}/hx3507_at_cmd.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507_hal.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507/hx3507_at_cmd.c
+)
+set(PUBLIC_HEADER
+ ${CMAKE_CURRENT_SOURCE_DIR}/hx3507
)
set(PUBLIC_DEFINES
SUPPORT_AT_HX3507
)
endif()
+set(SOURCES
+ ${SOURCES}
+ ${CMAKE_CURRENT_SOURCE_DIR}/rotary_encoder_drv.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/rotary_encoder_queue1.c
+)
set(PUBLIC_HEADER
+ ${PUBLIC_HEADER}
${CMAKE_CURRENT_SOURCE_DIR}
)
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2023-2023. All rights reserved. \n
+ *
+ * Description: Button driver source file \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2023-02-24, Create file. \n
+ */
+
+#include "pinctrl.h"
+#include "button_porting.h"
+#include "platform_core.h"
+#include "gpio.h"
+#include "gpio_porting.h"
+#include "debug_print.h"
+#include "rtc.h"
+#include "timer.h"
+#include "systick.h"
+#include "chip_core_irq.h"
+#include "tcxo.h"
+#include "errcode.h"
+#include "pm_veto.h"
+
+/**
+ * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司
+ *
+ * All rights reserved.
+ *
+*/
+/*****************************************************************************
+ * @file tyhx_crown_custom.c
+ * @author Jiandang.Dong
+ * @date 2022-08-09 created
+ * @Emial Jiandang.Dong@tianyihexin.com
+ * @brief HX3507 驱动程序
+******************************************************************************/
+/*
+整体应用流程, 请见应用文档.
+先初始化IO, 执行crown_init 保证通信正确;
+在需要HX3507工作的时候, 调用crown_start(), 定时器启动,
+定时器周期处理调用crown_data_handler()来读取HX3507的数据;
+在HX3507 不需要工作的时候, 调用crown_stop() 让HX3507 进入power down状态
+*/
+
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include "hx3507.h"
+
+// #ifdef CHIP_HX3507
+
+
+#include "cmsis_os2.h"
+
+osTimerId_t g_hx3507_timer = NULL;//定义一个定时器ID
+static uint8_t g_hx3695_timer_installed = 0;
+
+static int16_t crown_result = 0;
+
+/*----------------------以下为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/
+
+
+
+/**
+ * 定时器超时处理函数
+ * @param p_context 是对应的定时器;
+ */
+void crown_timer_handler(void * p_context)
+{
+ UNUSED(p_context);
+ crown_data_handler(NULL,0);
+}
+/**
+ * 表冠定时器创建函数
+ * @param NULL
+ */
+void crown_timer_creat(void)
+{
+ if (g_hx3695_timer_installed == 1)
+ return ;
+ g_hx3507_timer = osTimerNew((osTimerFunc_t)crown_timer_handler, osTimerPeriodic, NULL, NULL);
+ g_hx3695_timer_installed = true;
+ return ;
+ // app_timer_create(&crown_timer_id, APP_TIMER_MODE_REPEATED, crown_timer_handler);
+}
+
+/**
+ * 定时器start函数 , 目前定义的定时器是50ms, 用户可以根据需要改为100ms
+ * @param NULL
+ */
+void crown_timer_start(void)
+{
+ if(osTimerIsRunning(g_hx3507_timer)==0)
+ osTimerStart(g_hx3507_timer, 50);
+}
+
+/**
+ * 定时器stop函数
+ * @param timerid 是对应的定时器;
+ */
+void crown_timer_stop(void)
+{
+ if(osTimerIsRunning(g_hx3507_timer))
+ osTimerStop(g_hx3507_timer);
+}
+
+
+
+/*----------------------以上为定时函数相关定义 建立/启动/停止定时器//定时中断处理-------------------------------*/
+
+
+/*---------------------------以下为表冠的寄存器读写,初始化/开始/结束------------------------*/
+
+/**
+ * 通信重新同步函数, 作用是防止因为其他干扰而引起的错乱
+ * @param NULL;
+ */
+void crown_com_resync(void)
+{
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ uapi_tcxo_delay_us(5);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(5);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ uapi_tcxo_delay_ms(5);
+}
+
+/**
+ * 通信读寄存器值函数
+ * @param regaddr, hx3507的寄存器地址
+ * uapi_tcxo_delay_us(COM_DELAY), 读写函数的delay 按照实际平台调整, HX3507 通信sclk 最高支持1MHZ频率.
+ * 在最高频率的范围内, 尽量减小delay, 减少定时器周期读取的时间.
+ */
+uint8_t crown_read_reg(uint8_t regaddr)
+{
+ uint8_t readvalue = 0;
+
+ regaddr &= 0x7f;
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(COM_DELAY);
+
+ for(int i=0; i<8; i++)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ if(regaddr & 0x80)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH);
+ }
+ else
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+
+ regaddr<<=1;
+ //uapi_tcxo_delay_us(COM_DELAY);
+ }
+
+ //开始读操作,HOST要把SDIO从输出端口改为输入端口.
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT);
+ uapi_pin_set_pull(PIN_TYHX_SDIO, (pin_pull_t)HAL_PIO_PULL_UP);
+ uapi_pin_set_ie(PIN_TYHX_SDIO,HAL_PIO_IE_ENBALE);
+ uapi_tcxo_delay_us(COM_DELAY);
+ //nrf_gpio_pin_clear(PIN_TYHX_SCLK);
+ //uapi_tcxo_delay_us(COM_DELAY);
+
+ for(int i=0; i<8; i++)
+ {
+ readvalue<<=1;
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+ //uapi_tcxo_delay_us(COM_DELAY);
+ if(uapi_gpio_get_val(PIN_TYHX_SDIO))
+ {
+ readvalue |= 0x1;
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ }
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ return readvalue;
+}
+
+/**
+ * 通信读寄存器值函数
+ * @param regaddr, hx3507的寄存器地址
+ * @param regvalue, 要写的值
+ */
+void crown_write_reg(uint8_t regaddr, uint8_t regvalue)
+{
+
+ uint16_t writevalue;
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+ uapi_tcxo_delay_us(COM_DELAY);
+
+ //写通信协议, 最高位置1, 循环16次依次送出寄存器和值,在SCLK的上升沿前准备好数据
+ writevalue= (uint16_t)((regaddr|0x80)<<8) + regvalue;
+
+ for(int i=0; i<16; i++)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ if(writevalue & 0x8000)
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_HIGH);
+ }
+ else
+ {
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+
+ }
+ //uapi_tcxo_delay_us(COM_DELAY);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_HIGH);
+
+ writevalue<<=1;
+ }
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ return;
+}
+
+
+/**
+ * 某些OTS冠轴质量非常差, 这个是防呆处理
+ * @param xdata, 当前读到的OTS的有效轴的数据
+ * @result = true, 值有效, = false 这个值无效
+ */
+static bool crown_data_verify(int16_t xdata)
+{
+ static int16_t xstore[3] = {0};
+ uint16_t diff1, diff2, diff3= 0;
+
+ if(abs(xdata)>=600)//间隔50ms的一次读数
+ {
+ crown_timer_stop();
+ crown_start();
+ return false;
+ }
+ diff1 = abs(xstore[2]-xstore[1]);
+ diff2 = abs(xstore[1]-xstore[0]);
+ diff3 = abs(xstore[0]-xdata);
+
+ if((diff1<5) &&(diff2<=5) &&(diff3<=5) &&(abs(xdata)>=100))//连续四次读到接近的值
+ {
+ crown_timer_stop();
+ crown_start();
+ return false;
+ }
+ xstore[2] = xstore[1];
+ xstore[1] = xstore[0];
+ xstore[0] = xdata;
+ return true;
+}
+
+/**
+ * 周期定时器数据读取
+ * @param p_event_data, 参数暂时无用
+ * @param event_size, 参数暂时无用
+ */
+void crown_data_handler(void *p_event_data, uint16_t event_size)
+{
+ int16_t delatx = 0;
+ uint8_t sleepstatus = 0;
+ for(int i=0; i<5; i++)//先读一下芯片ID保证通信正常
+ {
+ if(crown_read_reg(HX3507_DID) == 0x30)
+ {
+ break;
+ }
+ else
+ {
+ crown_com_resync();
+ }
+ }
+ if(crown_read_reg(Motion_St)&0x80)
+ {
+#if defined(MOT_LOW_LEVEL_MODE)
+ //如果有使用中断, 需要读取Y的值, 值读完, 中断电平才能恢复
+ int16_t delaty = 0;
+ delaty = crown_read_reg(DeltaY) |(crown_read_reg(DeltaY_Hi)<<8);
+#endif
+ //HX3507 一个方向转动出正值, 另外一个方向就是负值, 正负值跟芯片的摆放方向有关
+ delatx = crown_read_reg(DeltaX) |(crown_read_reg(DeltaX_Hi)<<8);
+ if(crown_data_verify(delatx)) //先判断数据是否合理,
+ // 主要针对OTS冠轴质量,或者装配摆动幅度大引起的错误, 做的保护程序
+ {
+ //打印读取结果
+ TYHX_LOG("DeltaX = %d\r\n",delatx);
+ //把结果转换为大概的估算角度
+ put_crown_result(delatx);
+ }
+ }
+ else //下面这两个参数在产测程序里面需要加上
+ {
+ //冠轴静止的时候, 打印图像的质量和PD的饱和度, 这两个参数读取要放在出货测试的程序里面,
+ // 图像质量应该>=80, 否则可能代表芯片表面有脏污等或者装配问题或者有漏光
+ // PD的饱和度应该>=100 且 <=180, 如果有漏光等问题, 结果>=240以上, 相关漏光等要处理
+ // TYHX_LOG("pic qulity =%d, pd saturation=%d\r\n",crown_read_reg(Img_Qa),crown_read_reg(PD_SAT));
+ }
+
+#if (defined(MOT_LOW_LEVEL_MODE))//如果低电平中断模式,要读到芯片MOT变高
+ if(uapi_gpio_get_val(PIN_TYHX_MOT))
+ {
+ TYHX_LOG("PIN_TYHX_MOT is high \r\n");
+ crown_timer_stop();
+ }
+#endif
+
+#if (defined(MOT_FALLINGTRI_MODE))//如果是脉冲中断模式,要读到芯片进入sleep
+ sleepstatus = crown_read_reg(Op_St);
+ if((sleepstatus & 0x7) == 6)
+ {
+ TYHX_LOG("crown is sleep \r\n");
+ crown_timer_stop();
+ }
+#endif
+#if (defined(MOT_NO_USE_MODE))
+ //如果是MOT_NO_USE_MODE , 一般在屏幕熄掉,不需要HX3507工作的时候, 关闭定时器
+#endif
+
+}
+
+//MOT 中断处理程序, 这个是根据平台程序处理, 用户可以自行修改
+//这里加中断发生标志位或者把中断处理推送到其他任务队列, 因为中断函数里面不能加太多程序
+//下面的例子用的是NORDIC标准的程序,中断发生后GPIO的一个处理,并且把中断处理推送到任务队列
+#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE))
+static void crown_int_handler(nrf_drv_gpiote_pin_t pin, nrf_gpiote_polarity_t action)
+{
+ uint32_t err_code;
+ bool mothitolow = false;
+
+ nrf_drv_gpiote_in_uninit(PIN_TYHX_MOT);
+ if (action == NRF_GPIOTE_POLARITY_HITOLO)
+ {
+ mothitolow = true;
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_LOTOHI(false);
+ err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ APP_ERROR_CHECK(err_code);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+ }
+ else
+ {
+ mothitolow = false;
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
+ err_code = nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ APP_ERROR_CHECK(err_code);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+ }
+ nrf_gpio_pin_latch_clear(PIN_TYHX_MOT);
+ if(mothitolow)
+ {
+ TYHX_LOG("mot interrupt! \r\n");
+ mothitolow = false;
+ crown_timer_start();
+ }
+
+}
+
+#endif
+
+
+/**
+ * HX3507 初始化
+ * @param NULL
+ */
+void crown_init(void)
+{
+ int i;
+ uapi_gpio_set_dir(PIN_TYHX_SDIO,GPIO_DIRECTION_INPUT);
+ uapi_gpio_set_dir(PIN_TYHX_SCLK,GPIO_DIRECTION_OUTPUT);
+ uapi_gpio_set_val(PIN_TYHX_SDIO,GPIO_LEVEL_LOW);
+ uapi_gpio_set_val(PIN_TYHX_SCLK,GPIO_LEVEL_LOW);
+
+ uapi_tcxo_delay_us(COM_DELAY);
+ crown_com_resync();
+ for(i=0; i<10; i++)
+ {
+ if(crown_read_reg(HX3507_DID) == 0x30)
+ {
+ TYHX_LOG("read chip id is 0x30\r\n",i);
+ break;
+ }
+ if(i<7)//读到ID不对, 复位通信
+ {
+ crown_com_resync();
+ }
+ }
+ if(i==10)
+ {
+ TYHX_LOG("HX3507 communication err, please check\r\n");
+ return;
+ }
+
+#if (defined(MOT_LOW_LEVEL_MODE) || defined(MOT_FALLINGTRI_MODE))
+ //中断定义
+ nrf_drv_gpiote_in_config_t config_crown = GPIOTE_CONFIG_IN_SENSE_HITOLO(false);
+ config_crown.pull = NRF_GPIO_PIN_PULLUP;
+ nrf_drv_gpiote_in_init(PIN_TYHX_MOT, &config_crown, crown_int_handler);
+ nrf_drv_gpiote_in_event_enable(PIN_TYHX_MOT, true);
+
+#endif
+ //定时器创建
+ crown_timer_creat();
+}
+
+
+/**
+ * HX3507 启动
+ * @param NULL
+ */
+void crown_start(void)
+{
+ int i = 0;
+ for(int i=0; i<5; i++)
+ {
+ crown_write_reg(Config_St,0x89); //RESET
+ uapi_tcxo_delay_ms(10);
+ TYHX_LOG("Reset ic, now init ---\r\n");
+
+#if defined(MOT_LOW_LEVEL_MODE)
+ crown_write_reg(Config_St,0x01); //正常工作, MOT低电平中断
+ crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能
+ crown_write_reg(Sleep1_Setting,0xc0);
+ crown_write_reg(Enter_Time,0xc1);
+ crown_write_reg(Sleep2_Setting,0xc0);
+#elif defined(MOT_FALLINGTRI_MODE)
+ crown_write_reg(Config_St,0x41); //正常工作, MOT下降沿中断
+ crown_write_reg(Op_Mode,0xb8); //打开Sleep1 和 sleep2 功能
+ crown_write_reg(Sleep1_Setting,0xc0);
+ crown_write_reg(Enter_Time,0xc1);
+ crown_write_reg(Sleep2_Setting,0xc0);
+
+#elif defined(MOT_NO_USE_MODE)
+ crown_write_reg(Op_Mode,0xa0); //关闭sleep功能
+#endif
+ crown_write_reg(Write_Protect,0xc3); //enable all registers
+ crown_write_reg(Sleep1_Setting,0xc0); //0x70,32ms.loop = 40ms. return 0 slowly
+ crown_write_reg(Enter_Time,0x0); //sleep1=128*(Enter_Time[7:4]+1) sleep2=20480*(Enter_Time[3:0]+1)
+ crown_write_reg(DxDy_16bit,0x01); //0:8bit,1:16bit
+ crown_write_reg(CPI2_Setting,0x88); //800 cpi
+ crown_write_reg(HX3507_REV,0x00);
+ if(1 == crown_read_reg(DxDy_16bit) )
+ {
+ break;
+ }
+ else
+ {
+ crown_com_resync();
+ }
+ }
+ if(i==5)
+ {
+ TYHX_LOG("HX3507 init err, please check\r\n");
+ return;
+ }
+
+
+#if 0 //这里非常关键, 在调试初期, 需要用#if 1 来验证寄存器写入的值和读出来的值是一样的, 通信正确
+ TYHX_LOG("Op_Mode = 0x%x\r\n",crown_read_reg(Op_Mode));
+ TYHX_LOG("Sleep1_Setting = 0x%x\r\n",crown_read_reg(Sleep1_Setting));
+ TYHX_LOG("DxDy_16bit = 0x%x\r\n",crown_read_reg(DxDy_16bit));
+ TYHX_LOG("CPI2_Setting = 0x%x\r\n",crown_read_reg(CPI2_Setting));
+#endif
+
+#ifdef MOT_NO_USE_MODE // 如果是非中断模式, 初始后, 开启定时器;
+ crown_timer_start();
+#endif
+
+
+
+}
+
+
+/**
+ * HX3507 停止
+ * @param NULL
+ */
+void crown_stop(void)
+{
+#ifdef MOT_NO_USE_MODE
+ crown_timer_stop();
+ crown_write_reg(Config_St,0x89); // power down, power down 后芯片功耗9uA
+ uapi_tcxo_delay_ms(20);
+ TYHX_LOG("[tyhx_crown_stop]\r\n");
+#endif
+}
+
+
+/**
+ * HX3507 结果转换为角度, 供UI处理
+ * @param NULL
+ */
+void put_crown_result(int16_t x)
+{
+ if(abs(x)<=FILTER_MIN )
+ return;
+ if(abs(x)>=4 )
+ {
+ crown_result += x/4; //大于4的值除以4, 代表角度, 单位0.5°
+ }
+ else
+ {
+ if(x>0)
+ {
+ crown_result+=1; //2~4 默认一个单位, 0.5°
+ }
+ else
+ {
+ crown_result-=1; //2~4 默认一个单位, 0.5°
+ }
+ }
+}
+
+/**
+ * 获取表冠的数据结果接口函数
+ * @param NULL
+*/
+int16_t get_crown_result(void)
+{
+ int16_t resulttemp;
+ resulttemp=crown_result;
+ crown_result = 0;
+ return resulttemp;
+}
+
+// #endif
+
--- /dev/null
+/**
+ * Copyright (c) 2014 - 2023, 南京天易合芯电子有限公司
+ *
+ * All rights reserved.
+ *
+*/
+
+/***************************************************************************
+ * @file TYHX_CROWN_CUSTOM.h
+ * @author TYHX team
+ * @product CROWN
+ * @version V0.1
+ * @date 2022-08-09
+ * @modify date 2023-02-17
+
+****************************************************************************/
+#ifndef _TYHX_CROWN_CUSTOM_H_
+#define _TYHX_CROWN_CUSTOM_H_
+
+#include "debug_print.h"
+#define CHIP_HX3507
+
+
+//三种中断模式的应用具体见“天易合芯表冠产品应用文档.docx"的流程说明,用户也可以定义自己的流程模式
+//#define MOT_LOW_LEVEL_MODE //MOT使用低电平中断
+//#define MOT_FALLINGTRI_MODE //MOT 使用低脉冲中断
+#define MOT_NO_USE_MODE //用户不使用MOT 中断, 这个为常用的推荐模式
+
+
+//register define , addr, rw, default value, detail
+#define HX3507_DID 0x00 //R 0x30 芯片ID
+#define Motion_St 0x02 //R 是否有冠轴转动数据产生
+#define DeltaX 0x03 //R 0x30 DeltaX 的低8位数据
+#define DeltaY 0x04 //R 0x30 DeltaY 的低8位数据
+#define Op_Mode 0x05 //W/R 操作模式
+#define Config_St 0x06 //W/R 0x02 閰嶇疆
+#define Img_Qa 0x07 //R 图像质量
+#define Op_St 0x08 //R Sleep 和帧率设置
+#define Write_Protect 0x09 //W扩展寄存器的写使能
+#define Sleep1_Setting 0x0A //W/R Sleep1 的工作频率设置
+#define Enter_Time 0x0B //W/R 进入SLEEP的等待时间设置
+#define Sleep2_Setting 0x0C // W/R Sleep2的工作频率设置
+#define DeltaX_Hi 0x20 //R DeltaX 的高8位数据
+#define DeltaY_Hi 0x21 //R DeltaY的高8位数据
+#define DxDy_16bit 0x22 //数据输出寄存器选择16bit还是8bit格式
+#define CPI2_Setting 0x23 //W/R 扩展CPI 设置
+#define PD_SAT 0x3D //PD 感光的饱和度
+#define HX3507_REV 0x5F //W 保留寄存器
+
+#define COM_DELAY 5 // 通信的delay 单位, 用户根据平台实际调整, 最高支持1MHZ CLK
+#define FILTER_MIN 1 // 偶尔冠轴被震动等各种意外产生的小的数据, 可根据产品情况把小的出值滤掉
+
+//log 打印定义
+#define TYHX_LOG_ENABLE
+#ifdef TYHX_LOG_ENABLE
+#define TYHX_LOG(fmt, ...) \
+ do { \
+ PRINT(fmt" ", ##__VA_ARGS__); \
+ } while (0)
+#else
+#define TYHX_LOG(...)
+#endif //TYHX_LOG_ENABLE
+
+
+/*----------------------使用的IO定义-------------------------------*/
+
+#define PIN_TYHX_SDIO S_AGPIO_L12 //custom to do here
+#define PIN_TYHX_SCLK S_AGPIO_L13 //custom to do here
+#define PIN_TYHX_MOT S_AGPIO_L17 //custom to do here
+
+//定时器的 创建/启动/停止/溢出处理函数
+void crown_timer_creat(void);
+void crown_timer_start(void);
+void crown_timer_stop(void);
+void crown_timer_handler(void * p_context);
+
+//HX3507 初始化,启动,停止, 数据读取, 读寄存器, 写寄存器等, 通信同步
+void crown_init(void);
+void crown_start(void);
+void crown_stop(void);
+void crown_data_handler(void *p_event_data, uint16_t event_size);
+uint8_t crown_read_reg(uint8_t regaddr);
+void crown_write_reg(uint8_t regaddr, uint8_t regvalue);
+void crown_com_resync(void);
+
+//把读出的数据转换为大概角度函数
+void put_crown_result(int16_t x);
+
+//把角度结果上报的函数
+int16_t get_crown_result(void);
+#endif //_TYHX_CROWN_CUSTOM_H_
--- /dev/null
+
+// #include "hx3507.h"
+
+
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "hx3507.h"
+
+#define ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+#define HX3507_MAX_ARGC 8
+#define HX3507_MAX_ARGV_LEN 64
+
+#define HX3507_SUCCESS 0
+#define HX3507_FAILED (-1)
+
+static int ConvertCmdToParam(uint8_t *para, uint32_t paraLen,
+ uint8_t argv[HX3507_MAX_ARGC][HX3507_MAX_ARGV_LEN], uint32_t* argc)
+{
+ uint32_t pos = 0;
+ *argc = 0;
+
+ for (uint32_t i = 0; i < paraLen; i++) {
+ if ((para[i] == ' ' || para[i] == '\n') && pos != 0) {
+ argv[*argc][pos] = '\0';
+ *argc += 1;
+ pos = 0;
+ if (*argc >= HX3507_MAX_ARGC) {
+ return HX3507_FAILED;
+ }
+ } else {
+ argv[*argc][pos] = para[i];
+ pos++;
+ if (pos >= HX3507_MAX_ARGV_LEN) {
+ return HX3507_FAILED;
+ }
+ }
+ }
+ if (pos != 0) {
+ *argc += 1;
+ }
+
+ return HX3507_SUCCESS;
+}
+
+static uint8_t g_hx3507_test_started = 0;
+static uint32_t hx3507_test(uint8_t *para, uint32_t paraLen, char *strCommonCmd)
+{
+ UNUSED(strCommonCmd);
+ uint8_t argv[HX3507_MAX_ARGC][HX3507_MAX_ARGV_LEN] = { 0 };
+ uint32_t argc = 0;
+
+ int ret = ConvertCmdToParam(para, paraLen, argv, &argc);
+ if (ret != HX3507_SUCCESS) {
+ PRINT("HX3507TEST ATCMD Convert Command Failed\n");
+ return ERRCODE_FAIL;
+ }
+
+ if (argc != 1) {
+ PRINT("HX3507TEST ATCMD Set Parameter Failed argc %d\n",argc);
+ return ERRCODE_FAIL;
+ }
+ uint8_t start = (uint8_t)atoi((char*)argv[0]);
+ if (start == 1)
+ {
+ if (g_hx3507_test_started == 1)
+ {
+ PRINT("SKIP hx3507test start, already started\r\n");
+ return 0;
+ }
+ crown_init();
+ crown_start();
+ g_hx3507_test_started = 1;
+ }else{
+ if (g_hx3507_test_started == 0)
+ {
+ PRINT("SKIP hx3507test stop, already stopped\r\n");
+ return 0;
+ }
+ crown_stop();
+ g_hx3507_test_started = 0 ;
+ }
+ return ERRCODE_SUCC;
+}
+static const at_cmd_table_t g_hx3507_cmd[] = {
+ { (char *)"AT^HX3507TEST", hx3507_test, (char *)"1" },
+};
+
+at_cmd_table_t *get_hx3507_cmd_table(uint32_t *cmd_count)
+{
+ *cmd_count = ARRAY_COUNT(g_hx3507_cmd);
+ return (at_cmd_table_t *)g_hx3507_cmd;
+}
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef HX3507_AT_PROCESS_H
+#define HX3507_AT_PROCESS_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_mmc5603_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+
+// #include "hx3507.h"
+
+
+#include "at_cmd_api.h"
+#include "pm_control.h"
+#include "hx3507.h"
+#include "hx3507_hal.h"
+
+#include "rotary_encoder_def.h"
+#include "i2c.h"
+#include "debug_print.h"
+#include "hal_i2c.h"
+
+static uint8_t g_hx3507_test_started = 0;
+uint32_t hx3507_start(void)
+{
+ if (g_hx3507_test_started == 1)
+ {
+ re_print("SKIP hx3507test start, already started\r\n");
+ return 0;
+ }
+ crown_init();
+ crown_start();
+ g_hx3507_test_started = 1;
+ return ERRCODE_SUCC;
+}
+uint32_t hx3507_stop(void)
+{
+ if (g_hx3507_test_started == 0)
+ {
+ re_print("SKIP hx3507test stop, already stopped\r\n");
+ return 0;
+ }
+ crown_stop();
+ g_hx3507_test_started = 0 ;
+ return ERRCODE_SUCC;
+}
+
+static ext_errno hx3507_encoder_init(void *attr)
+{
+ re_print("hx3507_encoder_init\r\n");
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_deinit(void)
+{
+ re_print("hx3507_encoder_deinit\r\n");
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_get_encoderinfo(uint8_t *data, uint8_t data_len)
+{
+
+ re_print("hx3507_encoder_get_encoderinfo\r\n");
+ if (data_len != sizeof(re_input_event_info))
+ return EXT_ERR_NOT_SUPPORT;
+ re_input_event_info *encoder_info = (re_input_event_info*)data;
+ int16_t diff = get_crown_result();
+ if (diff > 0 )
+ {
+ encoder_info->re_event = MC_RE_SLIDE_UP;
+ }else{
+ encoder_info->re_event = MC_RE_SLIDE_DOWN;
+ }
+ encoder_info->re_event_info.x_axis[0] = diff;
+ encoder_info->re_event_info.y_axis[0] = diff;
+ encoder_info->re_event_info.z_axis[0] = diff;
+ encoder_info->finger_id = 0 ;
+ encoder_info->point_num = 0 ;
+ encoder_info->tv_usec = (uint32_t)uapi_tcxo_get_ms();
+
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_suspend(void)
+{
+ re_print("hx3507_encoder_suspend\r\n");
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_resume(void)
+{
+ re_print("hx3507_encoder_resume\r\n");
+ hx3507_start();
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_sleep(void)
+{
+ re_print("hx3507_encoder_sleep\r\n");
+ hx3507_stop();
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_reset(void)
+{
+ re_print("hx3507_encoder_reset\r\n");
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_encoder_bus_init(void *private_data)
+{
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_register_callback(void *peri_data, encoder_callback func)
+{
+ re_print("hx3507_register_callback\r\n");
+ return EXT_ERR_SUCCESS;
+}
+static ext_errno hx3507_unregister_callback(void *peri_data)
+{
+ re_print("hx3507_unregister_callback\r\n");
+ return EXT_ERR_SUCCESS;
+}
+
+encoder_peripheral_api g_hx3507_api = {
+ .encoder_init = hx3507_encoder_init,
+ .encoder_deinit = hx3507_encoder_deinit,
+ .encoder_get_encoderinfo = hx3507_encoder_get_encoderinfo,
+ .encoder_suspend = hx3507_encoder_suspend,
+ .encoder_resume = hx3507_encoder_resume,
+ .encoder_sleep = hx3507_encoder_sleep,
+ .encoder_reset = hx3507_encoder_reset,
+ .encoder_bus_init = hx3507_encoder_bus_init,
+ .register_callback = hx3507_register_callback,
+ .unregister_callback = hx3507_unregister_callback,
+};
+
+
+void *rotary_encoder_get_api(void)
+{
+ return ((void *)&g_hx3507_api);
+}
+
+void *rotary_encoder_get_peri_attr(void)
+{
+ return ((void *)NULL);
+}
\ No newline at end of file
--- /dev/null
+/**
+ * Copyright (c) @CompanyNameMagicTag 2022-2022. All rights reserved. \n
+ *
+ * Description: Provides at cmd register func \n
+ * Author: @CompanyNameTag \n
+ * History: \n
+ * 2022-07-20, Create file. \n
+ */
+#ifndef HX3507_HAL_H
+#define HX3507_HAL_H
+
+#include <stdint.h>
+#include <stdio.h>
+#include "errcode.h"
+#include "soc_osal.h"
+#include "at_cmd_api.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+at_cmd_table_t *get_mmc5603_cmd_table(uint32_t *cmd_count);
+
+#ifdef __cplusplus
+#if __cplusplus
+}
+#endif /* __cplusplus */
+#endif /* __cplusplus */
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: touch screen common definition.
+ * Author: @CompanyNameTag
+ * Create: 2022-04-12
+ */
+
+#ifndef ROTARY_ENCODER_DEF_H
+#define ROTARY_ENCODER_DEF_H
+
+#include "stdio.h"
+#include "soc_errno.h"
+#include "osal_ioctl.h"
+#include "input_manager.h"
+#include "debug_print.h"
+#if defined(SUPPORT_POWER_MANAGER)
+#include "power_display_service.h"
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+#define RE_DEBUG
+
+#define INPUT_TOUCH_MODULE_ID 0x61
+#define CMD_GET_TOUCH_INFO 0
+#define ROTARY_ENCODER_GET_EVENT _IOWR(INPUT_TOUCH_MODULE_ID, CMD_GET_TOUCH_INFO, re_input_event_info)
+
+/* common definitions */
+#define re_mem_free(sz) \
+ do { \
+ if ((sz) != NULL) { \
+ osal_kfree((sz)); \
+ } \
+ (sz) = NULL; \
+ } while (0)
+
+#ifdef RE_DEBUG
+#define re_print(fmt, ...) \
+ do { \
+ PRINT(fmt"\r\n", ##__VA_ARGS__); \
+ } while (0)
+#else
+#define re_print(ftm, ...)
+#endif
+
+#define re_err(x, ...) \
+ do { \
+ PRINT("[ERROR]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+
+#define re_warning(x, ...) \
+ do { \
+ PRINT("[WARNING]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+
+
+
+typedef enum {
+ MC_RE_PRESS = 0,
+ MC_RE_RELEASE = 1,
+ MC_RE_MOVE = 2,
+ MC_RE_COVER = 3,
+ MC_RE_SHORT_CLICK = 4,
+ MC_RE_DOUBLE_CLICK = 5,
+ MC_RE_SLIDE_UP = 6,
+ MC_RE_SLIDE_DOWN = 7,
+ MC_RE_INVALID,
+} re_event_type;
+
+typedef struct {
+ uint32_t x_axis[1];
+ uint32_t y_axis[1];
+ uint32_t z_axis[1];
+} re_dev_info;
+
+typedef struct {
+ re_dev_info re_event_info;
+ re_event_type re_event;
+ uint32_t finger_id;
+ uint32_t point_num;
+ uint32_t tv_usec;
+} re_input_event_info;
+
+typedef void (*encoder_callback)(void);
+
+typedef struct {
+ ext_errno (*encoder_init)(void *attr);
+ ext_errno (*encoder_deinit)(void);
+ ext_errno (*encoder_get_encoderinfo)(uint8_t *data, uint8_t data_len);
+ ext_errno (*encoder_suspend)(void);
+ ext_errno (*encoder_resume)(void);
+ ext_errno (*encoder_sleep)(void);
+ ext_errno (*encoder_reset)(void);
+ ext_errno (*encoder_bus_init)(void *private_data);
+ ext_errno (*register_callback)(void *peri_data, encoder_callback func);
+ ext_errno (*unregister_callback)(void *peri_data);
+} encoder_peripheral_api;
+
+uint32_t re_register_report_event_cb(report_event_cb callback);
+uint32_t re_unregister_report_event_cb(void);
+uint32_t re_init(void);
+uint32_t re_close(void);
+uint32_t re_read(const input_dev_data_t* data);
+void rotary_encoder_suspend(void);
+void rotary_encoder_resume(void);
+void rotary_encoder_restart(void);
+void encoder_suspend_for_i2c(void);
+void encoder_resume_for_i2c(void);
+#if defined(SUPPORT_POWER_MANAGER)
+uint32_t re_register_power_manager_cb(event_callback_func callback);
+#endif
+
+#ifdef __cplusplus
+#if __cplusplus
+ }
+#endif
+#endif
+
+#endif
--- /dev/null
+/*
+ * Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: rotary encoder driver.
+ * Author: @CompanyNameTag
+ * Create: 2022-04-12
+ */
+
+#include "rotary_encoder_drv.h"
+#include "tcxo.h"
+#include "i2c.h"
+#include "common_def.h"
+#include "soc_osal.h"
+#include "rotary_encoder_def.h"
+#include "input_app.h"
+#if defined(TPTYPE_TMA525B)
+#include "tma525b_drv1.h"
+#include "tma525b_ctrl.h"
+#elif defined(TPTYPE_ZTW523)
+#include "ztw523_drv1.h"
+#include "ztw523_ctrl.h"
+#elif defined(TPTYPE_FT6X46)
+#include "ft6x46_drv1.h"
+#include "ft6x46_ctrl.h"
+#else
+#include "ztw523_drv1.h"
+#include "ztw523_ctrl.h"
+#endif
+
+#define ROTARY_ENCODER_DEV_NAME_LEN 16
+#define ROTARY_ENCODER_DEVNAME "input/event"
+#define ROTARY_ENCODER_DYNAMIC_MINOR 65
+#define ROTARY_ENCODER_CMDID_MAX 16
+
+#define ROTARY_ENCODER_TASK_PRIO 5
+#define ROTARY_ENCODER_TASK_SIZE 0x800
+#define ROTARY_ENCODER_QUEUE_MAX_SIZE 60
+#define ROTARY_ENCODER_READY_EVENT (1 << 0)
+
+struct re_driver_data g_encoder_drv = {0};
+struct re_driver_data *g_attr_re = NULL;
+
+report_event_cb g_re_report_event_cb = NULL;
+
+#if defined(SUPPORT_POWER_MANAGER)
+event_callback_func g_power_manager_re_cb = NULL;
+#endif
+
+static struct re_driver_data *rotary_encoder_get_driver_data(void)
+{
+ return &g_encoder_drv;
+}
+
+static uint32_t rotary_encoder_get_state(struct re_driver_data *redd)
+{
+ if (redd != NULL && redd->queue != NULL) {
+ return (uint32_t)re_queue_is_empty(redd->queue);
+ }
+
+ if (redd == NULL) {
+ re_err("redd is null!");
+ return EXT_ERR_FAILURE;
+ }
+ if (redd->queue == NULL) {
+ re_err("redd queue is null!");
+ }
+
+ return EXT_ERR_FAILURE;
+}
+
+static void convert_encoder_info(input_dev_data_t* data, re_input_event_info* encoder_info)
+{
+ data->x = (int16_t)encoder_info->re_event_info.x_axis[0];
+ data->y = (int16_t)encoder_info->re_event_info.y_axis[0];
+ data->type = INDEV_TYPE_TOUCH;
+ data->timestamp = (uint32_t)encoder_info->tv_usec;
+ if ((encoder_info->re_event == MC_RE_PRESS) || (encoder_info->re_event == MC_RE_MOVE)) {
+ data->state = INDEV_STATE_PRESS;
+ } else if (encoder_info->re_event == MC_RE_RELEASE) {
+ data->state = INDEV_STATE_RELEASE;
+ } else {
+ data->state = INDEV_STATE_UNKNOWN;
+ }
+}
+
+static void report_or_enqueue_event(re_input_event_info* encoder_info, struct re_driver_data *redd)
+{
+ if (g_re_report_event_cb != NULL) {
+ input_dev_data_t data;
+ convert_encoder_info(&data, encoder_info);
+ if (data.state == INDEV_STATE_UNKNOWN) {
+ return;
+ }
+ g_re_report_event_cb(&data);
+ } else {
+ int32_t ret = re_en_queue(redd->queue, encoder_info);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("Failed to enqueue ts queue! ret=0x%x", ret);
+ }
+ }
+}
+#if defined(SUPPORT_POWER_MANAGER)
+static void report_event_to_power_manager(re_input_event_info *encoder_info)
+{
+ if (g_power_manager_re_cb != NULL) {
+ input_dev_data_t data;
+ convert_encoder_info(&data, encoder_info);
+ if (data.state == INDEV_STATE_UNKNOWN) {
+ return;
+ }
+ g_power_manager_re_cb(data.state, 0);
+ }
+ return;
+}
+
+uint32_t re_register_power_manager_cb(event_callback_func callback)
+{
+ if (g_power_manager_re_cb != NULL) {
+ return EXT_ERR_FAILURE;
+ }
+ g_power_manager_re_cb = callback;
+ return EXT_ERR_SUCCESS;
+}
+#endif
+ext_errno encoder_info_process(void)
+{
+ struct re_driver_data *redd = rotary_encoder_get_driver_data();
+ re_input_event_info encoder_info;
+ int32_t ret = 0;
+
+ if (redd->encoder_api->encoder_get_encoderinfo != NULL) {
+ ret = redd->encoder_api->encoder_get_encoderinfo((uint8_t *)(&encoder_info), sizeof(re_input_event_info));
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("get encoder info fail! ret=0x%x", ret);
+ }
+
+ report_or_enqueue_event(&encoder_info, redd);
+#if defined(SUPPORT_POWER_MANAGER)
+ report_event_to_power_manager(&encoder_info);
+#endif
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+static void re_callback_func(void)
+{
+ ext_errno ret;
+ if (g_attr_re != NULL) {
+ common_notify_mail_t mail = {0};
+ mail.comm.app = APP_ENCODER;
+ ret = osal_msg_queue_write_copy(get_app_queue_id(), (void *)&mail,
+ sizeof(common_notify_mail_t), 0);
+ if (ret != OSAL_SUCCESS) {
+ re_err("encoder app msg send failed! err=0x%x! \r\n", ret);
+ }
+ }
+}
+
+static ext_errno re_register_callback(struct re_driver_data *attr)
+{
+ ext_errno ret = EXT_ERR_FAILURE;
+ g_attr_re = attr;
+
+ if (attr->encoder_api->register_callback != NULL) {
+ ret = attr->encoder_api->register_callback(attr->private_data, re_callback_func);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("register rotary encoder callback fail! ret=0x%x", ret);
+ return ret;
+ }
+ } else {
+ re_err("rotary encoder callback register func is empty!");
+ }
+
+ return ret;
+}
+
+static ext_errno re_unregister_callback(struct re_driver_data *attr)
+{
+ ext_errno ret = EXT_ERR_FAILURE;
+
+ if (attr->encoder_api->unregister_callback != NULL) {
+ ret = attr->encoder_api->unregister_callback(attr->private_data);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("unregister rotary encoder callback fail! ret=0x%x", ret);
+ return ret;
+ }
+ g_attr_re = NULL;
+ } else {
+ re_err("rotary encoder callback unregister func is empty!");
+ }
+
+ return ret;
+}
+
+static int32_t re_dev_open(const void *private_data)
+{
+ int32_t ret;
+ struct re_driver_data *redd = NULL;
+ if (private_data == NULL) {
+ re_err("re_open: invalid dev or driver_data!\n");
+ return EXT_ERR_FAILURE;
+ }
+
+ // todo: get redd from private_data
+ redd = rotary_encoder_get_driver_data();
+ redd->queue = re_init_queue(ROTARY_ENCODER_QUEUE_MAX_SIZE);
+ if (redd->queue == NULL) {
+ re_err("create rotary encoder queue fail!\r\n");
+ return EXT_ERR_FAILURE;
+ }
+ ret = osal_event_init(&(redd->event));
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("encoder osal_event_init fail! ret=0x%x\r\n", ret);
+ return ret;
+ }
+
+ redd->task_handle = osal_kthread_create((osal_kthread_handler)encoder_info_process,
+ (void *)rotary_encoder_get_driver_data(),
+ "rotary_encoder", ROTARY_ENCODER_TASK_SIZE);
+ if (redd->task_handle == NULL) {
+ re_err("create rotary encoder thread fail!\r\n");
+ return EXT_ERR_FAILURE;
+ }
+ osal_kthread_set_priority(redd->task_handle, ROTARY_ENCODER_TASK_PRIO);
+
+ if (redd->encoder_api->encoder_init != NULL) {
+ ret = redd->encoder_api->encoder_init(redd->private_data);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("encoder_init fail! ret=0x%x\r\n", ret);
+ return ret;
+ }
+ }
+
+ ret = re_register_callback(redd);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("register callback fail! ret=0x%x\r\n", ret);
+ return ret;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+static int32_t re_dev_release(const void *private_data)
+{
+ int32_t ret;
+ struct re_driver_data *redd = NULL;
+ if (private_data == NULL) {
+ re_err("re_dev_release: invalid dev or driver_data!\n");
+ return EXT_ERR_FAILURE;
+ }
+
+ // todo: get redd from private_data
+ redd = rotary_encoder_get_driver_data();
+ ret = re_unregister_callback(redd);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("unregister callback fail! ret=0x%x\r\n", ret);
+ return ret;
+ }
+ return EXT_ERR_SUCCESS;
+}
+
+static uint32_t re_dev_poll(const osal_poll *osal_poll, const void *private_data)
+{
+ unused(osal_poll);
+ unused(private_data);
+ // todo: get redd from private_data
+ struct re_driver_data *redd = NULL;
+ redd = rotary_encoder_get_driver_data();
+ if (redd == NULL) {
+ re_err("re_driver_data is NULL");
+ return EXT_ERR_FAILURE;
+ }
+
+ if (redd->ops->priv_operator != NULL && redd->ops->priv_operator(redd) == 0) {
+ return OSAL_POLLIN | OSAL_POLLRDNORM;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+static int32_t re_ioctl_read_encoder_info(uint32_t cmd, void *arg, const void *private_data)
+{
+ unused(cmd);
+ ext_errno ret;
+ struct re_driver_data *redd = NULL;
+ re_input_event_info *encoder_info = (re_input_event_info *)arg;
+
+ if (private_data == NULL) {
+ re_err("invalid dev or driver_data!");
+ return EXT_ERR_FAILURE;
+ }
+
+ // todo: get redd from private_data
+ redd = rotary_encoder_get_driver_data();
+ if (redd->queue == NULL) {
+ re_err("invalid rotary encoder queue!");
+ return EXT_ERR_FAILURE;
+ }
+
+ ret = re_de_queue(redd->queue, encoder_info);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("get encoder info fail! ret=0x%x", ret);
+ return ret;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+static osal_ioctl_cmd g_re_cmd_list[ROTARY_ENCODER_CMDID_MAX] = {
+ {ROTARY_ENCODER_GET_EVENT, re_ioctl_read_encoder_info},
+};
+
+static osal_dev *g_re_dev = NULL;
+static osal_fileops g_re_ops = {
+ .open = re_dev_open,
+ .release = re_dev_release,
+ .poll = re_dev_poll,
+ .cmd_list = g_re_cmd_list,
+ .cmd_cnt = sizeof(g_re_cmd_list) / sizeof(g_re_cmd_list[0]),
+};
+
+struct re_ops g_re_status_ops = {
+ .priv_operator = rotary_encoder_get_state,
+};
+
+static ext_errno rotary_encoder_register_device(void)
+{
+ ext_errno ret;
+
+ g_encoder_drv.private_data = rotary_encoder_get_peri_attr();
+ g_encoder_drv.encoder_api = rotary_encoder_get_api();
+ g_encoder_drv.ops = &g_re_status_ops;
+ g_re_dev = osal_dev_create(ROTARY_ENCODER_DEVNAME);
+ g_re_dev->minor = ROTARY_ENCODER_DYNAMIC_MINOR;
+ g_re_dev->fops = &g_re_ops;
+
+ ret = osal_dev_register(g_re_dev);
+ if (ret != 0) {
+ re_err("rotary encoder osal_dev_register --------failed! ret=0x%x\n", ret);
+ return EXT_ERR_FAILURE;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+ext_errno rotary_encoder_module_init(void)
+{
+ ext_errno ret;
+
+ ret = rotary_encoder_register_device();
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("rotary_encoder_register_device ----------failed! ret=0x%x\n", ret);
+ }
+ re_err("rotary_encoder_register_device ----------succ!!!\n");
+
+ return EXT_ERR_SUCCESS;
+}
+
+ext_errno rotary_encoder_module_deinit(void)
+{
+ return EXT_ERR_SUCCESS;
+}
+
+uint32_t re_register_report_event_cb(report_event_cb callback)
+{
+ if (g_re_report_event_cb != NULL) {
+ return EXT_ERR_FAILURE;
+ }
+ g_re_report_event_cb = callback;
+ return EXT_ERR_SUCCESS;
+}
+
+uint32_t re_unregister_report_event_cb(void)
+{
+ g_re_report_event_cb = NULL;
+ return EXT_ERR_SUCCESS;
+}
+
+uint32_t re_init(void)
+{
+ int32_t ret;
+ struct re_driver_data *redd = NULL;
+
+ g_encoder_drv.private_data = rotary_encoder_get_peri_attr();
+ g_encoder_drv.encoder_api = rotary_encoder_get_api();
+ g_encoder_drv.ops = &g_re_status_ops;
+ redd = rotary_encoder_get_driver_data();
+ redd->queue = re_init_queue(ROTARY_ENCODER_QUEUE_MAX_SIZE);
+ if (redd->queue == NULL) {
+ re_err("create rotary encoder queue fail!\r\n");
+ return EXT_ERR_FAILURE;
+ }
+
+ ret = re_register_callback(redd);
+ if (ret != EXT_ERR_SUCCESS) {
+ re_err("register callback fail! ret=0x%x\r\n", ret);
+ return EXT_ERR_FAILURE;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+uint32_t re_read(const input_dev_data_t* data)
+{
+ unused(data);
+ return EXT_ERR_SUCCESS;
+}
+
+uint32_t re_close(void)
+{
+ return EXT_ERR_SUCCESS;
+}
+
+void rotary_encoder_suspend(void)
+{
+
+ /**灭屏,关闭Encoder*/
+ encoder_peripheral_api *encoder_ptr = rotary_encoder_get_api();
+ ext_errno ret = encoder_ptr->encoder_sleep();
+ if (ret != EXT_ERR_SUCCESS) { re_err("encoder sleep ret=0x%x", ret); }
+
+}
+
+void rotary_encoder_resume(void)
+{
+ /**亮屏,恢复Encoder工作*/
+ encoder_peripheral_api *encoder_ptr = (encoder_peripheral_api*)rotary_encoder_get_api();
+ ext_errno ret = encoder_ptr->encoder_resume();
+ if (ret != EXT_ERR_SUCCESS) { re_err("encoder resume ret=0x%x", ret); }
+}
+
+void encoder_suspend_for_i2c(void)
+{
+ // i2c_save_reg(TOUCH_I2C_BUS);
+}
+
+void encoder_resume_for_i2c(void)
+{
+ // i2c_recovery_reg(TOUCH_I2C_BUS);
+}
+
+void rotary_encoder_restart(void)
+{
+ // uapi_i2c_deinit(TOUCH_I2C_BUS);
+ // uapi_i2c_master_init(TOUCH_I2C_BUS, 400000, I2C_SPEED_MODE_FS); /* 400000: 400KHz */
+
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) @CompanyNameMagicTag 2021-2022. All rights reserved.
+ * Description: header of touch screen driver.
+ * Author: @CompanyNameTag
+ * Create: 2022-04-12
+ */
+
+#ifndef ROTARY_ENCODER_DRV_H
+#define ROTARY_ENCODER_DRV_H
+
+#include "soc_osal.h"
+#include "rotary_encoder_queue1.h"
+
+struct re_driver_data {
+ osal_task *task_handle;
+ osal_event event;
+ re_queue_t *queue;
+ osal_wait wait;
+ struct re_ops *ops;
+ encoder_peripheral_api *encoder_api;
+ void *private_data;
+};
+
+struct re_ops {
+ /* private operation */
+ uint32_t (*priv_operator)(struct re_driver_data *udd);
+};
+
+ext_errno rotary_encoder_module_init(void);
+ext_errno rotary_encoder_module_deinit(void);
+ext_errno encoder_info_process(void);
+
+#endif
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: touch screen msg queue.
+ * Author: @CompanyNameTag
+ * Create: 2022-04-18
+ */
+
+#include "rotary_encoder_queue1.h"
+#include "securec.h"
+#include "soc_osal.h"
+#include "debug_print.h"
+
+#define re_queue_err(x, ...) \
+ do { \
+ PRINT("[ERROR]%s(%d): "x"\r\n", __FUNCTION__, __LINE__, ##__VA_ARGS__); \
+ } while (0)
+
+osal_mutex g_re_mutex;
+
+static ext_errno re_lock_init(void)
+{
+ ext_errno ret;
+ ret = osal_mutex_init(&(g_re_mutex));
+ if (ret != EXT_ERR_SUCCESS) {
+ g_re_mutex.mutex = NULL;
+ return ret;
+ }
+
+ return EXT_ERR_SUCCESS;
+}
+
+static void re_lock_deinit(void)
+{
+ osal_mutex_destroy(&(g_re_mutex));
+}
+
+static void re_lock(void)
+{
+ osal_mutex_lock(&(g_re_mutex));
+}
+
+static void re_unlock(void)
+{
+ osal_mutex_unlock(&(g_re_mutex));
+}
+
+re_queue_t *re_init_queue(uint32_t capacity)
+{
+ ext_errno ret;
+ re_queue_t *q = (re_queue_t *)osal_kmalloc(sizeof(re_queue_t), OSAL_GFP_KERNEL);
+ if (q == NULL) {
+ return NULL;
+ }
+ q->cap = capacity;
+ q->cnt = 0;
+ q->head = q->tail = NULL;
+
+ ret = re_lock_init();
+ if (ret != EXT_ERR_SUCCESS) {
+ re_mem_free(q);
+ }
+
+ return q;
+}
+
+int32_t re_queue_get_length(re_queue_t *q)
+{
+ return (int32_t)q->cnt;
+}
+
+int32_t re_queue_is_empty(const re_queue_t *q)
+{
+ return (q->cnt == 0);
+}
+
+int32_t re_queue_is_full(const re_queue_t *q)
+{
+ return (q->cnt == q->cap);
+}
+
+int32_t re_de_queue(re_queue_t *q, re_input_event_info *msg)
+{
+ if (q == NULL || q->head == NULL || msg == NULL || re_queue_is_empty(q) != 0) {
+ return -1;
+ }
+
+ re_lock();
+ struct re_list *node = q->head;
+ errno_t ret = memcpy_s(msg, sizeof(re_input_event_info), node->msg, sizeof(re_input_event_info));
+ if (ret != EOK) {
+ PRINT("de queue memcpy_s fail\r\n");
+ }
+ q->head = q->head->next;
+ q->cnt--;
+
+ re_mem_free(node->msg);
+ re_mem_free(node);
+ if (q->cnt == 0) {
+ q->tail = NULL;
+ }
+ re_unlock();
+
+ return 0;
+}
+
+int32_t re_en_queue(re_queue_t *q, re_input_event_info *msg)
+{
+ if (q == NULL || msg == NULL) {
+ return -1;
+ }
+ if (re_queue_is_full(q) != 0) {
+ re_input_event_info tmp_msg = {0};
+ re_de_queue(q, &tmp_msg);
+ }
+
+ struct re_list *node = osal_kmalloc(sizeof(struct re_list), OSAL_GFP_KERNEL);
+ if (node == NULL) {
+ return -1;
+ }
+ node->msg = (re_input_event_info *)osal_kmalloc(sizeof(re_input_event_info), OSAL_GFP_KERNEL);
+ if (node->msg == NULL) {
+ re_mem_free(node);
+ return -1;
+ }
+
+ errno_t ret = memcpy_s(node->msg, sizeof(re_input_event_info), msg, sizeof(re_input_event_info));
+ if (ret != EOK) {
+ PRINT("en queue memcpy_s fail\r\n");
+ }
+ node->next = NULL;
+
+ re_lock();
+ if (re_queue_is_empty(q) != 0) {
+ q->head = node;
+ } else {
+ q->tail->next = node;
+ }
+ q->tail = node;
+ q->cnt++;
+ re_unlock();
+
+ return 0;
+}
+
+void re_clear_queue(re_queue_t *q)
+{
+ re_lock();
+ if (q == NULL) {
+ re_unlock();
+ return;
+ }
+ struct re_list *curr = q->head;
+ struct re_list *next = curr->next;
+
+ while (curr != NULL) {
+ re_mem_free(curr->msg);
+ re_mem_free(curr);
+ curr = next;
+ if (next != NULL) {
+ next = next->next;
+ }
+ }
+ q->cnt = 0;
+ re_unlock();
+}
+
+void re_delete_queue(re_queue_t *q)
+{
+ re_lock();
+ if (q == NULL) {
+ re_unlock();
+ return;
+ }
+ struct re_list *curr = q->head;
+ struct re_list *next = curr->next;
+
+ while (curr != NULL) {
+ re_mem_free(curr->msg);
+ re_mem_free(curr);
+ curr = next;
+ if (next != NULL) {
+ next = next->next;
+ }
+ }
+ q->cnt = 0;
+ re_mem_free(q);
+
+ re_unlock();
+ re_lock_deinit();
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) @CompanyNameMagicTag 2021-2021. All rights reserved.
+ * Description: touch screen msg queue.
+ * Author: @CompanyNameTag
+ * Create: 2022-04-18
+ */
+
+#ifndef ROTARY_ENCODER_QUEUE1_H
+#define ROTARY_ENCODER_QUEUE1_H
+
+#include "soc_osal.h"
+#include "rotary_encoder_def.h"
+
+#ifdef __cplusplus
+#if __cplusplus
+extern "C" {
+#endif
+#endif
+
+#define re_mem_free(sz) \
+ do { \
+ if ((sz) != NULL) { \
+ osal_kfree((sz)); \
+ } \
+ (sz) = NULL; \
+ } while (0)
+
+struct re_list {
+ re_input_event_info *msg;
+ struct re_list *next;
+};
+
+typedef struct {
+ struct re_list *head;
+ struct re_list *tail;
+ uint32_t cnt;
+ uint32_t cap;
+} re_queue_t;
+
+re_queue_t *re_init_queue(uint32_t capacity);
+int32_t re_queue_get_length(re_queue_t *q);
+int32_t re_queue_is_empty(const re_queue_t *q);
+int32_t re_queue_is_full(const re_queue_t *q);
+int32_t re_de_queue(re_queue_t *q, re_input_event_info *msg);
+int32_t re_en_queue(re_queue_t *q, re_input_event_info *msg);
+void re_clear_queue(re_queue_t *q);
+void re_delete_queue(re_queue_t *q);
+
+#ifdef __cplusplus
+#if __cplusplus
+ }
+#endif
+#endif
+
+#endif
\ No newline at end of file
data.receive_len = data_len;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_writeread(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_writeread(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = data_len;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_writeread(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_writeread(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = 0;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_write(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_write(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = 0;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_write(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_write(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = 0;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_write(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_write(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = 0;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_write(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_write(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
data.receive_len = 0;
for (retry = 0; retry < ZTW523_I2C_TIME_MAX; retry++) {
- ret = uapi_i2c_master_write(FT6X46_I2C_BUS, ZTW523_I2C_ADDR, &data);
+ ret = uapi_i2c_master_write(FT6X46_I2C_BUS, FT6X46_I2C_ADDR, &data);
if (ret == EXT_ERR_SUCCESS) {
break;
}
}
tp_print("TOUCH:i2c_id = %d i2c_speed = %d slave_addr = 0x%x \r\n",
- g_ctrl_attr.i2c_id, g_ctrl_attr.i2c_speed, ZTW523_I2C_ADDR);
+ g_ctrl_attr.i2c_id, g_ctrl_attr.i2c_speed, FT6X46_I2C_ADDR);
g_host_dev_init_flag = true;
return EXT_ERR_SUCCESS;
#include "ft6x46_touch1.h"
/* host peripheral definitions */
-#if CHIP_ASIC
-#define FT6X46_I2C_BUS I2C_BUS_1
-#define FT6X46_INT_GPIO S_AGPIO_R5
-#define ZTW523_RESET_GPIO S_AGPIO_R4
-#else
-#define FT6X46_I2C_BUS I2C_BUS_5
-#define FT6X46_INT_GPIO S_MGPIO11
-#define ZTW523_RST_REG 0x5600201c
-#define ZTW523_RST_HIGH 3
-#define ZTW523_RST_LOW 0
-#endif
-#define ZTW523_I2C_ADDR 0x20
+// #define ZTW523_I2C_ADDR 0x20
#define FT6X46_I2C_ADDR 0x38
#define ZTW523_I2C_SPEED I2C_SPEED_MODE_SS
#define ZTW523_REG_BYTE_LEN 2
#define CMD_GET_TOUCH_INFO 0
#define TOUCH_SCREEN_GET_EVENT _IOWR(INPUT_TOUCH_MODULE_ID, CMD_GET_TOUCH_INFO, input_event_info)
+#define TP_DEBUG
+
/* common definitions */
#define tp_mem_free(sz) \
do { \
if (ret != EXT_ERR_SUCCESS) { tp_err("touch resume ret=0x%x", ret); }
#elif defined(TPTYPE_ZTW523)
ztw523_resume();
+#elif defined(TPTYPE_FT6X46)
+ ztw523_resume();
+ // ft6x46_resume();
#else
ztw523_resume();
#endif
tma525b_resume();
#elif defined(TPTYPE_ZTW523)
ztw523_resume();
+#elif defined(TPTYPE_FT6X46)
+ // ft6x46_resume();
+ ztw523_resume();
#else
ztw523_resume();
#endif
return INPUT_FAILURE;
}
+
+__attribute__((weak)) uint32_t encoder_register_report_event_cb(report_event_cb callback)
+{
+ (void)(callback);
+ return INPUT_FAILURE;
+}
+__attribute__((weak)) uint32_t encoder_unregister_report_event_cb(void)
+{
+ return INPUT_FAILURE;
+}
+__attribute__((weak)) uint32_t encoder_init(void)
+{
+ return INPUT_FAILURE;
+}
+__attribute__((weak)) uint32_t encoder_close(void)
+{
+ return INPUT_FAILURE;
+}
+
static void InitInputDevices(void)
{
for (uint8_t i = 0; i < INDEV_TYPE_UNKNOWN; i++) {
g_inputDevs[i].initState = INDEV_UNINITIALIZED;
}
+ /* Init Encoder Device */
+ g_inputDevs[INDEV_TYPE_ENCODER].type = INDEV_TYPE_ENCODER;
+ g_inputDevs[INDEV_TYPE_ENCODER].funcs.Init = encoder_init;
+ g_inputDevs[INDEV_TYPE_ENCODER].funcs.Close = encoder_close;
+ g_inputDevs[INDEV_TYPE_ENCODER].funcs.RegisterReportEventCb = encoder_register_report_event_cb;
+ g_inputDevs[INDEV_TYPE_ENCODER].funcs.UnregisterReportEventCb = encoder_unregister_report_event_cb;
+
/* Init Touch Device */
g_inputDevs[INDEV_TYPE_TOUCH].type = INDEV_TYPE_TOUCH;
g_inputDevs[INDEV_TYPE_TOUCH].funcs.Init = ts_init;
--- /dev/null
+/*
+ * Copyright (c) 2022 CompanyNameMagicTag.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "lite_encoder_device.h"
+#include "gfx_utils/input_event_info.h"
+#include "lite_input_distributer.h"
+
+namespace OHOS {
+bool LiteEncoderDevice::Read(DeviceData& data)
+{
+ (void)LiteInputDistributer::GetInstance()->GetEventData(data, InputDevType::INDEV_TYPE_ENCODER);
+ return false;
+}
+
+bool LiteEncoderDevice::IsEventEmpty()
+{
+ return LiteInputDistributer::GetInstance()->IsEventEmpty(InputDevType::INDEV_TYPE_ENCODER);
+}
+}
--- /dev/null
+/*
+ * Copyright (c) 2022 CompanyNameMagicTag.
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef GRAPHIC_LITE_LITE_ENCODER_DEVICE_H
+#define GRAPHIC_LITE_LITE_ENCODER_DEVICE_H
+#include "dock/pointer_input_device.h"
+
+namespace OHOS {
+class LiteEncoderDevice : public PointerInputDevice {
+public:
+ LiteEncoderDevice() {}
+ ~LiteEncoderDevice() override {}
+ bool Read(DeviceData& data) override;
+ bool IsEventEmpty() override;
+};
+}
+#endif
#endif
namespace OHOS {
static DeviceData g_lastData = {0};
+static DeviceData g_lastEncoderData = {0};
LiteInputDistributer::LiteInputDistributer()
- : deviceData_({}) {}
+ : deviceData_({}),encoderData_({}) {}
LiteInputDistributer::~LiteInputDistributer() {}
{
RawEvent event = rawEvent;
DisplayDev* displayDev = DisplayDev::GetInstance();
- if ((event.type == InputDevType::INDEV_TYPE_TOUCH) &&
+ if ((event.type == InputDevType::INDEV_TYPE_TOUCH
+ // || event.type == InputDevType::INDEV_TYPE_ENCODER
+ ) &&
(displayDev->GetLayerRotateType(LAYER_0) == LayerRotateType::LAYER_ROTATE_90)) {
LayerBuffer* buffer = displayDev->GetCurrentBuffer(LAYER_0);
if (buffer == nullptr) {
void LiteInputDistributer::GetEventData(DeviceData& data, InputDevType type)
{
eventLock_.Lock();
+
+ if (type == InputDevType::INDEV_TYPE_ENCODER) {
+ g_lastEncoderData = encoderData_;
+ if (IsShowPoint() && (encoderData_.timestamp != g_lastEncoderData.timestamp)) {
+ DfxTPGetEvent();
+ }
+ data.point.x = encoderData_.point.x;
+ data.point.y = encoderData_.point.y;
+ data.encoderDiff = encoderData_.encoderDiff;
+ data.state = encoderData_.state;
+ data.timestamp = encoderData_.timestamp;
+ eventLock_.Unlock();
+ return;
+ }
if (type == InputDevType::INDEV_TYPE_TOUCH) {
g_lastData = deviceData_;
if (IsShowPoint() && (deviceData_.timestamp != g_lastData.timestamp)) {
{
LowPowerManager::GetInstance()->ExitLowPower();
eventLock_.Lock();
+ if (event.type == InputDevType::INDEV_TYPE_ENCODER) {
+ if (IsShowPoint()) {
+ DfxTPSetEvent(event.timestamp - encoderData_.timestamp);
+ }
+ encoderData_.encoderDiff = event.x;
+ encoderData_.point.x = event.x;
+ encoderData_.point.y = event.y;
+ encoderData_.state = event.state;
+ encoderData_.timestamp = event.timestamp;
+ eventLock_.Unlock();
+ return;
+ }
if (event.type == InputDevType::INDEV_TYPE_TOUCH) {
if (IsShowPoint()) {
DfxTPSetEvent(event.timestamp - deviceData_.timestamp);
return ((g_lastData.state == 0) && (deviceData_.state == 0));
} else if (type == InputDevType::INDEV_TYPE_KEY) {
return keyList_.IsEmpty();
+ } else if (type == InputDevType::INDEV_TYPE_ENCODER){
+ // return ((g_lastEncoderData.state == 0) && (encoderData_.state == 0));
}
return true;
}
#include "hals/lite_input_distributer.h"\r
#include "dock/lite_key_device.h"\r
#include "dock/lite_touch_device.h"\r
+#include "dock/lite_encoder_device.h"\r
#include "dfx/dfx_record.h"\r
\r
namespace OHOS {\r
event.state = data->state;\r
event.timestamp = data->timestamp;\r
event.type = InputDevType::INDEV_TYPE_TOUCH;\r
+ } else if (data->type == INDEV_TYPE_ENCODER) {\r
+ if (IsShowTPRaw()) {\r
+ GRAPHIC_LOGP("Encoder s: %u, x: %d, y: %d, diff: %d, t: %u", data->state, data->x, data->y,data->encoderDiff,\r
+ data->timestamp);\r
+ }\r
+ event.x = data->encoderDiff;\r
+ event.y = data->encoderDiff;\r
+ event.state = data->state;\r
+ event.timestamp = data->timestamp;\r
+ event.type = InputDevType::INDEV_TYPE_ENCODER;\r
} else if (data->type == INDEV_TYPE_KEY) {\r
if (!ConvertKeyId(data->keyId, &event.keyId)) {\r
return;\r
void LiteInputHal::AddToIndevManager(uint8_t type)\r
{\r
InputDevice* dev = nullptr;\r
- if (type == static_cast<uint8_t>(INDEV_TYPE_TOUCH)) {\r
+ if (type == static_cast<uint8_t>(INDEV_TYPE_ENCODER)) {\r
+ dev = new LiteEncoderDevice();\r
+ } else if (type == static_cast<uint8_t>(INDEV_TYPE_TOUCH)) {\r
dev = new LiteTouchDevice();\r
} else if (type == static_cast<uint8_t>(INDEV_TYPE_KEY)) {\r
dev = new LiteKeyDevice();\r
GraphicMutex eventLock_;
DeviceData deviceData_;
+ DeviceData encoderData_;
List<DeviceData*> keyList_;
};
}