/* * 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 #include #include #include #include #include #include "main.h" #if ENABLE_MOTOR_CONTROL #include "Rockchip_MADHT1505BA1.h" MADHT1505BA1_object slave[2]; #endif lv_ft_info_t ttf_main; lv_ft_info_t ttf_main_s; static struct meter meters[4]; static lv_obj_t *scr; static lv_obj_t *bg_img; static lv_obj_t *cont_speed; static lv_obj_t *cont_position; static lv_obj_t *mode_label; static lv_obj_t *mode_switch; static lv_anim_t slide_in; static lv_anim_t slide_out; static int g_indev_rotation = 0; static int g_disp_rotation = LV_DISP_ROT_90; static int quit = 0; int set_speed0 = 0; int set_speed1 = 0; int last_speed0 = 0; int last_speed1 = 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 = 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 = 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(); font_init(); } static int motor_init(void) { #if ENABLE_MOTOR_CONTROL int ret; ret = MADHT1505BA1_master_init(3); //bind cpu core 3 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; } void motor_start(void *s, int speed) { #if ENABLE_MOTOR_CONTROL if (s == &slave[0]) set_speed0 = speed * 100; else set_speed1 = speed * 100; #endif } void motor_stop(void *s) { #if ENABLE_MOTOR_CONTROL if (s == &slave[0]) set_speed0 = 0; else set_speed1 = 0; #endif } int motor_check(void *s) { #if ENABLE_MOTOR_CONTROL return MADHT1505BA1_check_motor(s); #else return 0; #endif } void motor_set_position(void *s, int angle) { } void update_tick_points(lv_point_t *p, int angle) { float degree = angle * 2 * PI / 360.0; p[0].x = 240 * cos(degree) + 290; p[0].y = 240 * sin(degree) + 290; p[1].x = 230 * cos(degree) + 290; p[1].y = 230 * sin(degree) + 290; p[2].x = 200 * cos(degree) + 290; p[2].y = 200 * sin(degree) + 290; } void update_needle_points(lv_point_t *p, int angle) { float degree = angle * 2 * PI / 360.0; p[0].x = 290 * cos(degree) + 290; p[0].y = 290 * sin(degree) + 290; p[1].x = 280 * cos(degree) + 290; p[1].y = 280 * sin(degree) + 290; } static void anim_x_cb(void *var, int32_t v) { lv_obj_set_x(cont_speed, lv_pct(-v)); lv_obj_set_x(cont_position, lv_pct(100 - v)); } static void anim_end_cb(lv_anim_t *anim) { lv_obj_add_flag(mode_switch, LV_OBJ_FLAG_CLICKABLE); } static void switch_cb(lv_event_t *e) { lv_event_code_t code = lv_event_get_code(e); lv_obj_t *obj = lv_event_get_target(e); if (code == LV_EVENT_VALUE_CHANGED) { if (lv_obj_has_state(obj, LV_STATE_CHECKED)) lv_anim_start(&slide_in); else lv_anim_start(&slide_out); lv_obj_clear_flag(obj, LV_OBJ_FLAG_CLICKABLE); } } static void ui_init(void) { int mode = 0; scr = lv_scr_act(); lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE); if (lv_obj_get_width(scr) > lv_obj_get_height(scr)) { mode = 0; } else { mode = 1; } bg_img = lv_img_create(scr); if (mode == 0) lv_img_set_src(bg_img, SRC_PNG(background)); else lv_img_set_src(bg_img, SRC_PNG(background_ver)); lv_obj_center(bg_img); #if ENABLE_MOTOR_CONTROL meters[0].slave = &slave[0]; meters[1].slave = &slave[1]; meters[2].slave = &slave[0]; meters[3].slave = &slave[1]; #endif cont_speed = lv_obj_create(scr); lv_obj_remove_style_all(cont_speed); lv_obj_set_size(cont_speed, lv_pct(100), lv_pct(100)); lv_obj_center(cont_speed); speed_control_ui(cont_speed, &meters[0], mode); #if ENABLE_POSITION_CONTROL cont_position = lv_obj_create(scr); lv_obj_remove_style_all(cont_position); lv_obj_set_size(cont_position, lv_pct(100), lv_pct(100)); lv_obj_center(cont_position); lv_obj_set_x(cont_position, lv_pct(100)); position_control_ui(cont_position, &meters[2], mode); mode_label = lv_label_create(scr); lv_obj_align(mode_label, LV_ALIGN_TOP_LEFT, 20, 20); lv_label_set_text(mode_label, "位置控制"); lv_obj_set_style_text_color(mode_label, lv_color_white(), LV_PART_MAIN); lv_obj_set_style_text_font(mode_label, ttf_main.font, LV_PART_MAIN); mode_switch = lv_switch_create(scr); lv_obj_set_size(mode_switch, 100, 50); lv_obj_align_to(mode_switch, mode_label, LV_ALIGN_OUT_RIGHT_MID, 0, 0); lv_obj_add_event_cb(mode_switch, switch_cb, LV_EVENT_VALUE_CHANGED, NULL); lv_anim_init(&slide_in); lv_anim_set_values(&slide_in, 0, 100); lv_anim_set_time(&slide_in, 300); lv_anim_set_exec_cb(&slide_in, anim_x_cb); lv_anim_set_deleted_cb(&slide_in, anim_end_cb); lv_anim_init(&slide_out); lv_anim_set_values(&slide_out, 100, 0); lv_anim_set_time(&slide_out, 300); lv_anim_set_exec_cb(&slide_out, anim_x_cb); lv_anim_set_deleted_cb(&slide_out, anim_end_cb); #endif } static void display_motor_information(void) { uint32_t min = 0; uint32_t max = 0; int cur_speed = 0; #if ENABLE_MOTOR_CONTROL cur_speed = MADHT1505BA1_check_motor(&slave[0]); if (cur_speed != -1) { if (last_speed0 != set_speed0) { MADHT1505BA1_motor_start(&slave[0], set_speed0); last_speed0 = set_speed0; } } cur_speed = MADHT1505BA1_check_motor(&slave[1]); if (cur_speed != -1) { if (last_speed1 != set_speed1) { MADHT1505BA1_motor_start(&slave[1], set_speed1); last_speed1 = set_speed1; } } #endif lv_label_set_text_fmt(label_jitter, "Jitter:\nMax: %10u\nMin: %10u", max, min); } int main(int argc, char **argv) { int maxpri; struct sched_param param; int ret = 0; int fre = 500; if (thread_bind_cpu(1) == -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, ¶m) == -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; }