From d466290d93a36104f21da47089be34010a1fee42 Mon Sep 17 00:00:00 2001 From: SnickerSun Date: Sat, 17 Feb 2024 12:10:31 +0800 Subject: [PATCH] =?utf8?q?=E6=B7=BB=E5=8A=A0=E8=A1=A8=E5=86=A0=EF=BC=88Enc?= =?utf8?q?oder=EF=BC=89=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- .../brandy/brandy_recovery/input_app.h | 1 + .../brandy/brandy_standard/input_app.h | 1 + .../brandy/brandy_testsuite/input_app.h | 1 + .../src/actions/display_action.c | 3 + .../peripheral/rotary_encoder/CMakeLists.txt | 22 +- .../peripheral/rotary_encoder/hx3507/hx3507.c | 542 ++++++++++++++++++ .../peripheral/rotary_encoder/hx3507/hx3507.h | 91 +++ .../rotary_encoder/hx3507/hx3507_at_cmd.c | 92 +++ .../rotary_encoder/hx3507/hx3507_at_cmd.h | 32 ++ .../rotary_encoder/hx3507/hx3507_hal.c | 132 +++++ .../rotary_encoder/hx3507/hx3507_hal.h | 32 ++ .../rotary_encoder/rotary_encoder_def.h | 122 ++++ .../rotary_encoder/rotary_encoder_drv.c | 447 +++++++++++++++ .../rotary_encoder/rotary_encoder_drv.h | 33 ++ .../rotary_encoder/rotary_encoder_queue1.c | 190 ++++++ .../rotary_encoder/rotary_encoder_queue1.h | 55 ++ .../touch/ft6x46_touch/ft6x46_ctrl.c | 16 +- .../touch/ft6x46_touch/ft6x46_ctrl.h | 13 +- .../peripheral/touch/touch_screen_def.h | 2 + .../peripheral/touch/touch_screen_drv.c | 6 + .../gui/hal/input/src/input_manager.c | 26 + .../frameworks/dock/lite_encoder_device.cpp | 31 + .../ui/frameworks/dock/lite_encoder_device.h | 29 + .../hals/lite_input_distributer.cpp | 35 +- .../utils/frameworks/hals/lite_input_hal.cpp | 15 +- .../innerkits/hals/lite_input_distributer.h | 1 + 26 files changed, 1943 insertions(+), 27 deletions(-) create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.c create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.h create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.c create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.h create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.c create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.h create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_def.h create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.c create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.h create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.c create mode 100644 code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.h create mode 100644 code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.cpp create mode 100644 code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.h diff --git a/code/sdk/application/brandy/brandy_recovery/input_app.h b/code/sdk/application/brandy/brandy_recovery/input_app.h index 81bdeff95..918ec12f3 100755 --- a/code/sdk/application/brandy/brandy_recovery/input_app.h +++ b/code/sdk/application/brandy/brandy_recovery/input_app.h @@ -103,6 +103,7 @@ typedef enum { typedef enum { APP_BUTTON, APP_TOUCH, + APP_ENCODER, } app_type; typedef struct { diff --git a/code/sdk/application/brandy/brandy_standard/input_app.h b/code/sdk/application/brandy/brandy_standard/input_app.h index 81bdeff95..918ec12f3 100755 --- a/code/sdk/application/brandy/brandy_standard/input_app.h +++ b/code/sdk/application/brandy/brandy_standard/input_app.h @@ -103,6 +103,7 @@ typedef enum { typedef enum { APP_BUTTON, APP_TOUCH, + APP_ENCODER, } app_type; typedef struct { diff --git a/code/sdk/application/brandy/brandy_testsuite/input_app.h b/code/sdk/application/brandy/brandy_testsuite/input_app.h index 3def5b715..473eb65fe 100755 --- a/code/sdk/application/brandy/brandy_testsuite/input_app.h +++ b/code/sdk/application/brandy/brandy_testsuite/input_app.h @@ -98,6 +98,7 @@ typedef enum { typedef enum { APP_BUTTON, APP_TOUCH, + APP_ENCODER, } app_type; typedef struct { diff --git a/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c b/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c index 3a0ffcf23..746856f56 100755 --- a/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c +++ b/code/sdk/application/wearable/service/power_manager/src/actions/display_action.c @@ -28,6 +28,7 @@ #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 @@ -156,6 +157,7 @@ static uint32_t action_display_lcd_on() #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); @@ -191,6 +193,7 @@ static uint32_t action_display_lcd_off() #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); diff --git a/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt b/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt index 8a107beff..ff6488d05 100644 --- a/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt +++ b/code/sdk/drivers/peripheral/rotary_encoder/CMakeLists.txt @@ -6,23 +6,37 @@ set(COMPONENT_NAME "rotary_encoder") 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} ) diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.c b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.c new file mode 100644 index 000000000..74b128913 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.c @@ -0,0 +1,542 @@ +/** + * 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 +#include +#include +#include +#include +#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 + diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.h b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.h new file mode 100644 index 000000000..647601e28 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507.h @@ -0,0 +1,91 @@ +/** + * 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_ diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.c b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.c new file mode 100644 index 000000000..064256ed5 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.c @@ -0,0 +1,92 @@ + +// #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; +} diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.h b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.h new file mode 100644 index 000000000..cb7de8558 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_at_cmd.h @@ -0,0 +1,32 @@ +/** + * 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 +#include +#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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.c b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.c new file mode 100644 index 000000000..670426e1b --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.c @@ -0,0 +1,132 @@ + +// #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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.h b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.h new file mode 100644 index 000000000..74e26339a --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/hx3507/hx3507_hal.h @@ -0,0 +1,32 @@ +/** + * 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 +#include +#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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_def.h b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_def.h new file mode 100644 index 000000000..773755e76 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_def.h @@ -0,0 +1,122 @@ +/* + * 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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.c b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.c new file mode 100644 index 000000000..f90f2c595 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.c @@ -0,0 +1,447 @@ +/* + * 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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.h b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.h new file mode 100644 index 000000000..3a37a05fd --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_drv.h @@ -0,0 +1,33 @@ +/* + * 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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.c b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.c new file mode 100644 index 000000000..4dc729645 --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.c @@ -0,0 +1,190 @@ +/* + * 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 diff --git a/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.h b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.h new file mode 100644 index 000000000..e02ab04db --- /dev/null +++ b/code/sdk/drivers/peripheral/rotary_encoder/rotary_encoder_queue1.h @@ -0,0 +1,55 @@ +/* + * 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 diff --git a/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c index ae02556c9..da5596b71 100644 --- a/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c +++ b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.c @@ -118,7 +118,7 @@ ext_errno tp_i2c_data_read(uint16_t reg_addr, uint8_t *data_buf, uint32_t data_l 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; } @@ -154,7 +154,7 @@ ext_errno tp_i2c_data_read(uint8_t reg_addr, uint8_t *data_buf, uint32_t data_le 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; } @@ -227,7 +227,7 @@ ext_errno tp_i2c_cmd_write(uint16_t cmd) 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; } @@ -261,7 +261,7 @@ ext_errno tp_i2c_cmd_write(uint8_t cmd) 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; } @@ -300,7 +300,7 @@ ext_errno tp_i2c_reg_write(uint16_t reg_addr, uint16_t reg_cfg) 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; } @@ -350,7 +350,7 @@ ext_errno tp_i2c_data_write(uint16_t reg_addr, uint8_t *data_buf, uint32_t data_ 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; } @@ -399,7 +399,7 @@ ext_errno tp_i2c_data_write(uint8_t reg_addr, uint8_t *data_buf, uint16_t data_l 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; } @@ -498,7 +498,7 @@ ext_errno ztw523_host_peripheral_init(ztw523_ctrl_attr *attr) } 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; diff --git a/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h index 4a56285c5..5d994b8ba 100644 --- a/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h +++ b/code/sdk/drivers/peripheral/touch/ft6x46_touch/ft6x46_ctrl.h @@ -17,19 +17,8 @@ #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 diff --git a/code/sdk/drivers/peripheral/touch/touch_screen_def.h b/code/sdk/drivers/peripheral/touch/touch_screen_def.h index e59cbcd40..ad2d184f8 100644 --- a/code/sdk/drivers/peripheral/touch/touch_screen_def.h +++ b/code/sdk/drivers/peripheral/touch/touch_screen_def.h @@ -27,6 +27,8 @@ extern "C" { #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 { \ diff --git a/code/sdk/drivers/peripheral/touch/touch_screen_drv.c b/code/sdk/drivers/peripheral/touch/touch_screen_drv.c index f88f41d3a..a34945c1f 100644 --- a/code/sdk/drivers/peripheral/touch/touch_screen_drv.c +++ b/code/sdk/drivers/peripheral/touch/touch_screen_drv.c @@ -449,6 +449,9 @@ void touch_screen_resume(void) 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 @@ -473,6 +476,9 @@ void touch_screen_restart(void) tma525b_resume(); #elif defined(TPTYPE_ZTW523) ztw523_resume(); +#elif defined(TPTYPE_FT6X46) + // ft6x46_resume(); + ztw523_resume(); #else ztw523_resume(); #endif diff --git a/code/sdk/middleware/services/gui/hal/input/src/input_manager.c b/code/sdk/middleware/services/gui/hal/input/src/input_manager.c index 8e8e6f69c..a3bbc9474 100755 --- a/code/sdk/middleware/services/gui/hal/input/src/input_manager.c +++ b/code/sdk/middleware/services/gui/hal/input/src/input_manager.c @@ -60,6 +60,25 @@ __attribute__((weak)) uint32_t button_close(void) 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++) { @@ -67,6 +86,13 @@ static void InitInputDevices(void) 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; diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.cpp b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.cpp new file mode 100644 index 000000000..ce13d8004 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.cpp @@ -0,0 +1,31 @@ +/* + * 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); +} +} diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.h b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.h new file mode 100644 index 000000000..757583c52 --- /dev/null +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/ui/frameworks/dock/lite_encoder_device.h @@ -0,0 +1,29 @@ +/* + * 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 diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_distributer.cpp b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_distributer.cpp index 1bb58c9b6..70947dae0 100755 --- a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_distributer.cpp +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_distributer.cpp @@ -26,8 +26,9 @@ #endif namespace OHOS { static DeviceData g_lastData = {0}; +static DeviceData g_lastEncoderData = {0}; LiteInputDistributer::LiteInputDistributer() - : deviceData_({}) {} + : deviceData_({}),encoderData_({}) {} LiteInputDistributer::~LiteInputDistributer() {} @@ -35,7 +36,9 @@ void LiteInputDistributer::SendRawEvent(const RawEvent& rawEvent) { 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) { @@ -55,6 +58,20 @@ void LiteInputDistributer::SendRawEvent(const RawEvent& rawEvent) 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)) { @@ -89,6 +106,18 @@ void LiteInputDistributer::SetEventData(const RawEvent& event) { 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); @@ -122,6 +151,8 @@ bool LiteInputDistributer::IsEventEmpty(InputDevType type) 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; } diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_hal.cpp b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_hal.cpp index 62983fab8..99bcd70f1 100755 --- a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_hal.cpp +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/frameworks/hals/lite_input_hal.cpp @@ -20,6 +20,7 @@ #include "hals/lite_input_distributer.h" #include "dock/lite_key_device.h" #include "dock/lite_touch_device.h" +#include "dock/lite_encoder_device.h" #include "dfx/dfx_record.h" namespace OHOS { @@ -52,6 +53,16 @@ static void EventCallback(InputDevData* data) event.state = data->state; event.timestamp = data->timestamp; event.type = InputDevType::INDEV_TYPE_TOUCH; + } else if (data->type == INDEV_TYPE_ENCODER) { + if (IsShowTPRaw()) { + GRAPHIC_LOGP("Encoder s: %u, x: %d, y: %d, diff: %d, t: %u", data->state, data->x, data->y,data->encoderDiff, + data->timestamp); + } + event.x = data->encoderDiff; + event.y = data->encoderDiff; + event.state = data->state; + event.timestamp = data->timestamp; + event.type = InputDevType::INDEV_TYPE_ENCODER; } else if (data->type == INDEV_TYPE_KEY) { if (!ConvertKeyId(data->keyId, &event.keyId)) { return; @@ -68,7 +79,9 @@ static void EventCallback(InputDevData* data) void LiteInputHal::AddToIndevManager(uint8_t type) { InputDevice* dev = nullptr; - if (type == static_cast(INDEV_TYPE_TOUCH)) { + if (type == static_cast(INDEV_TYPE_ENCODER)) { + dev = new LiteEncoderDevice(); + } else if (type == static_cast(INDEV_TYPE_TOUCH)) { dev = new LiteTouchDevice(); } else if (type == static_cast(INDEV_TYPE_KEY)) { dev = new LiteKeyDevice(); diff --git a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/lite_input_distributer.h b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/lite_input_distributer.h index 6fe069f5d..85b488200 100755 --- a/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/lite_input_distributer.h +++ b/code/sdk/middleware/services/gui/uikit/proprietary/src/utils/innerkits/hals/lite_input_distributer.h @@ -46,6 +46,7 @@ private: GraphicMutex eventLock_; DeviceData deviceData_; + DeviceData encoderData_; List keyList_; }; } -- 2.17.1