| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210 |
- /*
- @module sfd
- @summary SPI FLASH操作库
- @version 1.0
- @date 2021.05.18
- @tag LUAT_USE_SFD
- */
- #include "luat_base.h"
- #include "luat_spi.h"
- #include "luat_sfd.h"
- #define LUAT_LOG_TAG "sfd"
- #include "luat_log.h"
- extern const sdf_opts_t sfd_w25q_opts;
- extern const sdf_opts_t sfd_mem_opts;
- extern const sdf_opts_t sfd_onchip_opts;
- /*
- 初始化spi flash
- @api sfd.init(type, spi_id, spi_cs)
- @string 类型, 可以是"spi", 也可以是"zbuff", 或者"onchip"
- @int SPI总线的id, 或者 zbuff实例
- @int SPI FLASH的片选脚对应的GPIO, 当类型是spi时才需要传
- @return userdata 成功返回一个数据结构,否则返回nil
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "chip id", sfd.id(drv):toHex())
- end
- -- 2023.01.15之后的固件支持onchip类型, 支持直接读写片上flash的一小块区域,一般是64k
- -- 这块区域通常是fdb/fskv库所在的区域, 所以不要混着用
- local onchip = sfd.init("onchip")
- local data = sfd.read(onchip, 0x100, 256)
- sfd.erase(onchip, 0x100)
- sfd.write(onchip, 0x100, data or "Hi")
- */
- static int l_sfd_init(lua_State *L) {
- const char* type = luaL_checkstring(L, 1);
- if (!strcmp("spi", type)) {
-
- int spi_id = luaL_checkinteger(L, 2);
- int spi_cs = luaL_checkinteger(L, 3);
- sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
- memset(drv, 0, sizeof(sfd_drv_t));
- drv->cfg.spi.id = spi_id;
- drv->cfg.spi.cs = spi_cs;
- drv->opts = &sfd_w25q_opts;
- drv->type = 0;
- int re = drv->opts->initialize(drv);
- if (re == 0) {
- return 1;
- }
- return 0;
- }
- if (!strcmp("zbuff", type)) {
- sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
- memset(drv, 0, sizeof(sfd_drv_t));
- drv->type = 1;
- drv->cfg.zbuff = luaL_checkudata(L, 2, "ZBUFF*");
- drv->opts = &sfd_mem_opts;
- drv->sector_count = drv->cfg.zbuff->len / 256;
- int re = drv->opts->initialize(drv);
- if (re == 0) {
- return 1;
- }
- return 0;
- }
- if (!strcmp("onchip", type)) {
- sfd_drv_t *drv = (sfd_drv_t *)lua_newuserdata(L, sizeof(sfd_drv_t));
- memset(drv, 0, sizeof(sfd_drv_t));
- drv->type = 3;
- drv->opts = &sfd_onchip_opts;
- int re = drv->opts->initialize(drv);
- if (re == 0) {
- return 1;
- }
- return 0;
- }
- return 0;
- }
- /*
- 检查spi flash状态
- @api sfd.status(drv)
- @userdata sfd.init返回的数据结构
- @return int 状态值, 0 未初始化成功,1初始化成功且空闲,2正忙
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "status", sfd.status(drv))
- end
- */
- static int l_sfd_status(lua_State *L) {
- sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
- lua_pushinteger(L, drv->opts->status(drv));
- return 1;
- }
- /*
- 读取数据
- @api sfd.read(drv, offset, len)
- @userdata sfd.init返回的数据结构
- @int 起始偏移量
- @int 读取长度,当前限制在256以内
- @return string 数据
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "read", sfd.read(drv, 0x100, 256))
- end
- */
- static int l_sfd_read(lua_State *L) {
- sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
- size_t offset = luaL_checkinteger(L, 2);
- size_t len = luaL_checkinteger(L, 3);
- luaL_Buffer buff;
- luaL_buffinitsize(L, &buff, len);
- drv->opts->read(drv, buff.b, offset, len);
- luaL_pushresult(&buff);
- return 1;
- }
- /*
- 写入数据
- @api sfd.write(drv, offset, data)
- @userdata sfd.init返回的数据结构
- @int 起始偏移量
- @string 需要写入的数据,当前支持256字节及以下
- @return boolean 成功返回true,失败返回false
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "write", sfd.write(drv, 0x100, "hi,luatos"))
- end
- */
- static int l_sfd_write(lua_State *L) {
- sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
- size_t offset = luaL_checkinteger(L,2);
- size_t len = 0;
- const char* buff = luaL_checklstring(L, 3, &len);
- int re = drv->opts->write(drv, buff, offset, len);
- lua_pushboolean(L, re == 0 ? 1 : 0);
- return 1;
- }
- /*
- 擦除数据
- @api sfd.erase(drv, offset)
- @userdata sfd.init返回的数据结构
- @int 起始偏移量
- @return boolean 成功返回true,失败返回false
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "write", sfd.erase(drv, 0x100))
- end
- */
- static int l_sfd_erase(lua_State *L) {
- sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
- size_t offset = luaL_checkinteger(L, 2);
- size_t len = luaL_optinteger(L, 3, 4096);
- int re = drv->opts->erase(drv, offset, len);
- lua_pushboolean(L, re == 0 ? 1 : 0);
- return 1;
- }
- static int l_sfd_ioctl(lua_State *L) {
- return 0;
- }
- /*
- 芯片唯一id
- @api sfd.id(drv)
- @userdata sfd.init返回的数据结构
- @return string 8字节(64bit)的芯片id
- @usage
- local drv = sfd.init("spi", 0, 17)
- if drv then
- log.info("sfd", "chip id", sfd.id(drv))
- end
- */
- static int l_sfd_id(lua_State *L) {
- sfd_drv_t *drv = (sfd_drv_t *) lua_touserdata(L, 1);
- lua_pushlstring(L, drv->chip_id, 8);
- return 1;
- }
- #include "rotable2.h"
- static const rotable_Reg_t reg_sfd[] =
- {
- { "init" , ROREG_FUNC(l_sfd_init)},
- { "status", ROREG_FUNC(l_sfd_status)},
- { "read", ROREG_FUNC(l_sfd_read)},
- { "write", ROREG_FUNC(l_sfd_write)},
- { "erase", ROREG_FUNC(l_sfd_erase)},
- { "ioctl", ROREG_FUNC(l_sfd_ioctl)},
- { "id", ROREG_FUNC(l_sfd_id)},
- { NULL, ROREG_INT(0)}
- };
- LUAMOD_API int luaopen_sfd( lua_State *L ) {
- luat_newlib2(L, reg_sfd);
- return 1;
- }
|