main.lua 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234
  1. -- SPI接口TF卡和WAN口复用演示项目
  2. -- 项目功能:
  3. -- 1. 演示Air8000开发板上SPI1接口复用,同时支持TF卡存储和CH390网络芯片
  4. -- 2. TF卡功能:文件读写操作、启动次数记录、状态日志保存
  5. -- 3. WAN口功能:通过CH390芯片提供以太网连接,支持DHCP自动获取IP
  6. -- 4. 网络测试:定期进行HTTP请求测试,验证网络连通性
  7. -- 5. 状态监控:实时监控TF卡和网络状态,记录运行日志
  8. --
  9. -- 硬件配置:
  10. -- - SPI1: 复用接口,连接TF卡和CH390
  11. -- - GPIO20: TF卡片选引脚
  12. -- - GPIO12: CH390片选引脚
  13. -- - GPIO140: CH390供电控制引脚
  14. -- - SPI速度: 12.8MHz(兼容TF卡和CH390的统一速度)
  15. PROJECT = "spi_tf_wan"
  16. VERSION = "1.0.0"
  17. -- 引入必要的库文件(lua编写), 内部库不需要require
  18. sys = require("sys")
  19. sysplus = require("sysplus")
  20. local rtos_bsp = rtos.bsp()
  21. local USE_CH390 = true -- 使用ch390时,设置为true,否则为false
  22. local SPI_SPEED = 25600000
  23. if USE_CH390 then
  24. gpio.setup(140, 1, gpio.PULLUP) -- 打开ch390供电
  25. end
  26. -- spi_id,pin_cs
  27. local function fatfs_spi_pin()
  28. return 1, 20 -- Air8000整机开发板上的pin_cs为gpio20
  29. end
  30. -- TF卡和WAN口初始化函数
  31. local function tf_wan_init()
  32. sys.wait(1000)
  33. -- #################################################
  34. -- 首先初始化TF卡
  35. -- #################################################
  36. log.info("tf_wan", "开始初始化TF卡")
  37. -- fatfs.debug(1) -- 若挂载失败,可以尝试打开调试信息,查找原因
  38. -- 此为spi方式
  39. local spi_id, pin_cs,tp = fatfs_spi_pin()
  40. -- 仅SPI方式需要自行初始化spi, sdio不需要
  41. -- 使用较低的统一速度以兼容TF卡和CH390
  42. spi.setup(spi_id, nil, 0, 0, pin_cs, SPI_SPEED)
  43. gpio.setup(pin_cs, 1)
  44. fatfs.mount(fatfs.SPI, "/sd", spi_id, pin_cs, SPI_SPEED)
  45. local data, err = fatfs.getfree("/sd")
  46. if data then
  47. log.info("fatfs", "getfree", json.encode(data))
  48. else
  49. log.info("fatfs", "err", err)
  50. end
  51. -- #################################################
  52. -- 文件操作测试
  53. -- #################################################
  54. local f = io.open("/sd/boottime", "rb")
  55. local c = 0
  56. if f then
  57. local data = f:read("*a")
  58. log.info("fs", "data", data, data:toHex())
  59. c = tonumber(data)
  60. f:close()
  61. end
  62. log.info("fs", "boot count", c)
  63. if c == nil then
  64. c = 0
  65. end
  66. c = c + 1
  67. f = io.open("/sd/boottime", "wb")
  68. if f ~= nil then
  69. log.info("fs", "write c to file", c, tostring(c))
  70. f:write(tostring(c))
  71. f:close()
  72. else
  73. log.warn("sdio", "mount not good?!")
  74. end
  75. if fs then
  76. log.info("fsstat", fs.fsstat("/"))
  77. log.info("fsstat", fs.fsstat("/sd"))
  78. end
  79. -- 测试一下追加, fix in 2021.12.21
  80. os.remove("/sd/test_a")
  81. sys.wait(50)
  82. f = io.open("/sd/test_a", "w")
  83. if f then
  84. f:write("ABC")
  85. f:close()
  86. end
  87. f = io.open("/sd/test_a", "a+")
  88. if f then
  89. f:write("def")
  90. f:close()
  91. end
  92. f = io.open("/sd/test_a", "r")
  93. if f then
  94. local data = f:read("*a")
  95. log.info("data", data, data == "ABCdef")
  96. f:close()
  97. end
  98. -- 测试一下按行读取, fix in 2022-01-16
  99. f = io.open("/sd/testline", "w")
  100. if f then
  101. f:write("abc\n")
  102. f:write("123\n")
  103. f:write("wendal\n")
  104. f:close()
  105. end
  106. sys.wait(100)
  107. f = io.open("/sd/testline", "r")
  108. if f then
  109. log.info("sdio", "line1", f:read("*l"))
  110. log.info("sdio", "line2", f:read("*l"))
  111. log.info("sdio", "line3", f:read("*l"))
  112. f:close()
  113. end
  114. log.info("tf_wan", "TF卡初始化完成")
  115. -- #################################################
  116. -- 然后初始化WAN口
  117. -- #################################################
  118. log.info("tf_wan", "开始初始化WAN口")
  119. sys.wait(500)
  120. log.info("ch390", "打开LDO供电")
  121. gpio.setup(140, 1, gpio.PULLUP) --打开ch390供电
  122. sys.wait(6000)
  123. -- 初始化指定netdrv设备,
  124. -- socket.LWIP_ETH 网络适配器编号
  125. -- netdrv.CH390外挂CH390
  126. -- SPI ID 1, 片选 GPIO12
  127. netdrv.setup(socket.LWIP_ETH, netdrv.CH390, {spi=1,cs=12})
  128. netdrv.dhcp(socket.LWIP_ETH, true)
  129. log.info("tf_wan", "WAN口初始化完成")
  130. end
  131. -- 初始化TF卡和WAN口
  132. sys.taskInit(tf_wan_init)
  133. -- 网络和TF卡状态监控,包含文件读写和网络通信
  134. local function status_monitor()
  135. local boot_count = 0
  136. while true do
  137. sys.wait(1000) -- 每1秒检查一次
  138. local status_info = {}
  139. -- 检查WAN口状态
  140. local wan_link = netdrv.link(socket.LWIP_ETH)
  141. local wan_ready = netdrv.ready(socket.LWIP_ETH)
  142. table.insert(status_info, string.format("WAN: link=%s ready=%s", tostring(wan_link), tostring(wan_ready)))
  143. -- 检查TF卡状态并进行文件读写操作
  144. local tf_status = "未知"
  145. local data, err = fatfs.getfree("/sd")
  146. if data then
  147. tf_status = "正常"
  148. -- 读取启动次数文件
  149. local f = io.open("/sd/boottime", "rb")
  150. if f then
  151. local count_data = f:read("*a")
  152. boot_count = tonumber(count_data) or 0
  153. f:close()
  154. end
  155. boot_count = boot_count + 1
  156. -- 写入新的启动次数
  157. f = io.open("/sd/boottime", "wb")
  158. if f then
  159. f:write(tostring(boot_count))
  160. f:close()
  161. log.info("文件操作", "启动次数已更新:", boot_count)
  162. end
  163. -- 写入状态日志文件
  164. local timestamp = os.date("%Y-%m-%d %H:%M:%S")
  165. local status_log = string.format("[%s] %s\n", timestamp, table.concat(status_info, ", "))
  166. f = io.open("/sd/status.log", "ab")
  167. if f then
  168. f:write(status_log)
  169. f:close()
  170. end
  171. else
  172. tf_status = "异常"
  173. end
  174. table.insert(status_info, string.format("TF卡: %s (启动次数: %d)", tf_status, boot_count))
  175. log.info("状态", table.concat(status_info, ", "))
  176. -- WAN口网络通信测试
  177. if wan_ready then
  178. log.info("网络测试", "开始WAN口网络通信测试")
  179. local code, headers, body = http.request("GET", "http://httpbin.air32.cn/get", nil, nil, {adapter=socket.LWIP_ETH}).wait()
  180. if code == 200 then
  181. -- 将网络测试结果写入TF卡
  182. if tf_status == "正常" then
  183. local f = io.open("/sd/network_test.log", "ab")
  184. if f then
  185. local test_log = string.format("[%s] WAN HTTP测试成功, 响应码: %d\n", os.date("%Y-%m-%d %H:%M:%S"), code)
  186. log.info("网络测试", "WAN口HTTP请求成功, 响应码:", code)
  187. f:write(test_log)
  188. f:close()
  189. end
  190. end
  191. else
  192. log.info("网络测试", "WAN口HTTP请求失败, 响应码:", code)
  193. end
  194. end
  195. -- 输出内存使用情况
  196. log.info("内存", "Lua:", rtos.meminfo())
  197. log.info("内存", "Sys:", rtos.meminfo("sys"))
  198. end
  199. end
  200. -- 启动状态监控任务
  201. sys.taskInit(status_monitor)
  202. -- 用户代码已结束---------------------------------------------
  203. -- 结尾总是这一句
  204. sys.run()
  205. -- sys.run()之后后面不要加任何语句!!!!!