u8x8_nodemcu_hal.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // Do not use the code from u8g2 submodule and skip the complete source here
  2. // if the u8g2 module is not selected.
  3. // Reason: The whole u8g2 submodule code tree might not even exist in this case.
  4. #include "user_modules.h"
  5. #ifdef LUA_USE_MODULES_U8G2
  6. #include <string.h>
  7. #include <stdlib.h>
  8. #include "platform.h"
  9. #include "user_interface.h"
  10. #define U8X8_USE_PINS
  11. #define U8X8_WITH_USER_PTR
  12. #include "u8x8_nodemcu_hal.h"
  13. // static variables containing info about the i2c link
  14. // TODO: move to user space in u8x8_t once available
  15. typedef struct {
  16. uint8_t id;
  17. } hal_i2c_t;
  18. // static variables containing info about the spi link
  19. // TODO: move to user space in u8x8_t once available
  20. typedef struct {
  21. uint8_t host;
  22. //spi_device_handle_t device;
  23. uint8_t last_dc;
  24. struct {
  25. uint8_t *data;
  26. size_t size, used;
  27. } buffer;
  28. } hal_spi_t;
  29. static void flush_buffer_spi( hal_spi_t *hal )
  30. {
  31. if (hal->buffer.data && hal->buffer.used > 0) {
  32. platform_spi_blkwrite( hal->host, hal->buffer.used, hal->buffer.data );
  33. hal->buffer.used = 0;
  34. }
  35. }
  36. static void force_flush_buffer(u8x8_t *u8x8)
  37. {
  38. // spi hal has a buffer that can be flushed
  39. if (u8x8->byte_cb == u8x8_byte_nodemcu_spi) {
  40. hal_spi_t *hal = u8x8->user_ptr;
  41. flush_buffer_spi( hal );
  42. }
  43. }
  44. uint8_t u8x8_gpio_and_delay_nodemcu(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  45. {
  46. uint32_t temp;
  47. switch(msg)
  48. {
  49. case U8X8_MSG_GPIO_AND_DELAY_INIT: // called once during init phase of u8g2/u8x8
  50. // can be used to setup pins
  51. for (int idx = 0; idx < U8X8_PIN_OUTPUT_CNT; idx++) {
  52. if (u8x8->pins[idx] != U8X8_PIN_NONE) {
  53. // configure pin as output
  54. if (idx == U8X8_PIN_I2C_CLOCK || idx == U8X8_PIN_I2C_DATA) {
  55. platform_gpio_mode( u8x8->pins[idx], PLATFORM_GPIO_OPENDRAIN, PLATFORM_GPIO_PULLUP );
  56. } else {
  57. platform_gpio_mode( u8x8->pins[idx], PLATFORM_GPIO_OUTPUT, PLATFORM_GPIO_FLOAT );
  58. }
  59. }
  60. }
  61. break;
  62. case U8X8_MSG_DELAY_NANO: // delay arg_int * 1 nano second
  63. force_flush_buffer(u8x8);
  64. os_delay_us( 1 );
  65. break;
  66. case U8X8_MSG_DELAY_100NANO: // delay arg_int * 100 nano seconds
  67. force_flush_buffer(u8x8);
  68. temp = arg_int * 100;
  69. temp /= 1000;
  70. os_delay_us( temp > 0 ? temp : 1 );
  71. break;
  72. case U8X8_MSG_DELAY_10MICRO: // delay arg_int * 10 micro seconds
  73. force_flush_buffer(u8x8);
  74. os_delay_us( arg_int * 10 );
  75. break;
  76. case U8X8_MSG_DELAY_MILLI: // delay arg_int * 1 milli second
  77. force_flush_buffer(u8x8);
  78. os_delay_us( arg_int * 1000 );
  79. system_soft_wdt_feed();
  80. break;
  81. case U8X8_MSG_DELAY_I2C: // arg_int is the I2C speed in 100KHz, e.g. 4 = 400 KHz
  82. force_flush_buffer(u8x8);
  83. temp = 5000 / arg_int; // arg_int=1: delay by 5us, arg_int = 4: delay by 1.25us
  84. temp /= 1000;
  85. os_delay_us( temp > 0 ? temp : 1 );
  86. break;
  87. case U8X8_MSG_GPIO_D0: // D0 or SPI clock pin: Output level in arg_int
  88. //case U8X8_MSG_GPIO_SPI_CLOCK:
  89. break;
  90. case U8X8_MSG_GPIO_D1: // D1 or SPI data pin: Output level in arg_int
  91. //case U8X8_MSG_GPIO_SPI_DATA:
  92. break;
  93. case U8X8_MSG_GPIO_D2: // D2 pin: Output level in arg_int
  94. break;
  95. case U8X8_MSG_GPIO_D3: // D3 pin: Output level in arg_int
  96. break;
  97. case U8X8_MSG_GPIO_D4: // D4 pin: Output level in arg_int
  98. break;
  99. case U8X8_MSG_GPIO_D5: // D5 pin: Output level in arg_int
  100. break;
  101. case U8X8_MSG_GPIO_D6: // D6 pin: Output level in arg_int
  102. break;
  103. case U8X8_MSG_GPIO_D7: // D7 pin: Output level in arg_int
  104. break;
  105. case U8X8_MSG_GPIO_E: // E/WR pin: Output level in arg_int
  106. break;
  107. case U8X8_MSG_GPIO_CS: // CS (chip select) pin: Output level in arg_int
  108. platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
  109. break;
  110. case U8X8_MSG_GPIO_DC: // DC (data/cmd, A0, register select) pin: Output level in arg_int
  111. platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
  112. break;
  113. case U8X8_MSG_GPIO_RESET: // Reset pin: Output level in arg_int
  114. if (u8x8_GetPinValue( u8x8, msg ) != U8X8_PIN_NONE)
  115. platform_gpio_write( u8x8_GetPinValue(u8x8, msg), arg_int );
  116. break;
  117. case U8X8_MSG_GPIO_CS1: // CS1 (chip select) pin: Output level in arg_int
  118. break;
  119. case U8X8_MSG_GPIO_CS2: // CS2 (chip select) pin: Output level in arg_int
  120. break;
  121. case U8X8_MSG_GPIO_I2C_CLOCK: // arg_int=0: Output low at I2C clock pin
  122. // arg_int=1: Input dir with pullup high for I2C clock pin
  123. // for SW comm routine
  124. platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
  125. break;
  126. case U8X8_MSG_GPIO_I2C_DATA: // arg_int=0: Output low at I2C data pin
  127. // arg_int=1: Input dir with pullup high for I2C data pin
  128. // for SW comm routine
  129. platform_gpio_write( u8x8_GetPinValue( u8x8, msg ), arg_int );
  130. break;
  131. case U8X8_MSG_GPIO_MENU_SELECT:
  132. case U8X8_MSG_GPIO_MENU_NEXT:
  133. case U8X8_MSG_GPIO_MENU_PREV:
  134. case U8X8_MSG_GPIO_MENU_HOME:
  135. u8x8_SetGPIOResult( u8x8, /* get menu select pin state */ 0 );
  136. break;
  137. default:
  138. u8x8_SetGPIOResult( u8x8, 1 ); // default return value
  139. break;
  140. }
  141. return 1;
  142. }
  143. uint8_t u8x8_byte_nodemcu_i2c(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  144. {
  145. uint8_t *data;
  146. hal_i2c_t *hal = u8x8->user_ptr;
  147. switch(msg) {
  148. case U8X8_MSG_BYTE_SEND:
  149. if (hal->id < NUM_I2C) {
  150. data = (uint8_t *)arg_ptr;
  151. while( arg_int > 0 ) {
  152. platform_i2c_send_byte( hal->id, *data );
  153. data++;
  154. arg_int--;
  155. }
  156. } else {
  157. // invalid id
  158. return 0;
  159. }
  160. break;
  161. case U8X8_MSG_BYTE_INIT:
  162. {
  163. // the user pointer initially contains the i2c id
  164. int id = (int)hal;
  165. if (!(hal = malloc( sizeof ( hal_i2c_t ) )))
  166. return 0;
  167. hal->id = id;
  168. u8x8->user_ptr = hal;
  169. }
  170. break;
  171. case U8X8_MSG_BYTE_SET_DC:
  172. break;
  173. case U8X8_MSG_BYTE_START_TRANSFER:
  174. if (hal->id < NUM_I2C) {
  175. platform_i2c_send_start( hal->id );
  176. platform_i2c_send_address( hal->id, u8x8_GetI2CAddress(u8x8), PLATFORM_I2C_DIRECTION_TRANSMITTER );
  177. } else {
  178. // invalid id
  179. return 0;
  180. }
  181. break;
  182. case U8X8_MSG_BYTE_END_TRANSFER:
  183. if (hal->id < NUM_I2C) {
  184. platform_i2c_send_stop( hal->id );
  185. } else {
  186. // invalid id
  187. return 0;
  188. }
  189. break;
  190. default:
  191. return 0;
  192. }
  193. return 1;
  194. }
  195. uint8_t u8x8_byte_nodemcu_spi(u8x8_t *u8x8, uint8_t msg, uint8_t arg_int, void *arg_ptr)
  196. {
  197. hal_spi_t *hal = u8x8->user_ptr;
  198. switch(msg) {
  199. case U8X8_MSG_BYTE_INIT:
  200. {
  201. /* disable chipselect */
  202. u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_disable_level );
  203. // the user pointer initially contains the spi host id
  204. int host = (int)hal;
  205. if (!(hal = malloc( sizeof ( hal_spi_t ) )))
  206. return 0;
  207. hal->host = host;
  208. u8x8->user_ptr = hal;
  209. hal->buffer.data = NULL;
  210. hal->last_dc = 0;
  211. }
  212. break;
  213. case U8X8_MSG_BYTE_SET_DC:
  214. if (hal->last_dc != arg_int)
  215. flush_buffer_spi( hal );
  216. u8x8_gpio_SetDC( u8x8, arg_int );
  217. hal->last_dc = arg_int;
  218. break;
  219. case U8X8_MSG_BYTE_START_TRANSFER:
  220. hal->buffer.size = 256;
  221. if (!(hal->buffer.data = (uint8_t *)malloc( hal->buffer.size )))
  222. return 0;
  223. hal->buffer.used = 0;
  224. u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_enable_level );
  225. break;
  226. case U8X8_MSG_BYTE_SEND:
  227. if (!hal->buffer.data)
  228. return 0;
  229. while (hal->buffer.size - hal->buffer.used < arg_int) {
  230. hal->buffer.size *= 2;
  231. uint8_t *tmp;
  232. if (!(tmp = (uint8_t *)malloc( hal->buffer.size ))) {
  233. free( hal->buffer.data );
  234. hal->buffer.data = NULL;
  235. return 0;
  236. }
  237. os_memcpy( tmp, hal->buffer.data, hal->buffer.used );
  238. free( hal->buffer.data );
  239. hal->buffer.data = tmp;
  240. }
  241. os_memcpy( hal->buffer.data + hal->buffer.used, arg_ptr, arg_int );
  242. hal->buffer.used += arg_int;
  243. break;
  244. case U8X8_MSG_BYTE_END_TRANSFER:
  245. if (!hal->buffer.data)
  246. return 0;
  247. flush_buffer_spi( hal );
  248. u8x8_gpio_SetCS( u8x8, u8x8->display_info->chip_disable_level );
  249. free( hal->buffer.data );
  250. hal->buffer.data = NULL;
  251. break;
  252. default:
  253. return 0;
  254. }
  255. return 1;
  256. }
  257. #endif /* LUA_USE_MODULES_U8G2 */