luat_lib_tp.c 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265
  1. /*
  2. @module tp
  3. @summary 触摸库
  4. @version 1.0
  5. @date 2025.02.19
  6. @demo lcd
  7. @tag LUAT_USE_TP
  8. */
  9. #include "luat_base.h"
  10. #include "luat_tp.h"
  11. #include "luat_msgbus.h"
  12. #include "luat_mem.h"
  13. #include "luat_gpio.h"
  14. #ifdef LUAT_USE_LCD
  15. #include "luat_lcd.h"
  16. #endif
  17. #define LUAT_LOG_TAG "tp"
  18. #include "luat_log.h"
  19. typedef struct tp_reg {
  20. const char *name;
  21. const luat_tp_config_t *luat_tp_config;
  22. }tp_reg_t;
  23. static const tp_reg_t tp_regs[] = {
  24. {"gt911", &tp_config_gt911},
  25. // 临时措施, Air780EPM仅开启gt911触摸屏
  26. #if !defined(TYPE_EC718PM) && !defined(LUAT_USE_TP_TINY)
  27. {"gt9157", &tp_config_gt9157},
  28. {"jd9261t", &tp_config_jd9261t},
  29. {"jd9261t_inited", &tp_config_jd9261t_inited},
  30. {"ft3x68", &tp_config_ft3x68},
  31. {"cst820", &tp_config_cst820},
  32. {"cst9220", &tp_config_cst92xx},
  33. #endif
  34. {"", NULL}
  35. };
  36. static int l_tp_handler(lua_State* L, void* ptr) {
  37. rtos_msg_t *msg = (rtos_msg_t *)lua_topointer(L, -1);
  38. luat_tp_config_t* luat_tp_config = msg->ptr;
  39. luat_tp_data_t* luat_tp_data = msg->arg1;
  40. if (luat_tp_config->luat_cb) {
  41. lua_geti(L, LUA_REGISTRYINDEX, luat_tp_config->luat_cb);
  42. if (lua_isfunction(L, -1)) {
  43. lua_pushlightuserdata(L, luat_tp_config);
  44. lua_newtable(L);
  45. for (uint8_t i=0; i<LUAT_TP_TOUCH_MAX; i++){
  46. if ((TP_EVENT_TYPE_DOWN == luat_tp_data[i].event) || (TP_EVENT_TYPE_UP == luat_tp_data[i].event) || (TP_EVENT_TYPE_MOVE == luat_tp_data[i].event)){
  47. lua_newtable(L);
  48. lua_pushstring(L, "event");
  49. lua_pushinteger(L, luat_tp_data[i].event);
  50. lua_settable(L, -3);
  51. lua_pushstring(L, "track_id");
  52. lua_pushinteger(L, luat_tp_data[i].track_id);
  53. lua_settable(L, -3);
  54. lua_pushstring(L, "x");
  55. lua_pushinteger(L, luat_tp_data[i].x_coordinate);
  56. lua_settable(L, -3);
  57. lua_pushstring(L, "y");
  58. lua_pushinteger(L, luat_tp_data[i].y_coordinate);
  59. lua_settable(L, -3);
  60. lua_pushstring(L, "width");
  61. lua_pushinteger(L, luat_tp_data[i].width);
  62. lua_settable(L, -3);
  63. lua_pushstring(L, "timestamp");
  64. lua_pushinteger(L, luat_tp_data[i].timestamp);
  65. lua_settable(L, -3);
  66. lua_pushinteger(L, i + 1);
  67. lua_insert(L, -2);
  68. lua_settable(L, -3);
  69. }
  70. }
  71. lua_call(L, 2, 0);
  72. }
  73. }
  74. return 0;
  75. }
  76. int l_tp_callback(luat_tp_config_t* luat_tp_config, luat_tp_data_t* luat_tp_data){
  77. uint8_t i = 0;
  78. for(i = 0; i < LUAT_TP_TOUCH_MAX; i++) {
  79. if (luat_tp_data[i].event != TP_EVENT_TYPE_NONE) {
  80. rtos_msg_t msg = {.handler = l_tp_handler, .ptr=luat_tp_config, .arg1=luat_tp_data};
  81. luat_msgbus_put(&msg, 1);
  82. return 0;
  83. }
  84. }
  85. return -1;
  86. }
  87. /*
  88. 触摸初始化
  89. @api tp.init(tp, args)
  90. @string 触摸芯片型号,当前支持:<br>gt911 <br>gt9157 <br>jd9261t
  91. @table 附加参数,与具体设备有关:<br>port 驱动方式<br>port:硬件i2c端口,例如0,1,2...如果为软件i2c对象<br>pin_rst:复位引脚<br>pin_int:中断引脚<br>w:宽度(可选,默认会寻找已初始化的lcd的数据)<br>h:高度(可选,默认会寻找已初始化的lcd的数据)
  92. @function 回调函数(可选,使用lvgl时可不传入,lvgl会自动处理), 回调参数: <br>tp_device: userdata tp.init返回的触摸设备对象 <br>tp_data: table 触摸数据,内部为多个触摸点数据的表,每个表中包括参数有: event: number 触摸事件,见文档上方的触摸事件常量 x: number 触摸位置x坐标 y: number 触摸位置y坐标 timestamp: number 时间戳
  93. @return userdata tp_device:触摸设备对象
  94. @usage
  95. local function tp_callBack(tp_device, tp_data)
  96. log.info("TP", tp_data[1].x, tp_data[1].y, tp_data[1].event)
  97. sys.publish("TP", tp_device, tp_data)
  98. end
  99. -- 硬件i2c驱动
  100. --tp.init("gt911",{port=0,pin_rst = 22,pin_int = 23},tp_callBack)
  101. -- 软件i2c驱动
  102. --local softI2C = i2c.createSoft(20, 21)
  103. --tp.init("gt911",{port=softI2C,pin_rst = 22,pin_int = 23},tp_callBack)
  104. */
  105. static int l_tp_init(lua_State* L){
  106. int ret;
  107. size_t len = 0;
  108. luat_tp_config_t *luat_tp_config = (luat_tp_config_t *)luat_heap_malloc(sizeof(luat_tp_config_t));
  109. if (luat_tp_config == NULL) {
  110. LLOGE("out of system memory!!!");
  111. return 0;
  112. }
  113. memset(luat_tp_config, 0x00, sizeof(luat_tp_config_t));
  114. luat_tp_config->callback = l_tp_callback;
  115. luat_tp_config->pin_rst = LUAT_GPIO_NONE;
  116. #ifdef LUAT_USE_LCD
  117. luat_lcd_conf_t *lcd_conf = luat_lcd_get_default();
  118. if (lcd_conf){
  119. luat_tp_config->w = lcd_conf->w;
  120. luat_tp_config->h = lcd_conf->h;
  121. luat_tp_config->direction = lcd_conf->direction;
  122. if (lcd_conf->direction == LUAT_LCD_ROTATE_0 || lcd_conf->direction == LUAT_LCD_ROTATE_180){
  123. luat_tp_config->w = lcd_conf->w;
  124. luat_tp_config->h = lcd_conf->h;
  125. }else{
  126. luat_tp_config->w = lcd_conf->h;
  127. luat_tp_config->h = lcd_conf->w;
  128. }
  129. }
  130. #endif
  131. const char* tp_name = luaL_checklstring(L, 1, &len);
  132. for(int i = 0; i < 100; i++){
  133. if (strlen(tp_regs[i].name) == 0)
  134. break;
  135. if(strcmp(tp_regs[i].name,tp_name) == 0){
  136. luat_tp_config->opts = tp_regs[i].luat_tp_config;
  137. break;
  138. }
  139. }
  140. if (luat_tp_config->opts == NULL){
  141. LLOGE("tp_name:%s not found!!!", tp_name);
  142. return 0;
  143. }
  144. if (lua_isfunction(L, 3)) {
  145. lua_pushvalue(L, 3);
  146. luat_tp_config->luat_cb = luaL_ref(L, LUA_REGISTRYINDEX);
  147. }
  148. lua_settop(L, 2);
  149. lua_pushstring(L, "port");
  150. int port = lua_gettable(L, 2);
  151. if (LUA_TNUMBER == port) {
  152. luat_tp_config->i2c_id = luaL_checkinteger(L, -1);
  153. }else if(LUA_TUSERDATA == port){
  154. luat_tp_config->soft_i2c = (luat_ei2c_t*)lua_touserdata(L, -1);
  155. lua_pushvalue(L, -1);
  156. luat_tp_config->soft_i2c->ei2c_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  157. }else{
  158. LLOGE("port type error!!!");
  159. return 0;
  160. }
  161. lua_pop(L, 1);
  162. lua_pushstring(L, "pin_rst");
  163. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  164. luat_tp_config->pin_rst = luaL_checkinteger(L, -1);
  165. }
  166. lua_pop(L, 1);
  167. lua_pushstring(L, "pin_int");
  168. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  169. luat_tp_config->pin_int = luaL_checkinteger(L, -1);
  170. }
  171. lua_pop(L, 1);
  172. lua_pushstring(L, "w");
  173. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  174. luat_tp_config->w = luaL_checkinteger(L, -1);
  175. }
  176. lua_pop(L, 1);
  177. lua_pushstring(L, "h");
  178. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  179. luat_tp_config->h = luaL_checkinteger(L, -1);
  180. }
  181. lua_pop(L, 1);
  182. lua_pushstring(L, "refresh_rate");
  183. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  184. luat_tp_config->refresh_rate = luaL_checkinteger(L, -1);
  185. }
  186. lua_pop(L, 1);
  187. lua_pushstring(L, "int_type");
  188. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  189. luat_tp_config->int_type = luaL_checkinteger(L, -1);
  190. }
  191. lua_pop(L, 1);
  192. lua_pushstring(L, "tp_num");
  193. if (LUA_TNUMBER == lua_gettable(L, 2)) {
  194. luat_tp_config->tp_num = luaL_checkinteger(L, -1);
  195. }
  196. lua_pop(L, 1);
  197. // lua_pushstring(L, "swap_xy");
  198. // if (LUA_TBOOLEAN == lua_gettable(L, 2)) {
  199. // luat_tp_config->swap_xy = lua_toboolean(L, -1);
  200. // }
  201. // lua_pop(L, 1);
  202. ret = luat_tp_init(luat_tp_config);
  203. if (ret){
  204. // luat_tp_deinit(luat_tp_config);
  205. return 0;
  206. }else{
  207. lua_pushlightuserdata(L, luat_tp_config);
  208. return 1;
  209. }
  210. }
  211. #include "rotable2.h"
  212. static const rotable_Reg_t reg_tp[] =
  213. {
  214. { "init", ROREG_FUNC(l_tp_init)},
  215. //@const EVENT_NONE number 空事件,不应出现
  216. { "EVENT_NONE", ROREG_INT(TP_EVENT_TYPE_NONE)},
  217. //@const EVENT_DOWN number 按下
  218. { "EVENT_DOWN", ROREG_INT(TP_EVENT_TYPE_DOWN)},
  219. //@const EVENT_UP number 抬起
  220. { "EVENT_UP", ROREG_INT(TP_EVENT_TYPE_UP)},
  221. //@const EVENT_MOVE number 移动
  222. { "EVENT_MOVE", ROREG_INT(TP_EVENT_TYPE_MOVE)},
  223. { "EVENT_TYPE_DOWN", ROREG_INT(TP_EVENT_TYPE_DOWN)},
  224. { "EVENT_TYPE_DOWN", ROREG_INT(TP_EVENT_TYPE_DOWN)},
  225. { "EVENT_TYPE_UP", ROREG_INT(TP_EVENT_TYPE_UP)},
  226. { "EVENT_TYPE_MOVE", ROREG_INT(TP_EVENT_TYPE_MOVE)},
  227. { "RISING", ROREG_INT(LUAT_GPIO_RISING_IRQ)},
  228. { "FALLING", ROREG_INT(LUAT_GPIO_FALLING_IRQ)},
  229. { NULL, ROREG_INT(0) }
  230. };
  231. LUAMOD_API int luaopen_tp(lua_State *L)
  232. {
  233. luat_newlib2(L, reg_tp);
  234. return 1;
  235. }