linuxOS_AP06/app/lvgl_demo/motor_demo/main.c

970 lines
32 KiB
C
Raw Normal View History

2025-06-03 04:28:32 +00:00
/*
* Copyright (c) 2024 Rockchip, Inc. All Rights Reserved.
*
* 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.
*/
#define _GNU_SOURCE
#include <lvgl/lvgl.h>
#include <lvgl/lv_conf.h>
#include <stdlib.h>
#include <stdio.h>
#include <sched.h>
#include <pthread.h>
#include "main.h"
#include "ml_label.h"
#include "soc.h"
#include "ui_scaler.h"
#if ENABLE_MOTOR_CONTROL
#include "Rockchip_MADHT1505BA1.h"
#endif
#define START_ANGLE 90
#define MAX_SPEED ((METER_TICKS - 1) * 1000)
#define ANGLE_TO_SPEED(x) ((x) * (METER_TICKS - 1) * 1000 / max_angle)
#define SPEED_TO_ANGLE(x) ((x) * max_angle / (METER_TICKS - 1) / 1000)
#define CONVERSION_ANGULAR 2916
#define SCALER_RESIZE(x) ui_scaler_calc(ui_scaler, x)
static float max_angle = 360.0;
int interrupt_task = 1;
pthread_t motor_sync_thread;
struct axis_ui
{
lv_obj_t *cont;
lv_obj_t *light;
lv_obj_t *label;
lv_obj_t *pos;
lv_obj_t *pos_val;
lv_obj_t *target;
lv_obj_t *target_val;
#if ENABLE_MOTOR_CONTROL
MADHT1505BA1_object *slave;
#endif
int txt_idx;
};
#if ENABLE_MOTOR_CONTROL
MADHT1505BA1_object slave[2];
#endif
lv_ft_info_t ttf_main;
lv_ft_info_t ttf_main_s;
static lv_obj_t *scr;
static lv_obj_t *bg_img;
static lv_obj_t *label_title;
static lv_obj_t *btn_overview;
static lv_obj_t *btn_reset;
static lv_obj_t *btn_axissync;
static lv_obj_t *btn_alart;
static lv_obj_t *label_overview;
static lv_obj_t *label_autolocate;
static lv_obj_t *label_axissync;
static lv_obj_t *label_alart;
static lv_obj_t *position_cont;
static lv_obj_t *label_pos_ctrl_target;
static lv_obj_t *page_overview;
static lv_obj_t *language_switch;
static lv_obj_t *label_soc;
static struct meter *pos_meter;
lv_obj_t *label_jitter;
lv_obj_t *label_jitter_val;
/* 0 for Axis-X, 1 for Axis-Y */
static struct axis_ui axiss[2];
static struct axis_ui *position_ctrl_target = NULL;
static int quit = 0;
static char *compatible_name;
static char *soc_name;
static char *sys_version;
static void *ui_scaler;
int set_pos0 = 0;
int set_pos1 = 0;
int last_pos0 = 0;
int last_pos1 = 0;
static int thread_bind_cpu(int target_cpu)
{
cpu_set_t mask;
int cpu_num = sysconf(_SC_NPROCESSORS_CONF);
int i;
if (target_cpu >= cpu_num)
return -1;
CPU_ZERO(&mask);
CPU_SET(target_cpu, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
perror("pthread_setaffinity_np");
if (pthread_getaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)
perror("pthread_getaffinity_np");
printf("Thread(%ld) bound to cpu:", gettid());
for (i = 0; i < CPU_SETSIZE; i++)
{
if (CPU_ISSET(i, &mask))
{
printf(" %d", i);
break;
}
}
printf("\n");
return i >= cpu_num ? -1 : i;
}
static void sigterm_handler(int sig)
{
fprintf(stderr, "signal %d\n", sig);
quit = 1;
}
static void font_init(void)
{
lv_freetype_init(64, 1, 0);
ttf_main.weight = SCALER_RESIZE(68);
ttf_main.name = SRC_FONT("SmileySans-Oblique.ttf");
ttf_main.style = FT_FONT_STYLE_NORMAL;
lv_ft_font_init(&ttf_main);
ttf_main_s.weight = SCALER_RESIZE(48);
ttf_main_s.name = SRC_FONT("SmileySans-Oblique.ttf");
ttf_main_s.style = FT_FONT_STYLE_NORMAL;
lv_ft_font_init(&ttf_main_s);
}
static void lvgl_init(void)
{
lv_port_init();
ui_scaler = ui_scaler_new(1920, 1080);
ui_scaler_set_refer_size(ui_scaler, LV_HOR_RES, LV_VER_RES);
font_init();
}
static int motor_init(void)
{
#if ENABLE_MOTOR_CONTROL
int ret;
/* This place is the binding thread of the motor */
ret = MADHT1505BA1_master_init(7);
if (ret == -1)
{
printf("MADHT1505BA1_master_init is err\n");
MADHT1505BA1_master_deinit();
}
slave[0].alias = 0;
slave[0].position = 0;
slave[1].alias = 1;
slave[1].position = 0;
ret = MADHT1505BA1_slaves_init(&slave[0]);
if (ret == -1)
{
printf("MADHT1505BA1_slaves_init0 is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
ret = MADHT1505BA1_slaves_init(&slave[1]);
if (ret == -1)
{
printf("MADHT1505BA1_slaves_init1 is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
ret = MADHT1505BA1_master_activate();
if (ret == -1)
{
printf("MADHT1505BA1_master_activate is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
ret = MADHT1505BA1_slaves_activate(&slave[0]);
if (ret == -1)
{
printf("MADHT1505BA1_slaves_activate0 is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
ret = MADHT1505BA1_slaves_activate(&slave[1]);
if (ret == -1)
{
printf("MADHT1505BA1_slaves_activate1 is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
ret = MADHT1505BA1_slave_start(2, &slave[0], &slave[1]);
if (ret == -1)
{
printf("MADHT1505BA1_slaves_activate1 is err\n");
MADHT1505BA1_master_deinit();
return -1;
}
printf("Please wait while checking whether the motor is operational...\n");
while ((MADHT1505BA1_check_motor(&slave[0]) == -1) ||
(MADHT1505BA1_check_motor(&slave[1]) == -1))
{
sleep(1);
}
printf("motor is ok\n");
#endif
return 0;
}
#if 0
void motor_start(void *s, int pos)
{
if (s == &slave[0])
set_pos0 = pos * 100;
else
set_pos1 = pos * 100;
}
void motor_stop(void *s)
{
if (s == &slave[0])
set_pos0 = 0;
else
set_pos1 = 0;
}
#endif
int motor_check(void *s)
{
#if ENABLE_MOTOR_CONTROL
return MADHT1505BA1_check_motor(s);
#else
return 0;
#endif
}
static void toggle_led(lv_event_t *e)
{
struct axis_ui *axis = lv_event_get_user_data(e);
uint8_t bright;
bright = lv_led_get_brightness(axis->light);
if (bright > (LV_LED_BRIGHT_MIN + LV_LED_BRIGHT_MAX) >> 1)
{
lv_led_off(axis->light);
lv_obj_set_style_bg_color(axis->light, lv_color_hex(0x242424),
LV_PART_MAIN);
}
else
{
lv_led_on(axis->light);
lv_obj_set_style_bg_color(axis->light, lv_color_hex(0x24d957),
LV_PART_MAIN);
}
}
static void overview_cb(lv_event_t *e)
{
lv_obj_add_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
if (lv_obj_has_flag(page_overview, LV_OBJ_FLAG_HIDDEN))
lv_obj_clear_flag(page_overview, LV_OBJ_FLAG_HIDDEN);
else
lv_obj_add_flag(page_overview, LV_OBJ_FLAG_HIDDEN);
}
static void scr_cb(lv_event_t *e)
{
lv_obj_add_flag(page_overview, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
}
static void reset_cb(lv_event_t *e)
{
scr_cb(e);
printf("reset_cb debug\n");
interrupt_task = 1;
lv_label_set_text_fmt(axiss[0].target_val, "%d", 0);
lv_label_set_text_fmt(axiss[1].target_val, "%d", 0);
#if ENABLE_MOTOR_CONTROL
MADHT1505BA1_position_reset(&slave[0]);
MADHT1505BA1_position_reset(&slave[1]);
while ((MADHT1505BA1_run_position_acquisition(&slave[0]) / CONVERSION_ANGULAR !=
0) ||
(MADHT1505BA1_run_position_acquisition(&slave[1]) / CONVERSION_ANGULAR != 0))
{
sleep(1);
}
#endif
}
static void *motor_sync_th(void *arg)
{
#if ENABLE_MOTOR_CONTROL
while (1)
{
MADHT1505BA1_position_reset(&slave[0]);
MADHT1505BA1_position_reset(&slave[1]);
while ((MADHT1505BA1_run_position_acquisition(&slave[0]) / CONVERSION_ANGULAR !=
0) ||
(MADHT1505BA1_run_position_acquisition(&slave[0]) / CONVERSION_ANGULAR != 0))
{
if (interrupt_task == 1)
{
return;
}
sleep(0.1);
}
MADHT1505BA1_motor_set_position_run(CONVERSION_ANGULAR * 360, &slave[0]);
MADHT1505BA1_motor_set_position_run(CONVERSION_ANGULAR * 360, &slave[1]);
while ((MADHT1505BA1_run_position_acquisition(&slave[0]) / CONVERSION_ANGULAR !=
360) ||
(MADHT1505BA1_run_position_acquisition(&slave[0]) / CONVERSION_ANGULAR != 360))
{
if (interrupt_task == 1)
{
return;
}
sleep(0.1);
}
}
#endif
}
static void close_cb(lv_event_t *e)
{
lv_obj_add_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
}
static void sync_cb(lv_event_t *e)
{
scr_cb(e);
printf("sync_cb debug\n");
lv_label_set_text_fmt(axiss[0].target_val, "%d", 0);
lv_label_set_text_fmt(axiss[1].target_val, "%d", 0);
interrupt_task = 0;
pthread_create(&motor_sync_thread, NULL, motor_sync_th, NULL);
}
static void axis_cb(lv_event_t *e)
{
struct axis_ui *axis = lv_event_get_user_data(e);
//printf("%s %d\n", __func__, __LINE__);
lv_obj_add_flag(page_overview, LV_OBJ_FLAG_HIDDEN);
if (lv_obj_has_flag(position_cont, LV_OBJ_FLAG_HIDDEN))
lv_obj_clear_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
else if (position_ctrl_target == axis)
lv_obj_add_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
position_ctrl_target = axis;
ml_label_set_text(label_pos_ctrl_target, axis->txt_idx);
}
static void axis_ui_init(lv_obj_t *parent,
struct axis_ui *axis)
{
lv_obj_t *subcont;
axis->cont = lv_obj_create(parent);
lv_obj_set_flex_flow(axis->cont, LV_FLEX_FLOW_COLUMN);
lv_obj_add_flag(axis->cont, LV_OBJ_FLAG_CLICKABLE);
lv_obj_clear_flag(axis->cont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(axis->cont, SCALER_RESIZE(720), SCALER_RESIZE(280));
lv_obj_set_style_bg_color(axis->cont, lv_color_hex(0x2566a8),
LV_PART_MAIN);
lv_obj_set_style_pad_gap(axis->cont, 5, LV_PART_MAIN);
lv_obj_add_event_cb(axis->cont, axis_cb, LV_EVENT_CLICKED, axis);
subcont = lv_obj_create(axis->cont);
lv_obj_remove_style_all(subcont);
lv_obj_add_flag(subcont, LV_OBJ_FLAG_EVENT_BUBBLE);
lv_obj_set_size(subcont, lv_pct(100), SCALER_RESIZE(50));
axis->light = lv_led_create(subcont);
lv_obj_set_size(axis->light, SCALER_RESIZE(30), SCALER_RESIZE(30));
lv_obj_align(axis->light, LV_ALIGN_LEFT_MID, 10, 0);
lv_obj_set_style_bg_color(axis->light, lv_color_hex(0x242424),
LV_PART_MAIN);
lv_led_set_color(axis->light, lv_color_hex(0x24d957));
lv_led_off(axis->light);
lv_obj_add_flag(axis->light, LV_OBJ_FLAG_EVENT_BUBBLE);
axis->label = ml_label_create(subcont, axis->txt_idx);
lv_obj_set_style_text_color(axis->label, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(axis->label, ttf_main_s.font, LV_PART_MAIN);
lv_obj_align_to(axis->label, axis->light, LV_ALIGN_OUT_RIGHT_MID,
SCALER_RESIZE(20), 0);
lv_obj_add_flag(axis->label, LV_OBJ_FLAG_EVENT_BUBBLE);
subcont = lv_obj_create(axis->cont);
lv_obj_remove_style_all(subcont);
lv_obj_add_flag(subcont, LV_OBJ_FLAG_EVENT_BUBBLE);
lv_obj_set_size(subcont, lv_pct(100), SCALER_RESIZE(85));
axis->pos = ml_label_create(subcont, TXT_CUR_POS);
lv_obj_set_size(axis->pos, lv_pct(60), LV_SIZE_CONTENT);
lv_obj_set_style_text_color(axis->pos, lv_color_white(),
LV_PART_MAIN);
lv_obj_set_style_text_font(axis->pos, ttf_main_s.font, LV_PART_MAIN);
lv_obj_align(axis->pos, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_flag(axis->pos, LV_OBJ_FLAG_EVENT_BUBBLE);
axis->pos_val = lv_label_create(subcont);
lv_label_set_text(axis->pos_val, "000.00");
lv_obj_set_size(axis->pos_val, lv_pct(40), LV_SIZE_CONTENT);
lv_obj_set_style_radius(axis->pos_val, 5, LV_PART_MAIN);
lv_obj_set_style_text_color(axis->pos_val, lv_color_black(),
LV_PART_MAIN);
lv_obj_set_style_text_font(axis->pos_val, ttf_main_s.font, LV_PART_MAIN);
lv_obj_set_style_text_align(axis->pos_val, LV_TEXT_ALIGN_CENTER,
LV_PART_MAIN);
lv_obj_set_style_bg_color(axis->pos_val, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_bg_opa(axis->pos_val, LV_OPA_100, LV_PART_MAIN);
lv_obj_align(axis->pos_val, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_flag(axis->pos_val, LV_OBJ_FLAG_EVENT_BUBBLE);
subcont = lv_obj_create(axis->cont);
lv_obj_remove_style_all(subcont);
lv_obj_set_size(subcont, lv_pct(100), SCALER_RESIZE(85));
lv_obj_add_flag(subcont, LV_OBJ_FLAG_EVENT_BUBBLE);
axis->target = ml_label_create(subcont, TXT_TAR_POS);
lv_obj_set_size(axis->target, lv_pct(60), LV_SIZE_CONTENT);
lv_obj_set_style_text_color(axis->target, lv_color_white(),
LV_PART_MAIN);
lv_obj_set_style_text_font(axis->target, ttf_main_s.font, LV_PART_MAIN);
lv_obj_align(axis->target, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_flag(axis->target, LV_OBJ_FLAG_EVENT_BUBBLE);
axis->target_val = lv_label_create(subcont);
lv_label_set_text(axis->target_val, " 0.00");
lv_obj_set_size(axis->target_val, lv_pct(40), LV_SIZE_CONTENT);
lv_obj_set_style_radius(axis->target_val, 5, LV_PART_MAIN);
lv_obj_set_style_text_color(axis->target_val, lv_color_black(),
LV_PART_MAIN);
lv_obj_set_style_text_font(axis->target_val, ttf_main_s.font, LV_PART_MAIN);
lv_obj_set_style_text_align(axis->target_val, LV_TEXT_ALIGN_CENTER,
LV_PART_MAIN);
lv_obj_set_style_bg_color(axis->target_val, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_bg_opa(axis->target_val, LV_OPA_100, LV_PART_MAIN);
lv_obj_align(axis->target_val, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_flag(axis->target_val, LV_OBJ_FLAG_EVENT_BUBBLE);
}
static void switch_language(lv_event_t *e)
{
lv_obj_t *obj = lv_event_get_target(e);
if (lv_obj_get_state(obj) & LV_STATE_CHECKED)
ml_label_set_language(1);
else
ml_label_set_language(0);
}
void update_tick_points(lv_point_t *p, int angle)
{
float degree = angle * 2 * PI / 360.0;
p[0].x = SCALER_RESIZE(240) * cos(degree) + SCALER_RESIZE(290);
p[0].y = SCALER_RESIZE(240) * sin(degree) + SCALER_RESIZE(290);
p[1].x = SCALER_RESIZE(230) * cos(degree) + SCALER_RESIZE(290);
p[1].y = SCALER_RESIZE(230) * sin(degree) + SCALER_RESIZE(290);
p[2].x = SCALER_RESIZE(200) * cos(degree) + SCALER_RESIZE(290);
p[2].y = SCALER_RESIZE(200) * sin(degree) + SCALER_RESIZE(290);
}
void update_needle_points(lv_point_t *p, int angle)
{
float degree = angle * 2 * PI / 360.0;
p[0].x = SCALER_RESIZE(290) * cos(degree) + SCALER_RESIZE(290);
p[0].y = SCALER_RESIZE(290) * sin(degree) + SCALER_RESIZE(290);
p[1].x = SCALER_RESIZE(280) * cos(degree) + SCALER_RESIZE(290);
p[1].y = SCALER_RESIZE(280) * sin(degree) + SCALER_RESIZE(290);
}
static void needle_cb(lv_event_t *e)
{
struct meter *meter;
lv_indev_t *indev;
lv_area_t a;
lv_point_t p;
lv_point_t c;
lv_coord_t w, h;
lv_coord_t dx, dy;
lv_coord_t angle;
lv_coord_t final_angle;
meter = lv_event_get_user_data(e);
if ((e->code == LV_EVENT_PRESSING) ||
(e->code == LV_EVENT_RELEASED))
{
indev = lv_indev_get_act();
lv_indev_get_point(indev, &p);
lv_obj_get_coords(lv_event_get_target(e), &a);
w = a.x2 - a.x1;
h = a.y2 - a.y1;
c.x = a.x1 + w / 2;
c.y = a.y1 + h / 2;
dx = p.x - c.x;
dy = p.y - c.y;
angle = lv_atan2(dy, dx);
final_angle = angle - START_ANGLE;
if (final_angle < 0)
final_angle += 360;
lv_label_set_text_fmt(meter->label_val,
"%d°", final_angle);
lv_img_set_angle(meter->needle, angle * 10);
// if (e->code == LV_EVENT_RELEASED)
// motor_set_position(position_ctrl_target->slave, final_angle);
}
}
static struct meter *meter_create(lv_obj_t *parent)
{
struct meter *meter;
int max_ticks;
meter = malloc(sizeof(struct meter));
meter->cont = lv_obj_create(parent);
lv_obj_remove_style_all(meter->cont);
lv_obj_clear_flag(meter->cont, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(meter->cont, SCALER_RESIZE(580), SCALER_RESIZE(580));
lv_obj_center(meter->cont);
meter->main = lv_arc_create(meter->cont);
lv_obj_clear_flag(meter->main, LV_OBJ_FLAG_CLICKABLE);
lv_obj_clear_flag(meter->main, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(meter->main, lv_pct(100), lv_pct(100));
lv_arc_set_rotation(meter->main, START_ANGLE);
lv_arc_set_bg_angles(meter->main, 0, max_angle);
lv_obj_set_style_arc_width(meter->main, 20,
LV_PART_MAIN);
lv_obj_set_style_arc_width(meter->main, 20,
LV_PART_INDICATOR);
lv_obj_set_style_bg_opa(meter->main, LV_OPA_0,
LV_PART_MAIN);
lv_obj_set_style_bg_opa(meter->main, LV_OPA_0,
LV_PART_KNOB);
lv_arc_set_value(meter->main, 0);
lv_arc_set_range(meter->main, 0, MAX_SPEED);
lv_obj_center(meter->main);
meter->adorn = lv_arc_create(meter->cont);
lv_obj_clear_flag(meter->adorn, LV_OBJ_FLAG_CLICKABLE);
lv_obj_clear_flag(meter->adorn, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_size(meter->adorn, SCALER_RESIZE(520), SCALER_RESIZE(520));
lv_arc_set_rotation(meter->adorn, START_ANGLE);
lv_arc_set_bg_angles(meter->adorn, 0, max_angle);
lv_obj_set_style_arc_width(meter->adorn, 2,
LV_PART_MAIN);
lv_obj_set_style_arc_width(meter->adorn, 2,
LV_PART_INDICATOR);
lv_obj_set_style_bg_opa(meter->adorn, LV_OPA_0,
LV_PART_INDICATOR);
lv_obj_set_style_bg_opa(meter->adorn, LV_OPA_0,
LV_PART_KNOB);
lv_arc_set_value(meter->adorn, 0);
lv_arc_set_range(meter->adorn, 0, MAX_SPEED);
lv_obj_center(meter->adorn);
meter->needle = lv_img_create(meter->cont);
lv_img_set_src(meter->needle, SRC_PNG(needle));
lv_img_set_angle(meter->needle, START_ANGLE * 10);
lv_img_set_zoom(meter->needle, SCALER_RESIZE(256));
lv_obj_center(meter->needle);
lv_obj_add_flag(meter->needle, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(meter->needle, needle_cb,
LV_EVENT_ALL, meter);
max_ticks = METER_TICKS;
if (max_angle >= 360.0)
max_ticks -= 1;
for (int i = 0; i < max_ticks; i++)
{
int w, h;
meter->ticks[i].obj = lv_line_create(meter->cont);
update_tick_points(meter->ticks[i].p,
START_ANGLE + SPEED_TO_ANGLE(i * 1000));
lv_obj_set_style_line_color(meter->ticks[i].obj,
lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_line_width(meter->ticks[i].obj,
4, LV_PART_MAIN);
lv_line_set_points(meter->ticks[i].obj,
meter->ticks[i].p, 2);
meter->ticks[i].label = lv_label_create(meter->cont);
lv_label_set_text_fmt(meter->ticks[i].label,
"%d°", i * 30);
lv_obj_refr_size(meter->ticks[i].label);
w = lv_obj_get_width(meter->ticks[i].label);
h = lv_obj_get_height(meter->ticks[i].label);
lv_obj_set_pos(meter->ticks[i].label,
meter->ticks[i].p[2].x - w / 2,
meter->ticks[i].p[2].y - h / 2);
lv_obj_set_style_text_color(meter->ticks[i].label,
lv_color_black(), LV_PART_MAIN);
}
meter->label_val = lv_label_create(meter->cont);
lv_label_set_text(meter->label_val, "");
lv_obj_center(meter->label_val);
lv_obj_set_style_text_font(meter->label_val,
&lv_font_montserrat_48, LV_PART_MAIN);
lv_obj_set_style_text_color(meter->label_val,
lv_color_black(), LV_PART_MAIN);
return meter;
}
static void meter_cb(lv_event_t *e)
{
lv_coord_t angle;
lv_coord_t final_angle;
interrupt_task = 1;
angle = lv_img_get_angle(pos_meter->needle);
final_angle = angle / 10 - START_ANGLE;
if (final_angle < 0)
final_angle += 360;
lv_label_set_text_fmt(position_ctrl_target->target_val, "%3.2f",
final_angle / 1.0);
#if ENABLE_MOTOR_CONTROL
MADHT1505BA1_motor_set_position_run(CONVERSION_ANGULAR * final_angle,
position_ctrl_target->slave);
#endif
}
static void position_ctrl_create(void)
{
lv_obj_t *btn_cont;
lv_obj_t *btn;
lv_obj_t *label;
position_cont = lv_obj_create(scr);
lv_obj_set_size(position_cont, lv_pct(40), lv_pct(100));
lv_obj_align(position_cont, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_flag(position_cont, LV_OBJ_FLAG_HIDDEN);
lv_obj_clear_flag(position_cont, LV_OBJ_FLAG_SCROLLABLE);
label_pos_ctrl_target = ml_label_create(position_cont, TXT_AXIS_X);
lv_obj_align(label_pos_ctrl_target, LV_ALIGN_TOP_LEFT, 0, 0);
lv_obj_set_style_text_color(label_pos_ctrl_target, lv_color_black(),
LV_PART_MAIN);
lv_obj_set_style_text_font(label_pos_ctrl_target, ttf_main_s.font,
LV_PART_MAIN);
pos_meter = meter_create(position_cont);
btn_cont = lv_obj_create(position_cont);
lv_obj_remove_style_all(btn_cont);
lv_obj_set_size(btn_cont, lv_pct(80), SCALER_RESIZE(80));
lv_obj_align(btn_cont, LV_ALIGN_BOTTOM_MID, 0, 0);
btn = lv_btn_create(btn_cont);
lv_obj_set_size(btn, lv_pct(45), lv_pct(100));
lv_obj_align(btn, LV_ALIGN_LEFT_MID, 0, 0);
lv_obj_add_event_cb(btn, meter_cb, LV_EVENT_CLICKED, NULL);
label = ml_label_create(btn, TXT_CONFIRM);
lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_center(label);
btn = lv_btn_create(btn_cont);
lv_obj_set_size(btn, lv_pct(45), lv_pct(100));
lv_obj_align(btn, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_event_cb(btn, close_cb, LV_EVENT_CLICKED, NULL);
label = ml_label_create(btn, TXT_CLOSE);
lv_obj_set_style_text_color(label, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_center(label);
}
static void overview_page_create(void)
{
lv_obj_t *cont;
lv_obj_t *subcont;
lv_obj_t *obj;
lv_obj_t *label;
cont = page_overview = lv_obj_create(scr);
lv_obj_set_size(cont, lv_pct(40), lv_pct(100));
lv_obj_align(cont, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_set_flex_flow(cont, LV_FLEX_FLOW_COLUMN);
subcont = lv_obj_create(cont);
lv_obj_set_size(subcont, lv_pct(100), 200);
label = ml_label_create(subcont, TXT_LANGUAGE);
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_LEFT_MID, 0, 0);
label = lv_label_create(subcont);
lv_label_set_text(label, "English");
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_RIGHT_MID, 0, 0);
obj = lv_switch_create(subcont);
lv_obj_set_size(obj, 80, 48);
lv_obj_add_event_cb(obj, switch_language, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_align_to(obj, label, LV_ALIGN_OUT_LEFT_MID, 0, 0);
label = lv_label_create(subcont);
lv_label_set_text(label, "中文");
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align_to(label, obj, LV_ALIGN_OUT_LEFT_MID, 0, 0);
subcont = lv_obj_create(cont);
lv_obj_set_size(subcont, lv_pct(100), LV_SIZE_CONTENT);
label = ml_label_create(subcont, TXT_HW_VER);
lv_obj_set_size(label, lv_pct(33), LV_SIZE_CONTENT);
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
label = lv_label_create(subcont);
lv_obj_set_size(label, lv_pct(66), LV_SIZE_CONTENT);
lv_label_set_text(label, compatible_name);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_RIGHT_MID, 0, 0);
subcont = lv_obj_create(cont);
lv_obj_set_size(subcont, lv_pct(100), LV_SIZE_CONTENT);
label = ml_label_create(subcont, TXT_SYS_VER);
lv_obj_set_size(label, lv_pct(33), LV_SIZE_CONTENT);
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_TOP_LEFT, 0, 0);
label = lv_label_create(subcont);
lv_obj_set_size(label, lv_pct(66), LV_SIZE_CONTENT);
lv_label_set_text(label, sys_version);
lv_label_set_long_mode(label, LV_LABEL_LONG_WRAP);
lv_obj_set_style_text_color(label, lv_color_black(), LV_PART_MAIN);
lv_obj_set_style_text_font(label, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label, LV_ALIGN_RIGHT_MID, 0, 0);
lv_obj_add_flag(page_overview, LV_OBJ_FLAG_HIDDEN);
}
static void ui_init(void)
{
char *chip;
compatible_name = get_compatible_name();
soc_name = get_soc_name(compatible_name);
sys_version = get_system_version();
scr = lv_scr_act();
lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_add_flag(scr, LV_OBJ_FLAG_CLICKABLE);
lv_obj_add_event_cb(scr, scr_cb, LV_EVENT_CLICKED, NULL);
bg_img = lv_img_create(scr);
lv_img_set_src(bg_img, SRC_PNG(background_v2));
lv_obj_center(bg_img);
lv_obj_add_flag(bg_img, LV_OBJ_FLAG_EVENT_BUBBLE);
label_soc = lv_label_create(scr);
lv_label_set_text(label_soc, soc_name);
lv_obj_set_style_text_color(label_soc, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label_soc, ttf_main.font, LV_PART_MAIN);
lv_obj_set_pos(label_soc, 40, 40);
lv_obj_add_flag(label_soc, LV_OBJ_FLAG_EVENT_BUBBLE);
label_title = ml_label_create(scr, TXT_TITLE);
lv_obj_set_style_text_color(label_title, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label_title, ttf_main.font, LV_PART_MAIN);
lv_obj_align_to(label_title, label_soc, LV_ALIGN_OUT_RIGHT_MID, 40, 0);
lv_obj_add_flag(label_title, LV_OBJ_FLAG_EVENT_BUBBLE);
btn_overview = lv_btn_create(scr);
lv_obj_set_size(btn_overview, SCALER_RESIZE(300), SCALER_RESIZE(120));
lv_obj_set_pos(btn_overview, SCALER_RESIZE(20), SCALER_RESIZE(180));
lv_obj_set_style_bg_color(btn_overview, lv_color_hex(0x2591a8),
LV_PART_MAIN);
lv_obj_add_event_cb(btn_overview, overview_cb, LV_EVENT_CLICKED, NULL);
label_overview = ml_label_create(btn_overview, TXT_OVERVIEW);
lv_obj_set_style_text_color(label_overview, lv_color_white(),
LV_PART_MAIN);
lv_obj_set_style_text_font(label_overview, ttf_main.font, LV_PART_MAIN);
lv_obj_center(label_overview);
lv_obj_add_flag(label_overview, LV_OBJ_FLAG_EVENT_BUBBLE);
btn_reset = lv_btn_create(scr);
lv_obj_set_size(btn_reset, SCALER_RESIZE(300), SCALER_RESIZE(120));
lv_obj_set_pos(btn_reset, SCALER_RESIZE(20), SCALER_RESIZE(340));
lv_obj_set_style_bg_color(btn_reset, lv_color_hex(0x2591a8),
LV_PART_MAIN);
lv_obj_add_event_cb(btn_reset, reset_cb, LV_EVENT_CLICKED, NULL);
label_autolocate = ml_label_create(btn_reset, TXT_RESET);
lv_obj_set_style_text_color(label_autolocate, lv_color_white(),
LV_PART_MAIN);
lv_obj_set_style_text_font(label_autolocate, ttf_main.font, LV_PART_MAIN);
lv_obj_center(label_autolocate);
lv_obj_add_flag(label_autolocate, LV_OBJ_FLAG_EVENT_BUBBLE);
btn_axissync = lv_btn_create(scr);
lv_obj_set_size(btn_axissync, SCALER_RESIZE(300), SCALER_RESIZE(120));
lv_obj_set_pos(btn_axissync, SCALER_RESIZE(20), SCALER_RESIZE(500));
lv_obj_set_style_bg_color(btn_axissync, lv_color_hex(0x2591a8),
LV_PART_MAIN);
lv_obj_add_event_cb(btn_axissync, sync_cb, LV_EVENT_CLICKED, NULL);
label_axissync = ml_label_create(btn_axissync, TXT_SYNC);
lv_obj_set_style_text_color(label_axissync, lv_color_white(),
LV_PART_MAIN);
lv_obj_set_style_text_font(label_axissync, ttf_main.font, LV_PART_MAIN);
lv_obj_center(label_axissync);
lv_obj_add_flag(label_axissync, LV_OBJ_FLAG_EVENT_BUBBLE);
axiss[0].txt_idx = TXT_AXIS_X;
#if ENABLE_MOTOR_CONTROL
axiss[0].slave = &slave[0];
#endif
axis_ui_init(scr, &axiss[0]);
lv_obj_set_pos(axiss[0].cont, SCALER_RESIZE(350), SCALER_RESIZE(180));
axiss[1].txt_idx = TXT_AXIS_Y;
#if ENABLE_MOTOR_CONTROL
axiss[1].slave = &slave[1];
#endif
axis_ui_init(scr, &axiss[1]);
lv_obj_set_pos(axiss[1].cont, SCALER_RESIZE(350), SCALER_RESIZE(500));
label_jitter = ml_label_create(scr, TXT_JITTER);
lv_obj_set_style_text_color(label_jitter, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label_jitter, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align(label_jitter, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_obj_add_flag(label_jitter, LV_OBJ_FLAG_EVENT_BUBBLE);
label_jitter_val = lv_label_create(scr);
lv_label_set_text_fmt(label_jitter_val, "%10u us", 0);
lv_obj_set_style_text_color(label_jitter_val, lv_color_white(), LV_PART_MAIN);
lv_obj_set_style_text_font(label_jitter_val, ttf_main_s.font,
LV_PART_MAIN);
lv_obj_align_to(label_jitter_val, label_jitter, LV_ALIGN_OUT_RIGHT_BOTTOM, 50,
0);
lv_obj_add_flag(label_jitter_val, LV_OBJ_FLAG_EVENT_BUBBLE);
overview_page_create();
position_ctrl_create();
}
static void display_motor_information(void)
{
uint32_t min = 0;
uint32_t max = 0;
int cur_pos = 0;
#if ENABLE_MOTOR_CONTROL
cur_pos = MADHT1505BA1_run_position_acquisition(
&slave[0]); // CONVERSION_ANGULAR
lv_label_set_text_fmt(axiss[0].pos_val, "%d", cur_pos / CONVERSION_ANGULAR);
cur_pos = MADHT1505BA1_run_position_acquisition(&slave[1]);
lv_label_set_text_fmt(axiss[1].pos_val, "%d", cur_pos / CONVERSION_ANGULAR);
max = MADHT1505BA1_time_statistics_period_max_ns();
min = MADHT1505BA1_time_statistics_period_min_ns();
#endif
if ((max - min) / 1000 > 50)
{
//Because the first time you start up, the jitter will get bigger, so here are some adjustments to show it
lv_label_set_text_fmt(label_jitter_val, "%10u us", (max - min) / 1000 / 2);
}
else
{
lv_label_set_text_fmt(label_jitter_val, "%10u us", (max - min) / 1000);
}
}
int main(int argc, char **argv)
{
int maxpri;
struct sched_param param;
int ret = 0;
int fre = 500;
// This place is the ui binding thread
// if(thread_bind_cpu(4) == -1) {
// printf("bind cpu core fail\n");
// }
// The scheduling priority is the highest
maxpri = sched_get_priority_max(SCHED_FIFO);
if (maxpri == -1)
{
printf("sched_get_priority_max() failed");
}
param.sched_priority = maxpri;
if (sched_setscheduler(getpid(), SCHED_FIFO, &param) == -1)
{
perror("sched_setscheduler() failed");
}
signal(SIGINT, sigterm_handler);
lvgl_init();
while (motor_init() == -1)
{
printf("motor init is err \n");
sleep(1);
}
ui_init();
while (!quit)
{
if (fre == 0)
{
display_motor_information();
fre = 500;
}
fre--;
lv_task_handler();
usleep(1000);
}
return 0;
}