luat_lib_sfd.c 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. /*
  2. @module sfd
  3. @summary SPI FLASH操作库
  4. @version 1.0
  5. @date 2021.05.18
  6. @tag LUAT_USE_SFD
  7. */
  8. #include "luat_base.h"
  9. #include "luat_spi.h"
  10. #include "luat_sfd.h"
  11. #define LUAT_LOG_SDF
  12. #include "luat_log.h"
  13. extern const sdf_opts_t sfd_w25q_opts;
  14. extern const sdf_opts_t sfd_mem_opts;
  15. /*
  16. 初始化spi flash
  17. @api sfd.init(type, spi_id, spi_cs)
  18. @string 类型, 可以是"spi", 也可以是"zbuff"
  19. @int SPI总线的id, 或者 zbuff实例
  20. @int SPI FLASH的片选脚对应的GPIO, 当类型是spi时才需要传
  21. @return userdata 成功返回一个数据结构,否则返回nil
  22. @usage
  23. local drv = sfd.init("spi", 0, 17)
  24. if drv then
  25. log.info("sfd", "chip id", sfd.id(drv):toHex())
  26. end
  27. */
  28. static int l_sfd_init(lua_State *L) {
  29. const char* type = luaL_checkstring(L, 1);
  30. if (!strcmp("spi", type)) {
  31. int spi_id = luaL_checkinteger(L, 2);
  32. int spi_cs = luaL_checkinteger(L, 3);
  33. sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
  34. memset(drv, 0, sizeof(sfd_drv_t));
  35. drv->cfg.spi.id = spi_id;
  36. drv->cfg.spi.cs = spi_cs;
  37. drv->opts = &sfd_w25q_opts;
  38. drv->type = 0;
  39. int re = drv->opts->initialize(drv);
  40. if (re == 0) {
  41. return 1;
  42. }
  43. }
  44. if (!strcmp("zbuff", type)) {
  45. sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
  46. memset(drv, 0, sizeof(sfd_drv_t));
  47. drv->type = 1;
  48. drv->cfg.zbuff = luaL_checkudata(L, 2, "ZBUFF*");
  49. drv->opts = &sfd_mem_opts;
  50. drv->sector_count = drv->cfg.zbuff->len / 256;
  51. int re = drv->opts->initialize(drv);
  52. if (re == 0) {
  53. return 1;
  54. }
  55. }
  56. return 0;
  57. }
  58. /*
  59. 检查spi flash状态
  60. @api sfd.status(drv)
  61. @userdata sfd.init返回的数据结构
  62. @return int 状态值, 0 未初始化成功,1初始化成功且空闲,2正忙
  63. @usage
  64. local drv = sfd.init("spi", 0, 17)
  65. if drv then
  66. log.info("sfd", "status", sfd.status(drv))
  67. end
  68. */
  69. static int l_sfd_status(lua_State *L) {
  70. sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
  71. lua_pushinteger(L, drv->opts->status(drv));
  72. return 1;
  73. }
  74. /*
  75. 读取数据
  76. @api sfd.read(drv, offset, len)
  77. @userdata sfd.init返回的数据结构
  78. @int 起始偏移量
  79. @int 读取长度,当前限制在256以内
  80. @return string 数据
  81. @usage
  82. local drv = sfd.init("spi", 0, 17)
  83. if drv then
  84. log.info("sfd", "read", sfd.read(drv, 0x100, 256))
  85. end
  86. */
  87. static int l_sfd_read(lua_State *L) {
  88. sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
  89. size_t offset = luaL_checkinteger(L, 2);
  90. size_t len = luaL_checkinteger(L, 3);
  91. luaL_Buffer buff;
  92. luaL_buffinitsize(L, &buff, len);
  93. drv->opts->read(drv, buff.b, offset, len);
  94. luaL_pushresult(&buff);
  95. return 1;
  96. }
  97. /*
  98. 写入数据
  99. @api sfd.write(drv, offset, data)
  100. @userdata sfd.init返回的数据结构
  101. @int 起始偏移量
  102. @string 需要写入的数据,当前支持256字节及以下
  103. @return boolean 成功返回true,失败返回false
  104. @usage
  105. local drv = sfd.init("spi", 0, 17)
  106. if drv then
  107. log.info("sfd", "write", sfd.write(drv, 0x100, "hi,luatos"))
  108. end
  109. */
  110. static int l_sfd_write(lua_State *L) {
  111. sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
  112. size_t offset = luaL_checkinteger(L,2);
  113. size_t len = 0;
  114. const char* buff = luaL_checklstring(L, 3, &len);
  115. int re = drv->opts->write(drv, buff, offset, len);
  116. lua_pushboolean(L, re == 0 ? 1 : 0);
  117. return 1;
  118. }
  119. /*
  120. 擦除数据
  121. @api sfd.erase(drv, offset)
  122. @userdata sfd.init返回的数据结构
  123. @int 起始偏移量
  124. @return boolean 成功返回true,失败返回false
  125. @usage
  126. local drv = sfd.init("spi", 0, 17)
  127. if drv then
  128. log.info("sfd", "write", sfd.erase(drv, 0x100))
  129. end
  130. */
  131. static int l_sfd_erase(lua_State *L) {
  132. sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
  133. size_t offset = luaL_checkinteger(L, 2);
  134. size_t len = luaL_optinteger(L, 3, 4096);
  135. int re = drv->opts->erase(drv, offset, len);
  136. lua_pushboolean(L, re == 0 ? 1 : 0);
  137. return 1;
  138. }
  139. static int l_sfd_ioctl(lua_State *L) {
  140. return 0;
  141. }
  142. /*
  143. 芯片唯一id
  144. @api sfd.id(drv)
  145. @userdata sfd.init返回的数据结构
  146. @return string 8字节(64bit)的芯片id
  147. @usage
  148. local drv = sfd.init("spi", 0, 17)
  149. if drv then
  150. log.info("sfd", "chip id", sfd.id(drv))
  151. end
  152. */
  153. static int l_sfd_id(lua_State *L) {
  154. sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
  155. lua_pushlstring(L, drv->chip_id, 8);
  156. return 1;
  157. }
  158. #include "rotable2.h"
  159. static const rotable_Reg_t reg_sfd[] =
  160. {
  161. { "init" , ROREG_FUNC(l_sfd_init)},
  162. { "status", ROREG_FUNC(l_sfd_status)},
  163. { "read", ROREG_FUNC(l_sfd_read)},
  164. { "write", ROREG_FUNC(l_sfd_write)},
  165. { "erase", ROREG_FUNC(l_sfd_erase)},
  166. { "ioctl", ROREG_FUNC(l_sfd_ioctl)},
  167. { "id", ROREG_FUNC(l_sfd_id)},
  168. { NULL, ROREG_INT(0)}
  169. };
  170. LUAMOD_API int luaopen_sfd( lua_State *L ) {
  171. luat_newlib2(L, reg_sfd);
  172. return 1;
  173. }