uart.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  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 lua_State *gL = NULL;
  9. static int uart_receive_rf = LUA_NOREF;
  10. bool run_input = true;
  11. bool uart_on_data_cb(const char *buf, size_t len){
  12. if(!buf || len==0)
  13. return false;
  14. if(uart_receive_rf == LUA_NOREF)
  15. return false;
  16. if(!gL)
  17. return false;
  18. lua_rawgeti(gL, LUA_REGISTRYINDEX, uart_receive_rf);
  19. lua_pushlstring(gL, buf, len);
  20. lua_call(gL, 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 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. gL = L;
  73. if(run==0)
  74. run_input = false;
  75. } else {
  76. lua_pop(L, 1);
  77. }
  78. }else{
  79. lua_pop(L, 1);
  80. return luaL_error( L, "method not supported" );
  81. }
  82. return 0;
  83. }
  84. bool uart0_echo = true;
  85. // Lua: actualbaud = setup( id, baud, databits, parity, stopbits, echo )
  86. static int uart_setup( lua_State* L )
  87. {
  88. unsigned id, databits, parity, stopbits, echo = 1;
  89. u32 baud, res;
  90. id = luaL_checkinteger( L, 1 );
  91. MOD_CHECK_ID( uart, id );
  92. baud = luaL_checkinteger( L, 2 );
  93. databits = luaL_checkinteger( L, 3 );
  94. parity = luaL_checkinteger( L, 4 );
  95. stopbits = luaL_checkinteger( L, 5 );
  96. if(lua_isnumber(L,6)){
  97. echo = lua_tointeger(L,6);
  98. if(echo!=0)
  99. uart0_echo = true;
  100. else
  101. uart0_echo = false;
  102. }
  103. res = platform_uart_setup( id, baud, databits, parity, stopbits );
  104. lua_pushinteger( L, res );
  105. return 1;
  106. }
  107. // Lua: alt( set )
  108. static int uart_alt( lua_State* L )
  109. {
  110. unsigned set;
  111. set = luaL_checkinteger( L, 1 );
  112. platform_uart_alt( set );
  113. return 0;
  114. }
  115. // Lua: write( id, string1, [string2], ..., [stringn] )
  116. static int uart_write( lua_State* L )
  117. {
  118. int id;
  119. const char* buf;
  120. size_t len, i;
  121. int total = lua_gettop( L ), s;
  122. id = luaL_checkinteger( L, 1 );
  123. MOD_CHECK_ID( uart, id );
  124. for( s = 2; s <= total; s ++ )
  125. {
  126. if( lua_type( L, s ) == LUA_TNUMBER )
  127. {
  128. len = lua_tointeger( L, s );
  129. if( len > 255 )
  130. return luaL_error( L, "invalid number" );
  131. platform_uart_send( id, ( u8 )len );
  132. }
  133. else
  134. {
  135. luaL_checktype( L, s, LUA_TSTRING );
  136. buf = lua_tolstring( L, s, &len );
  137. for( i = 0; i < len; i ++ )
  138. platform_uart_send( id, buf[ i ] );
  139. }
  140. }
  141. return 0;
  142. }
  143. // Module function map
  144. static const LUA_REG_TYPE uart_map[] = {
  145. { LSTRKEY( "setup" ), LFUNCVAL( uart_setup ) },
  146. { LSTRKEY( "write" ), LFUNCVAL( uart_write ) },
  147. { LSTRKEY( "on" ), LFUNCVAL( uart_on ) },
  148. { LSTRKEY( "alt" ), LFUNCVAL( uart_alt ) },
  149. { LSTRKEY( "STOPBITS_1" ), LNUMVAL( PLATFORM_UART_STOPBITS_1 ) },
  150. { LSTRKEY( "STOPBITS_1_5" ), LNUMVAL( PLATFORM_UART_STOPBITS_1_5 ) },
  151. { LSTRKEY( "STOPBITS_2" ), LNUMVAL( PLATFORM_UART_STOPBITS_2 ) },
  152. { LSTRKEY( "PARITY_NONE" ), LNUMVAL( PLATFORM_UART_PARITY_NONE ) },
  153. { LSTRKEY( "PARITY_EVEN" ), LNUMVAL( PLATFORM_UART_PARITY_EVEN ) },
  154. { LSTRKEY( "PARITY_ODD" ), LNUMVAL( PLATFORM_UART_PARITY_ODD ) },
  155. { LNILKEY, LNILVAL }
  156. };
  157. NODEMCU_MODULE(UART, "uart", uart_map, NULL);