luat_lib_tp.c 8.8 KB

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