luat_lib_i2c.c 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. /*
  2. @module i2c
  3. @summary I2C操作
  4. @version 1.0
  5. @date 2020.03.30
  6. */
  7. #include "luat_base.h"
  8. #include "luat_log.h"
  9. #include "luat_timer.h"
  10. #include "luat_malloc.h"
  11. #include "luat_i2c.h"
  12. #define LUAT_LOG_TAG "luat.i2c"
  13. #include "luat_log.h"
  14. /*
  15. i2c编号是否存在
  16. @api i2c.exist(id)
  17. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  18. @return int 存在就返回1,否则返回0
  19. @usage
  20. -- 检查i2c1是否存在
  21. if i2c.exist(1) then
  22. log.info("存在 i2c1")
  23. end
  24. */
  25. static int l_i2c_exist(lua_State *L) {
  26. int re = luat_i2c_exist(luaL_checkinteger(L, 1));
  27. lua_pushinteger(L, re);
  28. return 1;
  29. }
  30. /*
  31. i2c初始化
  32. @api i2c.setup(id)
  33. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  34. @return int 成功就返回1,否则返回0
  35. @usage
  36. -- 初始化i2c1
  37. if i2c.setup(1) == 0 then
  38. log.info("存在 i2c1")
  39. else
  40. i2c.close(1) -- 关掉
  41. end
  42. */
  43. static int l_i2c_setup(lua_State *L) {
  44. int re = luat_i2c_setup(luaL_checkinteger(L, 1), luaL_optinteger(L, 2, 0), luaL_optinteger(L, 3, 0));
  45. lua_pushinteger(L, re == 0 ? luaL_optinteger(L, 2, 0) : -1);
  46. return 1;
  47. }
  48. /*
  49. i2c发送数据
  50. @api i2c.send(id, addr, data)
  51. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  52. @int I2C子设备的地址, 7位地址
  53. @string 待发送的数据
  54. @return nil 无返回值
  55. @usage
  56. -- 往i2c1发送2个字节的数据
  57. i2c.send(1, 0x5C, string.char(0x0F, 0x2F))
  58. */
  59. static int l_i2c_send(lua_State *L) {
  60. int id = luaL_checkinteger(L, 1);
  61. int addr = luaL_checkinteger(L, 2);
  62. size_t len;
  63. if (lua_isstring(L, 3)) {
  64. const char* buff = luaL_checklstring(L, 3, &len);
  65. luat_i2c_send(id, addr, (char*)buff, len);
  66. }
  67. else if (lua_isinteger(L, 3)) {
  68. len = lua_gettop(L) - 2;
  69. char buff[len+1];
  70. for (size_t i = 0; i < len; i++)
  71. {
  72. buff[i] = lua_tointeger(L, 3+i);
  73. }
  74. luat_i2c_send(id, addr, buff, len);
  75. }
  76. return 0;
  77. }
  78. /*
  79. i2c接收数据
  80. @api i2c.recv(id, addr, len)
  81. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  82. @int I2C子设备的地址, 7位地址
  83. @int 手机数据的长度
  84. @return string 收到的数据
  85. @usage
  86. -- 从i2c1读取2个字节的数据
  87. local data = i2c.recv(1, 0x5C, 2)
  88. */
  89. static int l_i2c_recv(lua_State *L) {
  90. int id = luaL_checkinteger(L, 1);
  91. int addr = luaL_checkinteger(L, 2);
  92. int len = luaL_checkinteger(L, 3);
  93. char buf[len];
  94. luat_i2c_recv(id, addr, &buf[0], len);
  95. lua_pushlstring(L, buf, len);
  96. return 1;
  97. }
  98. /*
  99. i2c写寄存器数据
  100. @api i2c.writeReg(id, addr, reg, data)
  101. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  102. @int I2C子设备的地址, 7位地址
  103. @int 寄存器地址
  104. @string 待发送的数据
  105. @return int 发送数据的结果,0为成功
  106. @usage
  107. -- 从i2c1的地址为0x5C的设备的寄存器0x01写入2个字节的数据
  108. i2c.writeReg(1, 0x5C, 0x01, string.char(0x00, 0xF2))
  109. */
  110. static int l_i2c_write_reg(lua_State *L) {
  111. int id = luaL_checkinteger(L, 1);
  112. int addr = luaL_checkinteger(L, 2);
  113. int reg = luaL_checkinteger(L, 3);
  114. size_t len;
  115. const char* lb = luaL_checklstring(L, 4, &len);
  116. char* buff = (char*)luat_heap_malloc(sizeof(char)*len+1);
  117. *buff = (char)reg;
  118. memcpy(buff+1,lb,sizeof(char)+len+1);
  119. int result = luat_i2c_send(id, addr, buff, len+1);
  120. luat_heap_free(buff);
  121. return result;
  122. }
  123. /*
  124. i2c读寄存器数据
  125. @api i2c.readReg(id, addr, reg, len)
  126. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  127. @int I2C子设备的地址, 7位地址
  128. @int 寄存器地址
  129. @int 待接收的数据长度
  130. @return string 收到的数据
  131. @usage
  132. -- 从i2c1的地址为0x5C的设备的寄存器0x01读出2个字节的数据
  133. i2c.readReg(1, 0x5C, 0x01, 2)
  134. */
  135. static int l_i2c_read_reg(lua_State *L) {
  136. int id = luaL_checkinteger(L, 1);
  137. int addr = luaL_checkinteger(L, 2);
  138. int reg = luaL_checkinteger(L, 3);
  139. int len = luaL_checkinteger(L, 4);
  140. char temp = (char)reg;
  141. int result = luat_i2c_send(id, addr, &temp, 1);
  142. if(result!=0){//如果返回值不为0,说明收失败了
  143. LLOGD("i2c send result %d", result);
  144. lua_pushlstring(L, NULL, 0);
  145. return 1;
  146. }
  147. char* buff = (char*)luat_heap_malloc(sizeof(char)*len);
  148. result = luat_i2c_recv(id, addr, buff, len);
  149. if(result!=0){//如果返回值不为0,说明收失败了
  150. len = 0;
  151. LLOGD("i2c receive result %d", result);
  152. }
  153. lua_pushlstring(L, buff, len);
  154. luat_heap_free(buff);
  155. return 1;
  156. }
  157. /*
  158. 关闭i2c设备
  159. @api i2c.close(id)
  160. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  161. @return nil 无返回值
  162. @usage
  163. -- 关闭i2c1
  164. i2c.close(1)
  165. */
  166. static int l_i2c_close(lua_State *L) {
  167. int id = luaL_checkinteger(L, 1);
  168. luat_ic2_close(id);
  169. return 0;
  170. }
  171. /*
  172. 从i2c总线读取DHT12的温湿度数据
  173. @api i2c.readDHT(id)
  174. @int 设备id, 例如i2c1的id为1, i2c2的id为2
  175. @int DHT12的设备地址,默认0x5C
  176. @return boolean 读取成功返回true,否则返回false
  177. @return int 湿度值,单位0.1%, 例如 591 代表 59.1%
  178. @return int 温度值,单位0.1摄氏度, 例如 292 代表 29.2摄氏度
  179. @usage
  180. -- 从i2c0读取DHT12
  181. i2c.setup(0)
  182. local re, H, T = i2c.readDHT(0)
  183. if re then
  184. log.info("dht12", H, T)
  185. end
  186. */
  187. static int l_i2c_readDHT12(lua_State *L) {
  188. int id = luaL_checkinteger(L, 1);
  189. int addr = luaL_optinteger(L, 2, 0x5C);
  190. char buff[5] = {0};
  191. char temp = 0x00;
  192. int result = luat_i2c_send(id, addr, &temp, 1);
  193. result = luat_i2c_recv(id, addr, buff, 5);
  194. if (result) {
  195. lua_pushboolean(L, 0);
  196. return 1;
  197. }
  198. else {
  199. if (buff[0] == 0 && buff[1] == 0 && buff[2] == 0 && buff[3] == 0 && buff[4] == 0) {
  200. LLOGD("DHT12 DATA emtry");
  201. lua_pushboolean(L, 0);
  202. return 1;
  203. }
  204. // 检查crc值
  205. LLOGD("DHT12 DATA %02X%02X%02X%02X%02X", buff[0], buff[1], buff[2], buff[3], buff[4]);
  206. uint8_t crc_act = (uint8_t)buff[0] + (uint8_t)buff[1] + (uint8_t)buff[2] + (uint8_t)buff [3];
  207. uint8_t crc_exp = (uint8_t)buff[4];
  208. if (crc_act != crc_exp) {
  209. LLOGD("DATA12 DATA crc not ok");
  210. lua_pushboolean(L, 0);
  211. return 1;
  212. }
  213. lua_pushboolean(L, 1);
  214. lua_pushinteger(L, (uint8_t)buff[0] * 10 + (uint8_t)buff[1]);
  215. if (((uint8_t)buff[2]) > 127)
  216. lua_pushinteger(L, ((uint8_t)buff[2] - 128) * -10 + (uint8_t)buff[3]);
  217. else
  218. lua_pushinteger(L, (uint8_t)buff[2] * 10 + (uint8_t)buff[3]);
  219. return 3;
  220. }
  221. }
  222. #include "rotable.h"
  223. static const rotable_Reg reg_i2c[] =
  224. {
  225. { "exist", l_i2c_exist, 0},
  226. { "setup", l_i2c_setup, 0},
  227. { "send", l_i2c_send, 0},
  228. { "recv", l_i2c_recv, 0},
  229. { "writeReg", l_i2c_write_reg, 0},
  230. { "readReg", l_i2c_read_reg, 0},
  231. { "close", l_i2c_close, 0},
  232. { "readDHT12", l_i2c_readDHT12, 0},
  233. { "FAST", NULL, 1},
  234. { "SLOW", NULL, 0},
  235. { NULL, NULL, 0}
  236. };
  237. LUAMOD_API int luaopen_i2c( lua_State *L ) {
  238. rotable_newlib(L, reg_i2c);
  239. return 1;
  240. }