u8g2.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696
  1. // Module for binding the u8g2 library
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #define U8X8_USE_PINS
  5. #include "u8g2.h"
  6. #include "u8x8_nodemcu_hal.h"
  7. #include "u8g2_displays.h"
  8. #include "u8g2_fonts.h"
  9. #include "spi_common.h"
  10. typedef struct {
  11. int font_ref;
  12. int host_ref;
  13. u8g2_nodemcu_t u8g2;
  14. } u8g2_ud_t;
  15. #define GET_U8G2() \
  16. u8g2_ud_t *ud = (u8g2_ud_t *)luaL_checkudata( L, 1, "u8g2.display" ); \
  17. u8g2_t *u8g2 = (u8g2_t *)(&(ud->u8g2));
  18. static int lu8g2_clearBuffer( lua_State *L )
  19. {
  20. GET_U8G2();
  21. u8g2_ClearBuffer( u8g2 );
  22. return 0;
  23. }
  24. static int lu8g2_drawBox( lua_State *L )
  25. {
  26. GET_U8G2();
  27. int stack = 1;
  28. int x = luaL_checkint( L, ++stack );
  29. int y = luaL_checkint( L, ++stack );
  30. int w = luaL_checkint( L, ++stack );
  31. int h = luaL_checkint( L, ++stack );
  32. u8g2_DrawBox( u8g2, x, y, w, h );
  33. return 0;
  34. }
  35. static int lu8g2_drawCircle( lua_State *L )
  36. {
  37. GET_U8G2();
  38. int stack = 1;
  39. int x0 = luaL_checkint( L, ++stack );
  40. int y0 = luaL_checkint( L, ++stack );
  41. int rad = luaL_checkint( L, ++stack );
  42. int opt = luaL_optint( L, ++stack, U8G2_DRAW_ALL );
  43. u8g2_DrawCircle( u8g2, x0, y0, rad, opt );
  44. return 0;
  45. }
  46. static int lu8g2_drawDisc( lua_State *L )
  47. {
  48. GET_U8G2();
  49. int stack = 1;
  50. int x0 = luaL_checkint( L, ++stack );
  51. int y0 = luaL_checkint( L, ++stack );
  52. int rad = luaL_checkint( L, ++stack );
  53. int opt = luaL_optint( L, ++stack, U8G2_DRAW_ALL );
  54. u8g2_DrawDisc( u8g2, x0, y0, rad, opt );
  55. return 0;
  56. }
  57. static int lu8g2_drawEllipse( lua_State *L )
  58. {
  59. GET_U8G2();
  60. int stack = 1;
  61. int x0 = luaL_checkint( L, ++stack );
  62. int y0 = luaL_checkint( L, ++stack );
  63. int rx = luaL_checkint( L, ++stack );
  64. int ry = luaL_checkint( L, ++stack );
  65. int opt = luaL_optint( L, ++stack, U8G2_DRAW_ALL );
  66. u8g2_DrawEllipse( u8g2, x0, y0, rx, ry, opt );
  67. return 0;
  68. }
  69. static int lu8g2_drawFilledEllipse( lua_State *L )
  70. {
  71. GET_U8G2();
  72. int stack = 1;
  73. int x0 = luaL_checkint( L, ++stack );
  74. int y0 = luaL_checkint( L, ++stack );
  75. int rx = luaL_checkint( L, ++stack );
  76. int ry = luaL_checkint( L, ++stack );
  77. int opt = luaL_optint( L, ++stack, U8G2_DRAW_ALL );
  78. u8g2_DrawFilledEllipse( u8g2, x0, y0, rx, ry, opt );
  79. return 0;
  80. }
  81. static int lu8g2_drawFrame( lua_State *L )
  82. {
  83. GET_U8G2();
  84. int stack = 1;
  85. int x = luaL_checkint( L, ++stack );
  86. int y = luaL_checkint( L, ++stack );
  87. int w = luaL_checkint( L, ++stack );
  88. int h = luaL_checkint( L, ++stack );
  89. u8g2_DrawFrame( u8g2, x, y, w, h );
  90. return 0;
  91. }
  92. static int lu8g2_drawGlyph( lua_State *L )
  93. {
  94. GET_U8G2();
  95. int stack = 1;
  96. int x = luaL_checkint( L, ++stack );
  97. int y = luaL_checkint( L, ++stack );
  98. int enc = luaL_checkint( L, ++stack );
  99. u8g2_DrawGlyph( u8g2, x, y, enc );
  100. return 0;
  101. }
  102. static int lu8g2_drawHLine( lua_State *L )
  103. {
  104. GET_U8G2();
  105. int stack = 1;
  106. int x = luaL_checkint( L, ++stack );
  107. int y = luaL_checkint( L, ++stack );
  108. int w = luaL_checkint( L, ++stack );
  109. u8g2_DrawHLine( u8g2, x, y, w );
  110. return 0;
  111. }
  112. static int lu8g2_drawLine( lua_State *L )
  113. {
  114. GET_U8G2();
  115. int stack = 1;
  116. int x0 = luaL_checkint( L, ++stack );
  117. int y0 = luaL_checkint( L, ++stack );
  118. int x1 = luaL_checkint( L, ++stack );
  119. int y1 = luaL_checkint( L, ++stack );
  120. u8g2_DrawLine( u8g2, x0, y0, x1, y1 );
  121. return 0;
  122. }
  123. static int lu8g2_drawPixel( lua_State *L )
  124. {
  125. GET_U8G2();
  126. int stack = 1;
  127. int x = luaL_checkint( L, ++stack );
  128. int y = luaL_checkint( L, ++stack );
  129. u8g2_DrawPixel( u8g2, x, y );
  130. return 0;
  131. }
  132. static int lu8g2_drawRBox( lua_State *L )
  133. {
  134. GET_U8G2();
  135. int stack = 1;
  136. int x = luaL_checkint( L, ++stack );
  137. int y = luaL_checkint( L, ++stack );
  138. int w = luaL_checkint( L, ++stack );
  139. int h = luaL_checkint( L, ++stack );
  140. int r = luaL_checkint( L, ++stack );
  141. u8g2_DrawRBox( u8g2, x, y, w, h, r );
  142. return 0;
  143. }
  144. static int lu8g2_drawRFrame( lua_State *L )
  145. {
  146. GET_U8G2();
  147. int stack = 1;
  148. int x = luaL_checkint( L, ++stack );
  149. int y = luaL_checkint( L, ++stack );
  150. int w = luaL_checkint( L, ++stack );
  151. int h = luaL_checkint( L, ++stack );
  152. int r = luaL_checkint( L, ++stack );
  153. u8g2_DrawRFrame( u8g2, x, y, w, h, r );
  154. return 0;
  155. }
  156. static int lu8g2_drawStr( lua_State *L )
  157. {
  158. GET_U8G2();
  159. int stack = 1;
  160. int x = luaL_checkint( L, ++stack );
  161. int y = luaL_checkint( L, ++stack );
  162. const char *str = luaL_checkstring( L, ++stack );
  163. u8g2_DrawStr( u8g2, x, y, str );
  164. return 0;
  165. }
  166. static int lu8g2_drawTriangle( lua_State *L )
  167. {
  168. GET_U8G2();
  169. int stack = 1;
  170. int x0 = luaL_checkint( L, ++stack );
  171. int y0 = luaL_checkint( L, ++stack );
  172. int x1 = luaL_checkint( L, ++stack );
  173. int y1 = luaL_checkint( L, ++stack );
  174. int x2 = luaL_checkint( L, ++stack );
  175. int y2 = luaL_checkint( L, ++stack );
  176. u8g2_DrawTriangle( u8g2, x0, y0, x1, y1, x2, y2 );
  177. return 0;
  178. }
  179. static int lu8g2_drawUTF8( lua_State *L )
  180. {
  181. GET_U8G2();
  182. int stack = 1;
  183. int x = luaL_checkint( L, ++stack );
  184. int y = luaL_checkint( L, ++stack );
  185. const char *str = luaL_checkstring( L, ++stack );
  186. u8g2_DrawUTF8( u8g2, x, y, str );
  187. return 0;
  188. }
  189. static int lu8g2_drawVLine( lua_State *L )
  190. {
  191. GET_U8G2();
  192. int stack = 1;
  193. int x = luaL_checkint( L, ++stack );
  194. int y = luaL_checkint( L, ++stack );
  195. int h = luaL_checkint( L, ++stack );
  196. u8g2_DrawVLine( u8g2, x, y, h );
  197. return 0;
  198. }
  199. static int lu8g2_drawXBM( lua_State *L )
  200. {
  201. GET_U8G2();
  202. int stack = 1;
  203. int x = luaL_checkint( L, ++stack );
  204. int y = luaL_checkint( L, ++stack );
  205. int w = luaL_checkint( L, ++stack );
  206. int h = luaL_checkint( L, ++stack );
  207. size_t len;
  208. const char *bitmap = luaL_checklstring( L, ++stack, &len );
  209. u8g2_DrawXBM( u8g2, x, y, w, h, (uint8_t *)bitmap );
  210. return 0;
  211. }
  212. static int lu8g2_getAscent( lua_State *L )
  213. {
  214. GET_U8G2();
  215. lua_pushinteger( L, u8g2_GetAscent( u8g2 ) );
  216. return 1;
  217. }
  218. static int lu8g2_getDescent( lua_State *L )
  219. {
  220. GET_U8G2();
  221. lua_pushinteger( L, u8g2_GetDescent( u8g2 ) );
  222. return 1;
  223. }
  224. static int lu8g2_getStrWidth( lua_State *L )
  225. {
  226. GET_U8G2();
  227. int stack = 1;
  228. const char *s = luaL_checkstring( L, ++stack );
  229. lua_pushinteger( L, u8g2_GetStrWidth( u8g2, s ) );
  230. return 1;
  231. }
  232. static int lu8g2_getUTF8Width( lua_State *L )
  233. {
  234. GET_U8G2();
  235. int stack = 1;
  236. const char *s = luaL_checkstring( L, ++stack );
  237. lua_pushinteger( L, u8g2_GetUTF8Width( u8g2, s ) );
  238. return 1;
  239. }
  240. static int lu8g2_sendBuffer( lua_State *L )
  241. {
  242. GET_U8G2();
  243. u8g2_SendBuffer( u8g2 );
  244. return 0;
  245. }
  246. static int lu8g2_setBitmapMode( lua_State *L )
  247. {
  248. GET_U8G2();
  249. int stack = 1;
  250. int is_transparent = luaL_checkint( L, ++stack );
  251. u8g2_SetBitmapMode( u8g2, is_transparent );
  252. return 0;
  253. }
  254. static int lu8g2_setContrast( lua_State *L )
  255. {
  256. GET_U8G2();
  257. int stack = 1;
  258. int value = luaL_checkint( L, ++stack );
  259. u8g2_SetContrast( u8g2, value );
  260. return 0;
  261. }
  262. static int lu8g2_setDisplayRotation( lua_State *L )
  263. {
  264. GET_U8G2();
  265. int stack = 1;
  266. const u8g2_cb_t *u8g2_cb = (u8g2_cb_t *)lua_touserdata( L, ++stack );
  267. u8g2_SetDisplayRotation( u8g2, u8g2_cb );
  268. return 0;
  269. }
  270. static int lu8g2_setDrawColor( lua_State *L )
  271. {
  272. GET_U8G2();
  273. int stack = 1;
  274. int col = luaL_checkint( L, ++stack );
  275. u8g2_SetDrawColor( u8g2, col );
  276. return 0;
  277. }
  278. static int lu8g2_setFlipMode( lua_State *L )
  279. {
  280. GET_U8G2();
  281. int stack = 1;
  282. int is_enable = luaL_checkint( L, ++stack );
  283. u8g2_SetFlipMode( u8g2, is_enable );
  284. return 0;
  285. }
  286. static int lu8g2_setFont( lua_State *L )
  287. {
  288. GET_U8G2();
  289. int stack = 1;
  290. const uint8_t *font = NULL;
  291. luaL_unref( L, LUA_REGISTRYINDEX, ud->font_ref );
  292. ud->font_ref = LUA_NOREF;
  293. if (lua_islightuserdata( L, ++stack )) {
  294. font = (const uint8_t *)lua_touserdata( L, stack );
  295. } else if (lua_isstring( L, stack )) {
  296. // ref the font string to safe it in case the string variable gets gc'ed
  297. lua_pushvalue( L, stack );
  298. ud->font_ref = luaL_ref( L, LUA_REGISTRYINDEX );
  299. size_t len;
  300. font = (const uint8_t *)luaL_checklstring( L, stack, &len );
  301. }
  302. luaL_argcheck( L, font != NULL, stack, "invalid font" );
  303. u8g2_SetFont( u8g2, font );
  304. return 0;
  305. }
  306. static int lu8g2_setFontDirection( lua_State *L )
  307. {
  308. GET_U8G2();
  309. int stack = 1;
  310. int dir = luaL_checkint( L, ++stack );
  311. u8g2_SetFontDirection( u8g2, dir );
  312. return 0;
  313. }
  314. static int lu8g2_setFontMode( lua_State *L )
  315. {
  316. GET_U8G2();
  317. int stack = 1;
  318. int is_transparent = luaL_checkint( L, ++stack );
  319. u8g2_SetFontMode( u8g2, is_transparent );
  320. return 0;
  321. }
  322. static int lu8g2_setFontPosBaseline( lua_State *L )
  323. {
  324. GET_U8G2();
  325. u8g2_SetFontPosBaseline( u8g2 );
  326. return 0;
  327. }
  328. static int lu8g2_setFontPosBottom( lua_State *L )
  329. {
  330. GET_U8G2();
  331. u8g2_SetFontPosBottom( u8g2 );
  332. return 0;
  333. }
  334. static int lu8g2_setFontPosTop( lua_State *L )
  335. {
  336. GET_U8G2();
  337. u8g2_SetFontPosTop( u8g2 );
  338. return 0;
  339. }
  340. static int lu8g2_setFontPosCenter( lua_State *L )
  341. {
  342. GET_U8G2();
  343. u8g2_SetFontPosCenter( u8g2 );
  344. return 0;
  345. }
  346. static int lu8g2_setFontRefHeightAll( lua_State *L )
  347. {
  348. GET_U8G2();
  349. u8g2_SetFontRefHeightAll( u8g2 );
  350. return 0;
  351. }
  352. static int lu8g2_setFontRefHeightExtendedText( lua_State *L )
  353. {
  354. GET_U8G2();
  355. u8g2_SetFontRefHeightExtendedText( u8g2 );
  356. return 0;
  357. }
  358. static int lu8g2_setFontRefHeightText( lua_State *L )
  359. {
  360. GET_U8G2();
  361. u8g2_SetFontRefHeightText( u8g2 );
  362. return 0;
  363. }
  364. static int lu8g2_setPowerSave( lua_State *L )
  365. {
  366. GET_U8G2();
  367. int stack = 1;
  368. int is_enable = luaL_checkint( L, ++stack );
  369. u8g2_SetPowerSave( u8g2, is_enable );
  370. return 0;
  371. }
  372. static const LUA_REG_TYPE lu8g2_display_map[] = {
  373. { LSTRKEY( "clearBuffer" ), LFUNCVAL( lu8g2_clearBuffer ) },
  374. { LSTRKEY( "drawBox" ), LFUNCVAL( lu8g2_drawBox ) },
  375. { LSTRKEY( "drawCircle" ), LFUNCVAL( lu8g2_drawCircle ) },
  376. { LSTRKEY( "drawDisc" ), LFUNCVAL( lu8g2_drawDisc ) },
  377. { LSTRKEY( "drawEllipse" ), LFUNCVAL( lu8g2_drawEllipse ) },
  378. { LSTRKEY( "drawFilledEllipse" ), LFUNCVAL( lu8g2_drawFilledEllipse ) },
  379. { LSTRKEY( "drawFrame" ), LFUNCVAL( lu8g2_drawFrame ) },
  380. { LSTRKEY( "drawGlyph" ), LFUNCVAL( lu8g2_drawGlyph ) },
  381. { LSTRKEY( "drawHLine" ), LFUNCVAL( lu8g2_drawHLine ) },
  382. { LSTRKEY( "drawLine" ), LFUNCVAL( lu8g2_drawLine ) },
  383. { LSTRKEY( "drawPixel" ), LFUNCVAL( lu8g2_drawPixel ) },
  384. { LSTRKEY( "drawRBox" ), LFUNCVAL( lu8g2_drawRBox ) },
  385. { LSTRKEY( "drawRFrame" ), LFUNCVAL( lu8g2_drawRFrame ) },
  386. { LSTRKEY( "drawStr" ), LFUNCVAL( lu8g2_drawStr ) },
  387. { LSTRKEY( "drawTriangle" ), LFUNCVAL( lu8g2_drawTriangle ) },
  388. { LSTRKEY( "drawUTF8" ), LFUNCVAL( lu8g2_drawUTF8 ) },
  389. { LSTRKEY( "drawVLine" ), LFUNCVAL( lu8g2_drawVLine ) },
  390. { LSTRKEY( "drawXBM" ), LFUNCVAL( lu8g2_drawXBM ) },
  391. { LSTRKEY( "getAscent" ), LFUNCVAL( lu8g2_getAscent ) },
  392. { LSTRKEY( "getDescent" ), LFUNCVAL( lu8g2_getDescent ) },
  393. { LSTRKEY( "getStrWidth" ), LFUNCVAL( lu8g2_getStrWidth ) },
  394. { LSTRKEY( "getUTF8Width" ), LFUNCVAL( lu8g2_getUTF8Width ) },
  395. { LSTRKEY( "sendBuffer" ), LFUNCVAL( lu8g2_sendBuffer ) },
  396. { LSTRKEY( "setBitmapMode" ), LFUNCVAL( lu8g2_setBitmapMode ) },
  397. { LSTRKEY( "setContrast" ), LFUNCVAL( lu8g2_setContrast ) },
  398. { LSTRKEY( "setDisplayRotation" ), LFUNCVAL( lu8g2_setDisplayRotation ) },
  399. { LSTRKEY( "setDrawColor" ), LFUNCVAL( lu8g2_setDrawColor ) },
  400. { LSTRKEY( "setFlipMode" ), LFUNCVAL( lu8g2_setFlipMode ) },
  401. { LSTRKEY( "setFont" ), LFUNCVAL( lu8g2_setFont ) },
  402. { LSTRKEY( "setFontDirection" ), LFUNCVAL( lu8g2_setFontDirection ) },
  403. { LSTRKEY( "setFontMode" ), LFUNCVAL( lu8g2_setFontMode ) },
  404. { LSTRKEY( "setFontPosBaseline" ), LFUNCVAL( lu8g2_setFontPosBaseline ) },
  405. { LSTRKEY( "setFontPosBottom" ), LFUNCVAL( lu8g2_setFontPosBottom ) },
  406. { LSTRKEY( "setFontPosTop" ), LFUNCVAL( lu8g2_setFontPosTop ) },
  407. { LSTRKEY( "setFontPosCenter" ), LFUNCVAL( lu8g2_setFontPosCenter ) },
  408. { LSTRKEY( "setFontRefHeightAll" ), LFUNCVAL( lu8g2_setFontRefHeightAll ) },
  409. { LSTRKEY( "setFontRefHeightExtendedText" ), LFUNCVAL( lu8g2_setFontRefHeightExtendedText ) },
  410. { LSTRKEY( "setFontRefHeightText" ), LFUNCVAL( lu8g2_setFontRefHeightText ) },
  411. { LSTRKEY( "setPowerSave" ), LFUNCVAL( lu8g2_setPowerSave ) },
  412. //{ LSTRKEY( "__gc" ), LFUNCVAL( lu8g2_display_free ) },
  413. { LSTRKEY( "__index" ), LROVAL( lu8g2_display_map ) },
  414. {LNILKEY, LNILVAL}
  415. };
  416. // ***************************************************************************
  417. // Device constructors
  418. //
  419. //
  420. // I2C based devices will use this function template to implement the Lua binding.
  421. #undef U8G2_DISPLAY_TABLE_ENTRY
  422. #define U8G2_DISPLAY_TABLE_ENTRY(function, binding) \
  423. static int l ## binding( lua_State *L ) \
  424. { \
  425. int stack = 0; \
  426. \
  427. int id = luaL_checkint( L, ++stack ); \
  428. \
  429. int i2c_addr = luaL_checkint( L, ++stack ); \
  430. luaL_argcheck( L, i2c_addr >= 0 && i2c_addr <= 0x7f, stack, "invalid i2c address" ); \
  431. \
  432. u8g2_ud_t *ud = (u8g2_ud_t *)lua_newuserdata( L, sizeof( u8g2_ud_t ) ); \
  433. u8g2_nodemcu_t *u8g2 = &(ud->u8g2); \
  434. ud->font_ref = LUA_NOREF; \
  435. ud->host_ref = LUA_NOREF; \
  436. /* the i2c driver id is forwarded in the hal member */ \
  437. u8g2->hal = (void *)id; \
  438. \
  439. function( (u8g2_t *)u8g2, U8G2_R0, u8x8_byte_nodemcu_i2c, u8x8_gpio_and_delay_nodemcu ); \
  440. u8x8_SetI2CAddress( (u8x8_t *)u8g2, i2c_addr ); \
  441. \
  442. u8g2_InitDisplay( (u8g2_t *)u8g2 ); \
  443. u8g2_ClearDisplay( (u8g2_t *)u8g2 ); \
  444. u8g2_SetPowerSave( (u8g2_t *)u8g2, 0 ); \
  445. \
  446. /* set its metatable */ \
  447. luaL_getmetatable(L, "u8g2.display"); \
  448. lua_setmetatable(L, -2); \
  449. \
  450. return 1; \
  451. }
  452. //
  453. // Unroll the display table and insert binding functions for I2C based displays.
  454. U8G2_DISPLAY_TABLE_I2C
  455. //
  456. //
  457. //
  458. // SPI based devices will use this function template to implement the Lua binding.
  459. #undef U8G2_DISPLAY_TABLE_ENTRY
  460. #define U8G2_DISPLAY_TABLE_ENTRY(function, binding) \
  461. static int l ## binding( lua_State *L ) \
  462. { \
  463. int stack = 0; \
  464. \
  465. lspi_host_t *host = (lspi_host_t *)luaL_checkudata( L, ++stack, "spi.master" ); \
  466. /* reference host object to avoid automatic gc */ \
  467. lua_pushvalue( L, stack ); \
  468. int host_ref = luaL_ref( L, LUA_REGISTRYINDEX ); \
  469. \
  470. int cs = luaL_checkint( L, ++stack ); \
  471. int dc = luaL_checkint( L, ++stack ); \
  472. int res = luaL_optint( L, ++stack, -1 ); \
  473. \
  474. u8g2_ud_t *ud = (u8g2_ud_t *)lua_newuserdata( L, sizeof( u8g2_ud_t ) ); \
  475. u8g2_nodemcu_t *u8g2 = &(ud->u8g2); \
  476. ud->font_ref = LUA_NOREF; \
  477. ud->host_ref = host_ref; \
  478. /* the spi host id is forwarded in the hal member */ \
  479. u8g2->hal = (void *)(host->host); \
  480. \
  481. function( (u8g2_t *)u8g2, U8G2_R0, u8x8_byte_nodemcu_spi, u8x8_gpio_and_delay_nodemcu ); \
  482. u8x8_SetPin( (u8x8_t *)u8g2, U8X8_PIN_CS, cs ); \
  483. u8x8_SetPin( (u8x8_t *)u8g2, U8X8_PIN_DC, dc ); \
  484. if (res >= 0) \
  485. u8x8_SetPin( (u8x8_t *)u8g2, U8X8_PIN_RESET, res ); \
  486. \
  487. u8g2_InitDisplay( (u8g2_t *)u8g2 ); \
  488. u8g2_ClearDisplay( (u8g2_t *)u8g2 ); \
  489. u8g2_SetPowerSave( (u8g2_t *)u8g2, 0 ); \
  490. \
  491. /* set its metatable */ \
  492. luaL_getmetatable(L, "u8g2.display"); \
  493. lua_setmetatable(L, -2); \
  494. \
  495. return 1; \
  496. }
  497. //
  498. // Unroll the display table and insert binding functions for SPI based displays.
  499. U8G2_DISPLAY_TABLE_SPI
  500. //
  501. //
  502. //
  503. #undef U8G2_FONT_TABLE_ENTRY
  504. #undef U8G2_DISPLAY_TABLE_ENTRY
  505. #define U8G2_DISPLAY_TABLE_ENTRY(function, binding) \
  506. { LSTRKEY( #binding ), LFUNCVAL( l ## binding ) },
  507. static const LUA_REG_TYPE lu8g2_map[] = {
  508. U8G2_DISPLAY_TABLE_I2C
  509. U8G2_DISPLAY_TABLE_SPI
  510. //
  511. // Register fonts
  512. #define U8G2_FONT_TABLE_ENTRY(font) \
  513. { LSTRKEY( #font ), LUDATA( (void *)(u8g2_ ## font) ) },
  514. U8G2_FONT_TABLE
  515. //
  516. { LSTRKEY( "DRAW_UPPER_RIGHT" ), LNUMVAL( U8G2_DRAW_UPPER_RIGHT ) },
  517. { LSTRKEY( "DRAW_UPPER_LEFT" ), LNUMVAL( U8G2_DRAW_UPPER_LEFT ) },
  518. { LSTRKEY( "DRAW_LOWER_RIGHT" ), LNUMVAL( U8G2_DRAW_LOWER_RIGHT ) },
  519. { LSTRKEY( "DRAW_LOWER_LEFT" ), LNUMVAL( U8G2_DRAW_LOWER_LEFT ) },
  520. { LSTRKEY( "DRAW_ALL" ), LNUMVAL( U8G2_DRAW_ALL ) },
  521. { LSTRKEY( "R0" ), LUDATA( (void *)U8G2_R0 ) },
  522. { LSTRKEY( "R1" ), LUDATA( (void *)U8G2_R1 ) },
  523. { LSTRKEY( "R2" ), LUDATA( (void *)U8G2_R2 ) },
  524. { LSTRKEY( "R3" ), LUDATA( (void *)U8G2_R3 ) },
  525. { LSTRKEY( "MIRROR" ), LUDATA( (void *)U8G2_MIRROR ) },
  526. {LNILKEY, LNILVAL}
  527. };
  528. int luaopen_u8g2( lua_State *L ) {
  529. luaL_rometatable(L, "u8g2.display", (void *)lu8g2_display_map);
  530. return 0;
  531. }
  532. NODEMCU_MODULE(U8G2, "u8g2", lu8g2_map, luaopen_u8g2);