727 lines
22 KiB
C
727 lines
22 KiB
C
#include "encoder_port.h"
|
|
#include "cmsis_os2.h"
|
|
#include "gpio.h"
|
|
#include "input_manager.h"
|
|
#include "pinctrl.h"
|
|
#include "pm.h"
|
|
#include "power_display_service.h"
|
|
#include "rtc.h"
|
|
#include "semaphore.h"
|
|
#include "soc_errno.h"
|
|
#include "sys_config.h"
|
|
#include "task_driver_event.h"
|
|
#include "tcxo.h"
|
|
#include "time.h"
|
|
|
|
#if defined(TJD_PCBA_1)
|
|
#include "common_i2c.h"
|
|
#include "common_pm.h"
|
|
#include "encoder_drv_kth5763.h"
|
|
#endif
|
|
|
|
#define ENABLE_PRINT_INFO 1
|
|
#if ENABLE_PRINT_INFO
|
|
#define static_print_info(...) sys_enc_log_i(__VA_ARGS__) // 一般信息打印宏控制
|
|
#define static_print_warn(...) sys_enc_log_w(__VA_ARGS__) // 警告信息打印一般常开
|
|
#define static_print_error(...) sys_enc_log_e(__VA_ARGS__) // 错误信息打印一般常开
|
|
#define static_print_debug(...) sys_enc_log_d(__VA_ARGS__) // 调试信息打印一般常开
|
|
#else
|
|
#define static_print_info(...)
|
|
#define static_print_warn(...)
|
|
#define static_print_error(...)
|
|
#define static_print_debug(...)
|
|
#endif
|
|
|
|
#if defined(TJD_PCBA_0)
|
|
static osTimerId_t g_rotary_timer_handle;
|
|
#define A_SIGNAL_PIN S_MGPIO7
|
|
#define B_SIGNAL_PIN S_MGPIO6
|
|
#endif
|
|
|
|
#define REPORT_OUT_TIME_MS 155
|
|
|
|
static report_event_cb g_report_event_cb = NULL;
|
|
|
|
static struct rotary_encoder g_rotary_encoder = {
|
|
#if defined(TJD_PCBA_1)
|
|
.i2c_bus = I2C_BUS_2,
|
|
.i2c_speed = 400000,
|
|
#if (CALIBRATION_MODE)
|
|
.i2c_addr = KTH5701_I2C_ADDR,
|
|
#else
|
|
.i2c_addr = KTH5763_I2C_ADDR,
|
|
#endif
|
|
.int_pin = S_MGPIO9,
|
|
#endif
|
|
.steps = 10,
|
|
.pos = 0,
|
|
#if defined(TJD_PCBA_0)
|
|
.gpio_descs =
|
|
{
|
|
.desc = {A_SIGNAL_PIN, B_SIGNAL_PIN},
|
|
.ndescs = 2,
|
|
}
|
|
#endif
|
|
};
|
|
|
|
#if defined(TJD_PCBA_1)
|
|
#define I2C_RETRY_TIMES 3
|
|
static osThreadId_t g_rotary_duty_handle = NULL;
|
|
static uint8_t g_send_buf[4] = {0};
|
|
static uint8_t g_recv_buf[32] = {0};
|
|
static osThreadState_t g_rotary_duty_state = osThreadInactive;
|
|
|
|
static bool g_encoder_host_dev_init_flag = false;
|
|
|
|
static uint32_t get_currunt_time(void)
|
|
{
|
|
#define MILLISEC_TO_NANOSEC 1000000
|
|
#define SEC_TO_MILLISEC 1000
|
|
struct timespec time;
|
|
clock_gettime(CLOCK_MONOTONIC, &time);
|
|
return time.tv_sec * SEC_TO_MILLISEC + time.tv_nsec / MILLISEC_TO_NANOSEC;
|
|
}
|
|
|
|
static uint32_t get_elapse_time(uint32_t startTime)
|
|
{
|
|
uint32_t currentTime = get_currunt_time();
|
|
uint32_t elapseTime;
|
|
|
|
if (currentTime > startTime) {
|
|
elapseTime = currentTime - startTime;
|
|
} else {
|
|
elapseTime = (UINT32_MAX - startTime) + currentTime + 1;
|
|
}
|
|
|
|
return elapseTime;
|
|
}
|
|
|
|
static ext_errno encoder_peripheral_init_status_check(void)
|
|
{
|
|
if (g_encoder_host_dev_init_flag != true) {
|
|
return EXT_ERR_TP_DEV_INFO_NOT_REGISTER;
|
|
}
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_i2c_cmd_write(uint8_t cmd)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
errcode_t ret;
|
|
uint8_t retry;
|
|
i2c_data_t data;
|
|
|
|
ret = encoder_peripheral_init_status_check();
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("host peripheral not init! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
g_send_buf[0] = cmd;
|
|
|
|
data.send_buf = g_send_buf;
|
|
data.send_len = 1;
|
|
data.receive_buf = NULL;
|
|
data.receive_len = 0;
|
|
|
|
for (retry = 0; retry < I2C_RETRY_TIMES; retry++) {
|
|
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_ENCODER_ID, &data);
|
|
if (ret == ENC_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("encoder data write fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_i2c_package_write(uint8_t *data_buf, uint32_t data_len)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
|
|
errcode_t ret;
|
|
uint8_t retry;
|
|
ret = encoder_peripheral_init_status_check();
|
|
if (ret != 0) {
|
|
static_print_error("host peripheral not init! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
i2c_data_t data = {.send_buf = data_buf, .send_len = data_len};
|
|
|
|
for (retry = 0; retry < I2C_RETRY_TIMES; retry++) {
|
|
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_ENCODER_ID, &data);
|
|
if (ret == ENC_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("encoder package write fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_i2c_reg_write(uint32_t reg_addr, uint8_t reg_len, uint8_t reg_cfg)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
errcode_t ret;
|
|
uint32_t retry;
|
|
i2c_data_t data;
|
|
|
|
ret = encoder_peripheral_init_status_check();
|
|
if (ret != 0) {
|
|
static_print_error("host peripheral not init! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
reg_len = reg_len & 0x0F;
|
|
memset(g_send_buf, 0, sizeof(g_send_buf));
|
|
int i = reg_len;
|
|
while (i) {
|
|
i--;
|
|
g_send_buf[i] = reg_addr;
|
|
reg_addr >>= 8;
|
|
}
|
|
g_send_buf[reg_len] = reg_cfg;
|
|
|
|
data.send_buf = g_send_buf;
|
|
data.send_len = reg_len + 1;
|
|
data.receive_buf = NULL;
|
|
data.receive_len = 0;
|
|
|
|
for (retry = 0; retry < I2C_RETRY_TIMES; retry++) {
|
|
ret = tjd_driver_common_i2c_get_ops()->write(I2C_MODEL_ENCODER_ID, &data);
|
|
if (ret == ENC_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("encoder reg write fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_i2c_data_read(uint32_t reg_addr, uint8_t reg_len, uint8_t *data_buf, uint16_t data_len)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
errcode_t ret;
|
|
uint32_t retry;
|
|
i2c_data_t data;
|
|
|
|
ret = encoder_peripheral_init_status_check();
|
|
if (ret != 0) {
|
|
static_print_error("host peripheral not init! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
reg_len = reg_len & 0x0F;
|
|
memset(g_send_buf, 0, sizeof(g_send_buf));
|
|
|
|
if (memset_s(g_recv_buf, data_len, 0, data_len) != EOK) {
|
|
static_print_error("encoder read buff set fail! ret=0x%x", ret);
|
|
return EXT_ERR_FAILURE;
|
|
}
|
|
|
|
int i = reg_len;
|
|
while (i) {
|
|
i--;
|
|
g_send_buf[i] = reg_addr;
|
|
reg_addr >>= 8;
|
|
}
|
|
|
|
data.send_buf = g_send_buf;
|
|
data.send_len = reg_len;
|
|
data.receive_buf = g_recv_buf;
|
|
data.receive_len = data_len;
|
|
|
|
for (retry = 0; retry < I2C_RETRY_TIMES; retry++) {
|
|
ret = tjd_driver_common_i2c_get_ops()->writeread(I2C_MODEL_ENCODER_ID, &data);
|
|
if (ret == ENC_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("encoder reg read fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = (uint32_t)memcpy_s(data_buf, data_len, g_recv_buf, data_len);
|
|
if (ret != EOK) {
|
|
static_print_error("encoder data buf content copy fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_i2c_data_write_read(uint8_t *send_buf, uint16_t data_len, uint8_t *recv_buf, uint16_t recv_len)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
errcode_t ret;
|
|
uint8_t retry;
|
|
i2c_data_t data;
|
|
ret = encoder_peripheral_init_status_check();
|
|
if (ret != 0) {
|
|
static_print_error("host peripheral not init! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
data.send_buf = send_buf;
|
|
data.send_len = data_len;
|
|
data.receive_buf = g_recv_buf;
|
|
data.receive_len = recv_len;
|
|
|
|
for (retry = 0; retry < I2C_RETRY_TIMES; retry++) {
|
|
ret = tjd_driver_common_i2c_get_ops()->writeread(I2C_MODEL_ENCODER_ID, &data);
|
|
if (ret == ENC_SUCC) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("encoder package write fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = (uint32_t)memcpy_s(recv_buf, recv_len, g_recv_buf, recv_len);
|
|
if (ret != EOK) {
|
|
static_print_error("encoder data buf content copy fail! ret=0x%x", ret);
|
|
return ret;
|
|
}
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
void enocder_open(void)
|
|
{
|
|
const struct power_manager_class_ops *power_manager_ops = tjd_driver_common_pm_get_ops();
|
|
power_manager_ops->set_model_power_status(POWER_MODEL_ENCODER_ID, PM_POWER_STATUS_ON);
|
|
osDelay(80);
|
|
}
|
|
|
|
void enocder_close(void)
|
|
{
|
|
const struct power_manager_class_ops *power_manager_ops = tjd_driver_common_pm_get_ops();
|
|
// power_manager_ops->set_model_power_status(POWER_MODEL_ENCODER_ID, PM_POWER_STATUS_OFF);
|
|
}
|
|
#endif
|
|
|
|
uint32_t encoder_register_report_event_cb(ReportEventCb callback)
|
|
{
|
|
if (g_report_event_cb != NULL) {
|
|
return ENC_FAIL;
|
|
}
|
|
g_report_event_cb = callback;
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t encoder_unregister_report_event_cb(void)
|
|
{
|
|
if (g_report_event_cb == NULL) {
|
|
return ENC_FAIL;
|
|
}
|
|
g_report_event_cb = NULL;
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
static void rotary_encoder_report_event(struct rotary_encoder *encoder)
|
|
{
|
|
const power_display_svr_api_t *display_api = power_display_svr_get_api();
|
|
int16_t pos = encoder->pos;
|
|
|
|
// static_print_debug("rotary_encoder_get_state pos:%x", pos);
|
|
|
|
/* turning clockwise */
|
|
// if (pos < encoder->steps)
|
|
// pos++;
|
|
|
|
// encoder->pos = pos;
|
|
|
|
InputDevData data = {
|
|
.type = INDEV_TYPE_ENCODER, .state = 1, .rotate = pos, .timestamp = (uint32_t)uapi_tcxo_get_ms()};
|
|
|
|
if (display_api->get_screen_state() != SCREEN_ON) {
|
|
return;
|
|
}
|
|
|
|
display_api->set_auto_timeout_function(false);
|
|
if (g_report_event_cb != NULL) {
|
|
g_report_event_cb(&data);
|
|
}
|
|
|
|
/* 释放屏幕和低功耗 */
|
|
display_api->set_auto_timeout_function(true);
|
|
}
|
|
|
|
void rotary_out_time_callback(void *data)
|
|
{
|
|
unused(data);
|
|
struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
encoder->pos = 0;
|
|
rotary_encoder_report_event(encoder);
|
|
}
|
|
|
|
typedef struct
|
|
{
|
|
signed int (*func_event_handler)(void *param); // 事件处理函数
|
|
void *param; // 事件处理函数入参
|
|
void (*func_event_debug)(char *str, ...); // 打印
|
|
void *payload;
|
|
} encoder_driver_event_info_t;
|
|
|
|
#if defined(TJD_PCBA_0)
|
|
static void rotary_encoder_get_state(struct rotary_encoder *encoder)
|
|
{
|
|
static uint16_t cnt = 0;
|
|
static uint16_t signal_b = 0;
|
|
if (uapi_gpio_get_val(encoder->gpio_descs.desc[0]) == 0 && cnt == 0) { // A相下降沿触发第一次中断
|
|
cnt++;
|
|
signal_b = 0;
|
|
if (uapi_gpio_get_val(encoder->gpio_descs.desc[1]) == 1) {
|
|
signal_b = 1;
|
|
}
|
|
}
|
|
if (uapi_gpio_get_val(encoder->gpio_descs.desc[0]) == 1 && cnt == 1) { // A相上升沿触发第二次中断
|
|
cnt = 0;
|
|
if (signal_b == 1 && uapi_gpio_get_val(encoder->gpio_descs.desc[1]) == 0) {
|
|
encoder->pos += 1; // 正转
|
|
rotary_encoder_report_event(encoder);
|
|
} else if (signal_b == 0 && uapi_gpio_get_val(encoder->gpio_descs.desc[1]) == 1) {
|
|
encoder->pos -= 1; // 反转
|
|
rotary_encoder_report_event(encoder);
|
|
}
|
|
}
|
|
}
|
|
|
|
static signed int encoder_event_handler(void *param)
|
|
{
|
|
unused(param);
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
|
|
rotary_encoder_get_state(encoder);
|
|
if (osTimerIsRunning(g_rotary_timer_handle)) {
|
|
osTimerStop(g_rotary_timer_handle);
|
|
}
|
|
osTimerStart(g_rotary_timer_handle, REPORT_OUT_TIME_MS);
|
|
return 0;
|
|
}
|
|
|
|
static void rotary_encoder_irq(pin_t pin, uintptr_t param)
|
|
{
|
|
uint32_t ret = 0;
|
|
static encoder_driver_event_info_t g_msg_data = {
|
|
.func_event_handler = encoder_event_handler,
|
|
.param = NULL,
|
|
.func_event_debug = NULL,
|
|
.payload = NULL,
|
|
};
|
|
static unsigned int g_msg_size = sizeof(encoder_driver_event_info_t);
|
|
ret = osal_msg_queue_write_copy(tjd_task_driver_event_get_queue_id(), &g_msg_data, g_msg_size, 0);
|
|
if (ret != 0) {
|
|
static_print_error("msg send failed! err=0x%x", ret);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(TJD_PCBA_1)
|
|
struct rotary_calculate
|
|
{
|
|
uint16_t angle_old;
|
|
uint16_t diff_angle;
|
|
uint8_t power_flag : 1;
|
|
uint8_t key_update_flag : 1;
|
|
uint8_t key_state : 1;
|
|
uint8_t last_key_state : 1;
|
|
};
|
|
|
|
static void rotary_duty_task(void *arg)
|
|
{
|
|
unused(arg);
|
|
#define ANGLE_TRESHOLD 100
|
|
struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
struct rotary_calculate calculate = {0};
|
|
uint16_t angle = 0;
|
|
uint32_t ret = 0;
|
|
uint32_t report_timer_counter = 0;
|
|
g_rotary_duty_state = osThreadRunning;
|
|
while (1) {
|
|
uapi_pm_add_sleep_veto_with_timeout(PM_ID_ENCODER, 50);
|
|
ret = kth5763_measurement(0x04, &angle);
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("KTH5763: measurement mode failed, %x", ret);
|
|
osDelay(50);
|
|
continue;
|
|
}
|
|
if (calculate.power_flag == 0) {
|
|
calculate.power_flag = 1;
|
|
calculate.angle_old = angle;
|
|
}
|
|
if (angle > calculate.angle_old) {
|
|
if (angle < calculate.angle_old + 1800) { // 顺时针
|
|
if (angle >= calculate.angle_old + ANGLE_TRESHOLD) {
|
|
calculate.diff_angle = angle - calculate.angle_old;
|
|
calculate.key_update_flag = 1; // 有效旋转
|
|
calculate.key_state = 1; // 正转
|
|
calculate.angle_old = angle;
|
|
}
|
|
} else if (angle >= calculate.angle_old + 1800) { // 逆时针
|
|
if (3600 - angle + calculate.angle_old >= ANGLE_TRESHOLD) {
|
|
calculate.diff_angle = calculate.angle_old + 3600 - angle;
|
|
calculate.key_update_flag = 1;
|
|
calculate.key_state = 0; // 反转
|
|
calculate.angle_old = angle;
|
|
}
|
|
}
|
|
} else if (angle < calculate.angle_old) {
|
|
if (angle + 1800 > calculate.angle_old) {
|
|
if (angle + ANGLE_TRESHOLD <= calculate.angle_old) {
|
|
calculate.diff_angle = calculate.angle_old - angle;
|
|
calculate.key_update_flag = 1;
|
|
calculate.key_state = 0; // 反转
|
|
calculate.angle_old = angle;
|
|
}
|
|
} else if (angle + 1800 <= calculate.angle_old) {
|
|
if (3600 - calculate.angle_old + angle > ANGLE_TRESHOLD) {
|
|
calculate.diff_angle = 3600 + angle - calculate.angle_old;
|
|
calculate.key_update_flag = 1;
|
|
calculate.key_state = 1; // 正转
|
|
calculate.angle_old = angle;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (calculate.key_update_flag == 1) {
|
|
/* 往相反方向转动 */
|
|
if (calculate.last_key_state != calculate.key_state) {
|
|
encoder->pos = 0;
|
|
}
|
|
uint8_t pos_offset = (calculate.diff_angle / 100) * 1 + 1;
|
|
if (calculate.key_state) {
|
|
encoder->pos = 10; // 反转
|
|
} else {
|
|
encoder->pos = -10; // 正转
|
|
}
|
|
calculate.last_key_state = calculate.key_state;
|
|
// static_print_info("encoder->pos = %d", encoder->pos);
|
|
rotary_encoder_report_event(encoder);
|
|
report_timer_counter = get_currunt_time();
|
|
calculate.key_update_flag = 0;
|
|
}
|
|
if (report_timer_counter != 0 && get_elapse_time(report_timer_counter) >= 200) {
|
|
rotary_out_time_callback(NULL);
|
|
report_timer_counter = 0;
|
|
}
|
|
osDelay(50);
|
|
}
|
|
}
|
|
|
|
#if (CALIBRATION_MODE)
|
|
void rotary_calibration_duty_task(void *arg)
|
|
{
|
|
struct rotary_calibration_data
|
|
{
|
|
uint16_t x_max;
|
|
uint16_t y_max;
|
|
uint16_t z_max;
|
|
uint16_t x_min;
|
|
uint16_t y_min;
|
|
uint16_t z_min;
|
|
} rotary_data = {
|
|
.x_max = 32768,
|
|
.y_max = 32768,
|
|
.z_max = 32768,
|
|
.x_min = 32768,
|
|
.y_min = 32768,
|
|
.z_min = 32768,
|
|
};
|
|
|
|
uint16_t x_data = 0;
|
|
uint16_t y_data = 0;
|
|
uint16_t z_data = 0;
|
|
uint8_t data[9] = {0};
|
|
uint32_t ret = 0;
|
|
osDelay(100);
|
|
while (1) {
|
|
ret = kth5763_xyz_measurement(XYZ_MODE, data);
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("KTH5763: measurement mode failed, %x", ret);
|
|
osDelay(50);
|
|
continue;
|
|
}
|
|
|
|
x_data = (data[3] << 8) + data[4]; // 读取X轴输出值
|
|
y_data = (data[5] << 8) + data[6]; // 读取y轴输出值
|
|
z_data = (data[7] << 8) + data[8]; // 读取z轴输出值
|
|
static_print_info("X = %d, Y = %d, Z = %d", x_data, y_data, z_data);
|
|
|
|
if (rotary_data.x_min == 0 && rotary_data.y_min == 0 && rotary_data.z_min == 0) {
|
|
rotary_data.x_min = x_data;
|
|
rotary_data.y_min = y_data;
|
|
rotary_data.z_min = z_data;
|
|
}
|
|
|
|
if (rotary_data.x_max < x_data) {
|
|
rotary_data.x_max = x_data;
|
|
}
|
|
if (rotary_data.y_max < y_data) {
|
|
rotary_data.y_max = y_data;
|
|
}
|
|
if (rotary_data.z_max < z_data) {
|
|
rotary_data.z_max = z_data;
|
|
}
|
|
if (rotary_data.x_min > x_data) {
|
|
rotary_data.x_min = x_data;
|
|
}
|
|
if (rotary_data.y_min > y_data) {
|
|
rotary_data.y_min = y_data;
|
|
}
|
|
if (rotary_data.z_min > z_data) {
|
|
rotary_data.z_min = z_data;
|
|
}
|
|
static_print_debug("x_max = %d, y_max = %d, z_max = %d x_min = %d, y_min = %d, z_min = %d", rotary_data.x_max,
|
|
rotary_data.y_max, rotary_data.z_max, rotary_data.x_min, rotary_data.y_min,
|
|
rotary_data.z_min);
|
|
osDelay(50);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
|
|
void rotary_suspend_for_i2c(void)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
static_print_info("rotary_suspend_for_i2c %d", encoder->i2c_bus);
|
|
i2c_save_reg(encoder->i2c_bus);
|
|
}
|
|
|
|
void rotary_resume_for_i2c(void)
|
|
{
|
|
const struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
static_print_info("rotary_resume_for_i2c %d", encoder->i2c_bus);
|
|
i2c_recovery_reg(encoder->i2c_bus);
|
|
}
|
|
|
|
uint32_t encoder_suspend(void)
|
|
{
|
|
rotary_encoder_deinit();
|
|
return 0;
|
|
}
|
|
|
|
uint32_t encoder_resume(void)
|
|
{
|
|
rotary_encoder_init(NULL);
|
|
return 0;
|
|
}
|
|
|
|
uint32_t rotary_encoder_init(struct rotary_encoder *encoder_attr)
|
|
{
|
|
unused(encoder_attr);
|
|
uint32_t ret = 0;
|
|
|
|
struct rotary_encoder *encoder = &g_rotary_encoder;
|
|
|
|
/* register int io interrupt handler */
|
|
uapi_gpio_init();
|
|
uapi_pin_init();
|
|
|
|
#if defined(TJD_PCBA_1)
|
|
enocder_open();
|
|
|
|
/* v1版本采用i2c方式 */
|
|
ret = tjd_driver_common_i2c_get_ops()->open(I2C_MODEL_ENCODER_ID, encoder->i2c_bus, encoder->i2c_addr,
|
|
encoder->i2c_speed);
|
|
if (ret != ENC_SUCC && ret != ERRCODE_I2C_ALREADY_INIT) {
|
|
static_print_error("i2c master init failed, %x", ret);
|
|
enocder_close();
|
|
return ENC_FAIL;
|
|
}
|
|
g_encoder_host_dev_init_flag = true;
|
|
|
|
ret = kth5763_init();
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("KTH5763: init failed, %x", ret);
|
|
enocder_close();
|
|
return ENC_FAIL;
|
|
}
|
|
osDelay(10);
|
|
|
|
osThreadAttr_t task_attr = {"tjd_encoder_task", 0, NULL, 0, NULL, 0x900, 17, 0, 0};
|
|
task_attr.stack_mem = memalign(16, task_attr.stack_size);
|
|
#if (CALIBRATION_MODE)
|
|
g_rotary_duty_handle = osThreadNew(rotary_calibration_duty_task, NULL, &task_attr);
|
|
#else
|
|
g_rotary_duty_handle = osThreadNew(rotary_duty_task, NULL, &task_attr);
|
|
#endif
|
|
if (g_rotary_duty_handle == NULL) {
|
|
static_print_error("create rotary timer failed");
|
|
enocder_close();
|
|
return ENC_FAIL;
|
|
}
|
|
#endif
|
|
|
|
#if defined(TJD_PCBA_0)
|
|
g_rotary_timer_handle = osTimerNew((osTimerFunc_t)rotary_out_time_callback, osTimerOnce, 0, NULL);
|
|
if (g_rotary_timer_handle == NULL) {
|
|
static_print_error("create rotary timer failed");
|
|
return ENC_FAIL;
|
|
}
|
|
|
|
for (int i = 0; i < encoder->gpio_descs.ndescs; ++i) {
|
|
uapi_pin_set_mode(encoder->gpio_descs.desc[i], HAL_PIO_FUNC_GPIO);
|
|
uapi_pin_set_pull(encoder->gpio_descs.desc[i], HAL_PIO_PULL_UP);
|
|
uapi_gpio_set_dir(encoder->gpio_descs.desc[i], GPIO_DIRECTION_INPUT);
|
|
}
|
|
uapi_tcxo_delay_ms(5);
|
|
ret = uapi_gpio_register_isr_func(encoder->gpio_descs.desc[0], GPIO_INTERRUPT_DEDGE, rotary_encoder_irq);
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("register isr func failed, %x", ret);
|
|
return ret;
|
|
}
|
|
|
|
uapi_tcxo_delay_ms(5);
|
|
ret = uapi_gpio_enable_interrupt(encoder->gpio_descs.desc[0]);
|
|
if (ret != ENC_SUCC) {
|
|
static_print_error("enable interrupt failed, %x", ret);
|
|
return ret;
|
|
}
|
|
#endif
|
|
|
|
static_print_info("rotary encoder init success");
|
|
|
|
return ENC_SUCC;
|
|
}
|
|
|
|
uint32_t rotary_encoder_deinit(void)
|
|
{
|
|
uint32_t ret = 0;
|
|
#if defined(TJD_PCBA_0)
|
|
uapi_gpio_disable_interrupt(g_rotary_encoder.gpio_descs.desc[0]);
|
|
uapi_gpio_unregister_isr_func(g_rotary_encoder.gpio_descs.desc[0]);
|
|
#endif
|
|
#if defined(TJD_PCBA_1)
|
|
if (g_rotary_duty_handle == NULL) {
|
|
return ENC_SUCC;
|
|
}
|
|
if (g_rotary_duty_state == osThreadRunning) {
|
|
if (osThreadTerminate(g_rotary_duty_handle) != osOK) {
|
|
static_print_error("terminate rotary task failed");
|
|
}
|
|
g_rotary_duty_state = osThreadInactive;
|
|
}
|
|
osDelay(25);
|
|
|
|
kth5763_enter_idle();
|
|
|
|
tjd_driver_common_i2c_get_ops()->close(I2C_MODEL_ENCODER_ID);
|
|
g_encoder_host_dev_init_flag = false;
|
|
static_print_info("rotary encoder deinit success");
|
|
#endif
|
|
enocder_close();
|
|
|
|
return ENC_SUCC;
|
|
} |