ucg.c 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965
  1. // Module for Ucglib
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include "c_stdlib.h"
  6. #include "ucg.h"
  7. #include "ucg_config.h"
  8. struct _lucg_userdata_t
  9. {
  10. ucg_t ucg;
  11. ucg_dev_fnptr dev_cb;
  12. ucg_dev_fnptr ext_cb;
  13. // For Print() function
  14. ucg_int_t tx, ty;
  15. uint8_t tdir;
  16. };
  17. typedef struct _lucg_userdata_t lucg_userdata_t;
  18. #define delayMicroseconds os_delay_us
  19. static int16_t ucg_com_esp8266_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data);
  20. // shorthand macro for the ucg structure inside the userdata
  21. #define LUCG (&(lud->ucg))
  22. // helper function: retrieve and check userdata argument
  23. static lucg_userdata_t *get_lud( lua_State *L )
  24. {
  25. lucg_userdata_t *lud = (lucg_userdata_t *)luaL_checkudata(L, 1, "ucg.display");
  26. luaL_argcheck(L, lud, 1, "ucg.display expected");
  27. return lud;
  28. }
  29. // helper function: retrieve given number of integer arguments
  30. static void lucg_get_int_args( lua_State *L, uint8_t stack, uint8_t num, ucg_int_t *args)
  31. {
  32. while (num-- > 0)
  33. {
  34. *args++ = luaL_checkinteger( L, stack++ );
  35. }
  36. }
  37. // Lua: ucg.begin( self, fontmode )
  38. static int lucg_begin( lua_State *L )
  39. {
  40. lucg_userdata_t *lud;
  41. if ((lud = get_lud( L )) == NULL)
  42. return 0;
  43. ucg_Init( LUCG, lud->dev_cb, lud->ext_cb, ucg_com_esp8266_hw_spi );
  44. ucg_int_t fontmode = luaL_checkinteger( L, 2 );
  45. ucg_SetFontMode( LUCG, fontmode );
  46. return 0;
  47. }
  48. // Lua: ucg.clearScreen( self )
  49. static int lucg_clearScreen( lua_State *L )
  50. {
  51. lucg_userdata_t *lud;
  52. if ((lud = get_lud( L )) == NULL)
  53. return 0;
  54. ucg_ClearScreen( LUCG );
  55. return 0;
  56. }
  57. // Lua: ucg.draw90Line( self, x, y, len, dir, col_idx )
  58. static int lucg_draw90Line( lua_State *L )
  59. {
  60. lucg_userdata_t *lud;
  61. if ((lud = get_lud( L )) == NULL)
  62. return 0;
  63. ucg_int_t args[5];
  64. lucg_get_int_args( L, 2, 5, args );
  65. ucg_Draw90Line( LUCG, args[0], args[1], args[2], args[3], args[4] );
  66. return 0;
  67. }
  68. // Lua: ucg.drawBox( self, x, y, w, h )
  69. static int lucg_drawBox( lua_State *L )
  70. {
  71. lucg_userdata_t *lud;
  72. if ((lud = get_lud( L )) == NULL)
  73. return 0;
  74. ucg_int_t args[4];
  75. lucg_get_int_args( L, 2, 4, args );
  76. ucg_DrawBox( LUCG, args[0], args[1], args[2], args[3] );
  77. return 0;
  78. }
  79. // Lua: ucg.drawCircle( self, x0, y0, rad, option )
  80. static int lucg_drawCircle( lua_State *L )
  81. {
  82. lucg_userdata_t *lud;
  83. if ((lud = get_lud( L )) == NULL)
  84. return 0;
  85. ucg_int_t args[4];
  86. lucg_get_int_args( L, 2, 4, args );
  87. ucg_DrawCircle( LUCG, args[0], args[1], args[2], args[3] );
  88. return 0;
  89. }
  90. // Lua: ucg.drawDisc( self, x0, y0, rad, option )
  91. static int lucg_drawDisc( lua_State *L )
  92. {
  93. lucg_userdata_t *lud;
  94. if ((lud = get_lud( L )) == NULL)
  95. return 0;
  96. ucg_int_t args[4];
  97. lucg_get_int_args( L, 2, 4, args );
  98. ucg_DrawDisc( LUCG, args[0], args[1], args[2], args[3] );
  99. return 0;
  100. }
  101. // Lua: ucg.drawFrame( self, x, y, w, h )
  102. static int lucg_drawFrame( lua_State *L )
  103. {
  104. lucg_userdata_t *lud;
  105. if ((lud = get_lud( L )) == NULL)
  106. return 0;
  107. ucg_int_t args[4];
  108. lucg_get_int_args( L, 2, 4, args );
  109. ucg_DrawFrame( LUCG, args[0], args[1], args[2], args[3] );
  110. return 0;
  111. }
  112. // Lua: ucg.drawGradientBox( self, x, y, w, h )
  113. static int lucg_drawGradientBox( lua_State *L )
  114. {
  115. lucg_userdata_t *lud;
  116. if ((lud = get_lud( L )) == NULL)
  117. return 0;
  118. ucg_int_t args[4];
  119. lucg_get_int_args( L, 2, 4, args );
  120. ucg_DrawGradientBox( LUCG, args[0], args[1], args[2], args[3] );
  121. return 0;
  122. }
  123. // Lua: width = ucg.drawGlyph( self, x, y, dir, encoding )
  124. static int lucg_drawGlyph( lua_State *L )
  125. {
  126. lucg_userdata_t *lud;
  127. if ((lud = get_lud( L )) == NULL)
  128. return 0;
  129. ucg_int_t args[3];
  130. lucg_get_int_args( L, 2, 3, args );
  131. const char *c = luaL_checkstring( L, (1+3) + 1 );
  132. if (c == NULL)
  133. return 0;
  134. lua_pushinteger( L, ucg_DrawGlyph( LUCG, args[0], args[1], args[2], *c ) );
  135. return 1;
  136. }
  137. // Lua: ucg.drawGradientLine( self, x, y, len, dir )
  138. static int lucg_drawGradientLine( lua_State *L )
  139. {
  140. lucg_userdata_t *lud;
  141. if ((lud = get_lud( L )) == NULL)
  142. return 0;
  143. ucg_int_t args[4];
  144. lucg_get_int_args( L, 2, 4, args );
  145. ucg_DrawGradientLine( LUCG, args[0], args[1], args[2], args[3] );
  146. return 0;
  147. }
  148. // Lua: ucg.drawHLine( self, x, y, len )
  149. static int lucg_drawHLine( lua_State *L )
  150. {
  151. lucg_userdata_t *lud;
  152. if ((lud = get_lud( L )) == NULL)
  153. return 0;
  154. ucg_int_t args[3];
  155. lucg_get_int_args( L, 2, 3, args );
  156. ucg_DrawHLine( LUCG, args[0], args[1], args[2] );
  157. return 0;
  158. }
  159. // Lua: ucg.drawLine( self, x1, y1, x2, y2 )
  160. static int lucg_drawLine( lua_State *L )
  161. {
  162. lucg_userdata_t *lud;
  163. if ((lud = get_lud( L )) == NULL)
  164. return 0;
  165. ucg_int_t args[4];
  166. lucg_get_int_args( L, 2, 4, args );
  167. ucg_DrawLine( LUCG, args[0], args[1], args[2], args[3] );
  168. return 0;
  169. }
  170. // Lua: ucg.drawPixel( self, x, y )
  171. static int lucg_drawPixel( lua_State *L )
  172. {
  173. lucg_userdata_t *lud;
  174. if ((lud = get_lud( L )) == NULL)
  175. return 0;
  176. ucg_int_t args[2];
  177. lucg_get_int_args( L, 2, 2, args );
  178. ucg_DrawPixel( LUCG, args[0], args[1] );
  179. return 0;
  180. }
  181. // Lua: ucg.drawRBox( self, x, y, w, h, r )
  182. static int lucg_drawRBox( lua_State *L )
  183. {
  184. lucg_userdata_t *lud;
  185. if ((lud = get_lud( L )) == NULL)
  186. return 0;
  187. ucg_int_t args[5];
  188. lucg_get_int_args( L, 2, 5, args );
  189. ucg_DrawRBox( LUCG, args[0], args[1], args[2], args[3], args[4] );
  190. return 0;
  191. }
  192. // Lua: ucg.drawRFrame( self, x, y, w, h, r )
  193. static int lucg_drawRFrame( lua_State *L )
  194. {
  195. lucg_userdata_t *lud;
  196. if ((lud = get_lud( L )) == NULL)
  197. return 0;
  198. ucg_int_t args[5];
  199. lucg_get_int_args( L, 2, 5, args );
  200. ucg_DrawRFrame( LUCG, args[0], args[1], args[2], args[3], args[4] );
  201. return 0;
  202. }
  203. // Lua: width = ucg.drawString( self, x, y, dir, str )
  204. static int lucg_drawString( lua_State *L )
  205. {
  206. lucg_userdata_t *lud;
  207. if ((lud = get_lud( L )) == NULL)
  208. return 0;
  209. ucg_int_t args[3];
  210. lucg_get_int_args( L, 2, 3, args );
  211. const char *s = luaL_checkstring( L, (1+3) + 1 );
  212. if (s == NULL)
  213. return 0;
  214. lua_pushinteger( L, ucg_DrawString( LUCG, args[0], args[1], args[2], s ) );
  215. return 1;
  216. }
  217. // Lua: ucg.drawTetragon( self, x0, y0, x1, y1, x2, y2, x3, y3 )
  218. static int lucg_drawTetragon( lua_State *L )
  219. {
  220. lucg_userdata_t *lud;
  221. if ((lud = get_lud( L )) == NULL)
  222. return 0;
  223. ucg_int_t args[8];
  224. lucg_get_int_args( L, 2, 8, args );
  225. ucg_DrawTetragon( LUCG, args[0], args[1], args[2], args[3], args[4], args[5], args[6], args[7] );
  226. return 0;
  227. }
  228. // Lua: ucg.drawTriangle( self, x0, y0, x1, y1, x2, y2 )
  229. static int lucg_drawTriangle( lua_State *L )
  230. {
  231. lucg_userdata_t *lud;
  232. if ((lud = get_lud( L )) == NULL)
  233. return 0;
  234. ucg_int_t args[6];
  235. lucg_get_int_args( L, 2, 6, args );
  236. ucg_DrawTriangle( LUCG, args[0], args[1], args[2], args[3], args[4], args[5] );
  237. return 0;
  238. }
  239. // Lua: ucg.drawVLine( self, x, y, len )
  240. static int lucg_drawVLine( lua_State *L )
  241. {
  242. lucg_userdata_t *lud;
  243. if ((lud = get_lud( L )) == NULL)
  244. return 0;
  245. ucg_int_t args[3];
  246. lucg_get_int_args( L, 2, 3, args );
  247. ucg_DrawVLine( LUCG, args[0], args[1], args[2] );
  248. return 0;
  249. }
  250. // Lua: height = ucg.getFontAscent( self )
  251. static int lucg_getFontAscent( lua_State *L )
  252. {
  253. lucg_userdata_t *lud;
  254. if ((lud = get_lud( L )) == NULL)
  255. return 0;
  256. lua_pushinteger( L, ucg_GetFontAscent( LUCG ) );
  257. return 1;
  258. }
  259. // Lua: height = ucg.getFontDescent( self )
  260. static int lucg_getFontDescent( lua_State *L )
  261. {
  262. lucg_userdata_t *lud;
  263. if ((lud = get_lud( L )) == NULL)
  264. return 0;
  265. lua_pushinteger( L, ucg_GetFontDescent( LUCG ) );
  266. return 1;
  267. }
  268. // Lua: height = ucg.getHeight( self )
  269. static int lucg_getHeight( lua_State *L )
  270. {
  271. lucg_userdata_t *lud;
  272. if ((lud = get_lud( L )) == NULL)
  273. return 0;
  274. lua_pushinteger( L, ucg_GetHeight( LUCG ) );
  275. return 1;
  276. }
  277. // Lua: width = ucg.getStrWidth( self, string )
  278. static int lucg_getStrWidth( lua_State *L )
  279. {
  280. lucg_userdata_t *lud;
  281. if ((lud = get_lud( L )) == NULL)
  282. return 0;
  283. const char *s = luaL_checkstring( L, 2 );
  284. if (s == NULL)
  285. return 0;
  286. lua_pushinteger( L, ucg_GetStrWidth( LUCG, s ) );
  287. return 1;
  288. }
  289. // Lua: width = ucg.getWidth( self )
  290. static int lucg_getWidth( lua_State *L )
  291. {
  292. lucg_userdata_t *lud;
  293. if ((lud = get_lud( L )) == NULL)
  294. return 0;
  295. lua_pushinteger( L, ucg_GetWidth( LUCG ) );
  296. return 1;
  297. }
  298. // Lua: ucg.setClipRange( self, x, y, w, h )
  299. static int lucg_setClipRange( lua_State *L )
  300. {
  301. lucg_userdata_t *lud;
  302. if ((lud = get_lud( L )) == NULL)
  303. return 0;
  304. ucg_int_t args[4];
  305. lucg_get_int_args( L, 2, 4, args );
  306. ucg_SetClipRange( LUCG, args[0], args[1], args[2], args[3] );
  307. return 0;
  308. }
  309. // Lua: ucg.setColor( self, [idx], r, g, b )
  310. static int lucg_setColor( lua_State *L )
  311. {
  312. lucg_userdata_t *lud;
  313. if ((lud = get_lud( L )) == NULL)
  314. return 0;
  315. ucg_int_t args[3];
  316. lucg_get_int_args( L, 2, 3, args );
  317. ucg_int_t opt = luaL_optint( L, (1+3) + 1, -1 );
  318. if (opt < 0)
  319. ucg_SetColor( LUCG, 0, args[0], args[1], args[2] );
  320. else
  321. ucg_SetColor( LUCG, args[0], args[1], args[2], opt );
  322. return 0;
  323. }
  324. // Lua: ucg.setFont( self, font )
  325. static int lucg_setFont( lua_State *L )
  326. {
  327. lucg_userdata_t *lud;
  328. if ((lud = get_lud( L )) == NULL)
  329. return 0;
  330. ucg_fntpgm_uint8_t *font = (ucg_fntpgm_uint8_t *)lua_touserdata( L, 2 );
  331. if (font != NULL)
  332. ucg_SetFont( LUCG, font );
  333. else
  334. luaL_argerror(L, 2, "font data expected");
  335. return 0;
  336. }
  337. // Lua: ucg.print( self, str )
  338. static int lucg_print( lua_State *L )
  339. {
  340. lucg_userdata_t *lud;
  341. if ((lud = get_lud( L )) == NULL)
  342. return 0;
  343. const char *s = luaL_checkstring( L, 2 );
  344. if (s == NULL)
  345. return 0;
  346. while (*s)
  347. {
  348. ucg_int_t delta;
  349. delta = ucg_DrawGlyph(LUCG, lud->tx, lud->ty, lud->tdir, *(s++));
  350. switch(lud->tdir)
  351. {
  352. case 0: lud->tx += delta; break;
  353. case 1: lud->ty += delta; break;
  354. case 2: lud->tx -= delta; break;
  355. default: case 3: lud->ty -= delta; break;
  356. }
  357. }
  358. return 0;
  359. }
  360. // Lua: ucg.setFontMode( self, fontmode )
  361. static int lucg_setFontMode( lua_State *L )
  362. {
  363. lucg_userdata_t *lud;
  364. if ((lud = get_lud( L )) == NULL)
  365. return 0;
  366. ucg_int_t fontmode = luaL_checkinteger( L, 2 );
  367. ucg_SetFontMode( LUCG, fontmode );
  368. return 0;
  369. }
  370. // Lua: ucg.setFontPosBaseline( self )
  371. static int lucg_setFontPosBaseline( lua_State *L )
  372. {
  373. lucg_userdata_t *lud;
  374. if ((lud = get_lud( L )) == NULL)
  375. return 0;
  376. ucg_SetFontPosBaseline( LUCG );
  377. return 0;
  378. }
  379. // Lua: ucg.setFontPosBottom( self )
  380. static int lucg_setFontPosBottom( lua_State *L )
  381. {
  382. lucg_userdata_t *lud;
  383. if ((lud = get_lud( L )) == NULL)
  384. return 0;
  385. ucg_SetFontPosBottom( LUCG );
  386. return 0;
  387. }
  388. // Lua: ucg.setFontPosCenter( self )
  389. static int lucg_setFontPosCenter( lua_State *L )
  390. {
  391. lucg_userdata_t *lud;
  392. if ((lud = get_lud( L )) == NULL)
  393. return 0;
  394. ucg_SetFontPosCenter( LUCG );
  395. return 0;
  396. }
  397. // Lua: ucg.setFontPosTop( self )
  398. static int lucg_setFontPosTop( lua_State *L )
  399. {
  400. lucg_userdata_t *lud;
  401. if ((lud = get_lud( L )) == NULL)
  402. return 0;
  403. ucg_SetFontPosTop( LUCG );
  404. return 0;
  405. }
  406. // Lua: ucg.setMaxClipRange( self )
  407. static int lucg_setMaxClipRange( lua_State *L )
  408. {
  409. lucg_userdata_t *lud;
  410. if ((lud = get_lud( L )) == NULL)
  411. return 0;
  412. ucg_SetMaxClipRange( LUCG );
  413. return 0;
  414. }
  415. // Lua: ucg.setPrintPos( self, x, y )
  416. static int lucg_setPrintPos( lua_State *L )
  417. {
  418. lucg_userdata_t *lud;
  419. if ((lud = get_lud( L )) == NULL)
  420. return 0;
  421. ucg_int_t args[2];
  422. lucg_get_int_args( L, 2, 2, args );
  423. lud->tx = args[0];
  424. lud->ty = args[1];
  425. return 0;
  426. }
  427. // Lua: ucg.setPrintDir( self, dir )
  428. static int lucg_setPrintDir( lua_State *L )
  429. {
  430. lucg_userdata_t *lud;
  431. if ((lud = get_lud( L )) == NULL)
  432. return 0;
  433. lud->tdir = luaL_checkinteger( L, 2 );
  434. return 0;
  435. }
  436. // Lua: ucg.setRotate90( self )
  437. static int lucg_setRotate90( lua_State *L )
  438. {
  439. lucg_userdata_t *lud;
  440. if ((lud = get_lud( L )) == NULL)
  441. return 0;
  442. ucg_SetRotate90( LUCG );
  443. return 0;
  444. }
  445. // Lua: ucg.setRotate180( self )
  446. static int lucg_setRotate180( lua_State *L )
  447. {
  448. lucg_userdata_t *lud;
  449. if ((lud = get_lud( L )) == NULL)
  450. return 0;
  451. ucg_SetRotate180( LUCG );
  452. return 0;
  453. }
  454. // Lua: ucg.setRotate270( self )
  455. static int lucg_setRotate270( lua_State *L )
  456. {
  457. lucg_userdata_t *lud;
  458. if ((lud = get_lud( L )) == NULL)
  459. return 0;
  460. ucg_SetRotate270( LUCG );
  461. return 0;
  462. }
  463. // Lua: ucg.setScale2x2( self )
  464. static int lucg_setScale2x2( lua_State *L )
  465. {
  466. lucg_userdata_t *lud;
  467. if ((lud = get_lud( L )) == NULL)
  468. return 0;
  469. ucg_SetScale2x2( LUCG );
  470. return 0;
  471. }
  472. // Lua: ucg.undoRotate( self )
  473. static int lucg_undoRotate( lua_State *L )
  474. {
  475. lucg_userdata_t *lud;
  476. if ((lud = get_lud( L )) == NULL)
  477. return 0;
  478. ucg_UndoRotate( LUCG );
  479. return 0;
  480. }
  481. // Lua: ucg.undoScale( self )
  482. static int lucg_undoScale( lua_State *L )
  483. {
  484. lucg_userdata_t *lud;
  485. if ((lud = get_lud( L )) == NULL)
  486. return 0;
  487. ucg_UndoScale( LUCG );
  488. return 0;
  489. }
  490. spi_data_type cache;
  491. uint8_t cached;
  492. #define CACHED_TRANSFER(dat, num) cache = cached = 0; \
  493. while( arg > 0 ) { \
  494. if (cached == 4) { \
  495. platform_spi_transaction( 1, 0, 0, 32, cache, 0, 0, 0 ); \
  496. cache = cached = 0; \
  497. } \
  498. cache = (cache << num*8) | dat; \
  499. cached += num; \
  500. arg--; \
  501. } \
  502. if (cached > 0) { \
  503. platform_spi_transaction( 1, 0, 0, cached * 8, cache, 0, 0, 0 ); \
  504. }
  505. static int16_t ucg_com_esp8266_hw_spi(ucg_t *ucg, int16_t msg, uint16_t arg, uint8_t *data)
  506. {
  507. switch(msg)
  508. {
  509. case UCG_COM_MSG_POWER_UP:
  510. /* "data" is a pointer to ucg_com_info_t structure with the following information: */
  511. /* ((ucg_com_info_t *)data)->serial_clk_speed value in nanoseconds */
  512. /* ((ucg_com_info_t *)data)->parallel_clk_speed value in nanoseconds */
  513. /* setup pins */
  514. // we assume that the SPI interface was already initialized
  515. // just care for the /CS and D/C pins
  516. //platform_gpio_write( ucg->pin_list[0], value );
  517. if ( ucg->pin_list[UCG_PIN_RST] != UCG_PIN_VAL_NONE )
  518. platform_gpio_mode( ucg->pin_list[UCG_PIN_RST], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
  519. platform_gpio_mode( ucg->pin_list[UCG_PIN_CD], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
  520. if ( ucg->pin_list[UCG_PIN_CS] != UCG_PIN_VAL_NONE )
  521. platform_gpio_mode( ucg->pin_list[UCG_PIN_CS], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
  522. break;
  523. case UCG_COM_MSG_POWER_DOWN:
  524. break;
  525. case UCG_COM_MSG_DELAY:
  526. delayMicroseconds(arg);
  527. break;
  528. case UCG_COM_MSG_CHANGE_RESET_LINE:
  529. if ( ucg->pin_list[UCG_PIN_RST] != UCG_PIN_VAL_NONE )
  530. platform_gpio_write( ucg->pin_list[UCG_PIN_RST], arg );
  531. break;
  532. case UCG_COM_MSG_CHANGE_CS_LINE:
  533. if ( ucg->pin_list[UCG_PIN_CS] != UCG_PIN_VAL_NONE )
  534. platform_gpio_write( ucg->pin_list[UCG_PIN_CS], arg );
  535. break;
  536. case UCG_COM_MSG_CHANGE_CD_LINE:
  537. platform_gpio_write( ucg->pin_list[UCG_PIN_CD], arg );
  538. break;
  539. case UCG_COM_MSG_SEND_BYTE:
  540. platform_spi_send( 1, 8, arg );
  541. break;
  542. case UCG_COM_MSG_REPEAT_1_BYTE:
  543. CACHED_TRANSFER(data[0], 1);
  544. break;
  545. case UCG_COM_MSG_REPEAT_2_BYTES:
  546. CACHED_TRANSFER((data[0] << 8) | data[1], 2);
  547. break;
  548. case UCG_COM_MSG_REPEAT_3_BYTES:
  549. while( arg > 0 ) {
  550. platform_spi_transaction( 1, 0, 0, 24, (data[0] << 16) | (data[1] << 8) | data[2], 0, 0, 0 );
  551. arg--;
  552. }
  553. break;
  554. case UCG_COM_MSG_SEND_STR:
  555. CACHED_TRANSFER(*data++, 1);
  556. break;
  557. case UCG_COM_MSG_SEND_CD_DATA_SEQUENCE:
  558. while(arg > 0)
  559. {
  560. if ( *data != 0 )
  561. {
  562. /* set the data line directly, ignore the setting from UCG_CFG_CD */
  563. if ( *data == 1 )
  564. {
  565. platform_gpio_write( ucg->pin_list[UCG_PIN_CD], 0 );
  566. }
  567. else
  568. {
  569. platform_gpio_write( ucg->pin_list[UCG_PIN_CD], 1 );
  570. }
  571. }
  572. data++;
  573. platform_spi_send( 1, 8, *data );
  574. data++;
  575. arg--;
  576. }
  577. break;
  578. }
  579. return 1;
  580. }
  581. // device destructor
  582. static int lucg_close_display( lua_State *L )
  583. {
  584. lucg_userdata_t *lud;
  585. if ((lud = get_lud( L )) == NULL)
  586. return 0;
  587. return 0;
  588. }
  589. // ***************************************************************************
  590. // Device constructors
  591. //
  592. //
  593. #undef UCG_DISPLAY_TABLE_ENTRY
  594. #define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) \
  595. static int lucg_ ## binding( lua_State *L ) \
  596. { \
  597. unsigned cs = luaL_checkinteger( L, 1 ); \
  598. if (cs == 0) \
  599. return luaL_error( L, "CS pin required" ); \
  600. unsigned dc = luaL_checkinteger( L, 2 ); \
  601. if (dc == 0) \
  602. return luaL_error( L, "D/C pin required" ); \
  603. unsigned res = luaL_optinteger( L, 3, UCG_PIN_VAL_NONE ); \
  604. \
  605. lucg_userdata_t *lud = (lucg_userdata_t *) lua_newuserdata( L, sizeof( lucg_userdata_t ) ); \
  606. \
  607. /* do a dummy init so that something usefull is part of the ucg structure */ \
  608. ucg_Init( LUCG, ucg_dev_default_cb, ucg_ext_none, (ucg_com_fnptr)0 ); \
  609. \
  610. /* reset cursor position */ \
  611. lud->tx = 0; \
  612. lud->ty = 0; \
  613. lud->tdir = 0; /* default direction */ \
  614. \
  615. uint8_t i; \
  616. for( i = 0; i < UCG_PIN_COUNT; i++ ) \
  617. lud->ucg.pin_list[i] = UCG_PIN_VAL_NONE; \
  618. \
  619. lud->dev_cb = device; \
  620. lud->ext_cb = extension; \
  621. lud->ucg.pin_list[UCG_PIN_RST] = res; \
  622. lud->ucg.pin_list[UCG_PIN_CD] = dc; \
  623. lud->ucg.pin_list[UCG_PIN_CS] = cs; \
  624. \
  625. /* set its metatable */ \
  626. luaL_getmetatable(L, "ucg.display"); \
  627. lua_setmetatable(L, -2); \
  628. \
  629. return 1; \
  630. }
  631. //
  632. // Unroll the display table and insert binding functions.
  633. UCG_DISPLAY_TABLE
  634. //
  635. // ***************************************************************************
  636. // Module function map
  637. static const LUA_REG_TYPE lucg_display_map[] =
  638. {
  639. { LSTRKEY( "begin" ), LFUNCVAL( lucg_begin ) },
  640. { LSTRKEY( "clearScreen" ), LFUNCVAL( lucg_clearScreen ) },
  641. { LSTRKEY( "draw90Line" ), LFUNCVAL( lucg_draw90Line ) },
  642. { LSTRKEY( "drawBox" ), LFUNCVAL( lucg_drawBox ) },
  643. { LSTRKEY( "drawCircle" ), LFUNCVAL( lucg_drawCircle ) },
  644. { LSTRKEY( "drawDisc" ), LFUNCVAL( lucg_drawDisc ) },
  645. { LSTRKEY( "drawFrame" ), LFUNCVAL( lucg_drawFrame ) },
  646. { LSTRKEY( "drawGlyph" ), LFUNCVAL( lucg_drawGlyph ) },
  647. { LSTRKEY( "drawGradientBox" ), LFUNCVAL( lucg_drawGradientBox ) },
  648. { LSTRKEY( "drawGradientLine" ), LFUNCVAL( lucg_drawGradientLine ) },
  649. { LSTRKEY( "drawHLine" ), LFUNCVAL( lucg_drawHLine ) },
  650. { LSTRKEY( "drawLine" ), LFUNCVAL( lucg_drawLine ) },
  651. { LSTRKEY( "drawPixel" ), LFUNCVAL( lucg_drawPixel ) },
  652. { LSTRKEY( "drawRBox" ), LFUNCVAL( lucg_drawRBox ) },
  653. { LSTRKEY( "drawRFrame" ), LFUNCVAL( lucg_drawRFrame ) },
  654. { LSTRKEY( "drawString" ), LFUNCVAL( lucg_drawString ) },
  655. { LSTRKEY( "drawTetragon" ), LFUNCVAL( lucg_drawTetragon ) },
  656. { LSTRKEY( "drawTriangle" ), LFUNCVAL( lucg_drawTriangle ) },
  657. { LSTRKEY( "drawVLine" ), LFUNCVAL( lucg_drawVLine ) },
  658. { LSTRKEY( "getFontAscent" ), LFUNCVAL( lucg_getFontAscent ) },
  659. { LSTRKEY( "getFontDescent" ), LFUNCVAL( lucg_getFontDescent ) },
  660. { LSTRKEY( "getHeight" ), LFUNCVAL( lucg_getHeight ) },
  661. { LSTRKEY( "getStrWidth" ), LFUNCVAL( lucg_getStrWidth ) },
  662. { LSTRKEY( "getWidth" ), LFUNCVAL( lucg_getWidth ) },
  663. { LSTRKEY( "print" ), LFUNCVAL( lucg_print ) },
  664. { LSTRKEY( "setClipRange" ), LFUNCVAL( lucg_setClipRange ) },
  665. { LSTRKEY( "setColor" ), LFUNCVAL( lucg_setColor ) },
  666. { LSTRKEY( "setFont" ), LFUNCVAL( lucg_setFont ) },
  667. { LSTRKEY( "setFontMode" ), LFUNCVAL( lucg_setFontMode ) },
  668. { LSTRKEY( "setFontPosBaseline" ), LFUNCVAL( lucg_setFontPosBaseline ) },
  669. { LSTRKEY( "setFontPosBottom" ), LFUNCVAL( lucg_setFontPosBottom ) },
  670. { LSTRKEY( "setFontPosCenter" ), LFUNCVAL( lucg_setFontPosCenter ) },
  671. { LSTRKEY( "setFontPosTop" ), LFUNCVAL( lucg_setFontPosTop ) },
  672. { LSTRKEY( "setMaxClipRange" ), LFUNCVAL( lucg_setMaxClipRange ) },
  673. { LSTRKEY( "setPrintDir" ), LFUNCVAL( lucg_setPrintDir ) },
  674. { LSTRKEY( "setPrintPos" ), LFUNCVAL( lucg_setPrintPos ) },
  675. { LSTRKEY( "setRotate90" ), LFUNCVAL( lucg_setRotate90 ) },
  676. { LSTRKEY( "setRotate180" ), LFUNCVAL( lucg_setRotate180 ) },
  677. { LSTRKEY( "setRotate270" ), LFUNCVAL( lucg_setRotate270 ) },
  678. { LSTRKEY( "setScale2x2" ), LFUNCVAL( lucg_setScale2x2 ) },
  679. { LSTRKEY( "undoClipRange" ), LFUNCVAL( lucg_setMaxClipRange ) },
  680. { LSTRKEY( "undoRotate" ), LFUNCVAL( lucg_undoRotate ) },
  681. { LSTRKEY( "undoScale" ), LFUNCVAL( lucg_undoScale ) },
  682. { LSTRKEY( "__gc" ), LFUNCVAL( lucg_close_display ) },
  683. { LSTRKEY( "__index" ), LROVAL ( lucg_display_map ) },
  684. { LNILKEY, LNILVAL }
  685. };
  686. static const LUA_REG_TYPE lucg_map[] =
  687. {
  688. #undef UCG_DISPLAY_TABLE_ENTRY
  689. #define UCG_DISPLAY_TABLE_ENTRY(binding, device, extension) { LSTRKEY( #binding ), LFUNCVAL ( lucg_ ##binding ) },
  690. UCG_DISPLAY_TABLE
  691. // Register fonts
  692. #undef UCG_FONT_TABLE_ENTRY
  693. #define UCG_FONT_TABLE_ENTRY(font) { LSTRKEY( #font ), LUDATA( (void *)(ucg_ ## font) ) },
  694. UCG_FONT_TABLE
  695. // Font modes
  696. { LSTRKEY( "FONT_MODE_TRANSPARENT" ), LNUMVAL( UCG_FONT_MODE_TRANSPARENT ) },
  697. { LSTRKEY( "FONT_MODE_SOLID" ), LNUMVAL( UCG_FONT_MODE_SOLID ) },
  698. // Options for circle/ disc drawing
  699. { LSTRKEY( "DRAW_UPPER_RIGHT" ), LNUMVAL( UCG_DRAW_UPPER_RIGHT ) },
  700. { LSTRKEY( "DRAW_UPPER_LEFT" ), LNUMVAL( UCG_DRAW_UPPER_LEFT ) },
  701. { LSTRKEY( "DRAW_LOWER_RIGHT" ), LNUMVAL( UCG_DRAW_LOWER_RIGHT ) },
  702. { LSTRKEY( "DRAW_LOWER_LEFT" ), LNUMVAL( UCG_DRAW_LOWER_LEFT ) },
  703. { LSTRKEY( "DRAW_ALL" ), LNUMVAL( UCG_DRAW_ALL ) },
  704. { LSTRKEY( "__metatable" ), LROVAL( lucg_map ) },
  705. { LNILKEY, LNILVAL }
  706. };
  707. int luaopen_ucg( lua_State *L )
  708. {
  709. luaL_rometatable(L, "ucg.display", (void *)lucg_display_map); // create metatable
  710. return 0;
  711. }
  712. NODEMCU_MODULE(UCG, "ucg", lucg_map, luaopen_ucg);