gpio.c 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. // Module for interfacing with GPIO
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include "rom.h"
  6. #include "c_types.h"
  7. #include "c_string.h"
  8. #define PULLUP PLATFORM_GPIO_PULLUP
  9. #define FLOAT PLATFORM_GPIO_FLOAT
  10. #define OUTPUT PLATFORM_GPIO_OUTPUT
  11. #define INPUT PLATFORM_GPIO_INPUT
  12. #define INTERRUPT PLATFORM_GPIO_INT
  13. #define HIGH PLATFORM_GPIO_HIGH
  14. #define LOW PLATFORM_GPIO_LOW
  15. #ifdef GPIO_INTERRUPT_ENABLE
  16. static int gpio_cb_ref[GPIO_PIN_NUM];
  17. static lua_State* gL = NULL;
  18. void lua_gpio_unref(unsigned pin){
  19. if(gpio_cb_ref[pin] != LUA_NOREF){
  20. if(gL!=NULL)
  21. luaL_unref(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
  22. }
  23. gpio_cb_ref[pin] = LUA_NOREF;
  24. }
  25. void gpio_intr_callback( unsigned pin, unsigned level )
  26. {
  27. NODE_DBG("pin:%d, level:%d \n", pin, level);
  28. if(gpio_cb_ref[pin] == LUA_NOREF)
  29. return;
  30. if(!gL)
  31. return;
  32. lua_rawgeti(gL, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
  33. lua_pushinteger(gL, level);
  34. lua_call(gL, 1, 0);
  35. }
  36. // Lua: trig( pin, type, function )
  37. static int lgpio_trig( lua_State* L )
  38. {
  39. unsigned type;
  40. unsigned pin;
  41. size_t sl;
  42. pin = luaL_checkinteger( L, 1 );
  43. MOD_CHECK_ID( gpio, pin );
  44. if(pin==0)
  45. return luaL_error( L, "no interrupt for D0" );
  46. const char *str = luaL_checklstring( L, 2, &sl );
  47. if (str == NULL)
  48. return luaL_error( L, "wrong arg type" );
  49. if(sl == 2 && c_strcmp(str, "up") == 0){
  50. type = GPIO_PIN_INTR_POSEDGE;
  51. }else if(sl == 4 && c_strcmp(str, "down") == 0){
  52. type = GPIO_PIN_INTR_NEGEDGE;
  53. }else if(sl == 4 && c_strcmp(str, "both") == 0){
  54. type = GPIO_PIN_INTR_ANYEDGE;
  55. }else if(sl == 3 && c_strcmp(str, "low") == 0){
  56. type = GPIO_PIN_INTR_LOLEVEL;
  57. }else if(sl == 4 && c_strcmp(str, "high") == 0){
  58. type = GPIO_PIN_INTR_HILEVEL;
  59. }else{
  60. type = GPIO_PIN_INTR_DISABLE;
  61. }
  62. // luaL_checkanyfunction(L, 3);
  63. if (lua_type(L, 3) == LUA_TFUNCTION || lua_type(L, 3) == LUA_TLIGHTFUNCTION){
  64. lua_pushvalue(L, 3); // copy argument (func) to the top of stack
  65. if(gpio_cb_ref[pin] != LUA_NOREF)
  66. luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
  67. gpio_cb_ref[pin] = luaL_ref(L, LUA_REGISTRYINDEX);
  68. }
  69. platform_gpio_intr_init(pin, type);
  70. return 0;
  71. }
  72. #endif
  73. // Lua: mode( pin, mode, pullup )
  74. static int lgpio_mode( lua_State* L )
  75. {
  76. unsigned mode, pullup = FLOAT;
  77. unsigned pin;
  78. pin = luaL_checkinteger( L, 1 );
  79. MOD_CHECK_ID( gpio, pin );
  80. mode = luaL_checkinteger( L, 2 );
  81. if ( mode!=OUTPUT && mode!=INPUT && mode!=INTERRUPT)
  82. return luaL_error( L, "wrong arg type" );
  83. if(pin==0 && mode==INTERRUPT)
  84. return luaL_error( L, "no interrupt for D0" );
  85. if(lua_isnumber(L, 3))
  86. pullup = lua_tointeger( L, 3 );
  87. if(pullup!=FLOAT)
  88. pullup = PULLUP;
  89. #ifdef GPIO_INTERRUPT_ENABLE
  90. gL = L; // save to local gL, for callback function
  91. if (mode!=INTERRUPT){ // disable interrupt
  92. if(gpio_cb_ref[pin] != LUA_NOREF){
  93. luaL_unref(L, LUA_REGISTRYINDEX, gpio_cb_ref[pin]);
  94. }
  95. gpio_cb_ref[pin] = LUA_NOREF;
  96. }
  97. #endif
  98. int r = platform_gpio_mode( pin, mode, pullup );
  99. if( r<0 )
  100. return luaL_error( L, "wrong pin num." );
  101. return 0;
  102. }
  103. // Lua: read( pin )
  104. static int lgpio_read( lua_State* L )
  105. {
  106. unsigned pin;
  107. pin = luaL_checkinteger( L, 1 );
  108. MOD_CHECK_ID( gpio, pin );
  109. unsigned level = platform_gpio_read( pin );
  110. lua_pushinteger( L, level );
  111. return 1;
  112. }
  113. // Lua: write( pin, level )
  114. static int lgpio_write( lua_State* L )
  115. {
  116. unsigned level;
  117. unsigned pin;
  118. pin = luaL_checkinteger( L, 1 );
  119. MOD_CHECK_ID( gpio, pin );
  120. level = luaL_checkinteger( L, 2 );
  121. if ( level!=HIGH && level!=LOW )
  122. return luaL_error( L, "wrong arg type" );
  123. platform_gpio_write(pin, level);
  124. return 0;
  125. }
  126. #define DELAY_TABLE_MAX_LEN 256
  127. #define noInterrupts ets_intr_lock
  128. #define interrupts ets_intr_unlock
  129. #define delayMicroseconds os_delay_us
  130. #define DIRECT_WRITE(pin, level) (GPIO_OUTPUT_SET(GPIO_ID_PIN(pin_num[pin]), level))
  131. // Lua: serout( pin, firstLevel, delay_table, [repeatNum] )
  132. // -- serout( pin, firstLevel, delay_table, [repeatNum] )
  133. // gpio.mode(1,gpio.OUTPUT,gpio.PULLUP)
  134. // gpio.serout(1,1,{30,30,60,60,30,30}) -- serial one byte, b10110010
  135. // gpio.serout(1,1,{30,70},8) -- serial 30% pwm 10k, lasts 8 cycles
  136. // gpio.serout(1,1,{3,7},8) -- serial 30% pwm 100k, lasts 8 cycles
  137. // gpio.serout(1,1,{0,0},8) -- serial 50% pwm as fast as possible, lasts 8 cycles
  138. // gpio.mode(1,gpio.OUTPUT,gpio.PULLUP)
  139. // gpio.serout(1,0,{20,10,10,20,10,10,10,100}) -- sim uart one byte 0x5A at about 100kbps
  140. // gpio.serout(1,1,{8,18},8) -- serial 30% pwm 38k, lasts 8 cycles
  141. static int lgpio_serout( lua_State* L )
  142. {
  143. unsigned level;
  144. unsigned pin;
  145. unsigned table_len = 0;
  146. unsigned repeat = 0;
  147. int delay_table[DELAY_TABLE_MAX_LEN];
  148. pin = luaL_checkinteger( L, 1 );
  149. MOD_CHECK_ID( gpio, pin );
  150. level = luaL_checkinteger( L, 2 );
  151. if ( level!=HIGH && level!=LOW )
  152. return luaL_error( L, "wrong arg type" );
  153. if( lua_istable( L, 3 ) )
  154. {
  155. table_len = lua_objlen( L, 3 );
  156. if (table_len <= 0 || table_len>DELAY_TABLE_MAX_LEN)
  157. return luaL_error( L, "wrong arg range" );
  158. int i;
  159. for( i = 0; i < table_len; i ++ )
  160. {
  161. lua_rawgeti( L, 3, i + 1 );
  162. delay_table[i] = ( int )luaL_checkinteger( L, -1 );
  163. lua_pop( L, 1 );
  164. if( delay_table[i] < 0 || delay_table[i] > 1000000 ) // can not delay more than 1000000 us
  165. return luaL_error( L, "delay must < 1000000 us" );
  166. }
  167. } else {
  168. return luaL_error( L, "wrong arg range" );
  169. }
  170. if(lua_isnumber(L, 4))
  171. repeat = lua_tointeger( L, 4 );
  172. if( repeat < 0 || repeat > DELAY_TABLE_MAX_LEN )
  173. return luaL_error( L, "delay must < 256" );
  174. if(repeat==0)
  175. repeat = 1;
  176. int j;
  177. bool skip_loop = true;
  178. do
  179. {
  180. if(skip_loop){ // skip the first loop.
  181. skip_loop = false;
  182. continue;
  183. }
  184. for(j=0;j<table_len;j++){
  185. noInterrupts();
  186. // platform_gpio_write(pin, level);
  187. DIRECT_WRITE(pin, level);
  188. interrupts();
  189. delayMicroseconds(delay_table[j]);
  190. level=!level;
  191. }
  192. repeat--;
  193. } while (repeat>0);
  194. return 0;
  195. }
  196. #undef DELAY_TABLE_MAX_LEN
  197. // Module function map
  198. static const LUA_REG_TYPE gpio_map[] = {
  199. { LSTRKEY( "mode" ), LFUNCVAL( lgpio_mode ) },
  200. { LSTRKEY( "read" ), LFUNCVAL( lgpio_read ) },
  201. { LSTRKEY( "write" ), LFUNCVAL( lgpio_write ) },
  202. { LSTRKEY( "serout" ), LFUNCVAL( lgpio_serout ) },
  203. #ifdef GPIO_INTERRUPT_ENABLE
  204. { LSTRKEY( "trig" ), LFUNCVAL( lgpio_trig ) },
  205. { LSTRKEY( "INT" ), LNUMVAL( INTERRUPT ) },
  206. #endif
  207. { LSTRKEY( "OUTPUT" ), LNUMVAL( OUTPUT ) },
  208. { LSTRKEY( "INPUT" ), LNUMVAL( INPUT ) },
  209. { LSTRKEY( "HIGH" ), LNUMVAL( HIGH ) },
  210. { LSTRKEY( "LOW" ), LNUMVAL( LOW ) },
  211. { LSTRKEY( "FLOAT" ), LNUMVAL( FLOAT ) },
  212. { LSTRKEY( "PULLUP" ), LNUMVAL( PULLUP ) },
  213. { LNILKEY, LNILVAL }
  214. };
  215. int luaopen_gpio( lua_State *L ) {
  216. #ifdef GPIO_INTERRUPT_ENABLE
  217. int i;
  218. for(i=0;i<GPIO_PIN_NUM;i++){
  219. gpio_cb_ref[i] = LUA_NOREF;
  220. }
  221. platform_gpio_init(gpio_intr_callback);
  222. #endif
  223. return 0;
  224. }
  225. NODEMCU_MODULE(GPIO, "gpio", gpio_map, luaopen_gpio);