Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use LV_INDEV_TYPE_BUTTON cause crash #567

Closed
WangYifa opened this issue Nov 20, 2018 · 23 comments

Comments

Projects
None yet
3 participants
@WangYifa
Copy link

commented Nov 20, 2018

I'm using a PC simulator.
I want to use some hardware button.
This is my configuration cause crash.
(I use LV_INDEV_TYPE_POINT is normal.)

    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_BUTTON
    indev_drv.read = button_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_indev_drv_register(&indev_drv);
bool button_read(lv_indev_data_t*data)
{
    static uint32_t last_btn = 0;   /*Store the last pressed button*/ 
    int btn_pr = my_btn_read();     /*Get the ID (0,1,2...) of the pressed button*/
    if(btn_pr >= 0) {               /*Is there a button press?*/  
       last_btn = btn_pr;           /*Save the ID of the pressed button*/
       data->state = LV_INDEV_STATE_PR;  /*Set the pressed state*/
    } else {
       data->state = LV_INDEV_STATE_REL; /*Set the released state*/
    }
  
    data->btn = last_btn;            /*Set the last button*/         
   
    return false;                    /*No buffering so no more data read*/
}
@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 20, 2018

Hi,

How/Where do you set the point assigned to the buttons? (lv_indev_set_button_points)

@WangYifa

This comment has been minimized.

Copy link
Author

commented Nov 20, 2018

I haven't used it yet.(lv_indev_set_button_points)
is it because this is not configured?

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 20, 2018

@WangYifa WangYifa closed this Nov 20, 2018

@WangYifa WangYifa reopened this Nov 20, 2018

@WangYifa

This comment has been minimized.

Copy link
Author

commented Nov 20, 2018

static void hal_init(void)
{
    /* Add a display
     * Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
    monitor_init();
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
    disp_drv.disp_flush = monitor_flush;
    disp_drv.disp_fill = monitor_fill;
    disp_drv.disp_map = monitor_map;
    lv_disp_drv_register(&disp_drv);

    /* Add the mouse (or touchpad) as input device
     * Use the 'mouse' driver which reads the PC's mouse*/
    mouse_init();
    lv_indev_t indev_drv;
    lv_indev_init();          /*Basic initialization*/
    indev_drv.driver.type = LV_INDEV_TYPE_BUTTON;
    indev_drv.driver.read = mouse_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_point_t points_array[] = {{12,30},{60,90}};
    lv_indev_set_button_points(&indev_drv, points_array);
    lv_indev_drv_register(&indev_drv.driver);

    /* Tick init.
     * You have to call 'lv_tick_handler()' in every milliseconds
     * Create an SDL thread to do this*/
    SDL_CreateThread(tick_thread, "tick", NULL);
}
@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 20, 2018

lv_point_t points_array[] should be static or global because only it's pointer is saved .
static lv_point_t points_array[] = {{12,30},{60,90}};

@WangYifa

This comment has been minimized.

Copy link
Author

commented Nov 20, 2018

@kisvegabor I've been trying for a long time. Can you help me to configure "hal_init about "indev_frv"?

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 20, 2018

Ok, you would like to achieve? What kind of input device do you have?

@WangYifa

This comment has been minimized.

Copy link
Author

commented Nov 20, 2018

I have three buttons connected to the gpio of MCU.
I have finished the driver of the buttons.
I don't know how to register the three buttons into your GUI.
I've seen the documents, , but it always fails.

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 20, 2018

Would you like to navigate with the buttons i.e. move the focus between the objects or press a GUI button with the external button?

@WangYifa

This comment has been minimized.

Copy link
Author

commented Nov 20, 2018

i want to move the focus between the objects.If this is difficult to implement, I would like to press a GUI button with the external button.

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Nov 21, 2018

i want to move the focus between the objects.

It is supported. Have look at this: https://github.com/littlevgl/lvgl/wiki/Input-devices

@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 12, 2018

lv_indev_set_button_points(&indev_drv, points_array); [1]

@WangYifa there is error in this line,

# correct
lv_indev_t *indev;
lv_indev_driver_t indev_drv;
[...]
indev = lv_indev_drv_register(&indev_drv.driver);
[...]
lv_indev_set_button_points(indev, points_array);

# wrong
lv_indev_set_button_points(&indev_drv, points_array);

📋 Reference

  1. #567 (comment)
@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 12, 2018

We have two phsical buttons. We link physical buttons with LV_BTN.

int8_t my_btn_read() { }
bool my_input_read(lv_indev_data_t*data) { }

void button_init(void) {
  static lv_indev_t *indev;
  lv_indev_drv_t indev_drv;

  lv_indev_drv_init(&indev_drv);

  indev_drv.read = my_input_read;
  indev_drv.type = LV_INDEV_TYPE_BUTTON;
  indev = lv_indev_drv_register(&indev_drv);

  // static OR global
  static lv_point_t points_array[] = {{20, 20}, {110, 110}};
  lv_indev_set_button_points(indev, points_array);
}

static lv_res_t btn_click_action1(lv_obj_t * btn) { }
static lv_res_t btn_click_action2(lv_obj_t * btn) { }

main() {
  ...
  button_init();
  ...

  lv_obj_t * btn1 = lv_btn_create(lv_scr_act(), NULL);
  lv_obj_set_pos(btn1, 10, 10);
  lv_obj_set_size(btn1, 50, 50);
  lv_btn_set_action(btn1, LV_BTN_ACTION_CLICK, btn_click_action1); 

  lv_obj_t * btn2 = lv_btn_create(lv_scr_act(), NULL);
  lv_obj_set_pos(btn2, 100, 100);
  lv_obj_set_size(btn2, 50, 50);
  lv_btn_set_action(btn2, LV_BTN_ACTION_CLICK, btn_click_action2); 
}

But we see that indev.btn_points is not set with points_array in the indev_button_proc function. We think that there is a bug related with memory allocation/variable scope etc.

We solved with workaround trick

// lv_hal_indev.c
static void indev_button_proc(lv_indev_t * i, lv_indev_data_t * data)
{
  const lv_point_t points_array[] =  {{20, 20}, {110, 110}};
  i->proc.act_point.x = points_array[data->btn].x;
  i->proc.act_point.y = points_array[data->btn].y;

  // i->proc.act_point.x = i->btn_points[data->btn].x;
  // i->proc.act_point.y = i->btn_points[data->btn].y;
  ...
}

// lv_indev.c
void lv_indev_set_button_points(lv_indev_t * indev, lv_point_t * points)
{
    if(indev->driver.type == LV_INDEV_TYPE_BUTTON) indev->btn_points = points;
}

What is your suggestion? @kisvegabor

Our test environment is LittlevGL v5.2.

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Dec 13, 2018

@seyyah I tested it the PC simulator and point_array remained in the indev for me.

In lv_indev.h in the definition of lv_indev_t the pointer to the points array is defined in an union:

    union {
        struct _lv_obj_t *cursor;       /*Cursor for LV_INPUT_TYPE_POINTER*/
        struct _lv_group_t *group;      /*Keypad destination group*/
        lv_point_t * btn_points;      /*Array points assigned to the button ()screen will be pressed here by the buttons*/
    };

I thought maybe setting group or cursor to NULL overwrites the btn_points but I didn't find it in the library.

@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 13, 2018

We have two different indev: touch, hardware button. We use default configuration indev. We don't use cursor or group option.

We'll test

// lv_hal_indev.h
// new: debug purpose
/*The main input device descriptor with driver, runtime data ('proc') and some additional information*/
typedef struct _lv_indev_t {
    lv_indev_drv_t driver;
    lv_indev_proc_t proc;
    uint32_t last_activity_time;
    lv_point_t * btn_points;
    struct _lv_indev_t *next;
} lv_indev_t;

// old
/*The main input device descriptor with driver, runtime data ('proc') and some additional information*/
typedef struct _lv_indev_t {
    lv_indev_drv_t driver;
    lv_indev_proc_t proc;
    uint32_t last_activity_time;
    union {
        struct _lv_obj_t *cursor;       /*Cursor for LV_INPUT_TYPE_POINTER*/
        struct _lv_group_t *group;      /*Keypad destination group*/
        lv_point_t * btn_points;      /*Array points assigned to the button ()screen will be pressed here by the buttons*/
    };
    struct _lv_indev_t *next;
} lv_indev_t;
@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 13, 2018

We're very sorry. Problem origanated from us :(

// correct
static lv_point_t points_array[] = {{20, 20}, {110, 110}};

// wrong
const lv_point_t points_array[] = {{20, 20}, {110, 110}};
@kisvegabor

This comment has been minimized.

Copy link
Member

commented Dec 14, 2018

@seyyah Glad to hear it works now. Thank you for the feedback!

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Dec 14, 2018

As there was no activity about the original question for a while and the issue of @seyyah seems to be solved I close this issue.

@kisvegabor kisvegabor closed this Dec 14, 2018

@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 14, 2018

@kisvegabor we'll write a blog entry for the hardware button.

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Dec 16, 2018

@seyyah Awesome! I'm very waiting for that! I hope it will easy to add a post a guest blogger. Let me know if something is not working as expected.

@seyyah

This comment has been minimized.

Copy link
Contributor

commented Dec 20, 2018

🔑 Keywords: stm32f429i-disco, hardware button, led toggle, LV_INDEV_TYPE_BUTTON

First step, we record a video for this purpose: https://www.youtube.com/watch?v=dk772McmJs4

Thanks to @ogunduz

@kisvegabor

This comment has been minimized.

Copy link
Member

commented Dec 20, 2018

Great! Thanks for sharing it!

@seyyah

This comment has been minimized.

Copy link
Contributor

commented Jan 18, 2019

Keywords: stm32f429i-disco, hardware button, led toggle, LV_INDEV_TYPE_BUTTON

First step, we record a video for this purpose: https://www.youtube.com/watch?v=dk772McmJs4

Thanks to @ogunduz

https://blog.littlevgl.com/2019-01-08/hardware-button

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.