lvgl touch added

This commit is contained in:
gemu2015 2021-04-24 16:20:39 +02:00
parent 9e27eb394e
commit 70c2290c9d
4 changed files with 121 additions and 151 deletions

View File

@ -22,107 +22,15 @@ static void lv_tick_handler(void) { lv_tick_inc(lv_tick_interval_ms); }
#define ADC_YMIN 240 #define ADC_YMIN 240
#define ADC_YMAX 840 #define ADC_YMAX 840
uint32_t Touch_Status(uint32_t sel);
static bool touchscreen_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data) { static bool touchscreen_read(struct _lv_indev_drv_t *indev_drv, lv_indev_data_t *data) {
// static lv_coord_t last_x = 0, last_y = 0; //lv_coord_t last_x = 0, last_y = 0;
// static uint8_t release_count = 0; //static uint8_t release_count = 0;
data->point.x = Touch_Status(1); // Last-pressed coordinates
// // Get pointer to glue object from indev user data data->point.y = Touch_Status(2);
// Adafruit_LvGL_Glue *glue = (Adafruit_LvGL_Glue *)indev_drv->user_data; data->state = Touch_Status(0);
// uDisplay_lvgl *disp = glue->display;
// if (glue->is_adc_touch) {
// TouchScreen *touch = (TouchScreen *)glue->touchscreen;
// TSPoint p = touch->getPoint();
// // Serial.printf("%d %d %d\r\n", p.x, p.y, p.z);
// // Having an issue with spurious z=0 results from TouchScreen lib.
// // Since touch is polled periodically, workaround is to watch for
// // several successive z=0 results, and only then regard it as
// // a release event (otherwise still touched).
// if (p.z < touch->pressureThreshhold) { // A zero-ish value
// release_count += (release_count < 255);
// if (release_count >= 4) {
// data->state = LV_INDEV_STATE_REL; // Is REALLY RELEASED
// } else {
// data->state = LV_INDEV_STATE_PR; // Is STILL PRESSED
// }
// } else {
// release_count = 0; // Reset release counter
// data->state = LV_INDEV_STATE_PR; // Is PRESSED
// switch (glue->display->getRotation()) {
// case 0:
// last_x = map(p.x, ADC_XMIN, ADC_XMAX, 0, disp->width() - 1);
// last_y = map(p.y, ADC_YMAX, ADC_YMIN, 0, disp->height() - 1);
// break;
// case 1:
// last_x = map(p.y, ADC_YMAX, ADC_YMIN, 0, disp->width() - 1);
// last_y = map(p.x, ADC_XMAX, ADC_XMIN, 0, disp->height() - 1);
// break;
// case 2:
// last_x = map(p.x, ADC_XMAX, ADC_XMIN, 0, disp->width() - 1);
// last_y = map(p.y, ADC_YMIN, ADC_YMAX, 0, disp->height() - 1);
// break;
// case 3:
// last_x = map(p.y, ADC_YMIN, ADC_YMAX, 0, disp->width() - 1);
// last_y = map(p.x, ADC_XMIN, ADC_XMAX, 0, disp->height() - 1);
// break;
// }
// }
// data->point.x = last_x; // Last-pressed coordinates
// data->point.y = last_y;
// return false; // No buffering of ADC touch data
// } else {
// uint8_t fifo; // Number of points in touchscreen FIFO
// bool moar = false;
// Adafruit_STMPE610 *touch = (Adafruit_STMPE610 *)glue->touchscreen;
// // Before accessing SPI touchscreen, wait on any in-progress
// // DMA screen transfer to finish (shared bus).
// //disp->dmaWait();
// // disp->endWrite();
// if ((fifo = touch->bufferSize())) { // 1 or more points await
// data->state = LV_INDEV_STATE_PR; // Is PRESSED
// TS_Point p = touch->getPoint();
// // Serial.printf("%d %d %d\r\n", p.x, p.y, p.z);
// // On big TFT FeatherWing, raw X axis is flipped??
// if ((glue->display->width() == 480) || (glue->display->height() == 480)) {
// p.x = (TS_MINX + TS_MAXX) - p.x;
// }
// switch (glue->display->getRotation()) {
// case 0:
// last_x = map(p.x, TS_MAXX, TS_MINX, 0, disp->width() - 1);
// last_y = map(p.y, TS_MINY, TS_MAXY, 0, disp->height() - 1);
// break;
// case 1:
// last_x = map(p.y, TS_MINY, TS_MAXY, 0, disp->width() - 1);
// last_y = map(p.x, TS_MINX, TS_MAXX, 0, disp->height() - 1);
// break;
// case 2:
// last_x = map(p.x, TS_MINX, TS_MAXX, 0, disp->width() - 1);
// last_y = map(p.y, TS_MAXY, TS_MINY, 0, disp->height() - 1);
// break;
// case 3:
// last_x = map(p.y, TS_MAXY, TS_MINY, 0, disp->width() - 1);
// last_y = map(p.x, TS_MAXX, TS_MINX, 0, disp->height() - 1);
// break;
// }
// moar = (fifo > 1); // true if more in FIFO, false if last point
// #if defined(NRF52_SERIES)
// // Not sure what's up here, but nRF doesn't seem to always poll
// // the FIFO size correctly, causing false release events. If it
// // looks like we've read the last point from the FIFO, pause
// // briefly to allow any more FIFO events to pile up. This
// // doesn't seem to be necessary on SAMD or ESP32. ???
// if (!moar) {
// delay(50);
// }
// #endif
// } else { // FIFO empty
// data->state = LV_INDEV_STATE_REL; // Is RELEASED
// }
// data->point.x = last_x; // Last-pressed coordinates
// data->point.y = last_y;
// return moar;
// }
return false; /*No buffering now so no more data read*/ return false; /*No buffering now so no more data read*/
} }

View File

@ -28,6 +28,7 @@ public:
// LvGLStatus begin(uDisplay_lvgl *tft, TouchScreen *touch, // LvGLStatus begin(uDisplay_lvgl *tft, TouchScreen *touch,
// bool debug = false); // bool debug = false);
LvGLStatus begin(Renderer *tft, bool debug = false); LvGLStatus begin(Renderer *tft, bool debug = false);
LvGLStatus begin(Renderer *tft, void *touch, bool debug);
// These items need to be public for some internal callbacks, // These items need to be public for some internal callbacks,
// but should be avoided by user code please! // but should be avoided by user code please!
Renderer *display; ///< Pointer to the SPITFT display instance Renderer *display; ///< Pointer to the SPITFT display instance
@ -40,7 +41,6 @@ public:
void stopScreenshot(void) { screenshot = nullptr; } void stopScreenshot(void) { screenshot = nullptr; }
private: private:
LvGLStatus begin(Renderer *tft, void *touch, bool debug);
lv_disp_drv_t lv_disp_drv; lv_disp_drv_t lv_disp_drv;
lv_disp_buf_t lv_disp_buf; lv_disp_buf_t lv_disp_buf;
lv_color_t *lv_pixel_buf; lv_color_t *lv_pixel_buf;

View File

@ -7757,9 +7757,17 @@ const char ili9342[] PROGMEM =
":TI2,38,22,21\n" ":TI2,38,22,21\n"
"#\n"; "#\n";
void start_lvgl(const char * uconfig); void start_lvgl(const char * uconfig);
void btn_event_cb(lv_obj_t * btn, lv_event_t event);
void btn_event_cb(lv_obj_t * btn, lv_event_t event) {
if (event == LV_EVENT_CLICKED) {
AddLog_P(LOG_LEVEL_INFO,PSTR(">>> clicked"));
}
AddLog_P(LOG_LEVEL_INFO,PSTR(">>> clicked"));
}
int32_t lvgl_test(int32_t p) { int32_t lvgl_test(int32_t p) {
start_lvgl(ili9342); start_lvgl(ili9342);
lv_obj_clean(lv_scr_act()); lv_obj_clean(lv_scr_act());
@ -7775,73 +7783,120 @@ int32_t lvgl_test(int32_t p) {
lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0); lv_obj_align(label1, NULL, LV_ALIGN_CENTER, 0, 0);
lvgl_setup();
/*Add a button*/ /*Add a button*/
lv_obj_t *btn1 = lv_btn_create(lv_scr_act(), NULL); /*Add to the active screen*/ lv_obj_t *btn1 = lv_btn_create(lv_scr_act(), NULL); /*Add to the active screen*/
lv_obj_set_pos(btn1, 2, 2); /*Adjust the position*/ lv_obj_set_pos(btn1, 2, 2); /*Adjust the position*/
lv_obj_set_size(btn1, 96, 30); /* set size of button */ lv_obj_set_size(btn1, 96, 30); /* set size of button */
// lv_btn_set_action(btn1, LV_BTN_ACTION_CLICK, my_click_action); /*Assign a callback for clicking*/ lv_obj_set_event_cb(btn1, btn_event_cb);
/*Add text*/ /*Add text*/
lv_obj_t *label = lv_label_create(btn1, NULL); /*Put on 'btn1'*/ lv_obj_t *label = lv_label_create(btn1, NULL); /*Put on 'btn1'*/
lv_label_set_text(label, "Click"); lv_label_set_text(label, "Click");
return 0; return 0;
} }
/* lv_obj_t *tabview, // LittlevGL tabview object
*gauge, // Gauge object (on first of three tabs)
*chart, // Chart object (second tab)
*canvas; // Canvas object (third tab)
uint8_t active_tab = 0, // Index of currently-active tab (0-2)
prev_tab = 0; // Index of previously-active tab
lv_chart_series_t *series; // 'Series' data for the bar chart
lv_draw_line_dsc_t draw_dsc; // Drawing style (for canvas) is similarly global
lv_obj_t * myButton; #define CANVAS_WIDTH 200 // Dimensions in pixels
lv_obj_t * myButtonLabel; #define CANVAS_HEIGHT 150
lv_obj_t * myLabel;
lv_style_t myButtonStyleREL; //relesed style void lvgl_setup(void) {
lv_style_t myButtonStylePR; //pressed style // Create a tabview object, by default this covers the full display.
tabview = lv_tabview_create(lv_disp_get_scr_act(NULL), NULL);
// The CLUE display has a lot of pixels and can't refresh very fast.
// To show off the tabview animation, let's slow it down to 1 second.
lv_tabview_set_anim_time(tabview, 1000);
static lv_res_t btn_click_action(lv_obj_t * btn) { // Because they're referenced any time an object is drawn, styles need
uint8_t id = lv_obj_get_free_num(btn); //id usefull when there are multiple buttons // to be permanent in scope; either declared globally (outside all
// functions), or static. The styles used on tabs are never modified after
// they're used here, so let's use static on those...
static lv_style_t tab_style, tab_background_style, indicator_style;
if(id == 0) // This is the background style "behind" the tabs. This is what shows
{ // through for "off" (inactive) tabs -- a vertical green gradient,
char buffer[100]; // minimal padding around edges (zero at bottom).
sprintf(buffer, "button was clicked %i milliseconds from start", pros::millis()); lv_style_init(&tab_background_style);
lv_label_set_text(myLabel, buffer); lv_style_set_bg_color(&tab_background_style, LV_STATE_DEFAULT, lv_color_hex(0x408040));
} lv_style_set_bg_grad_color(&tab_background_style, LV_STATE_DEFAULT, lv_color_hex(0x304030));
lv_style_set_bg_grad_dir(&tab_background_style, LV_STATE_DEFAULT, LV_GRAD_DIR_VER);
lv_style_set_pad_top(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_left(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_right(&tab_background_style, LV_STATE_DEFAULT, 2);
lv_style_set_pad_bottom(&tab_background_style, LV_STATE_DEFAULT, 0);
lv_obj_add_style(tabview, LV_TABVIEW_PART_TAB_BG, &tab_background_style);
return LV_RES_OK; // Style for tabs. Active tab is white with opaque background, inactive
// tabs are transparent so the background shows through (only the white
// text is seen). A little top & bottom padding reduces scrunchyness.
lv_style_init(&tab_style);
lv_style_set_pad_top(&tab_style, LV_STATE_DEFAULT, 3);
lv_style_set_pad_bottom(&tab_style, LV_STATE_DEFAULT, 10);
lv_style_set_bg_color(&tab_style, LV_STATE_CHECKED, LV_COLOR_WHITE);
lv_style_set_bg_opa(&tab_style, LV_STATE_CHECKED, LV_OPA_100);
lv_style_set_text_color(&tab_style, LV_STATE_CHECKED, LV_COLOR_GRAY);
lv_style_set_bg_opa(&tab_style, LV_STATE_DEFAULT, LV_OPA_TRANSP);
lv_style_set_text_color(&tab_style, LV_STATE_DEFAULT, LV_COLOR_WHITE);
lv_obj_add_style(tabview, LV_TABVIEW_PART_TAB_BTN, &tab_style);
// Style for the small indicator bar that appears below the active tab.
lv_style_init(&indicator_style);
lv_style_set_bg_color(&indicator_style, LV_STATE_DEFAULT, LV_COLOR_RED);
lv_style_set_size(&indicator_style, LV_STATE_DEFAULT, 5);
lv_obj_add_style(tabview, LV_TABVIEW_PART_INDIC, &indicator_style);
// Back to creating widgets...
// Add three tabs to the tabview
lv_obj_t *tab1 = lv_tabview_add_tab(tabview, "Gauge");
lv_obj_t *tab2 = lv_tabview_add_tab(tabview, "Chart");
lv_obj_t *tab3 = lv_tabview_add_tab(tabview, "Canvas");
// And then add stuff in each tab...
// The first tab holds a gauge. To keep the demo simple, let's just use
// the default style and range (0-100). See LittlevGL docs for options.
gauge = lv_gauge_create(tab1, NULL);
lv_obj_set_size(gauge, 186, 186);
lv_obj_align(gauge, NULL, LV_ALIGN_CENTER, 0, 0);
// Second tab, make a chart...
chart = lv_chart_create(tab2, NULL);
lv_obj_set_size(chart, 200, 180);
lv_obj_align(chart, NULL, LV_ALIGN_CENTER, 0, 0);
lv_chart_set_type(chart, LV_CHART_TYPE_COLUMN);
// For simplicity, we'll stick with the chart's default 10 data points:
series = lv_chart_add_series(chart, LV_COLOR_RED);
lv_chart_init_points(chart, series, 0);
// Make each column shift left as new values enter on right:
lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
// Third tab is a canvas, which we'll fill with random colored lines.
// LittlevGL draw functions only work on TRUE_COLOR canvas.
/* canvas = lv_canvas_create(tab3, NULL);
lv_canvas_set_buffer(canvas, canvas_buffer,
CANVAS_WIDTH, CANVAS_HEIGHT, LV_IMG_CF_TRUE_COLOR);
lv_obj_align(canvas, NULL, LV_ALIGN_CENTER, 0, 0);
lv_canvas_fill_bg(canvas, LV_COLOR_WHITE, LV_OPA_100);
// Set up canvas line-drawing style based on defaults.
// Later we'll change color settings when drawing each line.
lv_draw_line_dsc_init(&draw_dsc);
*/
} }
#define LV_COLOR_MAKE lv_color_make
void initialize() {
lv_style_copy(&myButtonStyleREL, &lv_style_plain);
myButtonStyleREL.body.main_color = LV_COLOR_MAKE(150, 0, 0);
myButtonStyleREL.body.grad_color = LV_COLOR_MAKE(0, 0, 150);
myButtonStyleREL.body.radius = 0;
myButtonStyleREL.text.color = LV_COLOR_MAKE(255, 255, 255);
lv_style_copy(&myButtonStylePR, &lv_style_plain);
myButtonStylePR.body.main_color = LV_COLOR_MAKE(255, 0, 0);
myButtonStylePR.body.grad_color = LV_COLOR_MAKE(0, 0, 255);
myButtonStylePR.body.radius = 0;
myButtonStylePR.text.color = LV_COLOR_MAKE(255, 255, 255);
myButton = lv_btn_create(lv_scr_act(), NULL); //create button, lv_scr_act() is deafult screen object
lv_obj_set_free_num(myButton, 0); //set button is to 0
lv_btn_set_action(myButton, LV_BTN_ACTION_CLICK, btn_click_action); //set function to be called on button click
lv_btn_set_style(myButton, LV_BTN_STYLE_REL, &myButtonStyleREL); //set the relesed style
lv_btn_set_style(myButton, LV_BTN_STYLE_PR, &myButtonStylePR); //set the pressed style
lv_obj_set_size(myButton, 200, 50); //set the button size
lv_obj_align(myButton, NULL, LV_ALIGN_IN_TOP_LEFT, 10, 10); //set the position to top mid
myButtonLabel = lv_label_create(myButton, NULL); //create label and puts it inside of the button
lv_label_set_text(myButtonLabel, "Click the Button"); //sets label text
myLabel = lv_label_create(lv_scr_act(), NULL); //create label and puts it on the screen
lv_label_set_text(myLabel, "Button has not been clicked yet"); //sets label text
lv_obj_align(myLabel, NULL, LV_ALIGN_LEFT_MID, 10, 0); //set the position to center
}
*/
#endif #endif
@ -8008,6 +8063,12 @@ bool Xdrv10(uint8_t function)
case FUNC_EVERY_100_MSECOND: case FUNC_EVERY_100_MSECOND:
ScripterEvery100ms(); ScripterEvery100ms();
break; break;
#ifdef USE_LVGL
case FUNC_EVERY_50_MSECOND:
lv_task_handler();
break;
#endif // USE_LVGL
case FUNC_EVERY_SECOND: case FUNC_EVERY_SECOND:
ScriptEverySecond(); ScriptEverySecond();
break; break;

View File

@ -243,7 +243,8 @@ static lv_fs_res_t lvbe_fs_remove(lv_fs_drv_t * drv, const char *path) {
* display ecosystem. * display ecosystem.
************************************************************/ ************************************************************/
Renderer *Init_uDisplay(const char *desc, int8_t cs); Renderer *Init_uDisplay(const char *desc, int8_t cs);
void start_lvgl(const char * uconfig); void start_lvgl(const char * uconfig);
void start_lvgl(const char * uconfig) { void start_lvgl(const char * uconfig) {
@ -268,7 +269,7 @@ void start_lvgl(const char * uconfig) {
glue = new Adafruit_LvGL_Glue(); glue = new Adafruit_LvGL_Glue();
// Initialize glue, passing in address of display & touchscreen // Initialize glue, passing in address of display & touchscreen
LvGLStatus status = glue->begin(renderer); LvGLStatus status = glue->begin(renderer, (void*)1, false);
if (status != LVGL_OK) { if (status != LVGL_OK) {
AddLog(LOG_LEVEL_ERROR, PSTR("Glue error %d"), status); AddLog(LOG_LEVEL_ERROR, PSTR("Glue error %d"), status);
return; return;