luat_lib_sfd.c 5.7 KB

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