uart.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187
  1. // Module for interfacing with serial
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include <stdint.h>
  6. #include <string.h>
  7. #include "rom.h"
  8. #include "driver/input.h"
  9. static int uart_receive_rf = LUA_NOREF;
  10. void uart_on_data_cb(const char *buf, size_t len){
  11. lua_State *L = lua_getstate();
  12. lua_rawgeti(L, LUA_REGISTRYINDEX, uart_receive_rf);
  13. lua_pushlstring(L, buf, len);
  14. luaL_pcallx(L, 1, 0);
  15. }
  16. // Lua: uart.on("method", [number/char], function, [run_input])
  17. static int l_uart_on( lua_State* L )
  18. {
  19. size_t el;
  20. int stack = 2, data_len = -1;
  21. char end_char = 0;
  22. const char *method = lua_tostring( L, 1);
  23. bool run_input = true;
  24. luaL_argcheck(L, method && !strcmp(method, "data"), 1, "method not supported");
  25. if (lua_type( L, stack ) == LUA_TNUMBER) {
  26. data_len = luaL_checkinteger( L, stack );
  27. luaL_argcheck(L, data_len >= 0 && data_len < LUA_MAXINPUT, stack, "wrong arg range");
  28. stack++;
  29. } else if (lua_isstring(L, stack)) {
  30. const char *end = luaL_checklstring( L, stack, &el );
  31. end_char = end[0];
  32. stack++;
  33. if(el!=1) {
  34. return luaL_error( L, "wrong arg range" );
  35. }
  36. }
  37. if (lua_isfunction(L, stack)) {
  38. if (lua_isnumber(L, stack+1) && lua_tointeger(L, stack+1) == 0) {
  39. run_input = false;
  40. }
  41. lua_pushvalue(L, stack);
  42. luaL_unref(L, LUA_REGISTRYINDEX, uart_receive_rf);
  43. uart_receive_rf = luaL_ref(L, LUA_REGISTRYINDEX);
  44. } else {
  45. luaL_unref(L, LUA_REGISTRYINDEX, uart_receive_rf);
  46. uart_receive_rf = LUA_NOREF;
  47. }
  48. if (uart_receive_rf == LUA_NOREF) {
  49. input_setup_receive(NULL, 0, 0, 1);
  50. } else
  51. input_setup_receive(uart_on_data_cb, data_len, end_char, run_input);
  52. return 0;
  53. }
  54. bool uart0_echo = true;
  55. // Lua: actualbaud = setup( id, baud, databits, parity, stopbits, echo )
  56. static int l_uart_setup( lua_State* L )
  57. {
  58. uint32_t id, databits, parity, stopbits;
  59. uint32_t baud, res;
  60. id = luaL_checkinteger( L, 1 );
  61. MOD_CHECK_ID( uart, id );
  62. baud = luaL_checkinteger( L, 2 );
  63. databits = luaL_checkinteger( L, 3 );
  64. parity = luaL_checkinteger( L, 4 );
  65. stopbits = luaL_checkinteger( L, 5 );
  66. if (lua_isnumber(L,6)) {
  67. input_setecho(lua_tointeger(L,6) ? true : false);
  68. }
  69. res = platform_uart_setup( id, baud, databits, parity, stopbits );
  70. lua_pushinteger( L, res );
  71. return 1;
  72. }
  73. // uart.getconfig(id)
  74. static int l_uart_getconfig( lua_State* L )
  75. {
  76. uint32_t id, databits, parity, stopbits;
  77. uint32_t baud;
  78. id = luaL_checkinteger( L, 1 );
  79. MOD_CHECK_ID( uart, id );
  80. platform_uart_get_config(id, &baud, &databits, &parity, &stopbits);
  81. lua_pushinteger(L, baud);
  82. lua_pushinteger(L, databits);
  83. lua_pushinteger(L, parity);
  84. lua_pushinteger(L, stopbits);
  85. return 4;
  86. }
  87. // Lua: alt( set )
  88. static int l_uart_alt( lua_State* L )
  89. {
  90. unsigned set;
  91. set = luaL_checkinteger( L, 1 );
  92. platform_uart_alt( set );
  93. return 0;
  94. }
  95. // Lua: write( id, string1, [string2], ..., [stringn] )
  96. static int l_uart_write( lua_State* L )
  97. {
  98. int id;
  99. const char* buf;
  100. size_t len, i;
  101. int total = lua_gettop( L ), s;
  102. id = luaL_checkinteger( L, 1 );
  103. MOD_CHECK_ID( uart, id );
  104. for( s = 2; s <= total; s ++ )
  105. {
  106. if( lua_type( L, s ) == LUA_TNUMBER )
  107. {
  108. len = lua_tointeger( L, s );
  109. if( len > 255 )
  110. return luaL_error( L, "invalid number" );
  111. platform_uart_send( id, ( u8 )len );
  112. }
  113. else
  114. {
  115. luaL_checktype( L, s, LUA_TSTRING );
  116. buf = lua_tolstring( L, s, &len );
  117. for( i = 0; i < len; i ++ )
  118. platform_uart_send( id, buf[ i ] );
  119. }
  120. }
  121. return 0;
  122. }
  123. #define DIR_RX 0
  124. #define DIR_TX 1
  125. static int l_uart_fifodepth( lua_State* L )
  126. {
  127. int id = luaL_optinteger( L, 1, 0 );
  128. if ((id != 0) && (id != 1))
  129. return luaL_argerror(L, 1, "Bad UART id; must be 0 or 1");
  130. int dir = luaL_optinteger( L, 2, 0 );
  131. if ((dir != DIR_RX) && (dir != DIR_TX))
  132. return luaL_argerror(L, 2, "Bad direction; must be DIR_RX or DIR_TX");
  133. int reg = READ_PERI_REG(UART_STATUS(id));
  134. int rsh = reg >> ((dir == DIR_RX) ? UART_RXFIFO_CNT_S : UART_TXFIFO_CNT_S);
  135. int rm = rsh & ((dir == DIR_RX) ? UART_RXFIFO_CNT : UART_TXFIFO_CNT );
  136. lua_pushinteger(L, rm);
  137. return 1;
  138. }
  139. // Module function map
  140. LROT_BEGIN(uart, NULL, 0)
  141. LROT_FUNCENTRY( setup, l_uart_setup )
  142. LROT_FUNCENTRY( getconfig, l_uart_getconfig )
  143. LROT_FUNCENTRY( write, l_uart_write )
  144. LROT_FUNCENTRY( on, l_uart_on )
  145. LROT_FUNCENTRY( alt, l_uart_alt )
  146. LROT_FUNCENTRY( fifodepth, l_uart_fifodepth )
  147. LROT_NUMENTRY( STOPBITS_1, PLATFORM_UART_STOPBITS_1 )
  148. LROT_NUMENTRY( STOPBITS_1_5, PLATFORM_UART_STOPBITS_1_5 )
  149. LROT_NUMENTRY( STOPBITS_2, PLATFORM_UART_STOPBITS_2 )
  150. LROT_NUMENTRY( PARITY_NONE, PLATFORM_UART_PARITY_NONE )
  151. LROT_NUMENTRY( PARITY_EVEN, PLATFORM_UART_PARITY_EVEN )
  152. LROT_NUMENTRY( PARITY_ODD, PLATFORM_UART_PARITY_ODD )
  153. LROT_NUMENTRY( DIR_RX, DIR_RX )
  154. LROT_NUMENTRY( DIR_TX, DIR_TX )
  155. LROT_END(uart, NULL, 0)
  156. NODEMCU_MODULE(UART, "uart", uart, NULL);