ow.c 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310
  1. // Module for interfacing with the OneWire interface
  2. #include "module.h"
  3. #include "lauxlib.h"
  4. #include "platform.h"
  5. #include "driver/onewire.h"
  6. // Lua: ow.setup( id )
  7. static int ow_setup( lua_State *L )
  8. {
  9. unsigned id = luaL_checkinteger( L, 1 );
  10. if(id==0)
  11. return luaL_error( L, "no 1-wire for D0" );
  12. MOD_CHECK_ID( ow, id );
  13. onewire_init( id );
  14. return 0;
  15. }
  16. // Lua: r = ow.reset( id )
  17. static int ow_reset( lua_State *L )
  18. {
  19. unsigned id = luaL_checkinteger( L, 1 );
  20. MOD_CHECK_ID( ow, id );
  21. lua_pushinteger( L, onewire_reset(id) );
  22. return 1;
  23. }
  24. // Lua: ow.skip( id )
  25. static int ow_skip( lua_State *L )
  26. {
  27. unsigned id = luaL_checkinteger( L, 1 );
  28. MOD_CHECK_ID( ow, id );
  29. onewire_skip(id);
  30. return 0;
  31. }
  32. // Lua: ow.select( id, buf[8])
  33. static int ow_select( lua_State *L )
  34. {
  35. uint8_t rom[8];
  36. size_t datalen;
  37. int numdata, i;
  38. unsigned id = luaL_checkinteger( L, 1 );
  39. const char *pdata;
  40. MOD_CHECK_ID( ow, id );
  41. if( lua_istable( L, 2 ) )
  42. {
  43. datalen = lua_objlen( L, 2 );
  44. if (datalen!=8)
  45. return luaL_error( L, "wrong arg range" );
  46. for( i = 0; i < datalen; i ++ )
  47. {
  48. lua_rawgeti( L, 2, i + 1 );
  49. numdata = ( int )luaL_checkinteger( L, -1 );
  50. lua_pop( L, 1 );
  51. if( numdata > 255 )
  52. return luaL_error( L, "wrong arg range" );
  53. rom[i] = (uint8_t)numdata;
  54. }
  55. }
  56. else
  57. {
  58. pdata = luaL_checklstring( L, 2, &datalen );
  59. if (datalen!=8)
  60. return luaL_error( L, "wrong arg range" );
  61. for( i = 0; i < datalen; i ++ ){
  62. rom[i] = pdata[i];
  63. }
  64. }
  65. onewire_select(id, rom);
  66. return 0;
  67. }
  68. // Lua: ow.write( id, v, power)
  69. static int ow_write( lua_State *L )
  70. {
  71. int power = 0;
  72. unsigned id = luaL_checkinteger( L, 1 );
  73. MOD_CHECK_ID( ow, id );
  74. int v = (int)luaL_checkinteger( L, 2 );
  75. if( v > 255 )
  76. return luaL_error( L, "wrong arg range" );
  77. if(lua_isnumber(L, 3))
  78. power = lua_tointeger(L, 3);
  79. if(power!=0)
  80. power = 1;
  81. onewire_write((uint8_t)id, (uint8_t)v, (uint8_t)power);
  82. return 0;
  83. }
  84. // Lua: ow.write_bytes( id, buf, power)
  85. static int ow_write_bytes( lua_State *L )
  86. {
  87. int power = 0;
  88. size_t datalen;
  89. unsigned id = luaL_checkinteger( L, 1 );
  90. MOD_CHECK_ID( ow, id );
  91. const uint8_t *pdata = luaL_checklstring( L, 2, &datalen );
  92. if(lua_isnumber(L, 3))
  93. power = lua_tointeger(L, 3);
  94. if(power!=0)
  95. power = 1;
  96. onewire_write_bytes((uint8_t)id, pdata, (uint16_t)datalen, (uint8_t)power);
  97. return 0;
  98. }
  99. // Lua: r = ow.read( id )
  100. static int ow_read( lua_State *L )
  101. {
  102. unsigned id = luaL_checkinteger( L, 1 );
  103. MOD_CHECK_ID( ow, id );
  104. lua_pushinteger( L, onewire_read(id) );
  105. return 1;
  106. }
  107. // Lua: r = ow.read_bytes( id, size )
  108. static int ow_read_bytes( lua_State *L )
  109. {
  110. unsigned id = luaL_checkinteger( L, 1 );
  111. MOD_CHECK_ID( ow, id );
  112. u32 size = ( u32 )luaL_checkinteger( L, 2 );
  113. if( size == 0 )
  114. return 0;
  115. luaL_argcheck(L, size <= LUAL_BUFFERSIZE, 2, "Attempt to read too many characters");
  116. luaL_Buffer b;
  117. luaL_buffinit( L, &b );
  118. char *p = luaL_prepbuffer(&b);
  119. onewire_read_bytes(id, (uint8_t *)p, size);
  120. luaL_addsize(&b, size);
  121. luaL_pushresult( &b );
  122. return 1;
  123. }
  124. // Lua: ow.depower( id )
  125. static int ow_depower( lua_State *L )
  126. {
  127. unsigned id = luaL_checkinteger( L, 1 );
  128. MOD_CHECK_ID( ow, id );
  129. onewire_depower(id);
  130. return 0;
  131. }
  132. #if ONEWIRE_SEARCH
  133. // Clear the search state so that if will start from the beginning again.
  134. // Lua: ow.reset_search( id )
  135. static int ow_reset_search( lua_State *L )
  136. {
  137. unsigned id = luaL_checkinteger( L, 1 );
  138. MOD_CHECK_ID( ow, id );
  139. onewire_reset_search(id);
  140. return 0;
  141. }
  142. // Setup the search to find the device type 'family_code' on the next call
  143. // to search(*newAddr) if it is present.
  144. // Lua: ow.target_search( id, family_code)
  145. static int ow_target_search( lua_State *L )
  146. {
  147. unsigned id = luaL_checkinteger( L, 1 );
  148. MOD_CHECK_ID( ow, id );
  149. int code = (int)luaL_checkinteger( L, 2 );
  150. if( code > 255 )
  151. return luaL_error( L, "wrong arg range" );
  152. onewire_target_search((uint8_t)id, (uint8_t)code);
  153. return 0;
  154. }
  155. // Look for the next device. Returns 1 if a new address has been
  156. // returned. A zero might mean that the bus is shorted, there are
  157. // no devices, or you have already retrieved all of them. It
  158. // might be a good idea to check the CRC to make sure you didn't
  159. // get garbage. The order is deterministic. You will always get
  160. // the same devices in the same order.
  161. // Lua: r = ow.search( id )
  162. static int ow_search( lua_State *L )
  163. {
  164. unsigned id = luaL_checkinteger( L, 1 );
  165. MOD_CHECK_ID( ow, id );
  166. luaL_Buffer b;
  167. luaL_buffinit( L, &b );
  168. char *p = luaL_prepbuffer(&b);
  169. if(onewire_search(id, (uint8_t *)p)){
  170. luaL_addsize(&b, 8);
  171. luaL_pushresult( &b );
  172. } else {
  173. luaL_pushresult(&b); /* close buffer */
  174. lua_pop(L,1);
  175. lua_pushnil(L);
  176. }
  177. return 1;
  178. }
  179. #endif
  180. #if ONEWIRE_CRC
  181. // uint8_t onewire_crc8(const uint8_t *addr, uint8_t len);
  182. // Lua: r = ow.crc8( buf )
  183. static int ow_crc8( lua_State *L )
  184. {
  185. size_t datalen;
  186. const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
  187. if(datalen > 255)
  188. return luaL_error( L, "wrong arg range" );
  189. lua_pushinteger( L, onewire_crc8(pdata, (uint8_t)datalen) );
  190. return 1;
  191. }
  192. #if ONEWIRE_CRC16
  193. // bool onewire_check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc);
  194. // Lua: b = ow.check_crc16( buf, inverted_crc0, inverted_crc1, crc )
  195. static int ow_check_crc16( lua_State *L )
  196. {
  197. size_t datalen;
  198. uint8_t inverted_crc[2];
  199. const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
  200. if(datalen > 65535)
  201. return luaL_error( L, "wrong arg range" );
  202. int crc = 0;
  203. crc = luaL_checkinteger( L, 2 );
  204. if(datalen > 255)
  205. return luaL_error( L, "wrong arg range" );
  206. inverted_crc[0] = (uint8_t)crc;
  207. crc = luaL_checkinteger( L, 3 );
  208. if(datalen > 255)
  209. return luaL_error( L, "wrong arg range" );
  210. inverted_crc[1] = (uint8_t)crc;
  211. crc = 0;
  212. if(lua_isnumber(L, 4))
  213. crc = lua_tointeger(L, 4);
  214. if(crc > 65535)
  215. return luaL_error( L, "wrong arg range" );
  216. lua_pushboolean( L, onewire_check_crc16(pdata, (uint16_t)datalen, inverted_crc, (uint16_t)crc) );
  217. return 1;
  218. }
  219. // uint16_t onewire_crc16(const uint8_t* input, uint16_t len, uint16_t crc);
  220. // Lua: r = ow.crc16( buf, crc )
  221. static int ow_crc16( lua_State *L )
  222. {
  223. size_t datalen;
  224. const uint8_t *pdata = luaL_checklstring( L, 1, &datalen );
  225. if(datalen > 65535)
  226. return luaL_error( L, "wrong arg range" );
  227. int crc = 0;
  228. if(lua_isnumber(L, 2))
  229. crc = lua_tointeger(L, 2);
  230. if(crc > 65535)
  231. return luaL_error( L, "wrong arg range" );
  232. lua_pushinteger( L, onewire_crc16(pdata, (uint16_t)datalen, (uint16_t)crc) );
  233. return 1;
  234. }
  235. #endif
  236. #endif
  237. // Module function map
  238. static const LUA_REG_TYPE ow_map[] = {
  239. { LSTRKEY( "setup" ), LFUNCVAL( ow_setup ) },
  240. { LSTRKEY( "reset" ), LFUNCVAL( ow_reset ) },
  241. { LSTRKEY( "skip" ), LFUNCVAL( ow_skip ) },
  242. { LSTRKEY( "select" ), LFUNCVAL( ow_select ) },
  243. { LSTRKEY( "write" ), LFUNCVAL( ow_write ) },
  244. { LSTRKEY( "write_bytes" ), LFUNCVAL( ow_write_bytes ) },
  245. { LSTRKEY( "read" ), LFUNCVAL( ow_read ) },
  246. { LSTRKEY( "read_bytes" ), LFUNCVAL( ow_read_bytes ) },
  247. { LSTRKEY( "depower" ), LFUNCVAL( ow_depower ) },
  248. #if ONEWIRE_SEARCH
  249. { LSTRKEY( "reset_search" ), LFUNCVAL( ow_reset_search ) },
  250. { LSTRKEY( "target_search" ), LFUNCVAL( ow_target_search ) },
  251. { LSTRKEY( "search" ), LFUNCVAL( ow_search ) },
  252. #endif
  253. #if ONEWIRE_CRC
  254. { LSTRKEY( "crc8" ), LFUNCVAL( ow_crc8 ) },
  255. #if ONEWIRE_CRC16
  256. { LSTRKEY( "check_crc16" ), LFUNCVAL( ow_check_crc16 ) },
  257. { LSTRKEY( "crc16" ), LFUNCVAL( ow_crc16 ) },
  258. #endif
  259. #endif
  260. { LNILKEY, LNILVAL }
  261. };
  262. NODEMCU_MODULE(OW, "ow", ow_map, NULL);