马亚丹 2 месяцев назад
Родитель
Сommit
43d03dcbce

+ 4 - 4
module/Air8000/demo/accessory_board/AirSPINAND_1000/main.lua

@@ -6,8 +6,8 @@
 @author  马亚丹
 @usage
 本demo是演示合宙AirSPINAND_1000配件版的功能使用,可通过以下两种方式驱动nand flash模块,任选一种即可。
-1. ram_spi
-通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看ram_spi.lua 文件
+1. raw_spi
+通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看raw_spi.lua 文件
 2. lf_fs
 通过littleFS文件系统,对nand flash模块以文件系统的方式进行读写数据操作,详细逻辑请看lf_fs.lua 文件
 
@@ -71,8 +71,8 @@ end
 require "lf_fs"
 
 
--- 加载ram_spi功能模块
--- require "ram_spi"
+-- 加载raw_spi功能模块
+-- require "raw_spi"
 
 
 

+ 289 - 0
module/Air8000/demo/accessory_board/AirSPINAND_1000/raw_spi.lua

@@ -0,0 +1,289 @@
+--[[
+@module  raw_spi
+@summary raw_spi测试功能模块
+@version 1.0
+@date    2025.11.03
+@author  马亚丹
+@usage
+本demo演示的功能为:使用Air8000核心板通过SPI库原始SPI接口实现对 NAND Flash(W25N01GV)的操作,演示读数据写数据等操作。
+以 Air8000核心板为例, 接线如下:
+Air8000       AirSPINAND_1000配件版
+GND(任意)          GND
+VDD_EXT            VCC
+GPIO12/SPI1_CS     CS,片选
+SPI1_SLK           CLK,时钟
+SPI1_MOSI          DI,主机输出,从机输入
+SPI1_MISO          DO,主机输入,从机输出
+
+--使用SPI1,硬件SPI CS接在gpio12上
+
+核心逻辑:
+1.初始化并启用spi,如果初始化失败,退出程序
+2.spi启用后读取并验证nand flash芯片ID,如果验证失败,退出程序
+3.验证nand flash芯片后读取寄存器状态,确认芯片就绪
+4.验证是否是坏块,非坏块进行擦除块区,为写入数据做准备
+5.擦除块区后,写数据到块区,并读取块区数据与写入数据进行验证
+6.关闭写使能并关闭SPI。
+
+]]
+-- SPI配置参数
+local SPI_ID = 1                   -- SPI总线ID,根据实际情况修改
+local CS_PIN = 12                  -- CS引脚,根据实际情况修改
+local CPHA = 0                     -- 时钟相位
+local CPOL = 0                     -- 时钟极性
+local data_Width = 8               -- 数据宽度(位)
+local bandrate = 2000000           -- 波特率(Hz),初始化为2MHz
+local timeout = 1000               -- 操作超时时间(ms)
+local cspin = gpio.setup(CS_PIN, 1) --CS脚置于高电平
+spi_device = nil
+
+
+-- 1. 定义功能函数:发送和接收数据
+local function spi_transfer_func(sendData, recvLen)
+    -- 选中设备
+    cspin(0)
+
+    if sendData then
+        local sendLen = #sendData
+        -- 发送数据
+        spi_device:send(sendData, sendLen)
+    end
+
+    local recvData = ""
+    if recvLen and recvLen > 0 then
+        -- 接收数据
+        recvData = spi_device:recv(recvLen)
+    end
+
+    -- 取消选中
+    cspin(1)
+    return recvData
+end
+--2. 定义功能函数: 读状态寄存器(指令0x0F)
+local function spi_readStatus_func()
+    -- 发送0x0F指令(1字节),接收1字节状态
+    local status = spi_transfer_func(string.char(0x0F), 1)
+    return status and status:byte(1) or 0
+end
+
+-- 3. 定义功能函数:初始化SPI并复位芯片
+local function spiDev_init_func()
+    log.info("W25N01GV", "初始化SPI1...")
+    spi_device = spi.deviceSetup(SPI_ID, nil, CPHA, CPOL, data_Width, bandrate,
+        spi.MSB,    --高低位顺序
+        spi.master, --主模式
+        spi.half    --半双工
+    )
+    if not spi_device then
+        log.error("SPI初始化失败")
+        return false
+    end
+
+    return spi_device
+end
+
+--4. 定义功能函数:读取并验证芯片的JEDEC ID
+local function spi_readChipId_func()
+    -- 读ID指令0x9F,发送2字节指令,接收3字节ID
+    -- 发送长度=2(0x9F,0x00),接收长度=3
+    local id = spi_transfer_func(string.char(0x9F, 0x00), 3)
+    if #id ~= 3 then
+        log.error("读ID失败,返回长度:", #id)
+        return false
+    end
+    local b1, b2, b3 = id:byte(1, 3)
+    log.info("芯片ID:", string.format("0x%02X 0x%02X 0x%02X", b1, b2, b3))
+    -- W25N01GV的标准ID:0xEF(厂商)、0xAA(设备)、0x21(容量)
+    if b1 == 0xEF and b2 == 0xAA and b3 == 0x21 then
+        return true
+    else
+        log.error("非W25N01GV芯片")
+        return false
+    end
+end
+
+
+
+--5. 定义功能函数:等待写入完成
+local function spi_waitForComplete_func()
+    while timeout > 0 do
+        local status = spi_readStatus_func()
+        -- WIP位为0表示写入完成
+        if bit.band(status, 0x01) == 0 then
+            return true
+        end
+        sys.wait(10)
+        timeout = timeout - 10
+    end
+
+    log.error("spi", "等待写入超时")
+    return false
+end
+
+--6. 定义功能函数:读取数据
+local function spi_read_page(page_addr, length, column_addr)
+    local is_column_provided = column_addr ~= nil
+    column_addr = column_addr or 0x00
+    if length <= 0 or length > 2048 then
+        log.error("读取长度无效")
+        return ""
+    end
+    -- 0x03指令+4字节地址(3字节页地址+1字节列地址偏移)
+    local cmd = string.char(0x03)
+        .. string.char(bit.rshift(page_addr, 16) & 0xFF) -- 页地址高8位
+        .. string.char(bit.rshift(page_addr, 8) & 0xFF)  -- 页地址中8位
+        .. string.char(page_addr & 0xFF)                 -- 页地址低8位
+        .. string.char(column_addr & 0xFF)               -- 列地址偏移(页内起始字节)
+    local data = spi_transfer_func(cmd, length)
+    if is_column_provided then
+        log.info("读取主阵列(偏移0x" .. string.format("%02X", column_addr) .. ")", "读到的数据", string.toHex(data), "长度", #data)
+    else
+        log.info("读到的数据", string.toHex(data), "长度", #data)
+    end
+    return data
+end
+
+-- 7. 定义功能函数::读取页的数据区+OOB区(指令0x51),用于判断是否是坏块
+local function spi_read_page_with_oob(page_addr, data_len, oob_len)
+    if data_len < 0 or data_len > 2048 or oob_len < 0 or oob_len > 64 then
+        log.error("读取长度无效")
+        return "", ""
+    end
+    -- 0x51指令:读取数据+OOB
+    local cmd = string.char(0x51)
+        .. string.char(bit.rshift(page_addr, 16) & 0xFF)
+        .. string.char(bit.rshift(page_addr, 8) & 0xFF)
+        .. string.char(page_addr & 0xFF)
+    -- 总读取长度:数据区+OOB区
+    local total_data = spi_transfer_func(cmd, data_len + oob_len)
+    local data = total_data:sub(1, data_len)
+    local oob = total_data:sub(data_len + 1, data_len + oob_len)
+    return data, oob
+end
+
+-- 8. 定义功能函数:判断是否是坏块
+local function is_bad_block(block_addr)
+    -- 手册规定:块0~7出厂保证为有效块,可直接跳过检测
+    if block_addr >= 0 and block_addr <= 7 then
+        log.debug("块", block_addr, "是出厂保证有效块,直接判定为好块")
+        return false
+    end
+
+    -- 块的第0页
+    local page_addr = block_addr * 64
+    -- 读取主阵列第1字节(偏移0x01)
+    local main_data = spi_read_page(page_addr, 1, 0x01)
+    -- 读取OOB区前2字节
+    local _, oob = spi_read_page_with_oob(page_addr, 0, 2)
+
+    -- 检测主阵列第1字节是否为0xFF
+    local main_bad = false
+    if #main_data >= 1 and main_data:byte(1) ~= 0xFF then
+        main_bad = true
+    end
+
+    -- 检测OOB区前2字节是否为0xFF
+    local oob_bad = false
+    if #oob >= 2 and (oob:byte(1) ~= 0xFF or oob:byte(2) ~= 0xFF) then
+        oob_bad = true
+    end
+
+    -- 主阵列第1字节和OOB区前2字节,任一非0xFF则判定为坏块
+    local is_bad = main_bad or oob_bad
+    log.debug("块", block_addr,
+        "主阵列第1字节:0x" .. string.format("%02X", main_data:byte(1) or 0x00),
+        "OOB前2字节:0x" .. string.format("%02X, 0x%02X", oob:byte(1) or 0x00, oob:byte(2) or 0x00),
+        "判定为" .. (is_bad and "坏块" or "好块"))
+    return is_bad
+end
+
+
+-- 9. 定义功能函数: 块擦除(指令0xD8)
+local function spi_erase_block(block_addr)
+    if is_bad_block(block_addr) then
+        log.error("块", block_addr, "是坏块,跳过擦除")
+        return false
+    end
+    -- 写使能
+    spi_transfer_func(string.char(0x06))
+    local cmd = string.char(0xD8)
+        .. string.char(bit.rshift(block_addr, 16) & 0xFF)
+        .. string.char(bit.rshift(block_addr, 8) & 0xFF)
+        .. string.char(block_addr & 0xFF)
+    spi_transfer_func(cmd)
+    -- 确保等待擦除完成
+    if not spi_waitForComplete_func() then
+        log.error("擦除未完成")
+        return false
+    end
+    return true
+end
+
+-- 10. 定义功能函数: 页写入
+local function spi_write_page(page_addr, data)
+    if #data > 2048 then
+        log.error("数据超过页大小2048字节")
+        return false
+    end
+    -- 写使能
+    spi_transfer_func(string.char(0x06))
+
+    -- 加载缓冲区(0x02指令)
+    local cmd_load = string.char(0x02)
+        .. string.char(bit.rshift(page_addr, 16) & 0xFF)
+        .. string.char(bit.rshift(page_addr, 8) & 0xFF)
+        .. string.char(page_addr & 0xFF)
+    spi_transfer_func(cmd_load .. data)
+
+    -- 执行编程(0x10指令)
+    local cmd_exec = string.char(0x10)
+        .. string.char(bit.rshift(page_addr, 16) & 0xFF)
+        .. string.char(bit.rshift(page_addr, 8) & 0xFF)
+        .. string.char(page_addr & 0xFF)
+    spi_transfer_func(cmd_exec)
+    return spi_waitForComplete_func()
+end
+
+-- 11. 定义功能函数:核心测试函数
+local function spi_test_func()
+    --spi初始化
+    spi_device = spiDev_init_func()
+    if not spi_device then
+        return
+    end
+    --读取芯片id
+    if not spi_readChipId_func() then
+        spi.close(spi_device)
+        return
+    end
+    --坏块检查并进行块擦除,test_block是定义的操作的块编码
+    --手册规定:块0~7出厂保证为有效块,可直接跳过检测。块取值0~1023
+    local test_block = 7
+    log.info("擦除块", test_block, "...")
+    if not spi_erase_block(test_block) then
+        spi.close(spi_device)
+        return
+    end
+    local test_page = test_block * 64
+    local test_data = "Hello, W25N01GV!"
+    log.info("写入数据", test_data, "到页", test_page, "块", test_block)
+    --写数据到指定块
+    if not spi_write_page(test_page, test_data) then
+        log.info("写入失败")
+        spi.close(spi_device)
+        return
+    end
+    --读取当前块写入的数据,并验证与写入是否一致
+    local read_data = spi_read_page(test_page, #test_data)
+    if read_data == test_data then
+        log.info("数据验证成功:", read_data)
+    else
+        log.error("数据验证失败")
+        log.info("预期:", test_data)
+        log.info("实际:", string.toHex(read_data))
+    end
+    --操作完成关闭SPI
+    spi.close(spi_device)
+end
+
+sys.taskInit(spi_test_func)

+ 12 - 4
module/Air8000/demo/accessory_board/AirSPINAND_1000/readme.md

@@ -4,7 +4,7 @@
 
 2. lf_fs:通过littleFS文件系统,对nand flash模块以文件系统的方式进行读写数据操作,详细逻辑请看lf_fs.lua 文件
 
-3. ram_spi:通过原始spi接口对nand flash模块进行读写数据操作,详细逻辑请看ram_spi.lua 文件
+3. raw_spi:通过原始spi接口对nand flash模块进行读写数据操作,详细逻辑请看raw_spi.lua 文件
 
 ## 演示功能概述:
 
@@ -20,7 +20,7 @@
 
 5.操作文件读写,并验证写入一致性,追加文件等。
 
-### ram_spi:
+### raw_spi:
 
 1.初始化并启用spi,如果初始化失败,退出程序
 
@@ -81,7 +81,7 @@
 
 1. 搭建好硬件环境
 
-2. main.lua 中加载lf_fs功能模块或者ram_spi功能模块,二者使用其一
+2. main.lua 中加载lf_fs功能模块或者raw_spi功能模块,二者使用其一
 
 3. Luatools 烧录内核固件和 修改后的 demo 脚本
 
@@ -122,11 +122,14 @@
 
 ```
 
-6.ram_spi.lua 如下 log 显示:
+6.raw_spi.lua 如下 log 显示:
 
 华邦W25N01GV,手册说明块0~7出厂保证为有效块,可直接跳过检测。块取值0~1023
 
 nand flash中块编码大于块7的操作演示:
+
+```
+
     [2025-11-03 16:37:38.913][000000000.626] D/airlink Air8000s启动完成, 等待了 14 ms
     [2025-11-03 16:37:38.916][000000000.662] I/user.main Air8000_SPI_NAND 001.000.000
     [2025-11-03 16:37:38.959][000000000.694] I/user.W25N01GV 初始化SPI1...
@@ -142,8 +145,12 @@ nand flash中块编码大于块7的操作演示:
     [2025-11-03 16:37:41.212][000000003.034] D/mobile bearer act 0, result 0
     [2025-11-03 16:37:41.220][000000003.035] D/mobile NETIF_LINK_ON -> IP_READY
     [2025-11-03 16:37:41.229][000000003.070] D/mobile TIME_SYNC 0
+```
 
 nand flash中块编码小于块7的操作演示:
+
+```
+
     [2025-11-03 17:02:50.355][000000000.623] D/airlink Air8000s启动完成, 等待了 10 ms
     [2025-11-03 17:02:50.361][000000000.658] I/user.main Air8000_SPI_NAND 001.000.000
     [2025-11-03 17:02:50.367][000000000.673] I/user.W25N01GV 初始化SPI1...
@@ -158,3 +165,4 @@ nand flash中块编码小于块7的操作演示:
     [2025-11-03 17:02:52.589][000000002.985] D/mobile bearer act 0, result 0
     [2025-11-03 17:02:52.594][000000002.986] D/mobile NETIF_LINK_ON -> IP_READY
     [2025-11-03 17:02:52.602][000000003.017] D/mobile TIME_SYNC 0
+```

+ 4 - 4
module/Air8000/demo/accessory_board/AirSPINORFLASH_1000/main.lua

@@ -6,8 +6,8 @@
 @author  马亚丹
 @usage
 本demo是演示合宙AirSPINORFLASH_1000配件版的功能使用,可通过以下三种方式驱动flash模块,任选一种即可。
-1. ram_spi
-通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看ram_spi.lua 文件
+1. raw_spi
+通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看raw_spi.lua 文件
 2. lf_fs
 通过littleFS文件系统,对flash模块以文件系统的方式进行读写数据操作,详细逻辑请看lf_fs.lua 文件
 3. sfud_test
@@ -69,8 +69,8 @@ end
 
 
 
--- 加载ram_spi功能模块
---require "ram_spi"
+-- 加载raw_spi功能模块
+--require "raw_spi"
 
 -- 加载lf_fs功能模块
 require"lf_fs"

+ 264 - 0
module/Air8000/demo/accessory_board/AirSPINORFLASH_1000/raw_spi.lua

@@ -0,0 +1,264 @@
+--[[
+@module  raw_spi
+@summary raw_spi测试功能模块
+@version 1.0
+@date    2025.9.05
+@author  马亚丹
+@usage
+本demo演示的功能为:使用Air8000核心板通过SPI库实现对Flash的操作,演示读数据写数据、删除数据等操作。
+以 Air8000核心板为例, 接线如下:
+Air8000       AirSPINORFLASH_1000
+GND(任意)          GND
+VDD_EXT            VCC
+GPIO12/SPI1_CS     CS,片选
+SPI1_SLK           CLK,时钟
+SPI1_MOSI          DI,主机输出,从机输入
+SPI1_MISO          DO,主机输入,从机输出
+
+--使用SPI1,硬件SPI CS接在gpio12上
+核心逻辑:
+1.初始化并启用spi,如果初始化失败,退出程序
+2.spi启用后读取并验证flash芯片ID,如果验证失败,退出程序
+3.验证flash芯片后读取寄存器状态,确认芯片就绪
+4.擦除扇区,为写入数据做准备
+5.擦除扇区后,写数据到扇区,并读取扇区数据与写入数据进行验证
+6.关闭写使能并关闭SPI。
+
+]]
+
+
+-- SPI配置参数
+local SPI_ID = 1                   -- SPI总线ID,根据实际情况修改
+local CS_PIN = 12                  -- CS引脚,根据实际情况修改
+local CPHA = 0                     -- 时钟相位
+local CPOL = 0                     -- 时钟极性
+local data_Width = 8               -- 数据宽度(位)
+local bandrate = 2000000           -- 波特率(Hz),初始化为2MHz
+local timeout = 500                -- 操作超时时间(ms)
+local cspin = gpio.setup(CS_PIN, 1) --CS脚置于高电平
+
+
+-- 1. 设置并启用 SPI
+local function spiDev_init_func()
+    log.info("raw_spi", "SPI_ID", SPI_ID, "CS_PIN", CS_PIN)
+    local spiDevice = spi.setup(SPI_ID,nil, CPHA,CPOL,data_Width,bandrate
+    -- spi.MSB,--高低位顺序    可选,默认高位在前
+    -- spi.master,--主模式     可选,默认主
+    -- spi.full--全双工       可选,默认全双工
+    )
+
+    log.info("硬件spi", "初始化,波特率:", spiDevice, bandrate)
+    return true
+end
+
+
+-- 2. 定义功能函数:发送和接收数据
+local function spi_transfer_func(sendData, recvLen)
+    -- 选中设备
+    cspin(0)
+
+    if sendData then
+        -- 发送数据
+        spi.send(SPI_ID, sendData)
+    end
+
+    local recvData = ""
+    if recvLen and recvLen > 0 then
+        -- 接收数据
+        recvData = spi.recv(SPI_ID, recvLen)
+    end
+
+    -- 取消选中
+    cspin(1)
+    return recvData
+end
+
+-- 3. 定义功能函数:读取并验证芯片ID
+local function spi_readChipId_func()
+    --0x9F指令读取JEDEC ID
+    local id = spi_transfer_func(string.char(0x9F), 3)
+    --读取成功会返回 3 字节(制造商 + 设备 ID)
+    if #id == 3 then
+        local b1, b2, b3 = id:byte(1, 3)
+        log.info("spi", "芯片ID: 0x%02X 0x%02X 0x%02X", b1, b2, b3)
+
+        -- 验证是否为W25Q系列:
+        --制造商 ID(第 1 字节): 0xEF(代表 Winbond)
+        -- 设备类型(第 2 字节): 0x40(表示 W25Q 系列 NOR Flash)
+        -- 容量代码(第 3 字节): 0x18(对应 128Mbit = 16MB 容量)
+        if b1 == 0xEF and (b2 == 0x40 or b2 == 0x18) then
+            return true
+        end
+    end
+
+    log.error("spi", "读取芯片ID失败")
+    return false
+end
+
+-- 4. 定义功能函数:写数据使能
+local function spi_writeEnable_func()
+    --0x06指令设置Write Enable
+    spi_transfer_func(string.char(0x06))
+    return 0
+end
+
+-- 5. 定义功能函数:写数据禁用
+local function spi_writeDisable_func()
+    --0x04指令设置Write Disable
+    spi_transfer_func(string.char(0x04))
+end
+
+-- 6. 定义功能函数:读取状态寄存器
+local function spi_readStatus_func()
+    --0x05指令读取寄存器状态
+    local status = spi_transfer_func(string.char(0x05), 1)
+    if #status == 1 then
+        --返回0 表示WIP=0芯片就绪且未使能写操作
+        return status:byte(1)
+    end
+end
+
+
+--7.  等待写入完成
+local function spi_waitForWriteComplete_func()
+    while timeout > 0 do
+        local status = spi_readStatus_func()
+        -- WIP位为0表示写入完成
+        if bit.band(status, 0x01) == 0 then
+            return true
+        end
+        sys.wait(10)
+        timeout = timeout - 10
+    end
+
+    log.error("spi", "等待写入超时")
+    return false
+end
+
+--8. 扇区擦除,根据需要修改
+-- 0x20:扇区擦除(4KB)
+-- 0xD8:块擦除(64KB)
+-- 0xC7:整片擦除
+--address是要擦除的扇区的起始地址,本demo演示扇区擦除,块擦除和整片擦除可自行研究
+local function spi_erase_sector(address)
+    -- 使能写操作
+    if not spi_writeEnable_func() then
+        log.error("SPI", "写使能失败")
+        return false
+    end
+    -- 发送扇区擦除指令
+    local result = spi_transfer_func(string.char(0x20) ..
+        string.char(bit.rshift(address, 16) & 0xFF) ..
+        string.char(bit.rshift(address, 8) & 0xFF) ..
+        string.char(address & 0xFF))
+    if not result then
+        log.error("SPI", "发送扇区擦除指令失败")
+        return false
+    end
+    -- 等待写入完成
+    return spi_waitForWriteComplete_func()
+end
+
+--9. 页编程(写入数据到指定地址)
+local function spi_pageProgram_func(address, data)
+    -- 检查数据长度(不能超过256字节)
+    local len = #data
+    if len == 0 or len > 256 then
+        log.error("spi", "数据长度无效:", len)
+        return false
+    end
+    -- 准备写入命令和地址
+    local cmd = string.char(0x02) ..
+        string.char(bit.rshift(address, 16) & 0xFF) ..
+        string.char(bit.rshift(address, 8) & 0xFF) ..
+        string.char(address & 0xFF)
+    -- 写数据使能
+    spi_writeEnable_func()
+    -- 发送写命令和数据
+    spi_transfer_func(cmd .. data)
+    -- 等待写入完成
+    return spi_waitForWriteComplete_func()
+end
+
+-- 10. 读取数据
+local function spi_readData_func(address, length)
+    if length <= 0 then
+        return ""
+    end
+    -- 准备读取命令和地址
+    local cmd = string.char(0x03) ..
+        string.char(bit.rshift(address, 16) & 0xFF) ..
+        string.char(bit.rshift(address, 8) & 0xFF) ..
+        string.char(address & 0xFF)
+    -- 发送读取命令并接收数据
+    return spi_transfer_func(cmd, length)
+end
+
+
+-- 11. 关闭SPI设备,成功返回0
+local function spi_close_func()    
+    log.info("关闭spi", spi.close(SPI_ID))
+end
+
+
+
+--12. 功能演示核心函数
+local function spi_test_func()
+    --1.判断SPI初始化
+    if not spiDev_init_func() then
+        return
+    end
+    --2.判断flash芯片ID
+    if not spi_readChipId_func() then
+        spi_close_func()
+        return
+    end
+
+    -- 3.读取寄存器状态
+    local status = spi_readStatus_func()
+    --返回状态0表示芯片就绪且未使能写操作
+    log.info("spi", "寄存器状态为: 0x%02X", status)
+
+    -- 4.擦除扇区(4KB)
+    --0x000000是要擦除的扇区的起始地址,即第一个存储单元的位置,
+    --擦除从地址0x000000开始的整个 4KB 扇区,该扇区包含地址0x000000到0x000FFF的所有存储单元,可按需修改
+    log.info("spi", "擦除扇区 0x000000...")
+    if not spi_erase_sector(0x000000) then
+        log.error("spi", "擦除失败")
+        spi_close_func() --
+        return
+    end
+
+    -- 5.读取擦除后的数据(应为0xFF)
+    local erasedData = spi_readData_func(0x000000, 16)
+    log.info("spi", "擦除后数据:", string.toHex(erasedData))
+
+    -- 测试数据
+    local testData = "Hello, SPI Flash! "
+
+    -- 6.写入数据到地址0x000000
+    log.info("spi", "写入数据:", testData)
+    if spi_pageProgram_func(0x000000, testData) then
+        -- 读取数据
+        log.info("spi", "正在验证数据...")
+        local readData = spi_readData_func(0x000000, #testData)
+
+        -- 验证数据
+        if readData == testData then
+            log.info("spi", "数据验证成功!,读取到数据为:" .. readData)
+        else
+            log.error("spi", "数据验证失败!")
+            log.info("spi", "预期读到的数据是:", testData)
+            log.info("spi", "实际读取的数据是:", string.toHex(readData))
+        end
+    else
+        log.error("spi", "写入操作失败")
+    end
+    -- 7.禁用写操作
+    spi_writeDisable_func()
+    -- 8.关闭SPI设备
+    spi_close_func()
+end
+
+
+sys.taskInit(spi_test_func)

+ 4 - 4
module/Air8000/demo/accessory_board/AirSPINORFLASH_1000/readme.md

@@ -2,7 +2,7 @@
 
 1. main.lua:主程序入口,以下三个脚本按自己的需求选择其一使用即可,另外两个注释。
 
-2. ram_spi:通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看ram_spi.lua 文件
+2. raw_spi:通过原始spi接口对flash模块进行读写数据操作,详细逻辑请看raw_spi.lua 文件
 
 3. lf_fs:通过littleFS文件系统,对flash模块以文件系统的方式进行读写数据操作,详细逻辑请看lf_fs.lua 文件
 
@@ -10,7 +10,7 @@
 
 ## 演示功能概述:
 
-### ram_spi:
+### raw_spi:
 
 1.初始化并启用 spi,如果初始化失败,退出程序
 
@@ -97,11 +97,11 @@
 2. main.lua 中加载需要用的功能模块,三个功能模块同时只能选择一个使用,另一个注释。
 3. Luatools 烧录内核固件和修改后的 demo 脚本代码
 4. 烧录成功后,代码会自动运行,查看打印日志,如果正常运行,会打印相关信息,spi 初始化,数据读写,文件操作等。
-5. ram_spi.lua 如下 log 显示:
+5. raw_spi.lua 如下 log 显示:
 
 ```bash
 [2025-09-09 17:50:50.800][000000000.363] I/user.main Air8000_SPI_NOR 001.000.000
-[2025-09-09 17:50:50.823][000000000.376] I/user.ram_spi SPI_ID 1 CS_PIN 12
+[2025-09-09 17:50:50.823][000000000.376] I/user.raw_spi SPI_ID 1 CS_PIN 12
 [2025-09-09 17:50:50.839][000000000.377] SPI_HWInit 552:spi1 speed 2000000,1994805,154
 [2025-09-09 17:50:50.855][000000000.377] I/user.硬件spi 初始化,波特率: 0 2000000
 [2025-09-09 17:50:50.870][000000000.378] I/user.spi 芯片ID: 0x%02X 0x%02X 0x%02X 239 64 23