uart.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Module for interfacing with serial
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include "c_types.h"
  6. #include "c_string.h"
  7. #include "rom.h"
  8. static int uart_receive_rf = LUA_NOREF;
  9. bool run_input = true;
  10. bool uart_on_data_cb(const char *buf, size_t len){
  11. if(!buf || len==0)
  12. return false;
  13. if(uart_receive_rf == LUA_NOREF)
  14. return false;
  15. lua_State *L = lua_getstate();
  16. if(!L)
  17. return false;
  18. lua_rawgeti(L, LUA_REGISTRYINDEX, uart_receive_rf);
  19. lua_pushlstring(L, buf, len);
  20. lua_call(L, 1, 0);
  21. return !run_input;
  22. }
  23. uint16_t need_len = 0;
  24. int16_t end_char = -1;
  25. // Lua: uart.on("method", [number/char], function, [run_input])
  26. static int l_uart_on( lua_State* L )
  27. {
  28. size_t sl, el;
  29. int32_t run = 1;
  30. uint8_t stack = 1;
  31. const char *method = luaL_checklstring( L, stack, &sl );
  32. stack++;
  33. if (method == NULL)
  34. return luaL_error( L, "wrong arg type" );
  35. if( lua_type( L, stack ) == LUA_TNUMBER )
  36. {
  37. need_len = ( uint16_t )luaL_checkinteger( L, stack );
  38. stack++;
  39. end_char = -1;
  40. if( need_len > 255 ){
  41. need_len = 255;
  42. return luaL_error( L, "wrong arg range" );
  43. }
  44. }
  45. else if(lua_isstring(L, stack))
  46. {
  47. const char *end = luaL_checklstring( L, stack, &el );
  48. stack++;
  49. if(el!=1){
  50. return luaL_error( L, "wrong arg range" );
  51. }
  52. end_char = (int16_t)end[0];
  53. need_len = 0;
  54. }
  55. // luaL_checkanyfunction(L, stack);
  56. if (lua_type(L, stack) == LUA_TFUNCTION || lua_type(L, stack) == LUA_TLIGHTFUNCTION){
  57. if ( lua_isnumber(L, stack+1) ){
  58. run = lua_tointeger(L, stack+1);
  59. }
  60. lua_pushvalue(L, stack); // copy argument (func) to the top of stack
  61. } else {
  62. lua_pushnil(L);
  63. }
  64. if(sl == 4 && c_strcmp(method, "data") == 0){
  65. run_input = true;
  66. if(uart_receive_rf != LUA_NOREF){
  67. luaL_unref(L, LUA_REGISTRYINDEX, uart_receive_rf);
  68. uart_receive_rf = LUA_NOREF;
  69. }
  70. if(!lua_isnil(L, -1)){
  71. uart_receive_rf = luaL_ref(L, LUA_REGISTRYINDEX);
  72. if(run==0)
  73. run_input = false;
  74. } else {
  75. lua_pop(L, 1);
  76. }
  77. }else{
  78. lua_pop(L, 1);
  79. return luaL_error( L, "method not supported" );
  80. }
  81. return 0;
  82. }
  83. bool uart0_echo = true;
  84. // Lua: actualbaud = setup( id, baud, databits, parity, stopbits, echo )
  85. static int l_uart_setup( lua_State* L )
  86. {
  87. uint32_t id, databits, parity, stopbits, echo = 1;
  88. uint32_t baud, res;
  89. id = luaL_checkinteger( L, 1 );
  90. MOD_CHECK_ID( uart, id );
  91. baud = luaL_checkinteger( L, 2 );
  92. databits = luaL_checkinteger( L, 3 );
  93. parity = luaL_checkinteger( L, 4 );
  94. stopbits = luaL_checkinteger( L, 5 );
  95. if(lua_isnumber(L,6)){
  96. echo = lua_tointeger(L,6);
  97. if(echo!=0)
  98. uart0_echo = true;
  99. else
  100. uart0_echo = false;
  101. }
  102. res = platform_uart_setup( id, baud, databits, parity, stopbits );
  103. lua_pushinteger( L, res );
  104. return 1;
  105. }
  106. // uart.getconfig(id)
  107. static int l_uart_getconfig( lua_State* L )
  108. {
  109. uint32_t id, databits, parity, stopbits;
  110. uint32_t baud;
  111. id = luaL_checkinteger( L, 1 );
  112. MOD_CHECK_ID( uart, id );
  113. platform_uart_get_config(id, &baud, &databits, &parity, &stopbits);
  114. lua_pushinteger(L, baud);
  115. lua_pushinteger(L, databits);
  116. lua_pushinteger(L, parity);
  117. lua_pushinteger(L, stopbits);
  118. return 4;
  119. }
  120. // Lua: alt( set )
  121. static int l_uart_alt( lua_State* L )
  122. {
  123. unsigned set;
  124. set = luaL_checkinteger( L, 1 );
  125. platform_uart_alt( set );
  126. return 0;
  127. }
  128. // Lua: write( id, string1, [string2], ..., [stringn] )
  129. static int l_uart_write( lua_State* L )
  130. {
  131. int id;
  132. const char* buf;
  133. size_t len, i;
  134. int total = lua_gettop( L ), s;
  135. id = luaL_checkinteger( L, 1 );
  136. MOD_CHECK_ID( uart, id );
  137. for( s = 2; s <= total; s ++ )
  138. {
  139. if( lua_type( L, s ) == LUA_TNUMBER )
  140. {
  141. len = lua_tointeger( L, s );
  142. if( len > 255 )
  143. return luaL_error( L, "invalid number" );
  144. platform_uart_send( id, ( u8 )len );
  145. }
  146. else
  147. {
  148. luaL_checktype( L, s, LUA_TSTRING );
  149. buf = lua_tolstring( L, s, &len );
  150. for( i = 0; i < len; i ++ )
  151. platform_uart_send( id, buf[ i ] );
  152. }
  153. }
  154. return 0;
  155. }
  156. // Module function map
  157. static const LUA_REG_TYPE uart_map[] = {
  158. { LSTRKEY( "setup" ), LFUNCVAL( l_uart_setup ) },
  159. { LSTRKEY( "getconfig" ), LFUNCVAL( l_uart_getconfig ) },
  160. { LSTRKEY( "write" ), LFUNCVAL( l_uart_write ) },
  161. { LSTRKEY( "on" ), LFUNCVAL( l_uart_on ) },
  162. { LSTRKEY( "alt" ), LFUNCVAL( l_uart_alt ) },
  163. { LSTRKEY( "STOPBITS_1" ), LNUMVAL( PLATFORM_UART_STOPBITS_1 ) },
  164. { LSTRKEY( "STOPBITS_1_5" ), LNUMVAL( PLATFORM_UART_STOPBITS_1_5 ) },
  165. { LSTRKEY( "STOPBITS_2" ), LNUMVAL( PLATFORM_UART_STOPBITS_2 ) },
  166. { LSTRKEY( "PARITY_NONE" ), LNUMVAL( PLATFORM_UART_PARITY_NONE ) },
  167. { LSTRKEY( "PARITY_EVEN" ), LNUMVAL( PLATFORM_UART_PARITY_EVEN ) },
  168. { LSTRKEY( "PARITY_ODD" ), LNUMVAL( PLATFORM_UART_PARITY_ODD ) },
  169. { LNILKEY, LNILVAL }
  170. };
  171. NODEMCU_MODULE(UART, "uart", uart_map, NULL);