luat_lib_u8g2.c 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194
  1. /*
  2. @module u8g2
  3. @summary u8g2图形处理库
  4. @author Dozingfiretruck
  5. @version 1.0
  6. @date 2021.01.25
  7. */
  8. #include "luat_base.h"
  9. #include "luat_malloc.h"
  10. #include "luat_u8g2.h"
  11. #include "luat_gpio.h"
  12. #include "luat_timer.h"
  13. #include "luat_i2c.h"
  14. #include "luat_spi.h"
  15. #include "u8g2.h"
  16. #include "u8g2_luat_fonts.h"
  17. #include "../qrcode/qrcode.h"
  18. #define LUAT_LOG_TAG "u8g2"
  19. #include "luat_log.h"
  20. enum
  21. {
  22. font_opposansm8,
  23. font_opposansm12_chinese,
  24. font_unifont_t_symbols,
  25. font_open_iconic_weather_6x_t,
  26. };
  27. static u8g2_t* u8g2;
  28. static int u8g2_lua_ref;
  29. static uint8_t i2c_id;
  30. static uint8_t i2c_speed;
  31. static uint8_t i2c_scl;
  32. static uint8_t i2c_sda;
  33. // static uint8_t i2c_addr = 0x3C;
  34. static uint8_t spi_id;
  35. static uint8_t spi_res;
  36. static uint8_t spi_dc;
  37. static uint8_t spi_cs;
  38. /*
  39. u8g2显示屏初始化
  40. @api u8g2.begin(conf)
  41. @table conf 配置信息
  42. @return int 正常初始化1,已经初始化过2,内存不够3,初始化失败返回4
  43. @usage
  44. -- 初始化硬件i2c的ssd1306
  45. u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_hw",i2c_id=0}) -- direction 可选0 90 180 270
  46. -- 初始化软件i2c的ssd1306
  47. u8g2.begin({ic = "ssd1306",direction = 0,mode="i2c_sw", i2c_scl=1, i2c_sda=4}) -- 通过PA1 SCL / PA4 SDA模拟
  48. */
  49. static int l_u8g2_begin(lua_State *L) {
  50. if (u8g2 != NULL) {
  51. LLOGW("disp is aready inited");
  52. lua_pushinteger(L, 2);
  53. return 1;
  54. }
  55. u8g2 = (u8g2_t*)lua_newuserdata(L, sizeof(u8g2_t));
  56. if (u8g2 == NULL) {
  57. LLOGE("lua_newuserdata return NULL, out of memory ?!");
  58. lua_pushinteger(L, 3);
  59. return 1;
  60. }
  61. luat_u8g2_conf_t conf = {0};
  62. conf.pinType = 2; // I2C 硬件(或者是个假硬件)
  63. conf.ptr = u8g2;
  64. conf.direction = U8G2_R0;
  65. if (lua_istable(L, 1)) {
  66. // 参数解析
  67. lua_pushliteral(L, "ic");
  68. lua_gettable(L, 1);
  69. if (lua_isstring(L, -1)) {
  70. conf.cname = (char*)luaL_checkstring(L, -1);
  71. LLOGD("using ic: %s",conf.cname);
  72. }
  73. lua_pop(L, 1);
  74. lua_pushliteral(L, "direction");
  75. lua_gettable(L, 1);
  76. if (lua_isinteger(L, -1)) {
  77. int direction = luaL_checkinteger(L, -1);
  78. switch (direction)
  79. {
  80. case 0:
  81. conf.direction = U8G2_R0;
  82. break;
  83. case 90:
  84. conf.direction = U8G2_R1;
  85. break;
  86. case 180:
  87. conf.direction = U8G2_R2;
  88. break;
  89. case 270:
  90. conf.direction = U8G2_R3;
  91. break;
  92. default:
  93. conf.direction = U8G2_R0;
  94. break;
  95. }
  96. }
  97. lua_pop(L, 1);
  98. lua_pushliteral(L, "mode");
  99. lua_gettable(L, 1);
  100. if (lua_isstring(L, -1)) {
  101. const char* mode = luaL_checkstring(L, -1);
  102. LLOGD("mode = [%s]", mode);
  103. if (strcmp("i2c_sw", mode) == 0) {
  104. LLOGD("using i2c_sw");
  105. conf.pinType = 1;
  106. }
  107. else if (strcmp("i2c_hw", mode) == 0) {
  108. LLOGD("using i2c_hw");
  109. conf.pinType = 2;
  110. }
  111. else if (strcmp("spi_sw_3pin", mode) == 0) {
  112. LLOGD("using spi_sw_3pin");
  113. conf.pinType = 3;
  114. }
  115. else if (strcmp("spi_sw_4pin", mode) == 0) {
  116. LLOGD("using spi_sw_4pin");
  117. conf.pinType = 4;
  118. }
  119. else if (strcmp("spi_hw_4pin", mode) == 0) {
  120. LLOGD("using spi_hw_4pin");
  121. conf.pinType = 5;
  122. }
  123. }
  124. lua_pop(L, 1);
  125. lua_pushliteral(L, "i2c_scl");
  126. lua_gettable(L, 1);
  127. if (lua_isinteger(L, -1)) {
  128. i2c_scl = luaL_checkinteger(L, -1);
  129. }
  130. lua_pop(L, 1);
  131. lua_pushliteral(L, "i2c_sda");
  132. lua_gettable(L, 1);
  133. if (lua_isinteger(L, -1)) {
  134. i2c_sda = luaL_checkinteger(L, -1);
  135. }
  136. lua_pop(L, 1);
  137. lua_pushliteral(L, "i2c_id");
  138. lua_gettable(L, 1);
  139. if (lua_isinteger(L, -1)) {
  140. i2c_id = luaL_checkinteger(L, -1);
  141. }
  142. lua_pop(L, 1);
  143. lua_pushliteral(L, "i2c_speed");
  144. lua_gettable(L, 1);
  145. if (lua_isinteger(L, -1)) {
  146. i2c_speed = luaL_checkinteger(L, -1);
  147. }
  148. lua_pop(L, 1);
  149. lua_pushliteral(L, "spi_id");
  150. lua_gettable(L, 1);
  151. if (lua_isinteger(L, -1)) {
  152. spi_id = luaL_checkinteger(L, -1);
  153. LLOGD("spi_id=%d", spi_id);
  154. }
  155. lua_pop(L, 1);
  156. lua_pushliteral(L, "spi_res");
  157. lua_gettable(L, 1);
  158. if (lua_isinteger(L, -1)) {
  159. spi_res = luaL_checkinteger(L, -1);
  160. LLOGD("spi_res=%d", spi_res);
  161. }
  162. lua_pop(L, 1);
  163. lua_pushliteral(L, "spi_dc");
  164. lua_gettable(L, 1);
  165. if (lua_isinteger(L, -1)) {
  166. spi_dc = luaL_checkinteger(L, -1);
  167. LLOGD("spi_dc=%d", spi_dc);
  168. }
  169. lua_pop(L, 1);
  170. lua_pushliteral(L, "spi_cs");
  171. lua_gettable(L, 1);
  172. if (lua_isinteger(L, -1)) {
  173. spi_cs = luaL_checkinteger(L, -1);
  174. LLOGD("spi_cs=%d", spi_cs);
  175. }
  176. lua_pop(L, 1);
  177. }
  178. LLOGD("pinType=%d", conf.pinType);
  179. if (luat_u8g2_setup(&conf)) {
  180. u8g2 = NULL;
  181. LLOGW("disp init fail");
  182. lua_pushinteger(L, 4);
  183. return 1; // 初始化失败
  184. }
  185. u8g2_lua_ref = luaL_ref(L, LUA_REGISTRYINDEX);
  186. u8g2_SetFont(u8g2, u8g2_font_ncenB08_tr); // 设置默认字体
  187. lua_pushinteger(L, 1);
  188. return 1;
  189. }
  190. /*
  191. 关闭显示屏
  192. @api u8g2.close()
  193. @usage
  194. -- 关闭disp,再次使用disp相关API的话,需要重新初始化
  195. u8g2.close()
  196. */
  197. static int l_u8g2_close(lua_State *L) {
  198. if (u8g2_lua_ref != 0) {
  199. lua_geti(L, LUA_REGISTRYINDEX, u8g2_lua_ref);
  200. if (lua_isuserdata(L, -1)) {
  201. luaL_unref(L, LUA_REGISTRYINDEX, u8g2_lua_ref);
  202. }
  203. u8g2_lua_ref = 0;
  204. }
  205. lua_gc(L, LUA_GCCOLLECT, 0);
  206. u8g2 = NULL;
  207. return 0;
  208. }
  209. /*
  210. 清屏,清除内存帧缓冲区中的所有像素
  211. @api u8g2.ClearBuffer()
  212. @usage
  213. -- 清屏
  214. u8g2.ClearBuffer()
  215. */
  216. static int l_u8g2_ClearBuffer(lua_State *L) {
  217. if (u8g2 == NULL) return 0;
  218. u8g2_ClearBuffer(u8g2);
  219. return 0;
  220. }
  221. /*
  222. 将数据更新到屏幕,将存储器帧缓冲区的内容发送到显示器
  223. @api u8g2.SendBuffer()
  224. @usage
  225. -- 把显示数据更新到屏幕
  226. u8g2.SendBuffer()
  227. */
  228. static int l_u8g2_SendBuffer(lua_State *L) {
  229. if (u8g2 == NULL) return 0;
  230. u8g2_SendBuffer(u8g2);
  231. return 0;
  232. }
  233. /*
  234. 在显示屏上画一段文字,在显示屏上画一段文字,要调用u8g2.SendBuffer()才会更新到屏幕
  235. @api u8g2.DrawUTF8(str, x, y)
  236. @string 文件内容
  237. @int 横坐标
  238. @int 竖坐标
  239. @usage
  240. u8g2.DrawUTF8("wifi is ready", 10, 20)
  241. */
  242. static int l_u8g2_DrawUTF8(lua_State *L) {
  243. if (u8g2 == NULL) {
  244. LLOGW("disp not init yet!!!");
  245. return 0;
  246. }
  247. size_t len;
  248. size_t x, y;
  249. const char* str = luaL_checklstring(L, 1, &len);
  250. x = luaL_checkinteger(L, 2);
  251. y = luaL_checkinteger(L, 3);
  252. u8g2_DrawUTF8(u8g2, x, y, str);
  253. return 0;
  254. }
  255. /*
  256. 设置字体模式
  257. @api u8g2.SetFontMode(mode)
  258. @int mode字体模式,启用(1)或禁用(0)透明模式
  259. @usage
  260. u8g2.SetFontMode(1)
  261. */
  262. static int l_u8g2_SetFontMode(lua_State *L){
  263. if (u8g2 == NULL) return 0;
  264. int font_mode = luaL_checkinteger(L, 1);
  265. if (font_mode < 0) {
  266. lua_pushboolean(L, 0);
  267. }
  268. u8g2_SetFontMode(u8g2, font_mode);
  269. u8g2_SetFontDirection(u8g2, 0);
  270. lua_pushboolean(L, 1);
  271. return 1;
  272. }
  273. /*
  274. 设置字体
  275. @api u8g2.SetFont(font)
  276. @int font, u8g2.font_ncenB08_tr为纯英文8x8字节,u8g2.font_opposansm12_chinese 为12x12全中文,u8g2.font_unifont_t_symbols 为符号.
  277. @usage
  278. -- 设置为中文字体,对之后的drawStr有效,使用中文字体需在 luat_conf_bsp.h开启#define USE_U8G2_OPPOSANSM12_CHINESE
  279. u8g2.setFont(u8g2.font_wqy12_t_gb2312)
  280. */
  281. static int l_u8g2_SetFont(lua_State *L) {
  282. if (u8g2 == NULL) {
  283. LLOGI("disp not init yet!!!");
  284. lua_pushboolean(L, 0);
  285. return 1;
  286. }
  287. int font = luaL_checkinteger(L, 1);
  288. switch (font)
  289. {
  290. case font_opposansm8:
  291. LLOGI("font_opposansm8");
  292. u8g2_SetFont(u8g2, u8g2_font_opposansm8);
  293. lua_pushboolean(L, 1);
  294. break;
  295. #if defined USE_U8G2_OPPOSANSM12_CHINESE
  296. case font_opposansm12_chinese:
  297. LLOGI("font_opposansm12_chinese");
  298. u8g2_SetFont(u8g2, u8g2_font_opposansm12_chinese);
  299. lua_pushboolean(L, 1);
  300. break;
  301. #endif
  302. #if defined USE_U8G2_UNIFONT_SYMBOLS
  303. case font_unifont_t_symbols:
  304. LLOGI("font_unifont_t_symbols");
  305. u8g2_SetFont(u8g2, u8g2_font_unifont_t_symbols);
  306. lua_pushboolean(L, 1);
  307. break;
  308. #endif
  309. #if defined USE_U8G2_ICONIC_WEATHER_6X
  310. case font_open_iconic_weather_6x_t:
  311. LLOGI("font_open_iconic_weather_6x_t");
  312. u8g2_SetFont(u8g2, u8g2_font_open_iconic_weather_6x_t);
  313. lua_pushboolean(L, 1);
  314. break;
  315. #endif
  316. default:
  317. lua_pushboolean(L, 0);
  318. LLOGI("default");
  319. break;
  320. }
  321. return 0;
  322. }
  323. /*
  324. 获取显示屏高度
  325. @api u8g2.GetDisplayHeight()
  326. @return int 显示屏高度
  327. @usage
  328. u8g2.GetDisplayHeight()
  329. */
  330. static int l_u8g2_GetDisplayHeight(lua_State *L){
  331. if (u8g2 == NULL) return 0;
  332. lua_pushinteger(L, u8g2_GetDisplayHeight(u8g2));
  333. return 1;
  334. }
  335. /*
  336. 获取显示屏宽度
  337. @api u8g2.GetDisplayWidth()
  338. @return int 显示屏宽度
  339. @usage
  340. u8g2.GetDisplayWidth()
  341. */
  342. static int l_u8g2_GetDisplayWidth(lua_State *L){
  343. if (u8g2 == NULL) return 0;
  344. lua_pushinteger(L, u8g2_GetDisplayWidth(u8g2));
  345. return 1;
  346. }
  347. /*
  348. 画一个点.
  349. @api u8g2.DrawPixel(x,y)
  350. @int X位置.
  351. @int Y位置.
  352. @usage
  353. u8g2.DrawPixel(20, 5)
  354. */
  355. static int l_u8g2_DrawPixel(lua_State *L){
  356. if (u8g2 == NULL) return 0;
  357. u8g2_DrawPixel(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2));
  358. return 1;
  359. }
  360. /*
  361. 在两点之间画一条线.
  362. @api u8g2.DrawLine(x0,y0,x1,y1)
  363. @int 第一个点的X位置.
  364. @int 第一个点的Y位置.
  365. @int 第二个点的X位置.
  366. @int 第二个点的Y位置.
  367. @usage
  368. u8g2.DrawLine(20, 5, 5, 32)
  369. */
  370. static int l_u8g2_DrawLine(lua_State *L){
  371. if (u8g2 == NULL) return 0;
  372. u8g2_DrawLine(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4));
  373. return 1;
  374. }
  375. /*
  376. 在x,y位置画一个半径为rad的空心圆.
  377. @api u8g2.DrawCircle(x0,y0,rad,opt)
  378. @int 圆心位置
  379. @int 圆心位置
  380. @int 圆半径.
  381. @int 选择圆的部分或全部.
  382. 右上: 0x01
  383. 左上: 0x02
  384. 左下: 0x04
  385. 右下: 0x08
  386. 完整圆: (0x01|0x02|0x04|0x08)
  387. @usage
  388. u8g2.DrawCircle(60,30,8,15)
  389. */
  390. static int l_u8g2_DrawCircle(lua_State *L){
  391. if (u8g2 == NULL) return 0;
  392. u8g2_DrawCircle(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4));
  393. return 1;
  394. }
  395. /*
  396. 在x,y位置画一个半径为rad的实心圆.
  397. @api u8g2.DrawDisc(x0,y0,rad,opt)
  398. @int 圆心位置
  399. @int 圆心位置
  400. @int 圆半径.
  401. @int 选择圆的部分或全部.
  402. 右上: 0x01
  403. 左上: 0x02
  404. 左下: 0x04
  405. 右下: 0x08
  406. 完整圆: (0x01|0x02|0x04|0x08)
  407. @usage
  408. u8g2.DrawDisc(60,30,8,15)
  409. */
  410. static int l_u8g2_DrawDisc(lua_State *L){
  411. if (u8g2 == NULL) return 0;
  412. u8g2_DrawDisc(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4));
  413. return 1;
  414. }
  415. /*
  416. 在x,y位置画一个半径为rad的空心椭圆.
  417. @api u8g2.DrawEllipse(x0,y0,rx,ry,opt)
  418. @int 圆心位置
  419. @int 圆心位置
  420. @int 椭圆大小
  421. @int 椭圆大小
  422. @int 选择圆的部分或全部.
  423. 右上: 0x01
  424. 左上: 0x02
  425. 左下: 0x04
  426. 右下: 0x08
  427. 完整圆: (0x01|0x02|0x04|0x08)
  428. @usage
  429. u8g2.DrawEllipse(60,30,8,15)
  430. */
  431. static int l_u8g2_DrawEllipse(lua_State *L){
  432. if (u8g2 == NULL) return 0;
  433. u8g2_DrawEllipse(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4),luaL_checkinteger(L, 5));
  434. return 0;
  435. }
  436. /*
  437. 在x,y位置画一个半径为rad的实心椭圆.
  438. @api u8g2.DrawFilledEllipse(x0,y0,rx,ry,opt)
  439. @int 圆心位置
  440. @int 圆心位置
  441. @int 椭圆大小
  442. @int 椭圆大小
  443. @int 选择圆的部分或全部.
  444. 右上: 0x01
  445. 左上: 0x02
  446. 左下: 0x04
  447. 右下: 0x08
  448. 完整圆: (0x01|0x02|0x04|0x08)
  449. @usage
  450. u8g2.DrawFilledEllipse(60,30,8,15)
  451. */
  452. static int l_u8g2_DrawFilledEllipse(lua_State *L){
  453. if (u8g2 == NULL) return 0;
  454. u8g2_DrawFilledEllipse(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4),luaL_checkinteger(L, 5));
  455. return 0;
  456. }
  457. /*
  458. 从x / y位置(左上边缘)开始绘制一个框(填充的框).
  459. @api u8g2.DrawBox(x,y,w,h)
  460. @int 左上边缘的X位置
  461. @int 左上边缘的Y位置
  462. @int 盒子的宽度
  463. @int 盒子的高度
  464. @usage
  465. u8g2.DrawBox(3,7,25,15)
  466. */
  467. static int l_u8g2_DrawBox(lua_State *L){
  468. if (u8g2 == NULL) return 0;
  469. u8g2_DrawBox(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4));
  470. return 0;
  471. }
  472. /*
  473. 从x / y位置(左上边缘)开始绘制一个框(空框).
  474. @api u8g2.DrawFrame(x,y,w,h)
  475. @int 左上边缘的X位置
  476. @int 左上边缘的Y位置
  477. @int 盒子的宽度
  478. @int 盒子的高度
  479. @usage
  480. u8g2.DrawFrame(3,7,25,15)
  481. */
  482. static int l_u8g2_DrawFrame(lua_State *L){
  483. if (u8g2 == NULL) return 0;
  484. u8g2_DrawFrame(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4));
  485. return 0;
  486. }
  487. /*
  488. 绘制一个从x / y位置(左上边缘)开始具有圆形边缘的填充框/框架.
  489. @api u8g2.DrawRBox(x,y,w,h,r)
  490. @int 左上边缘的X位置
  491. @int 左上边缘的Y位置
  492. @int 盒子的宽度
  493. @int 盒子的高度
  494. @int 四个边缘的半径
  495. @usage
  496. u8g2.DrawRBox(3,7,25,15)
  497. */
  498. static int l_u8g2_DrawRBox(lua_State *L){
  499. if (u8g2 == NULL) return 0;
  500. u8g2_DrawRBox(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4),luaL_checkinteger(L, 5));
  501. return 0;
  502. }
  503. /*
  504. 绘制一个从x / y位置(左上边缘)开始具有圆形边缘的空框/框架.
  505. @api u8g2.DrawRFrame(x,y,w,h,r)
  506. @int 左上边缘的X位置
  507. @int 左上边缘的Y位置
  508. @int 盒子的宽度
  509. @int 盒子的高度
  510. @int 四个边缘的半径
  511. @usage
  512. u8g2.DrawRFrame(3,7,25,15)
  513. */
  514. static int l_u8g2_DrawRFrame(lua_State *L){
  515. if (u8g2 == NULL) return 0;
  516. u8g2_DrawRFrame(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4),luaL_checkinteger(L, 5));
  517. return 0;
  518. }
  519. /*
  520. 绘制一个图形字符。字符放置在指定的像素位置x和y.
  521. @api u8g2.DrawGlyph(x,y,encoding)
  522. @int 字符在显示屏上的位置
  523. @int 字符在显示屏上的位置
  524. @int 字符的Unicode值
  525. @usage
  526. u8g2.SetFont(u8g2_font_unifont_t_symbols)
  527. u8g2.DrawGlyph(5, 20, 0x2603) -- dec 9731/hex 2603 Snowman
  528. */
  529. static int l_u8g2_DrawGlyph(lua_State *L){
  530. if (u8g2 == NULL) return 0;
  531. u8g2_DrawGlyph(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3));
  532. return 0;
  533. }
  534. /*
  535. 绘制一个三角形(实心多边形).
  536. @api u8g2.DrawTriangle(x0,y0,x1,y1,x2,y2)
  537. @int 点0X位置
  538. @int 点0Y位置
  539. @int 点1X位置
  540. @int 点1Y位置
  541. @int 点2X位置
  542. @int 点2Y位置
  543. @usage
  544. u8g2.DrawTriangle(20,5, 27,50, 5,32)
  545. */
  546. static int l_u8g2_DrawTriangle(lua_State *L){
  547. if (u8g2 == NULL) return 0;
  548. u8g2_DrawTriangle(u8g2,luaL_checkinteger(L, 1),luaL_checkinteger(L, 2),luaL_checkinteger(L, 3),luaL_checkinteger(L, 4),luaL_checkinteger(L, 5),luaL_checkinteger(L, 6));
  549. return 0;
  550. }
  551. /*
  552. 定义位图函数是否将写入背景色
  553. @api u8g2.SetBitmapMode(mode)
  554. @int mode字体模式,启用(1)或禁用(0)透明模式
  555. @usage
  556. u8g2.SetBitmapMode(1)
  557. */
  558. static int l_u8g2_SetBitmapMode(lua_State *L){
  559. if (u8g2 == NULL) return 0;
  560. u8g2_SetBitmapMode(u8g2,luaL_checkinteger(L, 1));
  561. return 0;
  562. }
  563. /*
  564. 绘制位图
  565. @api u8g2.DrawXBM(x, y, w, h, data)
  566. @int X坐标
  567. @int y坐标
  568. @int 位图宽
  569. @int 位图高
  570. @int 位图数据,每一位代表一个像素
  571. @usage
  572. -- 取模使用PCtoLCD2002软件即可
  573. -- 在(0,0)为左上角,绘制 16x16 "今" 的位图
  574. u8g2.DrawXBM(0, 0, 16,16, string.char(
  575. 0x80,0x00,0x80,0x00,0x40,0x01,0x20,0x02,0x10,0x04,0x48,0x08,0x84,0x10,0x83,0x60,
  576. 0x00,0x00,0xF8,0x0F,0x00,0x08,0x00,0x04,0x00,0x04,0x00,0x02,0x00,0x01,0x80,0x00
  577. ))
  578. */
  579. static int l_u8g2_DrawXBM(lua_State *L){
  580. if (u8g2 == NULL) return 0;
  581. int x = luaL_checkinteger(L, 1);
  582. int y = luaL_checkinteger(L, 2);
  583. int w = luaL_checkinteger(L, 3);
  584. int h = luaL_checkinteger(L, 4);
  585. size_t len = 0;
  586. const char* data = luaL_checklstring(L, 5, &len);
  587. if (h < 1) return 0; // 行数必须大于0
  588. if (w < h) return 0; // 起码要填满一行
  589. //if (len % h != 0) return 0; // 必须是行数的整数倍
  590. u8g2_DrawXBM(u8g2, x, y, w, h, (const uint8_t*)data);
  591. lua_pushboolean(L, 1);
  592. return 1;
  593. }
  594. /**
  595. 缓冲区绘制QRCode
  596. @api u8g2.DrawDrcode(x, y, str, version)
  597. @int x坐标
  598. @int y坐标
  599. @string 二维码的内容
  600. @int 二维码版本号 可选1_40 对应21*21到177*177
  601. @return nil 无返回值
  602. */
  603. static int l_u8g2_DrawDrcode(lua_State *L)
  604. {
  605. size_t len;
  606. int x = luaL_checkinteger(L, 1);
  607. int y = luaL_checkinteger(L, 2);
  608. const char* str = luaL_checklstring(L, 3, &len);
  609. int version = luaL_checkinteger(L, 4);
  610. // Create the QR code
  611. QRCode qrcode;
  612. uint8_t qrcodeData[qrcode_getBufferSize(version)];
  613. qrcode_initText(&qrcode, qrcodeData, version, 0, str);
  614. for(int i = 0; i < qrcode.size; i++)
  615. {
  616. for (int j = 0; j < qrcode.size; j++)
  617. {
  618. if(qrcode_getModule(&qrcode, j, i)) u8g2_DrawPixel(u8g2, x+j, y+i);
  619. }
  620. }
  621. return 0;
  622. }
  623. #ifdef LUAT_USE_GTFONT
  624. #include "GT5SLCD2E_1A.h"
  625. extern void gtfont_draw_w(unsigned char *pBits,unsigned int x,unsigned int y,unsigned int widt,unsigned int high,int(*point)(void*),void* userdata,int mode);
  626. extern void gtfont_draw_gray_hz(unsigned char *data,unsigned short x,unsigned short y,unsigned short w ,unsigned short h,unsigned char grade, unsigned char HB_par,int(*point)(void*,uint16_t, uint16_t, uint32_t),void* userdata,int mode);
  627. static int gtfont_u8g2_DrawPixel(u8g2_t *u8g2, uint16_t x, uint16_t y,uint32_t color){
  628. u8g2_DrawPixel(u8g2,x, y);
  629. return 1;
  630. }
  631. /*
  632. 使用gtfont显示gb2312字符串
  633. @api u8g2.drawGtfontGb2312(str,size,x,y)
  634. @string str 显示字符串
  635. @int size 字体大小 (支持16-192号大小字体)
  636. @int x 横坐标
  637. @int y 竖坐标
  638. @usage
  639. u8g2.drawGtfontGb2312("啊啊啊",32,0,0)
  640. */
  641. static int l_u8g2_draw_gtfont_gb2312(lua_State *L) {
  642. unsigned char buf[128];
  643. int len;
  644. int i = 0;
  645. uint8_t strhigh,strlow ;
  646. uint16_t str;
  647. const char *fontCode = luaL_checklstring(L, 1,&len);
  648. unsigned char size = luaL_checkinteger(L, 2);
  649. int x = luaL_checkinteger(L, 3);
  650. int y = luaL_checkinteger(L, 4);
  651. while ( i < len){
  652. strhigh = *fontCode;
  653. fontCode++;
  654. strlow = *fontCode;
  655. str = (strhigh<<8)|strlow;
  656. fontCode++;
  657. get_font(buf, 1, str, size, size, size);
  658. gtfont_draw_w(buf , x ,y , size , size,gtfont_u8g2_DrawPixel,u8g2,2);
  659. x+=size;
  660. i+=2;
  661. }
  662. return 0;
  663. }
  664. #ifdef LUAT_USE_GTFONT_UTF8
  665. extern unsigned short unicodetogb2312 ( unsigned short chr);
  666. static uint8_t utf8_state;
  667. static uint16_t encoding;
  668. static uint16_t utf8_next(uint8_t b)
  669. {
  670. if ( b == 0 ) /* '\n' terminates the string to support the string list procedures */
  671. return 0x0ffff; /* end of string detected, pending UTF8 is discarded */
  672. if ( utf8_state == 0 )
  673. {
  674. if ( b >= 0xfc ) /* 6 byte sequence */
  675. {
  676. utf8_state = 5;
  677. b &= 1;
  678. }
  679. else if ( b >= 0xf8 )
  680. {
  681. utf8_state = 4;
  682. b &= 3;
  683. }
  684. else if ( b >= 0xf0 )
  685. {
  686. utf8_state = 3;
  687. b &= 7;
  688. }
  689. else if ( b >= 0xe0 )
  690. {
  691. utf8_state = 2;
  692. b &= 15;
  693. }
  694. else if ( b >= 0xc0 )
  695. {
  696. utf8_state = 1;
  697. b &= 0x01f;
  698. }
  699. else
  700. {
  701. /* do nothing, just use the value as encoding */
  702. return b;
  703. }
  704. encoding = b;
  705. return 0x0fffe;
  706. }
  707. else
  708. {
  709. utf8_state--;
  710. /* The case b < 0x080 (an illegal UTF8 encoding) is not checked here. */
  711. encoding<<=6;
  712. b &= 0x03f;
  713. encoding |= b;
  714. if ( utf8_state != 0 )
  715. return 0x0fffe; /* nothing to do yet */
  716. }
  717. return encoding;
  718. }
  719. /*
  720. 使用gtfont显示UTF8字符串
  721. @api u8g2.drawGtfontUtf8(str,size,x,y)
  722. @string str 显示字符串
  723. @int size 字体大小 (支持16-192号大小字体)
  724. @int x 横坐标
  725. @int y 竖坐标
  726. @usage
  727. u8g2.drawGtfontUtf8("啊啊啊",32,0,0)
  728. */
  729. static int l_u8g2_draw_gtfont_utf8(lua_State *L) {
  730. unsigned char buf[128];
  731. int len;
  732. int i = 0;
  733. uint8_t strhigh,strlow ;
  734. uint16_t e,str;
  735. const char *fontCode = luaL_checklstring(L, 1,&len);
  736. unsigned char size = luaL_checkinteger(L, 2);
  737. int x = luaL_checkinteger(L, 3);
  738. int y = luaL_checkinteger(L, 4);
  739. for(;;){
  740. e = utf8_next((uint8_t)*fontCode);
  741. if ( e == 0x0ffff )
  742. break;
  743. fontCode++;
  744. if ( e != 0x0fffe ){
  745. uint16_t str = unicodetogb2312(e);
  746. get_font(buf, 1, str, size, size, size);
  747. gtfont_draw_w(buf , x ,y , size , size,gtfont_u8g2_DrawPixel,u8g2,2);
  748. x+=size;
  749. }
  750. }
  751. return 0;
  752. }
  753. #endif // LUAT_USE_GTFONT_UTF8
  754. #endif // LUAT_USE_GTFONT
  755. #include "rotable2.h"
  756. static const rotable_Reg_t reg_u8g2[] =
  757. {
  758. { "begin", ROREG_FUNC(l_u8g2_begin)},
  759. { "close", ROREG_FUNC(l_u8g2_close)},
  760. { "ClearBuffer", ROREG_FUNC(l_u8g2_ClearBuffer)},
  761. { "SendBuffer", ROREG_FUNC(l_u8g2_SendBuffer)},
  762. { "DrawUTF8", ROREG_FUNC(l_u8g2_DrawUTF8)},
  763. { "SetFontMode", ROREG_FUNC(l_u8g2_SetFontMode)},
  764. { "SetFont", ROREG_FUNC(l_u8g2_SetFont)},
  765. { "GetDisplayHeight", ROREG_FUNC(l_u8g2_GetDisplayHeight)},
  766. { "GetDisplayWidth", ROREG_FUNC(l_u8g2_GetDisplayWidth)},
  767. { "DrawPixel", ROREG_FUNC(l_u8g2_DrawPixel)},
  768. { "DrawLine", ROREG_FUNC(l_u8g2_DrawLine)},
  769. { "DrawCircle", ROREG_FUNC(l_u8g2_DrawCircle)},
  770. { "DrawDisc", ROREG_FUNC(l_u8g2_DrawDisc)},
  771. { "DrawEllipse", ROREG_FUNC(l_u8g2_DrawEllipse)},
  772. { "DrawFilledEllipse", ROREG_FUNC(l_u8g2_DrawFilledEllipse)},
  773. { "DrawBox", ROREG_FUNC(l_u8g2_DrawBox)},
  774. { "DrawFrame", ROREG_FUNC(l_u8g2_DrawFrame)},
  775. { "DrawRBox", ROREG_FUNC(l_u8g2_DrawRBox)},
  776. { "DrawRFrame", ROREG_FUNC(l_u8g2_DrawRFrame)},
  777. { "DrawGlyph", ROREG_FUNC(l_u8g2_DrawGlyph)},
  778. { "DrawTriangle", ROREG_FUNC(l_u8g2_DrawTriangle)},
  779. { "SetBitmapMode",ROREG_FUNC(l_u8g2_SetBitmapMode)},
  780. { "DrawXBM", ROREG_FUNC(l_u8g2_DrawXBM)},
  781. { "DrawDrcode", ROREG_FUNC(l_u8g2_DrawDrcode)},
  782. #ifdef LUAT_USE_GTFONT
  783. { "drawGtfontGb2312", ROREG_FUNC(l_u8g2_draw_gtfont_gb2312)},
  784. #ifdef LUAT_USE_GTFONT_UTF8
  785. { "drawGtfontUtf8", ROREG_FUNC(l_u8g2_draw_gtfont_utf8)},
  786. #endif // LUAT_USE_GTFONT_UTF8
  787. #endif // LUAT_USE_GTFONT
  788. { "font_opposansm8", ROREG_INT(font_opposansm8)},
  789. { "font_opposansm12_chinese", ROREG_INT(font_opposansm12_chinese)},
  790. { "font_unifont_t_symbols", ROREG_INT(font_unifont_t_symbols)},
  791. { "font_open_iconic_weather_6x_t", ROREG_INT(font_open_iconic_weather_6x_t)},
  792. { NULL, {}}
  793. };
  794. LUAMOD_API int luaopen_u8g2( lua_State *L ) {
  795. u8g2_lua_ref = 0;
  796. u8g2 = NULL;
  797. luat_newlib2(L, reg_u8g2);
  798. return 1;
  799. }
  800. //-----------------------------
  801. // 往下是一些U8G2方法的默认实现
  802. uint8_t u8x8_luat_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  803. uint8_t u8x8_luat_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  804. uint8_t u8x8_luat_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr);
  805. LUAT_WEAK int luat_u8g2_setup(luat_u8g2_conf_t *conf) {
  806. if (conf->pinType == 1) {
  807. u8g2_t* u8g2 = (u8g2_t*)conf->ptr;
  808. if (strncmp("ssd1306", conf->cname, 7) == 0 || strncmp("SSD1306", conf->cname, 7) == 0){
  809. u8g2_Setup_ssd1306_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_byte_sw_i2c, u8x8_luat_gpio_and_delay);
  810. #ifdef U8G2_USE_SH1106
  811. }else if (strncmp("sh1106", conf->cname, 6) == 0 || strncmp("SH1106", conf->cname, 6) == 0){
  812. u8g2_Setup_sh1106_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_byte_sw_i2c, u8x8_luat_gpio_and_delay);
  813. #endif
  814. }else{
  815. u8g2_Setup_ssd1306_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_byte_sw_i2c, u8x8_luat_gpio_and_delay);
  816. }
  817. u8g2->u8x8.pins[U8X8_PIN_I2C_CLOCK] = i2c_scl;
  818. u8g2->u8x8.pins[U8X8_PIN_I2C_DATA] = i2c_sda;
  819. u8g2_InitDisplay(u8g2);
  820. u8g2_SetPowerSave(u8g2, 0);
  821. return 0;
  822. }
  823. else if (conf->pinType == 2) {
  824. u8g2_t* u8g2 = (u8g2_t*)conf->ptr;
  825. if (strncmp("ssd1306", conf->cname, 7) == 0 || strncmp("SSD1306", conf->cname, 7) == 0){
  826. u8g2_Setup_ssd1306_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_hw_i2c, u8x8_luat_gpio_and_delay);
  827. #ifdef U8G2_USE_SH1106
  828. }else if (strncmp("sh1106", conf->cname, 6) == 0 || strncmp("SH1106", conf->cname, 6) == 0){
  829. u8g2_Setup_sh1106_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_hw_i2c, u8x8_luat_gpio_and_delay);
  830. #endif
  831. }else{
  832. u8g2_Setup_ssd1306_i2c_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_hw_i2c, u8x8_luat_gpio_and_delay);
  833. }
  834. LLOGD("setup disp i2c.hw");
  835. u8g2_InitDisplay(u8g2);
  836. u8g2_SetPowerSave(u8g2, 0);
  837. return 0;
  838. }
  839. else if (conf->pinType == 5) {
  840. u8g2_t* u8g2 = (u8g2_t*)conf->ptr;
  841. if (strncmp("ssd1306", conf->cname, 7) == 0 || strncmp("SSD1306", conf->cname, 7) == 0){
  842. u8g2_Setup_ssd1306_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_4wire_hw_spi, u8x8_luat_gpio_and_delay);
  843. #ifdef U8G2_USE_SH1106
  844. }else if (strncmp("sh1106", conf->cname, 6) == 0 || strncmp("SH1106", conf->cname, 6) == 0){
  845. u8g2_Setup_sh1106_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_4wire_hw_spi, u8x8_luat_gpio_and_delay);
  846. #endif
  847. #ifdef U8G2_USE_ST7567
  848. }else if (strncmp("st7567", conf->cname, 6) == 0 || strncmp("ST7567", conf->cname, 6) == 0){
  849. u8g2_Setup_st7567_jlx12864_f( u8g2, conf->direction, u8x8_luat_byte_4wire_hw_spi, u8x8_luat_gpio_and_delay);
  850. #endif
  851. }else{
  852. u8g2_Setup_ssd1306_128x64_noname_f( u8g2, conf->direction, u8x8_luat_byte_4wire_hw_spi, u8x8_luat_gpio_and_delay);
  853. }
  854. LLOGD("setup disp spi.hw");
  855. u8x8_SetPin(u8g2_GetU8x8(u8g2), U8X8_PIN_CS, spi_cs);
  856. u8x8_SetPin(u8g2_GetU8x8(u8g2), U8X8_PIN_DC, spi_dc);
  857. u8x8_SetPin(u8g2_GetU8x8(u8g2), U8X8_PIN_RESET, spi_res);
  858. u8g2_InitDisplay(u8g2);
  859. u8g2_SetPowerSave(u8g2, 0);
  860. return 0;
  861. }
  862. LLOGI("only i2c sw mode is support, by default impl");
  863. return -1;
  864. }
  865. LUAT_WEAK int luat_u8g2_close(luat_u8g2_conf_t *conf) {
  866. return 0;
  867. }
  868. LUAT_WEAK uint8_t u8x8_luat_byte_hw_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
  869. static uint8_t buffer[32]; /* u8g2/u8x8 will never send more than 32 bytes */
  870. static uint8_t buf_idx;
  871. uint8_t *data;
  872. switch(msg)
  873. {
  874. case U8X8_MSG_BYTE_SEND:
  875. data = (uint8_t *)arg_ptr;
  876. while( arg_int > 0 )
  877. {
  878. buffer[buf_idx++] = *data;
  879. data++;
  880. arg_int--;
  881. }
  882. break;
  883. case U8X8_MSG_BYTE_INIT:
  884. //i2c_init(u8x8); /* init i2c communication */
  885. luat_i2c_setup(i2c_id,i2c_speed, 0);
  886. break;
  887. case U8X8_MSG_BYTE_SET_DC:
  888. /* ignored for i2c */
  889. break;
  890. case U8X8_MSG_BYTE_START_TRANSFER:
  891. buf_idx = 0;
  892. break;
  893. case U8X8_MSG_BYTE_END_TRANSFER:
  894. luat_i2c_send(i2c_id, u8x8_GetI2CAddress(u8x8) >> 1, buffer, buf_idx);
  895. break;
  896. default:
  897. return 0;
  898. }
  899. return 1;
  900. }
  901. int hw_spi_begin(uint8_t spi_mode, uint32_t max_hz, uint8_t cs_pin )
  902. {
  903. luat_spi_t u8g2_spi = {0};
  904. u8g2_spi.id = spi_id;
  905. switch(spi_mode)
  906. {
  907. case 0: u8g2_spi.CPHA = 0;u8g2_spi.CPOL = 0; break;
  908. case 1: u8g2_spi.CPHA = 1;u8g2_spi.CPOL = 0; break;
  909. case 2: u8g2_spi.CPHA = 0;u8g2_spi.CPOL = 1; break;
  910. case 3: u8g2_spi.CPHA = 1;u8g2_spi.CPOL = 1; break;
  911. }
  912. u8g2_spi.dataw = 8;
  913. u8g2_spi.bit_dict = 1;
  914. u8g2_spi.master = 1;
  915. u8g2_spi.mode = 1;
  916. u8g2_spi.bandrate = max_hz;
  917. u8g2_spi.cs = cs_pin;
  918. // LLOGI("cs_pin=%d",cs_pin);
  919. luat_spi_setup(&u8g2_spi);
  920. return 1;
  921. }
  922. #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
  923. uint8_t u8x8_luat_byte_4wire_hw_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr) {
  924. switch(msg)
  925. {
  926. case U8X8_MSG_BYTE_SEND:
  927. luat_spi_send(spi_id, (const char*)arg_ptr, arg_int);
  928. break;
  929. case U8X8_MSG_BYTE_INIT:
  930. /* SPI mode has to be mapped to the mode of the current controller, at least Uno, Due, 101 have different SPI_MODEx values */
  931. /* 0: clock active high, data out on falling edge, clock default value is zero, takover on rising edge */
  932. /* 1: clock active high, data out on rising edge, clock default value is zero, takover on falling edge */
  933. /* 2: clock active low, data out on rising edge */
  934. /* 3: clock active low, data out on falling edge */
  935. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  936. hw_spi_begin(u8x8->display_info->spi_mode, u8x8->display_info->sck_clock_hz, u8x8->pins[U8X8_PIN_CS]);
  937. break;
  938. case U8X8_MSG_BYTE_SET_DC:
  939. u8x8_gpio_SetDC(u8x8, arg_int);
  940. break;
  941. case U8X8_MSG_BYTE_START_TRANSFER:
  942. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_enable_level);
  943. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->post_chip_enable_wait_ns, NULL);
  944. break;
  945. case U8X8_MSG_BYTE_END_TRANSFER:
  946. u8x8->gpio_and_delay_cb(u8x8, U8X8_MSG_DELAY_NANO, u8x8->display_info->pre_chip_disable_wait_ns, NULL);
  947. u8x8_gpio_SetCS(u8x8, u8x8->display_info->chip_disable_level);
  948. break;
  949. default:
  950. return 0;
  951. }
  952. return 1;
  953. }
  954. LUAT_WEAK uint8_t u8x8_luat_gpio_and_delay(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  955. {
  956. switch(msg)
  957. {
  958. case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
  959. __asm__ volatile("nop");
  960. break;
  961. case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
  962. __asm__ volatile("nop");
  963. break;
  964. case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
  965. for (uint16_t n = 0; n < 320; n++)
  966. {
  967. __asm__ volatile("nop");
  968. }
  969. break;
  970. case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
  971. luat_timer_mdelay(arg_int);
  972. break;
  973. case U8X8_MSG_GPIO_AND_DELAY_INIT:
  974. // Function which implements a delay, arg_int contains the amount of ms
  975. // set spi pin mode
  976. if (u8x8->pins[U8X8_PIN_SPI_CLOCK] != 255) {
  977. luat_gpio_mode(u8x8->pins[U8X8_PIN_SPI_CLOCK],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);//d0 a5 15 d1 a7 17 res b0 18 dc b1 19 cs a4 14
  978. luat_gpio_mode(u8x8->pins[U8X8_PIN_SPI_DATA],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  979. luat_gpio_mode(u8x8->pins[U8X8_PIN_RESET],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  980. luat_gpio_mode(u8x8->pins[U8X8_PIN_DC],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  981. luat_gpio_mode(u8x8->pins[U8X8_PIN_CS],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  982. }
  983. // set i2c pin mode
  984. if (u8x8->pins[U8X8_PIN_I2C_DATA] != 255) {
  985. luat_gpio_mode(u8x8->pins[U8X8_PIN_I2C_DATA],Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_HIGH);
  986. luat_gpio_mode(u8x8->pins[U8X8_PIN_I2C_CLOCK],Luat_GPIO_OUTPUT, Luat_GPIO_DEFAULT, Luat_GPIO_HIGH);
  987. }
  988. // set 8080 pin mode
  989. if (u8x8->pins[U8X8_PIN_D0] != 255) {
  990. luat_gpio_mode(u8x8->pins[U8X8_PIN_D0],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  991. luat_gpio_mode(u8x8->pins[U8X8_PIN_D1],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  992. luat_gpio_mode(u8x8->pins[U8X8_PIN_D2],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  993. luat_gpio_mode(u8x8->pins[U8X8_PIN_D3],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  994. luat_gpio_mode(u8x8->pins[U8X8_PIN_D4],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  995. luat_gpio_mode(u8x8->pins[U8X8_PIN_D5],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  996. luat_gpio_mode(u8x8->pins[U8X8_PIN_D6],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  997. luat_gpio_mode(u8x8->pins[U8X8_PIN_D7],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  998. luat_gpio_mode(u8x8->pins[U8X8_PIN_E],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  999. luat_gpio_mode(u8x8->pins[U8X8_PIN_DC],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  1000. luat_gpio_mode(u8x8->pins[U8X8_PIN_RESET],Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, Luat_GPIO_HIGH);
  1001. }
  1002. // set value
  1003. luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_CLOCK],1);
  1004. luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_DATA],1);
  1005. luat_gpio_set(u8x8->pins[U8X8_PIN_RESET],1);
  1006. luat_gpio_set(u8x8->pins[U8X8_PIN_DC],1);
  1007. luat_gpio_set(u8x8->pins[U8X8_PIN_CS],1);
  1008. break;
  1009. case U8X8_MSG_DELAY_I2C:
  1010. // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
  1011. // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
  1012. for (uint16_t n = 0; n < (arg_int<=2?160:40); n++)
  1013. {
  1014. __asm__ volatile("nop");
  1015. }
  1016. break;
  1017. //case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
  1018. //case U8X8_MSG_GPIO_SPI_CLOCK:
  1019. //case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
  1020. //case U8X8_MSG_GPIO_SPI_DATA:
  1021. case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
  1022. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D2],1);
  1023. else luat_gpio_set(u8x8->pins[U8X8_PIN_D2],0);
  1024. break;
  1025. case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
  1026. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D3],1);
  1027. else luat_gpio_set(u8x8->pins[U8X8_PIN_D3],0);
  1028. break;
  1029. case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
  1030. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D4],1);
  1031. else luat_gpio_set(u8x8->pins[U8X8_PIN_D4],0);
  1032. break;
  1033. case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
  1034. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D5],1);
  1035. else luat_gpio_set(u8x8->pins[U8X8_PIN_D5],0);
  1036. break;
  1037. case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
  1038. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D6],1);
  1039. else luat_gpio_set(u8x8->pins[U8X8_PIN_D6],0);
  1040. break;
  1041. case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
  1042. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_D7],1);
  1043. else luat_gpio_set(u8x8->pins[U8X8_PIN_D7],0);
  1044. break;
  1045. case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
  1046. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_E],1);
  1047. else luat_gpio_set(u8x8->pins[U8X8_PIN_E],0);
  1048. break;
  1049. case U8X8_MSG_GPIO_I2C_CLOCK:
  1050. // arg_int=0: Output low at I2C clock pin
  1051. // arg_int=1: Input dir with pullup high for I2C clock pin
  1052. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_I2C_CLOCK],1);
  1053. else luat_gpio_set(u8x8->pins[U8X8_PIN_I2C_CLOCK],0);
  1054. break;
  1055. case U8X8_MSG_GPIO_I2C_DATA:
  1056. // arg_int=0: Output low at I2C data pin
  1057. // arg_int=1: Input dir with pullup high for I2C data pin
  1058. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_I2C_DATA],1);
  1059. else luat_gpio_set(u8x8->pins[U8X8_PIN_I2C_DATA],0);
  1060. break;
  1061. case U8X8_MSG_GPIO_SPI_CLOCK:
  1062. //Function to define the logic level of the clockline
  1063. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_CLOCK],1);
  1064. else luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_CLOCK],0);
  1065. break;
  1066. case U8X8_MSG_GPIO_SPI_DATA:
  1067. //Function to define the logic level of the data line to the display
  1068. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_DATA],1);
  1069. else luat_gpio_set(u8x8->pins[U8X8_PIN_SPI_DATA],0);
  1070. break;
  1071. case U8X8_MSG_GPIO_CS:
  1072. // Function to define the logic level of the CS line
  1073. if(arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_CS],1);
  1074. else luat_gpio_set(u8x8->pins[U8X8_PIN_CS],0);
  1075. break;
  1076. case U8X8_MSG_GPIO_DC:
  1077. //Function to define the logic level of the Data/ Command line
  1078. if(arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_DC],1);
  1079. else luat_gpio_set(u8x8->pins[U8X8_PIN_DC],0);
  1080. break;
  1081. case U8X8_MSG_GPIO_RESET:
  1082. //Function to define the logic level of the RESET line
  1083. if (arg_int) luat_gpio_set(u8x8->pins[U8X8_PIN_RESET],1);
  1084. else luat_gpio_set(u8x8->pins[U8X8_PIN_RESET],0);
  1085. break;
  1086. default:
  1087. //A message was received which is not implemented, return 0 to indicate an error
  1088. return 0;
  1089. }
  1090. return 1;
  1091. }