luat_lib_sfd.c 4.9 KB

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