luat_lib_spi.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618
  1. /*
  2. @module spi
  3. @summary spi操作库
  4. @version 1.0
  5. @date 2020.04.23
  6. */
  7. #include "luat_base.h"
  8. #include "luat_log.h"
  9. #include "luat_sys.h"
  10. #include "luat_msgbus.h"
  11. #include "luat_timer.h"
  12. #include "luat_malloc.h"
  13. #include "luat_spi.h"
  14. #include "luat_zbuff.h"
  15. #include "luat_gpio.h"
  16. #define LUAT_LOG_TAG "spi"
  17. #define META_SPI "SPI*"
  18. static void spi_soft_send_byte(luat_espi_t *espi, uint8_t data)
  19. {
  20. uint8_t i;
  21. for (i = 0; i < 8; i++)
  22. {
  23. if (data&0x80)
  24. {
  25. luat_gpio_set(espi->mosi, Luat_GPIO_HIGH);
  26. }
  27. else
  28. {
  29. luat_gpio_set(espi->mosi, Luat_GPIO_LOW);
  30. }
  31. data<<=1;
  32. if (espi->CPOL == 0)
  33. {
  34. luat_gpio_set(espi->clk, Luat_GPIO_HIGH);
  35. luat_gpio_set(espi->clk, Luat_GPIO_LOW);
  36. }
  37. else
  38. {
  39. luat_gpio_set(espi->clk, Luat_GPIO_LOW);
  40. luat_gpio_set(espi->clk, Luat_GPIO_HIGH);
  41. }
  42. }
  43. }
  44. static char spi_soft_recv_byte(luat_espi_t *espi)
  45. {
  46. unsigned char i = 8;
  47. unsigned char data = 0;
  48. while (i--)
  49. {
  50. data <<= 1;
  51. if (luat_gpio_get(espi->miso))
  52. {
  53. data |= 0x01;
  54. }
  55. if (espi->CPOL == 0)
  56. {
  57. luat_gpio_set(espi->clk, Luat_GPIO_HIGH);
  58. luat_gpio_set(espi->clk, Luat_GPIO_LOW);
  59. }else{
  60. luat_gpio_set(espi->clk, Luat_GPIO_LOW);
  61. luat_gpio_set(espi->clk, Luat_GPIO_HIGH);
  62. }
  63. }
  64. return data;
  65. }
  66. static int spi_soft_send(luat_espi_t *espi, const char*data, size_t len)
  67. {
  68. size_t i = 0;
  69. if (espi->cs != -1)
  70. {
  71. luat_gpio_set(espi->cs, Luat_GPIO_LOW);
  72. }
  73. for (i = 0; i < len; i++)
  74. {
  75. spi_soft_send_byte(espi, data[i]);
  76. }
  77. if (espi->cs != -1)
  78. {
  79. luat_gpio_set(espi->cs, Luat_GPIO_HIGH);
  80. }
  81. return 0;
  82. }
  83. static int spi_soft_recv(luat_espi_t *espi, char *buff, size_t len)
  84. {
  85. size_t i = 0;
  86. if (espi->cs != -1)
  87. {
  88. luat_gpio_set(espi->cs, Luat_GPIO_LOW);
  89. }
  90. luat_gpio_set(espi->mosi, Luat_GPIO_LOW);
  91. for (i = 0; i < len; i++)
  92. {
  93. *buff++ = spi_soft_recv_byte(espi);
  94. }
  95. if (espi->cs != -1)
  96. {
  97. luat_gpio_set(espi->cs, Luat_GPIO_HIGH);
  98. }
  99. luat_gpio_set(espi->mosi, Luat_GPIO_HIGH);
  100. return 0;
  101. }
  102. /**
  103. 设置并启用SPI
  104. @api spi.setup(id, cs, CPHA, CPOL, dataw, bandrate, bitdict, ms, mode)
  105. @int SPI号,例如0
  106. @int CS 片选脚,在w600不可用请填nil
  107. @int CPHA 默认0,可选0/1
  108. @int CPOL 默认0,可选0/1
  109. @int 数据宽度,默认8bit
  110. @int 波特率,默认2M=2000000
  111. @int 大小端, 默认spi.MSB, 可选spi.LSB
  112. @int 主从设置, 默认主1, 可选从机0. 通常只支持主机模式
  113. @int 工作模式, 全双工1, 半双工0, 默认全双工
  114. @return int 成功返回0,否则返回其他值
  115. @usage
  116. -- 初始化spi
  117. spi.setup(0,20,0,0,8,2000000,spi.MSB,1,1)
  118. */
  119. static int l_spi_setup(lua_State *L) {
  120. luat_spi_t spi_config = {0};
  121. spi_config.id = luaL_checkinteger(L, 1);
  122. spi_config.cs = luaL_optinteger(L, 2, 255); // 默认无
  123. spi_config.CPHA = luaL_optinteger(L, 3, 0); // CPHA0
  124. spi_config.CPOL = luaL_optinteger(L, 4, 0); // CPOL0
  125. spi_config.dataw = luaL_optinteger(L, 5, 8); // 8bit
  126. spi_config.bandrate = luaL_optinteger(L, 6, 2000000U); // 2000000U
  127. spi_config.bit_dict = luaL_optinteger(L, 7, 1); // MSB=1, LSB=0
  128. spi_config.master = luaL_optinteger(L, 8, 1); // master=1,slave=0
  129. spi_config.mode = luaL_optinteger(L, 9, 1); // FULL=1, half=0
  130. lua_pushinteger(L, luat_spi_setup(&spi_config));
  131. return 1;
  132. }
  133. /**
  134. 设置并启用软件SPI
  135. @api spi.createSoft(cs, mosi, miso, clk, CPHA, CPOL, dataw, bitdict, ms, mode)
  136. @int cs引脚编号,传入nil意为Lua控制cs脚
  137. @int mosi引脚编号
  138. @int miso引脚编号
  139. @int clk引脚编号
  140. @int 默认0,可选0/1
  141. @int 默认0,可选0/1
  142. @int 数据宽度,默认8bit
  143. @int 大小端,默认spi.MSB, 可选spi.LSB
  144. @int 主从设置,默认主1, 可选从机0. 通常只支持主机模式
  145. @int 工作模式,全双工1,半双工0,默认全双工
  146. @return 软件SPI对象 可当作SPI的id使用
  147. @usage
  148. -- 初始化软件spi
  149. local softSpiDevice = spi.createSoft(0, 1, 2, 3, 0, 0, 8, spi.MSB, 1, 1)
  150. local result = spi.send(softSpiDevice, string.char(0x9f))
  151. */
  152. static int l_spi_soft(lua_State *L) {
  153. luat_espi_t *espi = (luat_espi_t *)lua_newuserdata(L, sizeof(luat_espi_t));
  154. espi->cs = luaL_optinteger(L, 1, -1);
  155. espi->mosi = luaL_checkinteger(L, 2);
  156. espi->miso = luaL_checkinteger(L, 3);
  157. espi->clk = luaL_checkinteger(L, 4);
  158. espi->CPHA = luaL_optinteger(L, 5, 0);
  159. espi->CPOL = luaL_optinteger(L, 6, 0);
  160. espi->dataw = luaL_optinteger(L, 7, 8);
  161. espi->bit_dict = luaL_optinteger(L, 8, 1);
  162. espi->master = luaL_optinteger(L, 9, 1);
  163. espi->mode = luaL_optinteger(L, 10, 1);
  164. luat_gpio_mode(espi->cs, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  165. luat_gpio_mode(espi->mosi, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  166. luat_gpio_mode(espi->miso, Luat_GPIO_INPUT, Luat_GPIO_PULLDOWN, 0);
  167. if (espi->CPOL == 0)
  168. {
  169. luat_gpio_mode(espi->clk, Luat_GPIO_OUTPUT, Luat_GPIO_PULLDOWN, 0);
  170. }
  171. else if (espi->CPOL == 1)
  172. {
  173. luat_gpio_mode(espi->clk, Luat_GPIO_OUTPUT, Luat_GPIO_PULLUP, 1);
  174. }
  175. luaL_setmetatable(L, LUAT_ESPI_TYPE);
  176. return 1;
  177. }
  178. /**
  179. 关闭指定的SPI
  180. @api spi.close(id)
  181. @int SPI号,例如0
  182. @return int 成功返回0,否则返回其他值
  183. @usage
  184. -- 初始化spi
  185. spi.close(0)
  186. */
  187. static int l_spi_close(lua_State *L) {
  188. if (lua_isinteger(L, 1))
  189. {
  190. int id = luaL_checkinteger(L, 1);
  191. lua_pushinteger(L, luat_spi_close(id));
  192. }
  193. else
  194. {
  195. luat_espi_t *espi = (luat_espi_t*)lua_touserdata(L, 1);
  196. lua_pushinteger(L, 0);
  197. }
  198. return 1;
  199. }
  200. /**
  201. 传输SPI数据
  202. @api spi.transfer(id, send_data[, len])
  203. @int SPI号(例如0)或软件SPI对象
  204. @string/zbuff 待发送的数据,如果为zbuff数据,则会从对象所处的指针处开始读
  205. @int 可选。待发送数据的长度,默认为data长度
  206. @int 可选。读取数据的长度,默认为1
  207. @return string 读取成功返回字符串,否则返回nil
  208. @usage
  209. -- 初始化spi
  210. spi.setup(0,nil,0,0,8,2000000,spi.MSB,1,1)
  211. local recv = spi.transfer(0, "123")--发送123,并读取数据
  212. local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
  213. local recv = spi.transfer(0, buff)--把zbuff数据从指针开始,全发出去,并读取数据
  214. */
  215. static int l_spi_transfer(lua_State *L) {
  216. size_t send_length = 0;
  217. const char* send_buff = NULL;
  218. if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
  219. luat_zbuff_t *buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
  220. send_buff = (const char*)(buff->addr+buff->cursor);
  221. send_length = buff->len - buff->cursor;
  222. }else{
  223. send_buff = lua_tolstring(L, 2, &send_length);
  224. }
  225. size_t length = luaL_optinteger(L,3,1);
  226. if(length <= send_length)
  227. send_length = length;
  228. size_t recv_length = luaL_optinteger(L,4,1);
  229. //长度为0时,直接返回空字符串
  230. if(send_length <= 0){
  231. lua_pushlstring(L,NULL,0);
  232. return 1;
  233. }
  234. char* recv_buff = luat_heap_malloc(recv_length);
  235. if(recv_buff == NULL)
  236. return 0;
  237. if (lua_isinteger(L, 1))
  238. {
  239. int id = luaL_checkinteger(L, 1);
  240. int ret = luat_spi_transfer(id, send_buff, send_length, recv_buff, recv_length);
  241. if (ret > 0) {
  242. lua_pushlstring(L, recv_buff, ret);
  243. luat_heap_free(recv_buff);
  244. return 1;
  245. }
  246. }
  247. else
  248. {
  249. luat_espi_t *espi = toespi(L);
  250. int csPin = -1;
  251. if (espi->cs!=-1)
  252. {
  253. csPin = espi->cs;
  254. espi->cs = -1;
  255. luat_gpio_set(csPin, Luat_GPIO_LOW);
  256. }
  257. spi_soft_send(espi, send_buff, send_length);
  258. spi_soft_recv(espi, recv_buff, recv_length);
  259. if (csPin!=-1)
  260. {
  261. luat_gpio_set(csPin, Luat_GPIO_HIGH);
  262. espi->cs = csPin;
  263. }
  264. lua_pushlstring(L, recv_buff, recv_length);
  265. luat_heap_free(recv_buff);
  266. return 1;
  267. }
  268. luat_heap_free(recv_buff);
  269. return 0;
  270. }
  271. /**
  272. 接收指定长度的SPI数据
  273. @api spi.recv(id, size)
  274. @int SPI号,例如0
  275. @int 数据长度
  276. @return string 读取成功返回字符串,否则返回nil
  277. @usage
  278. -- 初始化spi
  279. spi.setup(0,nil,0,0,8,2000000,spi.MSB,1,1)
  280. local recv = spi.recv(0, 4)--接收4字节数据
  281. */
  282. static int l_spi_recv(lua_State *L) {
  283. int len = luaL_checkinteger(L, 2);
  284. char* recv_buff = luat_heap_malloc(len);
  285. if(recv_buff == NULL)
  286. return 0;
  287. if (lua_isinteger(L, 1))
  288. {
  289. int id = luaL_checkinteger(L, 1);
  290. int ret = luat_spi_recv(id, recv_buff, len);
  291. if (ret > 0) {
  292. lua_pushlstring(L, recv_buff, ret);
  293. luat_heap_free(recv_buff);
  294. return 1;
  295. }
  296. else
  297. {
  298. luat_heap_free(recv_buff);
  299. return 0;
  300. }
  301. }
  302. else
  303. {
  304. luat_espi_t *espi = toespi(L);
  305. spi_soft_recv(espi, recv_buff, len);
  306. lua_pushlstring(L, recv_buff, len);
  307. luat_heap_free(recv_buff);
  308. return 1;
  309. }
  310. }
  311. /**
  312. 发送SPI数据
  313. @api spi.send(id, data[, len])
  314. @int SPI号,例如0
  315. @string/zbuff 待发送的数据,如果为zbuff数据,则会从对象所处的指针处开始读
  316. @int 可选。待发送数据的长度,默认为data长度
  317. @return int 发送结果
  318. @usage
  319. -- 初始化spi
  320. spi.setup(0,nil,0,0,8,2000000,spi.MSB,1,1)
  321. local result = spi.send(0, "123")--发送123
  322. local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
  323. local result = spi.send(0, buff)--把zbuff数据从指针开始,全发出去
  324. */
  325. static int l_spi_send(lua_State *L) {
  326. size_t len = 0;
  327. const char* send_buff = NULL;
  328. if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
  329. luat_zbuff_t *buff = (luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE);
  330. send_buff = (const char*)(buff->addr+buff->cursor);
  331. len = buff->len - buff->cursor;
  332. }else{
  333. send_buff = lua_tolstring(L, 2, &len);
  334. }
  335. if(lua_isinteger(L,3)){//长度参数
  336. size_t len_temp = luaL_checkinteger(L,3);
  337. if(len_temp < len)
  338. len = len_temp;
  339. }
  340. //长度为0时,直接返回
  341. if(len <= 0){
  342. lua_pushinteger(L,0);
  343. return 1;
  344. }
  345. if (lua_isinteger(L, 1))
  346. {
  347. int id = luaL_checkinteger(L, 1);
  348. lua_pushinteger(L, luat_spi_send(id, send_buff, len));
  349. }
  350. else
  351. {
  352. luat_espi_t *espi = toespi(L);
  353. lua_pushinteger(L, spi_soft_send(espi, send_buff, len));
  354. }
  355. return 1;
  356. }
  357. /**
  358. 设置并启用SPI(对象方式)
  359. @api spi.deviceSetup(id, cs, CPHA, CPOL, dataw, bandrate, bitdict, ms, mode)
  360. @int SPI号,例如0
  361. @int CS 片选脚,在w600不可用请填nil
  362. @int CPHA 默认0,可选0/1
  363. @int CPOL 默认0,可选0/1
  364. @int 数据宽度,默认8bit
  365. @int 波特率,默认20M=20000000
  366. @int 大小端, 默认spi.MSB, 可选spi.LSB
  367. @int 主从设置, 默认主1, 可选从机0. 通常只支持主机模式
  368. @int 工作模式, 全双工1, 半双工0, 默认全双工
  369. @return userdata spi_device
  370. @usage
  371. -- 初始化spi
  372. local spi_device = spi.deviceSetup(0,17,0,0,8,2000000,spi.MSB,1,1)
  373. */
  374. static int l_spi_device_setup(lua_State *L) {
  375. int bus_id = luaL_checkinteger(L, 1);
  376. int cs = luaL_optinteger(L, 2, 255); // 默认无
  377. int CPHA = luaL_optinteger(L, 3, 0); // CPHA0
  378. int CPOL = luaL_optinteger(L, 4, 0); // CPOL0
  379. int dataw = luaL_optinteger(L, 5, 8); // 8bit
  380. int bandrate = luaL_optinteger(L, 6, 20000000U); // 20000000U
  381. int bit_dict = luaL_optinteger(L, 7, 1); // MSB=1, LSB=0
  382. int master = luaL_optinteger(L, 8, 1); // master=1,slave=0
  383. int mode = luaL_optinteger(L, 9, 1); // FULL=1, half=0
  384. luat_spi_device_t* spi_device = lua_newuserdata(L, sizeof(luat_spi_device_t));
  385. if (spi_device == NULL)return 0;
  386. memset(spi_device, 0, sizeof(luat_spi_device_t));
  387. spi_device->bus_id = bus_id;
  388. spi_device->spi_config.cs = cs;
  389. spi_device->spi_config.CPHA = CPHA;
  390. spi_device->spi_config.CPOL = CPOL;
  391. spi_device->spi_config.dataw = dataw;
  392. spi_device->spi_config.bandrate = bandrate;
  393. spi_device->spi_config.bit_dict = bit_dict;
  394. spi_device->spi_config.master = master;
  395. spi_device->spi_config.mode = mode;
  396. luat_spi_device_setup(spi_device);
  397. luaL_setmetatable(L, META_SPI);
  398. return 1;
  399. }
  400. /**
  401. 关闭指定的SPI(对象方式)
  402. @api spi_device:close()
  403. @userdata spi_device
  404. @return int 成功返回0,否则返回其他值
  405. @usage
  406. -- 初始化spi
  407. spi_device.close()
  408. */
  409. static int l_spi_device_close(lua_State *L) {
  410. luat_spi_device_t* spi_device = (luat_spi_device_t*)lua_touserdata(L, 1);
  411. int ret = luat_spi_device_close(spi_device);
  412. lua_pushboolean(L, ret == 0 ? 1 : 0);
  413. return 1;
  414. }
  415. /**
  416. 传输SPI数据(对象方式)
  417. @api spi_device:transfer(send_data[, len])
  418. @userdata spi_device
  419. @string/zbuff 待发送的数据,如果为zbuff数据,则会从对象所处的指针处开始读
  420. @int 可选。待发送数据的长度,默认为data长度
  421. @int 可选。读取数据的长度,默认为1
  422. @return string 读取成功返回字符串,否则返回nil
  423. @usage
  424. -- 初始化spi
  425. local spi_device = spi.device_setup(0,17,0,0,8,2000000,spi.MSB,1,1)
  426. local recv = spi_device:transfer("123")--发送123,并读取数据
  427. local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
  428. local recv = spi_device:transfer(buff)--把zbuff数据从指针开始,全发出去,并读取数据
  429. */
  430. static int l_spi_device_transfer(lua_State *L) {
  431. luat_spi_device_t* spi_device = (luat_spi_device_t*)lua_touserdata(L, 1);
  432. size_t send_length = 0;
  433. const char* send_buff = NULL;
  434. if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
  435. luat_zbuff_t *buff = (luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE);
  436. send_buff = (const char*)(buff->addr+buff->cursor);
  437. send_length = buff->len - buff->cursor;
  438. }else{
  439. send_buff = lua_tolstring(L, 2, &send_length);
  440. }
  441. size_t length = luaL_optinteger(L,3,1);
  442. if(length <= send_length)
  443. send_length = length;
  444. size_t recv_length = luaL_optinteger(L,4,1);
  445. //长度为0时,直接返回空字符串
  446. if(recv_length <= 0){
  447. lua_pushlstring(L,NULL,0);
  448. return 1;
  449. }
  450. char* recv_buff = luat_heap_malloc(recv_length);
  451. if(recv_buff == NULL)
  452. return 0;
  453. int ret = luat_spi_device_transfer(spi_device, send_buff, send_length, recv_buff, recv_length);
  454. if (ret > 0) {
  455. lua_pushlstring(L, recv_buff, ret);
  456. luat_heap_free(recv_buff);
  457. return 1;
  458. }
  459. luat_heap_free(recv_buff);
  460. return 0;
  461. }
  462. /**
  463. 发送SPI数据(对象方式)
  464. @api spi_device:send(data[, len])
  465. @userdata spi_device
  466. @string/zbuff 待发送的数据,如果为zbuff数据,则会从对象所处的指针处开始读
  467. @int 可选。待发送数据的长度,默认为data长度
  468. @return int 发送结果
  469. @usage
  470. -- 初始化spi
  471. local spi_device = spi.device_setup(0,17,0,0,8,2000000,spi.MSB,1,1)
  472. local result = spi_device:send("123")--发送123
  473. local buff = zbuff.create(1024, 0x33) --创建一个初值全为0x33的内存区域
  474. local result = spi_device:send(buff)--把zbuff数据从指针开始,全发出去
  475. */
  476. static int l_spi_device_send(lua_State *L) {
  477. luat_spi_device_t* spi_device = (luat_spi_device_t*)lua_touserdata(L, 1);
  478. size_t len = 0;
  479. const char* send_buff = NULL;
  480. if(lua_isuserdata(L, 2)){//zbuff对象特殊处理
  481. luat_zbuff_t *buff = (luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE);
  482. send_buff = (const char*)(buff->addr+buff->cursor);
  483. len = buff->len - buff->cursor;
  484. }else{
  485. send_buff = lua_tolstring(L, 2, &len);
  486. }
  487. if(lua_isinteger(L,3)){//长度参数
  488. size_t len_temp = luaL_checkinteger(L,3);
  489. if(len_temp < len)
  490. len = len_temp;
  491. }
  492. //长度为0时,直接返回
  493. if(len <= 0){
  494. lua_pushinteger(L,0);
  495. return 1;
  496. }
  497. lua_pushinteger(L, luat_spi_device_send(spi_device, send_buff, len));
  498. return 1;
  499. }
  500. /**
  501. 接收指定长度的SPI数据(对象方式)
  502. @api spi_device:recv(size)
  503. @userdata spi_device
  504. @int 数据长度
  505. @return string 读取成功返回字符串,否则返回nil
  506. @usage
  507. -- 初始化spi
  508. local spi_device = spi.device_setup(0,17,0,0,8,2000000,spi.MSB,1,1)
  509. local recv = spi_device:recv(4)--接收4字节数据
  510. */
  511. static int l_spi_device_recv(lua_State *L) {
  512. luat_spi_device_t* spi_device = (luat_spi_device_t*)lua_touserdata(L, 1);
  513. int len = luaL_checkinteger(L, 2);
  514. char* recv_buff = luat_heap_malloc(len);
  515. if(recv_buff == NULL) return 0;
  516. int ret = luat_spi_device_recv(spi_device, recv_buff, len);
  517. if (ret > 0) {
  518. lua_pushlstring(L, recv_buff, ret);
  519. luat_heap_free(recv_buff);
  520. return 1;
  521. }
  522. luat_heap_free(recv_buff);
  523. return 0;
  524. }
  525. int _spi_struct_newindex(lua_State *L) {
  526. const char* key = luaL_checkstring(L, 2);
  527. if (!strcmp("close", key)) {
  528. lua_pushcfunction(L, l_spi_device_close);
  529. return 1;
  530. }
  531. else if (!strcmp("transfer", key)) {
  532. lua_pushcfunction(L, l_spi_device_transfer);
  533. return 1;
  534. }
  535. else if (!strcmp("send", key)) {
  536. lua_pushcfunction(L, l_spi_device_send);
  537. return 1;
  538. }
  539. else if (!strcmp("recv", key)) {
  540. lua_pushcfunction(L, l_spi_device_recv);
  541. return 1;
  542. }
  543. return 0;
  544. }
  545. void luat_spi_struct_init(lua_State *L) {
  546. luaL_newmetatable(L, META_SPI);
  547. lua_pushcfunction(L, _spi_struct_newindex);
  548. lua_setfield( L, -2, "__index" );
  549. lua_pop(L, 1);
  550. }
  551. void luat_soft_spi_struct_init(lua_State *L) {
  552. luaL_newmetatable(L, LUAT_ESPI_TYPE);
  553. lua_pop(L, 1);
  554. }
  555. //------------------------------------------------------------------
  556. #include "rotable2.h"
  557. static const rotable_Reg_t reg_spi[] =
  558. {
  559. { "setup" , ROREG_FUNC(l_spi_setup)},
  560. { "createSoft", ROREG_FUNC(l_spi_soft) },
  561. { "close", ROREG_FUNC(l_spi_close)},
  562. { "transfer", ROREG_FUNC(l_spi_transfer)},
  563. { "recv", ROREG_FUNC(l_spi_recv)},
  564. { "send", ROREG_FUNC(l_spi_send)},
  565. { "deviceSetup", ROREG_FUNC(l_spi_device_setup)},
  566. { "MSB", ROREG_INT(1)},
  567. { "LSB", ROREG_INT(2)},
  568. { "master", ROREG_INT(1)},
  569. { "slave", ROREG_INT(2)},
  570. { "full", ROREG_INT(1)},
  571. { "half", ROREG_INT(0)},
  572. { "SPI_0", ROREG_INT(0)},
  573. { "SPI_1", ROREG_INT(1)},
  574. { "SPI_2", ROREG_INT(2)},
  575. { "SPI_3", ROREG_INT(3)},
  576. { "SPI_4", ROREG_INT(4)},
  577. { "HSPI_0", ROREG_INT(5)},
  578. { NULL, ROREG_INT(0) }
  579. };
  580. LUAMOD_API int luaopen_spi( lua_State *L ) {
  581. luat_newlib2(L, reg_spi);
  582. luat_spi_struct_init(L);
  583. luat_soft_spi_struct_init(L);
  584. return 1;
  585. }