-
-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add touch calibration. Unload/Load takes temp/extrude len. Fixed spoo…
…lman optional field. Fixed current layer count resets. Fixed mini print status not showing when the same file is printed repeatedly.
- Loading branch information
ballaswag
committed
Apr 10, 2024
1 parent
bcfa539
commit e21b163
Showing
15 changed files
with
999 additions
and
205 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,193 @@ | ||
/********************* | ||
* INCLUDES | ||
*********************/ | ||
|
||
#include "lv_tc.h" | ||
|
||
#include "math.h" | ||
|
||
#ifdef ESP_PLATFORM | ||
#include "esp_log.h" | ||
#endif | ||
|
||
/********************** | ||
* DEFINES | ||
*********************/ | ||
#define TAG "lv_tc" | ||
|
||
/********************** | ||
* STATIC PROTOTYPES | ||
**********************/ | ||
|
||
static void lv_tc_indev_drv_read_cb(lv_indev_drv_t *indevDrv, lv_indev_data_t *data); | ||
|
||
|
||
/********************** | ||
* STATIC VARIABLES | ||
**********************/ | ||
|
||
static lv_tc_coeff_t calibResult = {false, 0, 0, 0, 0, 0, 0}; | ||
|
||
static lv_obj_t *registeredTCScreen = NULL; | ||
static bool (*registeredInputCb)(lv_obj_t *screenObj, lv_indev_data_t *data) = NULL; | ||
static void (*registeredSaveCb)(lv_tc_coeff_t coeff) = NULL; | ||
|
||
|
||
/********************** | ||
* GLOBAL FUNCTIONS | ||
**********************/ | ||
|
||
void lv_tc_indev_drv_init(lv_indev_drv_t *indevDrv, void (*readCb)(lv_indev_drv_t *indevDrv, lv_indev_data_t *data)) { | ||
lv_indev_drv_init(indevDrv); | ||
indevDrv->type = LV_INDEV_TYPE_POINTER; | ||
indevDrv->read_cb = lv_tc_indev_drv_read_cb; | ||
indevDrv->user_data = readCb; | ||
} | ||
|
||
void _lv_tc_register_input_cb(lv_obj_t *screenObj, bool (*inputCb)(lv_obj_t *screenObj, lv_indev_data_t *data)) { | ||
registeredTCScreen = screenObj; | ||
registeredInputCb = inputCb; | ||
} | ||
|
||
void lv_tc_register_coeff_save_cb(void (*saveCb)(lv_tc_coeff_t coeff)) { | ||
registeredSaveCb = saveCb; | ||
} | ||
|
||
lv_tc_coeff_t* lv_tc_get_coeff() { | ||
return &calibResult; | ||
} | ||
|
||
void lv_tc_set_coeff(lv_tc_coeff_t coeff, bool save) { | ||
calibResult = coeff; | ||
|
||
if(save) { | ||
lv_tc_save_coeff(); | ||
} | ||
} | ||
|
||
#if defined CONFIG_USE_CUSTOM_LV_TC_COEFFICIENTS | ||
void lv_tc_load_coeff_from_config() { | ||
lv_tc_coeff_t coeff = { | ||
true, | ||
atoff(CONFIG_LV_TC_COEFFICIENT_A), | ||
atoff(CONFIG_LV_TC_COEFFICIENT_B), | ||
atoff(CONFIG_LV_TC_COEFFICIENT_C), | ||
atoff(CONFIG_LV_TC_COEFFICIENT_D), | ||
atoff(CONFIG_LV_TC_COEFFICIENT_E), | ||
atoff(CONFIG_LV_TC_COEFFICIENT_F) | ||
}; | ||
lv_tc_set_coeff(coeff, false); | ||
} | ||
#endif | ||
|
||
void lv_tc_save_coeff() { | ||
if(registeredSaveCb) { | ||
registeredSaveCb(calibResult); | ||
} | ||
} | ||
|
||
void lv_tc_compute_coeff(lv_point_t *scrP, lv_point_t *tchP, bool save) { //The computation is explained here: https://www.maximintegrated.com/en/design/technical-documents/app-notes/5/5296.html | ||
const lv_tc_val_t divisor = ( | ||
(lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y) | ||
- (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y | ||
+ (lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x | ||
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)tchP[1].x - (lv_tc_val_t)tchP[2].x) | ||
); | ||
|
||
lv_tc_coeff_t result = { | ||
true, | ||
( | ||
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y) | ||
- (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].y | ||
+ (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].y | ||
+ ((lv_tc_val_t)scrP[1].x - (lv_tc_val_t)scrP[2].x) * (lv_tc_val_t)tchP[0].y | ||
) / divisor, | ||
- ( | ||
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x) | ||
- (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].x | ||
+ (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].x | ||
+ ((lv_tc_val_t)scrP[1].x - (lv_tc_val_t)scrP[2].x) * (lv_tc_val_t)tchP[0].x | ||
) / divisor, | ||
( | ||
(lv_tc_val_t)scrP[0].x * ((lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y) | ||
+ (lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].y - (lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].y) | ||
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)scrP[2].x * (lv_tc_val_t)tchP[1].x - (lv_tc_val_t)scrP[1].x * (lv_tc_val_t)tchP[2].x) | ||
) / divisor, | ||
( | ||
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[2].y - (lv_tc_val_t)tchP[1].y) | ||
- (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].y | ||
+ (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].y | ||
+ ((lv_tc_val_t)scrP[1].y - (lv_tc_val_t)scrP[2].y) * (lv_tc_val_t)tchP[0].y | ||
) / divisor, | ||
- ( | ||
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x) | ||
- (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].x | ||
+ (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].x | ||
+ ((lv_tc_val_t)scrP[1].y - (lv_tc_val_t)scrP[2].y) * (lv_tc_val_t)tchP[0].x | ||
) / divisor, | ||
( | ||
(lv_tc_val_t)scrP[0].y * ((lv_tc_val_t)tchP[1].y * (lv_tc_val_t)tchP[2].x - (lv_tc_val_t)tchP[1].x * (lv_tc_val_t)tchP[2].y) | ||
+ (lv_tc_val_t)tchP[0].x * ((lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].y - (lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].y) | ||
+ (lv_tc_val_t)tchP[0].y * ((lv_tc_val_t)scrP[2].y * (lv_tc_val_t)tchP[1].x - (lv_tc_val_t)scrP[1].y * (lv_tc_val_t)tchP[2].x) | ||
) / divisor | ||
}; | ||
|
||
lv_tc_set_coeff(result, save); | ||
|
||
#ifdef ESP_PLATFORM | ||
ESP_LOGI(TAG, "touch calibration coefficients -> [a: %f, b: %f, c: %f, d: %f, e: %f, f: %f]", result.a, result.b, | ||
result.c, result.d, result.e, result.f); | ||
#endif | ||
} | ||
|
||
lv_point_t _lv_tc_transform_point_indev(lv_indev_data_t *data) { | ||
if(data->state == LV_INDEV_STATE_PRESSED) { | ||
return lv_tc_transform_point(data->point); | ||
} else { | ||
//Reject invalid points if the touch panel is in released state | ||
lv_point_t point = {0, 0}; | ||
return point; | ||
} | ||
} | ||
|
||
lv_point_t lv_tc_transform_point(lv_point_t point) { | ||
lv_point_t transformedPoint = point; | ||
if (calibResult.isValid) { | ||
transformedPoint.x = roundf((lv_tc_val_t)point.x * calibResult.a + (lv_tc_val_t)point.y * calibResult.b + calibResult.c); | ||
transformedPoint.y = roundf((lv_tc_val_t)point.x * calibResult.d + (lv_tc_val_t)point.y * calibResult.e + calibResult.f); | ||
|
||
lv_disp_t *disp = lv_disp_get_default(); | ||
if (disp->driver->rotated == LV_DISP_ROT_90 || disp->driver->rotated == LV_DISP_ROT_270) { | ||
lv_coord_t tmp = transformedPoint.y; | ||
transformedPoint.y = transformedPoint.x; | ||
transformedPoint.x = lv_disp_get_ver_res(NULL) - tmp - 1; | ||
} | ||
} | ||
|
||
return transformedPoint; | ||
} | ||
|
||
/********************** | ||
* STATIC FUNCTIONS | ||
**********************/ | ||
|
||
static void lv_tc_indev_drv_read_cb(lv_indev_drv_t *indevDrv, lv_indev_data_t *data) { | ||
if(!indevDrv->user_data) return; | ||
|
||
//Call the actual indev read callback | ||
((void (*)(lv_indev_drv_t*, lv_indev_data_t*))indevDrv->user_data)(indevDrv, data); | ||
|
||
//Pass the results to an ongoing calibration if there is one | ||
if(registeredTCScreen && registeredInputCb && registeredTCScreen == lv_scr_act()) { | ||
if(!registeredInputCb(registeredTCScreen, data)) { | ||
//Override state and point if the input has been handled by the registered calibration screen | ||
data->state = LV_INDEV_STATE_RELEASED; | ||
lv_point_t point = {0, 0}; | ||
data->point = point; | ||
|
||
return; | ||
} | ||
} | ||
|
||
data->point = _lv_tc_transform_point_indev(data); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
#pragma once | ||
|
||
#ifdef __cplusplus | ||
extern "C" { | ||
#endif | ||
|
||
/********************* | ||
* INCLUDES | ||
*********************/ | ||
|
||
#include "stdbool.h" | ||
#include "lvgl.h" | ||
|
||
|
||
/********************** | ||
* TYPEDEFS | ||
**********************/ | ||
|
||
typedef float lv_tc_val_t; | ||
|
||
typedef struct { | ||
bool isValid; | ||
|
||
lv_tc_val_t a; | ||
lv_tc_val_t b; | ||
lv_tc_val_t c; | ||
lv_tc_val_t d; | ||
lv_tc_val_t e; | ||
lv_tc_val_t f; | ||
} lv_tc_coeff_t; | ||
|
||
|
||
/********************** | ||
* GLOBAL PROTOTYPES | ||
**********************/ | ||
|
||
/** | ||
* Initialize a calibrated touch input driver. | ||
* @param indevDrv pointer to an input driver | ||
* @param readCb function pointer to read input driver data | ||
*/ | ||
void lv_tc_indev_drv_init(lv_indev_drv_t *indevDrv, void (*readCb)(struct _lv_indev_drv_t *indevDrv, lv_indev_data_t *data)); | ||
|
||
/** | ||
* Register a calibration screen to the modified input driver. | ||
* NOT TO BE CALLED IN APPLICATION CODE | ||
* @param screenObj pointer to the screen object | ||
* @param inputCb function pointer to handle the input | ||
*/ | ||
void _lv_tc_register_input_cb(lv_obj_t *screenObj, bool (*inputCb)(lv_obj_t *screenObj, lv_indev_data_t *data)); | ||
|
||
|
||
/** | ||
* Register a calibration coefficients save callback. | ||
* It will be called on completion of the calibration steps. | ||
* @param saveCb function pointer to save the coefficients (a lv_tc_coeff_t structure) | ||
*/ | ||
void lv_tc_register_coeff_save_cb(void (*saveCb)(lv_tc_coeff_t coeff)); | ||
|
||
|
||
/** | ||
* Get the current calibration coefficients. | ||
* @returns pointer to the coefficients structure (lv_tc_coeff_t*) | ||
*/ | ||
lv_tc_coeff_t* lv_tc_get_coeff(); | ||
|
||
/** | ||
* Set the current calibration coefficients. | ||
* @param coeff the new coefficients structure (lv_tc_coeff_t) | ||
* @param save select whether to save the coefficients or just to keep them in volatile storage | ||
*/ | ||
void lv_tc_set_coeff(lv_tc_coeff_t coeff, bool save); | ||
|
||
/** | ||
* Load previously calibrated coefficient data if defined in the config | ||
*/ | ||
#if defined CONFIG_USE_CUSTOM_LV_TC_COEFFICIENTS | ||
void lv_tc_load_coeff_from_config(); | ||
#endif | ||
|
||
/** | ||
* Save the current calibration coefficients. | ||
*/ | ||
void lv_tc_save_coeff(); | ||
|
||
/** | ||
* Compute calibration coefficients for a given set of points on the screen and touch panel. | ||
* @param scrP pointer to the first element of an array containing the screen points | ||
* @param tchP pointer to the first element of an array containing the touch panel points | ||
* @param save select whether to save the coefficients or just to keep them in volatile storage | ||
*/ | ||
void lv_tc_compute_coeff(lv_point_t *scrP, lv_point_t *tchP, bool save); | ||
|
||
|
||
/** | ||
* Transform a point read by an input driver into a point on the screen. | ||
* NOT TO BE CALLED IN APPLICATION CODE | ||
* @param data pointer to data from the input driver (lv_indev_data_t*) | ||
* @returns the point (lv_point_t) | ||
*/ | ||
lv_point_t _lv_tc_transform_point_indev(lv_indev_data_t *data); | ||
|
||
/** | ||
* Transform a point on the touch panel into a point on the screen. | ||
* @param point the point on the touch panel (lv_point_t) | ||
* @returns the point on the screen (lv_point_t) | ||
*/ | ||
lv_point_t lv_tc_transform_point(lv_point_t point); | ||
|
||
|
||
|
||
|
||
#ifdef __cplusplus | ||
} | ||
#endif |
Oops, something went wrong.