fix:删除4G模组tools目录
This commit is contained in:
@@ -1,14 +1,115 @@
|
|||||||
-- CMD
|
-- cmd.lua
|
||||||
require "linksocket"
|
-- 功能:解析串口帧,调用 linksocket 接口,执行系统命令
|
||||||
require "socket"
|
|
||||||
require "sys"
|
|
||||||
|
|
||||||
function handleCmd01(subCmd, payload)
|
local log = require "log"
|
||||||
--sendToSocket(subCmd, payload) --向socket发送数据
|
local sys = require "sys"
|
||||||
sendToSocket(subCmd, payload)
|
local uart = require "uart"
|
||||||
log.info("CMD 0x01 received, sub:", subCmd, "data len:", #payload)
|
local linksocket = require "linksocket"
|
||||||
|
|
||||||
|
local uartID = 1
|
||||||
|
|
||||||
|
-- 辅助函数:字节转十六进制(调试用)
|
||||||
|
local function toHexcode(str)
|
||||||
|
if not str then return "" end
|
||||||
|
local hex = ""
|
||||||
|
for i = 1, #str do
|
||||||
|
hex = hex .. string.format("%02X", str:byte(i))
|
||||||
|
end
|
||||||
|
return hex
|
||||||
end
|
end
|
||||||
|
|
||||||
function handleCmd02(subCmd, payload)
|
-- 发送通用响应帧:55 AA 83 subCmd socketId status AA 55
|
||||||
|
local function sendResponse(subCmd, socketId, status)
|
||||||
|
local frame = string.char(0x55, 0xAA, 0x83, subCmd, socketId, status, 0xAA, 0x55)
|
||||||
|
uart.write(uartID, frame)
|
||||||
|
log.debug("Response: subCmd=", subCmd, "socketId=", socketId, "status=", status)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 命令处理函数
|
||||||
|
local function handleCmd01(subCmd, payload)
|
||||||
|
local socketId = subCmd
|
||||||
|
if socketId < 1 or socketId > 6 then
|
||||||
|
log.error("Invalid socket id in cmd 0x01:", socketId)
|
||||||
|
sendResponse(0x01, socketId, 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local success = linksocket.sendToSocket(socketId, payload)
|
||||||
|
if not success then
|
||||||
|
log.warn("Send failed, socket", socketId, "not connected")
|
||||||
|
sendResponse(0x01, socketId, 1)
|
||||||
|
else
|
||||||
|
log.info("Data sent to socket", socketId, "len=", #payload)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function handleCmd02()
|
||||||
|
log.info("System restart command received")
|
||||||
sys.restart()
|
sys.restart()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function handleCmd03(subCmd, payload)
|
||||||
|
if #payload < 1 then
|
||||||
|
log.error("Cmd 0x03 missing socket id")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
local socketId = payload:byte(1)
|
||||||
|
if socketId < 1 or socketId > 6 then
|
||||||
|
log.error("Invalid socket id in cmd 0x03:", socketId)
|
||||||
|
sendResponse(subCmd, socketId, 1)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if subCmd == 0x01 then
|
||||||
|
local ok = linksocket.setKeepConnecting(socketId, true)
|
||||||
|
if ok then
|
||||||
|
sendResponse(subCmd, socketId, 3)
|
||||||
|
else
|
||||||
|
sendResponse(subCmd, socketId, 1)
|
||||||
|
end
|
||||||
|
elseif subCmd == 0x02 then
|
||||||
|
local ok = linksocket.setKeepConnecting(socketId, false)
|
||||||
|
if ok then
|
||||||
|
sendResponse(subCmd, socketId, 0)
|
||||||
|
else
|
||||||
|
sendResponse(subCmd, socketId, 1)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
log.error("Unknown subCmd for 0x03:", subCmd)
|
||||||
|
sendResponse(subCmd, socketId, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 对外接口:处理串口接收到的原始数据
|
||||||
|
local function process(rawData)
|
||||||
|
if not rawData or #rawData < 5 then
|
||||||
|
log.warn("Short data received, ignore")
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
log.info("CMD raw data:", toHexcode(rawData))
|
||||||
|
|
||||||
|
if rawData:byte(1) == 0x55 and rawData:byte(2) == 0xAA
|
||||||
|
and rawData:byte(-2) == 0xAA and rawData:byte(-1) == 0x55 then
|
||||||
|
local mainCmd = rawData:byte(3)
|
||||||
|
local subCmd = rawData:byte(4)
|
||||||
|
local payload = rawData:sub(5, -3)
|
||||||
|
|
||||||
|
if mainCmd == 0x01 then
|
||||||
|
handleCmd01(subCmd, payload)
|
||||||
|
elseif mainCmd == 0x02 then
|
||||||
|
handleCmd02()
|
||||||
|
elseif mainCmd == 0x03 then
|
||||||
|
handleCmd03(subCmd, payload)
|
||||||
|
else
|
||||||
|
log.warn("Unknown main command:", mainCmd)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
log.warn("Invalid frame header/footer")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 模块接口
|
||||||
|
local M = {
|
||||||
|
process = process,
|
||||||
|
}
|
||||||
|
return M
|
||||||
@@ -1,83 +1,160 @@
|
|||||||
require "socket"
|
-- linksocket.lua
|
||||||
require "log"
|
-- 功能:管理多个 TCP Socket 连接,支持手动连接/断开,自动重连,数据收发
|
||||||
|
|
||||||
-- 目标服务器IP和端口
|
local log = require "log"
|
||||||
local ip, port = "121.43.69.62", "8767"
|
local sys = require "sys"
|
||||||
-- 连接数量
|
local socket = require "socket"
|
||||||
local clientCount = 1
|
|
||||||
-- 存储所有客户端
|
-- 服务器配置
|
||||||
|
local SERVER_IP = "121.43.69.62"
|
||||||
|
local SERVER_PORT = 8767
|
||||||
|
local MAX_CLIENTS = 6
|
||||||
|
|
||||||
|
-- 客户端状态表
|
||||||
local clients = {}
|
local clients = {}
|
||||||
|
local keepConnecting = {}
|
||||||
|
local recvCallback = nil
|
||||||
|
|
||||||
-- 初始化多个socket连接
|
-- 初始化所有socket槽位
|
||||||
for i = 1, clientCount do
|
for i = 1, MAX_CLIENTS do
|
||||||
local client = {
|
clients[i] = {
|
||||||
id = i,
|
id = i,
|
||||||
socket = nil,
|
socket = nil,
|
||||||
connected = false
|
connected = false
|
||||||
}
|
}
|
||||||
|
keepConnecting[i] = false
|
||||||
|
end
|
||||||
|
|
||||||
-- 为每个socket创建独立的连接任务
|
-- 发送连接状态响应
|
||||||
|
local function sendConnStatus(subCmd, socketId, status)
|
||||||
|
local uart = require "uart"
|
||||||
|
local frame = string.char(0x55, 0xAA, 0x83, subCmd, socketId, status, 0xAA, 0x55)
|
||||||
|
uart.write(1, frame)
|
||||||
|
log.debug("Socket", socketId, "status response, subCmd=", subCmd, "status=", status)
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 设置是否保持连接
|
||||||
|
local function setKeepConnecting(id, keep)
|
||||||
|
if id < 1 or id > MAX_CLIENTS then
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
keepConnecting[id] = keep
|
||||||
|
if not keep and clients[id].connected and clients[id].socket then
|
||||||
|
clients[id].socket:close()
|
||||||
|
clients[id].socket = nil
|
||||||
|
clients[id].connected = false
|
||||||
|
sendConnStatus(0x02, id, 0)
|
||||||
|
end
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 发送数据到指定socket
|
||||||
|
local function sendToSocket(id, data)
|
||||||
|
if id < 1 or id > MAX_CLIENTS then
|
||||||
|
log.error("sendToSocket: invalid id", id)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if clients[id].connected and clients[id].socket then
|
||||||
|
clients[id].socket:asyncSend(data)
|
||||||
|
log.info("Send to socket", id, "len=", #data)
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
log.warn("Socket", id, "not connected, cannot send")
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 注册数据接收回调
|
||||||
|
local function setRecvCallback(cb)
|
||||||
|
recvCallback = cb
|
||||||
|
end
|
||||||
|
|
||||||
|
-- 为每个socket创建常驻任务
|
||||||
|
for id = 1, MAX_CLIENTS do
|
||||||
sys.taskInit(function()
|
sys.taskInit(function()
|
||||||
|
local socketId = id
|
||||||
|
log.debug("Socket", socketId, "control task started")
|
||||||
|
|
||||||
while true do
|
while true do
|
||||||
while not socket.isReady() do sys.wait(1000) end
|
while not keepConnecting[socketId] do
|
||||||
client.socket = socket.tcp()
|
sys.wait(1000)
|
||||||
log.debug("Client " .. client.id .. ": Connecting to " .. ip .. ":" .. port)
|
|
||||||
while not client.socket:connect(ip, port) do
|
|
||||||
log.warn("Client " .. client.id .. ": Connection failed, retrying...")
|
|
||||||
sys.wait(2000)
|
|
||||||
end
|
end
|
||||||
client.connected = true
|
|
||||||
log.debug("Client " .. client.id .. ": Connected successfully")
|
|
||||||
-- 发送连接成功信息到串口
|
|
||||||
uart.write(1, "Socket " .. client.id .. " connected\r\n")
|
|
||||||
|
|
||||||
-- 保持连接并处理数据
|
while keepConnecting[socketId] do
|
||||||
while client.socket:asyncSelect(60, "ping") do end
|
while not socket.isReady() do
|
||||||
|
if not keepConnecting[socketId] then break end
|
||||||
|
sys.wait(1000)
|
||||||
|
end
|
||||||
|
if not keepConnecting[socketId] then break end
|
||||||
|
|
||||||
client.connected = false
|
local sock = socket.tcp()
|
||||||
client.socket:close()
|
log.debug("Socket", socketId, "connecting to", SERVER_IP, SERVER_PORT)
|
||||||
log.error("Client " .. client.id .. ": Disconnected")
|
local connected = false
|
||||||
-- 发送断开连接信息到串口
|
while not connected and keepConnecting[socketId] do
|
||||||
|
connected = sock:connect(SERVER_IP, SERVER_PORT)
|
||||||
|
if not connected then
|
||||||
|
log.warn("Socket", socketId, "connect failed, retry in 3s")
|
||||||
|
sys.wait(3000)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if not keepConnecting[socketId] then
|
||||||
|
if sock then sock:close() end
|
||||||
|
break
|
||||||
|
end
|
||||||
|
|
||||||
|
clients[socketId].socket = sock
|
||||||
|
clients[socketId].connected = true
|
||||||
|
log.info("Socket", socketId, "connected")
|
||||||
|
sendConnStatus(0x01, socketId, 0)
|
||||||
|
|
||||||
|
while keepConnecting[socketId] and clients[socketId].connected do
|
||||||
|
local ok = sock:asyncSelect(60, "recv")
|
||||||
|
if not ok then
|
||||||
|
log.warn("Socket", socketId, "connection lost")
|
||||||
|
break
|
||||||
|
end
|
||||||
|
sys.wait(100)
|
||||||
|
end
|
||||||
|
|
||||||
|
if clients[socketId].socket then
|
||||||
|
clients[socketId].socket:close()
|
||||||
|
clients[socketId].socket = nil
|
||||||
|
end
|
||||||
|
clients[socketId].connected = false
|
||||||
|
|
||||||
|
if not keepConnecting[socketId] then
|
||||||
|
sendConnStatus(0x02, socketId, 0)
|
||||||
|
break
|
||||||
|
else
|
||||||
|
log.info("Socket", socketId, "will reconnect after 3s")
|
||||||
|
sys.wait(3000)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
-- 存储客户端
|
|
||||||
clients[i] = client
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- 订阅底层Socket接收事件
|
||||||
local function toHexcode(str)
|
sys.subscribe("SOCKET_RECV", function(socketId)
|
||||||
local hexcode = ""
|
|
||||||
for i = 1, #str do
|
|
||||||
hexcode = hexcode .. string.format("%02X", str:byte(i))
|
|
||||||
end
|
|
||||||
return hexcode
|
|
||||||
end
|
|
||||||
|
|
||||||
-- 测试代码,异步回调接收数据
|
|
||||||
sys.subscribe("SOCKET_RECV", function(id)
|
|
||||||
-- 遍历所有客户端,找到对应的连接
|
|
||||||
for i, client in ipairs(clients) do
|
for i, client in ipairs(clients) do
|
||||||
if client.socket and client.socket.id == id then
|
if client.socket and client.socket.id == socketId and client.connected then
|
||||||
-- 转发到串口,添加socket标识,并清理数据
|
|
||||||
local data = client.socket:asyncRecv()
|
local data = client.socket:asyncRecv()
|
||||||
log.info("Client " .. client.id .. ": Received data: " .. toHexcode(data))
|
if data and #data > 0 then
|
||||||
-- 转发到串口,添加socket标识
|
log.info("Socket", client.id, "received data len=", #data)
|
||||||
local frame = string.char(0x55) .. string.char(0xAA) .. string.char(0x01) .. string.char(i) .. string.char(#data) .. data .. string.char(0xAA) .. string.char(0x55)
|
if recvCallback then
|
||||||
uart.write(1, frame)
|
recvCallback(client.id, data)
|
||||||
|
end
|
||||||
|
end
|
||||||
break
|
break
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- 模块接口
|
||||||
|
local M = {
|
||||||
-- 发送数据到指定socket
|
setKeepConnecting = setKeepConnecting,
|
||||||
function sendToSocket(id_byte, msg)
|
sendToSocket = sendToSocket,
|
||||||
if clients[id_byte] and clients[id_byte].socket and clients[id_byte].connected then
|
setRecvCallback = setRecvCallback,
|
||||||
clients[id_byte].socket:asyncSend(msg)
|
}
|
||||||
else
|
return M
|
||||||
log.error("Socket " .. id_byte .. " not connected or does not exist")
|
|
||||||
end
|
|
||||||
end
|
|
||||||
@@ -1,9 +1,5 @@
|
|||||||
--- testSocket
|
-- main.lua
|
||||||
-- @module asyncSocket
|
-- 功能:初始化硬件、网络、串口,注册回调,启动系统
|
||||||
-- @author AIRM2M
|
|
||||||
-- @license MIT
|
|
||||||
-- @copyright openLuat.com
|
|
||||||
-- @release 2018.10.27
|
|
||||||
|
|
||||||
PROJECT = "4G_NETWORK"
|
PROJECT = "4G_NETWORK"
|
||||||
VERSION = "1.0.0"
|
VERSION = "1.0.0"
|
||||||
@@ -11,55 +7,42 @@ VERSION = "1.0.0"
|
|||||||
require "sys"
|
require "sys"
|
||||||
require "net"
|
require "net"
|
||||||
require "log"
|
require "log"
|
||||||
require "cmd"
|
|
||||||
require "uart"
|
require "uart"
|
||||||
require "linksocket"
|
require "netLed"
|
||||||
|
require "pmd"
|
||||||
|
|
||||||
-- 初始化 UART1
|
-- 初始化UART1
|
||||||
uart.setup(1, 115200, 8, uart.PAR_NONE, uart.STOP_1)
|
local uartID = 1
|
||||||
|
uart.setup(uartID, 115200, 8, uart.PAR_NONE, uart.STOP_1)
|
||||||
|
|
||||||
-- 启动网络指示灯功能模块
|
-- 启动网络指示灯功能模块
|
||||||
require "netLed"
|
pmd.ldoset(2, pmd.LDO_VLCD)
|
||||||
pmd.ldoset(2,pmd.LDO_VLCD)
|
netLed.setup(true, pio.P0_1, pio.P0_4)
|
||||||
netLed.setup(true,pio.P0_1,pio.P0_4)
|
|
||||||
|
|
||||||
local uartID = 1
|
-- 初始化网络
|
||||||
|
net.startQueryAll(8 * 1000, 60 * 1000)
|
||||||
|
ril.request("AT+RNDISCALL=0,1")
|
||||||
|
|
||||||
|
-- 加载自定义模块(必须放在网络初始化之后)
|
||||||
|
local cmd = require "cmd"
|
||||||
|
local linksocket = require "linksocket"
|
||||||
|
|
||||||
local function toHexcode(str)
|
-- 注册Socket数据接收回调
|
||||||
local hexcode = ""
|
linksocket.setRecvCallback(function(socketId, data)
|
||||||
for i = 1, #str do
|
-- 打包帧格式:55 AA 01 id len data AA 55
|
||||||
hexcode = hexcode .. string.format("%02X", str:byte(i))
|
local frame = string.char(0x55, 0xAA, 0x01, socketId, #data) .. data .. string.char(0xAA, 0x55)
|
||||||
end
|
uart.write(uartID, frame)
|
||||||
return hexcode
|
log.info("Forward data from socket", socketId, "len=", #data)
|
||||||
end
|
end)
|
||||||
|
|
||||||
|
-- 串口数据接收处理
|
||||||
uart.on(uartID, "receive", function()
|
uart.on(uartID, "receive", function()
|
||||||
local data = uart.read(uartID, 300)
|
local data = uart.read(uartID, 300)
|
||||||
if data and type(data) == "string" and #data > 0 then
|
if data and #data > 0 then
|
||||||
log.info("UART received:", toHexcode(data))
|
cmd.process(data)
|
||||||
if data:byte(1) == 0x55 and data:byte(2) == 0xAA and data:byte(-2) == 0xAA and data:byte(-1) == 0x55 then
|
|
||||||
local Main_Cmd = data:byte(3)
|
|
||||||
local Sub_Cmd = data:byte(4)
|
|
||||||
local payload = data:sub(5, -3)
|
|
||||||
|
|
||||||
if Main_Cmd ==0x01 then
|
|
||||||
handleCmd01(Sub_Cmd, payload)
|
|
||||||
end
|
|
||||||
if Main_Cmd == 0x02 then
|
|
||||||
handleCmd02(Sub_Cmd, payload)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else
|
|
||||||
log.warn("UART receive callback triggered but no valid data")
|
|
||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- 启动系统
|
||||||
net.startQueryAll(8 * 1000, 60 * 1000)
|
|
||||||
|
|
||||||
ril.request("AT+RNDISCALL=0,1")
|
|
||||||
|
|
||||||
|
|
||||||
sys.init(0, 0)
|
sys.init(0, 0)
|
||||||
sys.run()
|
sys.run()
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,59 +0,0 @@
|
|||||||
/* USER CODE BEGIN Header */
|
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* File Name : FMC.h
|
|
||||||
* Description : This file provides code for the configuration
|
|
||||||
* of the FMC peripheral.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* Copyright (c) 2026 STMicroelectronics.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This software is licensed under terms that can be found in the LICENSE file
|
|
||||||
* in the root directory of this software component.
|
|
||||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
/* USER CODE END Header */
|
|
||||||
/* Define to prevent recursive inclusion -------------------------------------*/
|
|
||||||
#ifndef __FMC_H
|
|
||||||
#define __FMC_H
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "main.h"
|
|
||||||
|
|
||||||
/* USER CODE BEGIN Includes */
|
|
||||||
|
|
||||||
/* USER CODE END Includes */
|
|
||||||
|
|
||||||
extern NAND_HandleTypeDef hnand1;
|
|
||||||
|
|
||||||
/* USER CODE BEGIN Private defines */
|
|
||||||
|
|
||||||
/* USER CODE END Private defines */
|
|
||||||
|
|
||||||
void MX_FMC_Init(void);
|
|
||||||
void HAL_NAND_MspInit(NAND_HandleTypeDef* hnand);
|
|
||||||
void HAL_NAND_MspDeInit(NAND_HandleTypeDef* hnand);
|
|
||||||
|
|
||||||
/* USER CODE BEGIN Prototypes */
|
|
||||||
|
|
||||||
/* USER CODE END Prototypes */
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
#endif /*__FMC_H */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
@@ -47,7 +47,7 @@
|
|||||||
/* #define HAL_DMA2D_MODULE_ENABLED */
|
/* #define HAL_DMA2D_MODULE_ENABLED */
|
||||||
#define HAL_ETH_MODULE_ENABLED
|
#define HAL_ETH_MODULE_ENABLED
|
||||||
/* #define HAL_ETH_LEGACY_MODULE_ENABLED */
|
/* #define HAL_ETH_LEGACY_MODULE_ENABLED */
|
||||||
#define HAL_NAND_MODULE_ENABLED
|
/* #define HAL_NAND_MODULE_ENABLED */
|
||||||
/* #define HAL_NOR_MODULE_ENABLED */
|
/* #define HAL_NOR_MODULE_ENABLED */
|
||||||
/* #define HAL_OTFDEC_MODULE_ENABLED */
|
/* #define HAL_OTFDEC_MODULE_ENABLED */
|
||||||
/* #define HAL_SRAM_MODULE_ENABLED */
|
/* #define HAL_SRAM_MODULE_ENABLED */
|
||||||
|
|||||||
@@ -1,233 +0,0 @@
|
|||||||
/* USER CODE BEGIN Header */
|
|
||||||
/**
|
|
||||||
******************************************************************************
|
|
||||||
* File Name : FMC.c
|
|
||||||
* Description : This file provides code for the configuration
|
|
||||||
* of the FMC peripheral.
|
|
||||||
******************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* Copyright (c) 2026 STMicroelectronics.
|
|
||||||
* All rights reserved.
|
|
||||||
*
|
|
||||||
* This software is licensed under terms that can be found in the LICENSE file
|
|
||||||
* in the root directory of this software component.
|
|
||||||
* If no LICENSE file comes with this software, it is provided AS-IS.
|
|
||||||
*
|
|
||||||
******************************************************************************
|
|
||||||
*/
|
|
||||||
/* USER CODE END Header */
|
|
||||||
|
|
||||||
/* Includes ------------------------------------------------------------------*/
|
|
||||||
#include "fmc.h"
|
|
||||||
|
|
||||||
/* USER CODE BEGIN 0 */
|
|
||||||
|
|
||||||
/* USER CODE END 0 */
|
|
||||||
|
|
||||||
NAND_HandleTypeDef hnand1;
|
|
||||||
|
|
||||||
/* FMC initialization function */
|
|
||||||
void MX_FMC_Init(void)
|
|
||||||
{
|
|
||||||
/* USER CODE BEGIN FMC_Init 0 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_Init 0 */
|
|
||||||
|
|
||||||
FMC_NAND_PCC_TimingTypeDef ComSpaceTiming = {0};
|
|
||||||
FMC_NAND_PCC_TimingTypeDef AttSpaceTiming = {0};
|
|
||||||
|
|
||||||
/* USER CODE BEGIN FMC_Init 1 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_Init 1 */
|
|
||||||
|
|
||||||
/** Perform the NAND1 memory initialization sequence
|
|
||||||
*/
|
|
||||||
hnand1.Instance = FMC_NAND_DEVICE;
|
|
||||||
/* hnand1.Init */
|
|
||||||
hnand1.Init.NandBank = FMC_NAND_BANK3;
|
|
||||||
hnand1.Init.Waitfeature = FMC_NAND_WAIT_FEATURE_ENABLE;
|
|
||||||
hnand1.Init.MemoryDataWidth = FMC_NAND_MEM_BUS_WIDTH_8;
|
|
||||||
hnand1.Init.EccComputation = FMC_NAND_ECC_DISABLE;
|
|
||||||
hnand1.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_512BYTE;
|
|
||||||
hnand1.Init.TCLRSetupTime = 9;
|
|
||||||
hnand1.Init.TARSetupTime = 9;
|
|
||||||
/* hnand1.Config */
|
|
||||||
hnand1.Config.PageSize = 2048;
|
|
||||||
hnand1.Config.SpareAreaSize = 64;
|
|
||||||
hnand1.Config.BlockSize = 64;
|
|
||||||
hnand1.Config.BlockNbr = 2048;
|
|
||||||
hnand1.Config.PlaneNbr = 2;
|
|
||||||
hnand1.Config.PlaneSize = 4096;
|
|
||||||
hnand1.Config.ExtraCommandEnable = DISABLE;
|
|
||||||
/* ComSpaceTiming */
|
|
||||||
ComSpaceTiming.SetupTime = 9;
|
|
||||||
ComSpaceTiming.WaitSetupTime = 9;
|
|
||||||
ComSpaceTiming.HoldSetupTime = 10;
|
|
||||||
ComSpaceTiming.HiZSetupTime = 9;
|
|
||||||
/* AttSpaceTiming */
|
|
||||||
AttSpaceTiming.SetupTime = 9;
|
|
||||||
AttSpaceTiming.WaitSetupTime = 9;
|
|
||||||
AttSpaceTiming.HoldSetupTime = 10;
|
|
||||||
AttSpaceTiming.HiZSetupTime = 9;
|
|
||||||
|
|
||||||
if (HAL_NAND_Init(&hnand1, &ComSpaceTiming, &AttSpaceTiming) != HAL_OK)
|
|
||||||
{
|
|
||||||
Error_Handler( );
|
|
||||||
}
|
|
||||||
|
|
||||||
/* USER CODE BEGIN FMC_Init 2 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_Init 2 */
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t FMC_Initialized = 0;
|
|
||||||
|
|
||||||
static void HAL_FMC_MspInit(void){
|
|
||||||
/* USER CODE BEGIN FMC_MspInit 0 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_MspInit 0 */
|
|
||||||
GPIO_InitTypeDef GPIO_InitStruct = {0};
|
|
||||||
if (FMC_Initialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FMC_Initialized = 1;
|
|
||||||
RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = {0};
|
|
||||||
|
|
||||||
/** Initializes the peripherals clock
|
|
||||||
*/
|
|
||||||
PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_FMC;
|
|
||||||
PeriphClkInitStruct.FmcClockSelection = RCC_FMCCLKSOURCE_D1HCLK;
|
|
||||||
if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
|
|
||||||
{
|
|
||||||
Error_Handler();
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Peripheral clock enable */
|
|
||||||
__HAL_RCC_FMC_CLK_ENABLE();
|
|
||||||
|
|
||||||
/** FMC GPIO Configuration
|
|
||||||
PE7 ------> FMC_D4
|
|
||||||
PE8 ------> FMC_D5
|
|
||||||
PE9 ------> FMC_D6
|
|
||||||
PE10 ------> FMC_D7
|
|
||||||
PD11 ------> FMC_CLE
|
|
||||||
PD12 ------> FMC_ALE
|
|
||||||
PD14 ------> FMC_D0
|
|
||||||
PD15 ------> FMC_D1
|
|
||||||
PC6 ------> FMC_NWAIT
|
|
||||||
PC8 ------> FMC_NCE
|
|
||||||
PD0 ------> FMC_D2
|
|
||||||
PD1 ------> FMC_D3
|
|
||||||
PD4 ------> FMC_NOE
|
|
||||||
PD5 ------> FMC_NWE
|
|
||||||
*/
|
|
||||||
/* GPIO_InitStruct */
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10;
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
||||||
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
|
|
||||||
|
|
||||||
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
/* GPIO_InitStruct */
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
||||||
|
|
||||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
/* GPIO_InitStruct */
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|
|
||||||
|GPIO_PIN_4|GPIO_PIN_5;
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
||||||
GPIO_InitStruct.Alternate = GPIO_AF12_FMC;
|
|
||||||
|
|
||||||
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
/* GPIO_InitStruct */
|
|
||||||
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_8;
|
|
||||||
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
|
|
||||||
GPIO_InitStruct.Pull = GPIO_NOPULL;
|
|
||||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
|
|
||||||
GPIO_InitStruct.Alternate = GPIO_AF9_FMC;
|
|
||||||
|
|
||||||
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
|
|
||||||
|
|
||||||
/* USER CODE BEGIN FMC_MspInit 1 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_MspInit 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_NAND_MspInit(NAND_HandleTypeDef* nandHandle){
|
|
||||||
/* USER CODE BEGIN NAND_MspInit 0 */
|
|
||||||
|
|
||||||
/* USER CODE END NAND_MspInit 0 */
|
|
||||||
HAL_FMC_MspInit();
|
|
||||||
/* USER CODE BEGIN NAND_MspInit 1 */
|
|
||||||
|
|
||||||
/* USER CODE END NAND_MspInit 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
static uint32_t FMC_DeInitialized = 0;
|
|
||||||
|
|
||||||
static void HAL_FMC_MspDeInit(void){
|
|
||||||
/* USER CODE BEGIN FMC_MspDeInit 0 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_MspDeInit 0 */
|
|
||||||
if (FMC_DeInitialized) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
FMC_DeInitialized = 1;
|
|
||||||
/* Peripheral clock enable */
|
|
||||||
__HAL_RCC_FMC_CLK_DISABLE();
|
|
||||||
|
|
||||||
/** FMC GPIO Configuration
|
|
||||||
PE7 ------> FMC_D4
|
|
||||||
PE8 ------> FMC_D5
|
|
||||||
PE9 ------> FMC_D6
|
|
||||||
PE10 ------> FMC_D7
|
|
||||||
PD11 ------> FMC_CLE
|
|
||||||
PD12 ------> FMC_ALE
|
|
||||||
PD14 ------> FMC_D0
|
|
||||||
PD15 ------> FMC_D1
|
|
||||||
PC6 ------> FMC_NWAIT
|
|
||||||
PC8 ------> FMC_NCE
|
|
||||||
PD0 ------> FMC_D2
|
|
||||||
PD1 ------> FMC_D3
|
|
||||||
PD4 ------> FMC_NOE
|
|
||||||
PD5 ------> FMC_NWE
|
|
||||||
*/
|
|
||||||
|
|
||||||
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10);
|
|
||||||
|
|
||||||
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_14|GPIO_PIN_15
|
|
||||||
|GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_4|GPIO_PIN_5);
|
|
||||||
|
|
||||||
HAL_GPIO_DeInit(GPIOC, GPIO_PIN_6|GPIO_PIN_8);
|
|
||||||
|
|
||||||
/* USER CODE BEGIN FMC_MspDeInit 1 */
|
|
||||||
|
|
||||||
/* USER CODE END FMC_MspDeInit 1 */
|
|
||||||
}
|
|
||||||
|
|
||||||
void HAL_NAND_MspDeInit(NAND_HandleTypeDef* nandHandle){
|
|
||||||
/* USER CODE BEGIN NAND_MspDeInit 0 */
|
|
||||||
|
|
||||||
/* USER CODE END NAND_MspDeInit 0 */
|
|
||||||
HAL_FMC_MspDeInit();
|
|
||||||
/* USER CODE BEGIN NAND_MspDeInit 1 */
|
|
||||||
|
|
||||||
/* USER CODE END NAND_MspDeInit 1 */
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @}
|
|
||||||
*/
|
|
||||||
@@ -1,749 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file ftl.c
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2023-03-24
|
|
||||||
* @brief NAND FLASH FTL层算法 代码
|
|
||||||
* @license Copyright (c) 2022-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20230324
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "string.h"
|
|
||||||
#include "./BSP/NAND/ftl.h"
|
|
||||||
#include "./MALLOC/malloc.h"
|
|
||||||
#include "./BSP/NAND/nand.h"
|
|
||||||
#include "./SYSTEM/usart/usart.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 每个块,第一个page的spare区,前四个字节的含义:
|
|
||||||
* 第一个字节,表示该块是否是坏块:0XFF,正常块;其他值,坏块.
|
|
||||||
* 第二个字节,表示该块是否被用过:0XFF,没有写过数据;0XCC,写过数据了.
|
|
||||||
* 第三和第四个字节,表示该块所属的逻辑块编号.
|
|
||||||
|
|
||||||
* 每个page,spare区16字节以后的字节含义:
|
|
||||||
* 第十六字节开始,后续每4个字节用于存储一个扇区(大小:NAND_ECC_SECTOR_SIZE)的ECC值,用于ECC校验
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FTL层初始化
|
|
||||||
* @param 无
|
|
||||||
* @retval 0,正常;其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_init(void)
|
|
||||||
{
|
|
||||||
uint8_t temp;
|
|
||||||
|
|
||||||
if (nand_init())
|
|
||||||
{
|
|
||||||
return 1; /* 初始化NAND FLASH */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nand_dev.lut)
|
|
||||||
{
|
|
||||||
myfree(SRAMIN, nand_dev.lut);
|
|
||||||
}
|
|
||||||
|
|
||||||
nand_dev.lut = mymalloc(SRAMIN, (nand_dev.block_totalnum) * 2); /* 给LUT表申请内存 */
|
|
||||||
memset(nand_dev.lut, 0, nand_dev.block_totalnum * 2); /* 全部清理 */
|
|
||||||
|
|
||||||
if (!nand_dev.lut)
|
|
||||||
{
|
|
||||||
return 1; /* 内存申请失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = ftl_create_lut(1);
|
|
||||||
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
printf("format nand flash...\r\n");
|
|
||||||
temp = ftl_format(); /* 格式化NAND */
|
|
||||||
|
|
||||||
if (temp)
|
|
||||||
{
|
|
||||||
printf("format failed!\r\n");
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else /* 创建LUT表成功 */
|
|
||||||
{
|
|
||||||
printf("total block num: %d\r\n", nand_dev.block_totalnum);
|
|
||||||
printf("good block num: %d\r\n", nand_dev.good_blocknum);
|
|
||||||
printf("valid block num: %d\r\n", nand_dev.valid_blocknum);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 标记某一个块为坏块
|
|
||||||
* @param blocknum : 块编号,范围:0~(block_totalnum-1)
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
void ftl_badblock_mark(uint32_t blocknum)
|
|
||||||
{
|
|
||||||
uint32_t temp = 0XAAAAAAAA;/* 坏块标记mark,任意值都OK,只要不是0XFF.这里写前4个字节,方便ftl_find_unused_block函数检查坏块.(不检查备份区,以提高速度) */
|
|
||||||
nand_writespare(blocknum * nand_dev.block_pagenum, 0, (uint8_t *)&temp, 4); /* 在第一个page的spare区,第一个字节做坏块标记(前4个字节都写) */
|
|
||||||
nand_writespare(blocknum * nand_dev.block_pagenum + 1, 0, (uint8_t *)&temp, 4); /* 在第二个page的spare区,第一个字节做坏块标记(备份用,前4个字节都写) */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 检查某一块是否是坏块
|
|
||||||
* @param blocknum : 块编号,范围:0~(block_totalnum-1)
|
|
||||||
* @retval 0,好块;
|
|
||||||
* 其他,坏块
|
|
||||||
*/
|
|
||||||
uint8_t ftl_check_badblock(uint32_t blocknum)
|
|
||||||
{
|
|
||||||
uint8_t flag = 0;
|
|
||||||
|
|
||||||
nand_readspare(blocknum * nand_dev.block_pagenum, 0, &flag, 1); /* 读取坏块标志 */
|
|
||||||
|
|
||||||
if (flag == 0XFF) /* 好块?,读取备份区坏块标记 */
|
|
||||||
{
|
|
||||||
nand_readspare(blocknum * nand_dev.block_pagenum + 1, 0, &flag, 1); /* 读取备份区坏块标志 */
|
|
||||||
|
|
||||||
if (flag == 0XFF)
|
|
||||||
{
|
|
||||||
return 0; /* 好块 */
|
|
||||||
}
|
|
||||||
|
|
||||||
else return 1; /* 坏块 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 标记某一个块已经使用
|
|
||||||
* @param blocknum : 块编号,范围:0~(block_totalnum-1)
|
|
||||||
* @retval 0,成功;
|
|
||||||
* 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_used_blockmark(uint32_t blocknum)
|
|
||||||
{
|
|
||||||
uint8_t buf[4];
|
|
||||||
uint8_t temp = 0;
|
|
||||||
nand_readspare(blocknum * nand_dev.block_pagenum, 0, buf, 4); /* 读出4字节 */
|
|
||||||
|
|
||||||
buf[1] = 0XCC;
|
|
||||||
temp = nand_writespare(blocknum * nand_dev.block_pagenum, 0, buf, 4); /* 写入块已经被使用标志 */
|
|
||||||
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从给定的块开始找到往前找到一个未被使用的块(指定奇数/偶数)
|
|
||||||
* @param sblock : 开始块,范围:0~(block_totalnum-1)
|
|
||||||
* @param flag : 0,偶数快; 1,奇数块.
|
|
||||||
* @retval 0XFFFFFFFF,失败;
|
|
||||||
* 其他值,未使用块号
|
|
||||||
*/
|
|
||||||
uint32_t ftl_find_unused_block(uint32_t sblock, uint8_t flag)
|
|
||||||
{
|
|
||||||
uint32_t temp = 0;
|
|
||||||
uint32_t blocknum = 0;
|
|
||||||
|
|
||||||
for (blocknum = sblock + 1; blocknum > 0; blocknum--)
|
|
||||||
{
|
|
||||||
if (((blocknum - 1) % 2) == flag) /* 奇偶合格,才检测 */
|
|
||||||
{
|
|
||||||
nand_readspare((blocknum - 1) * nand_dev.block_pagenum, 0, (uint8_t *)&temp, 4); /* 读块是否被使用标记 */
|
|
||||||
|
|
||||||
if (temp == 0XFFFFFFFF)
|
|
||||||
{
|
|
||||||
return (blocknum - 1); /* 找到一个空块,返回块编号 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0XFFFFFFFF; /* 未找到空余块 */
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 查找与给定块在同一个plane内的未使用的块
|
|
||||||
* @param sblock : 给定块,范围:0~(block_totalnum-1)
|
|
||||||
* @retval 0XFFFFFFFF,失败;
|
|
||||||
* 其他值,未使用块号
|
|
||||||
*/
|
|
||||||
uint32_t ftl_find_same_plane_unusedBlock(uint32_t sblock)
|
|
||||||
{
|
|
||||||
static uint32_t curblock = 0XFFFFFFFF;
|
|
||||||
uint32_t unusedblock = 0;
|
|
||||||
|
|
||||||
if (curblock > (nand_dev.block_totalnum - 1))
|
|
||||||
{
|
|
||||||
curblock = nand_dev.block_totalnum - 1; /* 超出范围了,强制从最后一个块开始 */
|
|
||||||
}
|
|
||||||
|
|
||||||
unusedblock = ftl_find_unused_block(curblock, sblock % 2); /* 从当前块,开始,向前查找空余块 */
|
|
||||||
|
|
||||||
if (unusedblock == 0XFFFFFFFF && curblock < (nand_dev.block_totalnum - 1)) /* 未找到,且不是从最末尾开始找的 */
|
|
||||||
{
|
|
||||||
curblock = nand_dev.block_totalnum - 1; /* 强制从最后一个块开始 */
|
|
||||||
unusedblock = ftl_find_unused_block(curblock, sblock % 2);/* 从最末尾开始,重新找一遍 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (unusedblock == 0XFFFFFFFF)
|
|
||||||
{
|
|
||||||
return 0XFFFFFFFF; /* 找不到空闲block */
|
|
||||||
}
|
|
||||||
|
|
||||||
curblock = unusedblock; /* 当前块号等于未使用块编号.下次则从此处开始查找 */
|
|
||||||
|
|
||||||
return unusedblock; /* 返回找到的空闲block */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将一个块的数据拷贝到另一块,并且可以写入数据
|
|
||||||
* @param source_pagenum : 要写入数据的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要写入的列开始地址(也就是页内地址),范围:0~(page_totalsize-1)
|
|
||||||
* @param pbuffer : 要写入的数据
|
|
||||||
* @param numbytetowrite : 要写入的字节数,该值不能超过块内剩余容量大小
|
|
||||||
* @retval 0,成功;
|
|
||||||
* 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_copy_and_write_to_block(uint32_t source_pagenum, uint16_t colnum, uint8_t *pbuffer, uint32_t numbytetowrite)
|
|
||||||
{
|
|
||||||
uint16_t i = 0, temp = 0, wrlen;
|
|
||||||
uint32_t source_block = 0, pageoffset = 0;
|
|
||||||
uint32_t unusedblock = 0;
|
|
||||||
source_block = source_pagenum / nand_dev.block_pagenum; /* 获得页所在的块号 */
|
|
||||||
pageoffset = source_pagenum % nand_dev.block_pagenum; /* 获得页在所在块内的偏移 */
|
|
||||||
|
|
||||||
retry:
|
|
||||||
unusedblock = ftl_find_same_plane_unusedBlock(source_block); /* 查找与源块在一个plane的未使用块 */
|
|
||||||
|
|
||||||
if (unusedblock > nand_dev.block_totalnum)
|
|
||||||
{
|
|
||||||
return 1; /* 当找到的空余块号大于块总数量的话肯定是出错了 */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_pagenum; i++) /* 将一个块的数据复制到找到的未使用块中 */
|
|
||||||
{
|
|
||||||
if (i >= pageoffset && numbytetowrite) /* 数据要写入到当前页 */
|
|
||||||
{
|
|
||||||
if (numbytetowrite > (nand_dev.page_mainsize - colnum)) /* 要写入的数据,超过了当前页的剩余数据 */
|
|
||||||
{
|
|
||||||
wrlen = nand_dev.page_mainsize - colnum; /* 写入长度等于当前页剩余数据长度 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
wrlen = numbytetowrite; /* 写入全部数据 */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = nand_copypage_withwrite(source_block * nand_dev.block_pagenum + i, unusedblock * nand_dev.block_pagenum + i, colnum, pbuffer, wrlen);
|
|
||||||
colnum = 0; /* 列地址归零 */
|
|
||||||
pbuffer += wrlen; /* 写地址偏移 */
|
|
||||||
numbytetowrite -= wrlen; /* 写入数据减少 */
|
|
||||||
}
|
|
||||||
|
|
||||||
else /* 无数据写入,直接拷贝即可 */
|
|
||||||
{
|
|
||||||
temp = nand_copypage_withoutwrite(source_block * nand_dev.block_pagenum + i, unusedblock * nand_dev.block_pagenum + i);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp) /* 返回值非零,当坏块处理 */
|
|
||||||
{
|
|
||||||
ftl_badblock_mark(unusedblock); /* 标记为坏块 */
|
|
||||||
ftl_create_lut(1); /* 重建LUT表 */
|
|
||||||
goto retry;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (i == nand_dev.block_pagenum) /* 拷贝完成 */
|
|
||||||
{
|
|
||||||
ftl_used_blockmark(unusedblock); /* 标记块已经使用 */
|
|
||||||
nand_eraseblock(source_block); /* 擦除源块 */
|
|
||||||
|
|
||||||
//printf("\r\ncopy block %d to block %d\r\n",source_block,unusedblock);/* 打印调试信息 */
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 修正LUT表,用unusedblock替换source_block */
|
|
||||||
{
|
|
||||||
if (nand_dev.lut[i] == source_block)
|
|
||||||
{
|
|
||||||
nand_dev.lut[i] = unusedblock;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 逻辑块号转换为物理块号
|
|
||||||
* @param lbnnum : 逻辑块编号
|
|
||||||
* @retval 物理块编号
|
|
||||||
*/
|
|
||||||
uint16_t ftl_lbn_to_pbn(uint32_t lbnnum)
|
|
||||||
{
|
|
||||||
uint16_t PBNNo = 0;
|
|
||||||
|
|
||||||
/* 当逻辑块号大于有效块数的时候返回0XFFFF */
|
|
||||||
if (lbnnum > nand_dev.valid_blocknum)
|
|
||||||
{
|
|
||||||
return 0XFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
PBNNo = nand_dev.lut[lbnnum];
|
|
||||||
|
|
||||||
return PBNNo;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 写扇区(支持多扇区写),FATFS文件系统使用
|
|
||||||
* @param pbuffer : 要写入的数据
|
|
||||||
* @param sectorno : 起始扇区号
|
|
||||||
* @param sectorsize : 扇区大小(不能大于NAND_ECC_SECTOR_SIZE定义的大小,否则会出错!!)
|
|
||||||
* @param sectorcount : 要写入的扇区数量
|
|
||||||
* @retval 0,成功;
|
|
||||||
* 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_write_sectors(uint8_t *pbuffer, uint32_t sectorno, uint16_t sectorsize, uint32_t sectorcount)
|
|
||||||
{
|
|
||||||
uint8_t flag = 0;
|
|
||||||
uint16_t temp;
|
|
||||||
uint32_t i = 0;
|
|
||||||
uint16_t wsecs; /* 写页大小 */
|
|
||||||
uint32_t wlen; /* 写入长度 */
|
|
||||||
uint32_t LBNNo; /* 逻辑块号 */
|
|
||||||
uint32_t PBNNo; /* 物理块号 */
|
|
||||||
uint32_t PhyPageNo; /* 物理页号 */
|
|
||||||
uint32_t PageOffset; /* 页内偏移地址 */
|
|
||||||
uint32_t BlockOffset; /* 块内偏移地址 */
|
|
||||||
uint32_t markdpbn = 0XFFFFFFFF; /* 标记了的物理块编号 */
|
|
||||||
|
|
||||||
for (i = 0; i < sectorcount; i++)
|
|
||||||
{
|
|
||||||
LBNNo = (sectorno + i) / (nand_dev.block_pagenum * (nand_dev.page_mainsize / sectorsize)); /* 根据逻辑扇区号和扇区大小计算出逻辑块号 */
|
|
||||||
PBNNo = ftl_lbn_to_pbn(LBNNo); /* 将逻辑块转换为物理块 */
|
|
||||||
|
|
||||||
if (PBNNo >= nand_dev.block_totalnum)
|
|
||||||
{
|
|
||||||
return 1; /* 物理块号大于NAND FLASH的总块数,则失败. */
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockOffset = ((sectorno + i) % (nand_dev.block_pagenum * (nand_dev.page_mainsize / sectorsize))) * sectorsize; /* 计算块内偏移 */
|
|
||||||
PhyPageNo = PBNNo * nand_dev.block_pagenum + BlockOffset / nand_dev.page_mainsize; /* 计算出物理页号 */
|
|
||||||
PageOffset = BlockOffset % nand_dev.page_mainsize; /* 计算出页内偏移地址 */
|
|
||||||
temp = nand_dev.page_mainsize - PageOffset; /* page内剩余字节数 */
|
|
||||||
temp /= sectorsize; /* 可以连续写入的sector数 */
|
|
||||||
wsecs = sectorcount - i; /* 还剩多少个sector要写 */
|
|
||||||
|
|
||||||
if (wsecs >= temp)
|
|
||||||
{
|
|
||||||
wsecs = temp; /* 大于可连续写入的sector数,则写入temp个扇区 */
|
|
||||||
}
|
|
||||||
|
|
||||||
wlen = wsecs * sectorsize; /* 每次写wsecs个sector */
|
|
||||||
|
|
||||||
/* 读出写入大小的内容判断是否全为0XFF */
|
|
||||||
flag = nand_readpagecomp(PhyPageNo, PageOffset, 0XFFFFFFFF, wlen / 4, &temp); /* 读一个wlen/4大小个数据,并与0XFFFFFFFF对比 */
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
return 2; /* 读写错误,坏块 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (temp == (wlen / 4))
|
|
||||||
{
|
|
||||||
flag = nand_writepage(PhyPageNo, PageOffset, pbuffer, wlen);/* 全为0XFF,可以直接写数据 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
flag = 1; /* 不全是0XFF,则另作处理 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag == 0 && (markdpbn != PBNNo)) /* 全是0XFF,且写入成功,且标记了的物理块与当前物理块不同 */
|
|
||||||
{
|
|
||||||
flag = ftl_used_blockmark(PBNNo); /* 标记此块已经使用 */
|
|
||||||
markdpbn = PBNNo; /* 标记完成,标记块=当前块,防止重复标记 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag) /* 不全为0XFF/标记失败,将数据写到另一个块 */
|
|
||||||
{
|
|
||||||
temp = ((uint32_t)nand_dev.block_pagenum * nand_dev.page_mainsize - BlockOffset) / sectorsize;/* 计算整个block还剩下多少个SECTOR可以写入 */
|
|
||||||
wsecs = sectorcount - i; /* 还剩多少个sector要写 */
|
|
||||||
|
|
||||||
if (wsecs >= temp)
|
|
||||||
{
|
|
||||||
wsecs = temp; /* 大于可连续写入的sector数,则写入temp个扇区 */
|
|
||||||
}
|
|
||||||
|
|
||||||
wlen = wsecs * sectorsize; /* 每次写wsecs个sector */
|
|
||||||
flag = ftl_copy_and_write_to_block(PhyPageNo, PageOffset, pbuffer, wlen); /* 拷贝到另外一个block,并写入数据 */
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
return 3; /* 失败 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
i += wsecs - 1;
|
|
||||||
pbuffer += wlen; /* 数据缓冲区指针偏移 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读扇区(支持多扇区读),FATFS文件系统使用
|
|
||||||
* @param pbuffer : 数据缓存区
|
|
||||||
* @param sectorno : 起始扇区号
|
|
||||||
* @param sectorsize : 扇区大小
|
|
||||||
* @param sectorcount : 要写入的扇区数量
|
|
||||||
* @retval 0,成功;
|
|
||||||
* 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_read_sectors(uint8_t *pbuffer, uint32_t sectorno, uint16_t sectorsize, uint32_t sectorcount)
|
|
||||||
{
|
|
||||||
uint8_t flag = 0;
|
|
||||||
uint16_t rsecs; /* 单次读取页数 */
|
|
||||||
uint32_t i = 0;
|
|
||||||
uint32_t LBNNo; /* 逻辑块号 */
|
|
||||||
uint32_t PBNNo; /* 物理块号 */
|
|
||||||
uint32_t PhyPageNo; /* 物理页号 */
|
|
||||||
uint32_t PageOffset; /* 页内偏移地址 */
|
|
||||||
uint32_t BlockOffset; /* 块内偏移地址 */
|
|
||||||
|
|
||||||
for (i = 0; i < sectorcount; i++)
|
|
||||||
{
|
|
||||||
LBNNo = (sectorno + i) / (nand_dev.block_pagenum * (nand_dev.page_mainsize / sectorsize));/* 根据逻辑扇区号和扇区大小计算出逻辑块号 */
|
|
||||||
PBNNo = ftl_lbn_to_pbn(LBNNo); /* 将逻辑块转换为物理块 */
|
|
||||||
|
|
||||||
if (PBNNo >= nand_dev.block_totalnum)
|
|
||||||
{
|
|
||||||
return 1; /* 物理块号大于NAND FLASH的总块数,则失败. */
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockOffset = ((sectorno + i) % (nand_dev.block_pagenum * (nand_dev.page_mainsize / sectorsize))) * sectorsize; /* 计算块内偏移 */
|
|
||||||
PhyPageNo = PBNNo * nand_dev.block_pagenum + BlockOffset / nand_dev.page_mainsize; /* 计算出物理页号 */
|
|
||||||
PageOffset = BlockOffset % nand_dev.page_mainsize; /* 计算出页内偏移地址 */
|
|
||||||
rsecs = (nand_dev.page_mainsize - PageOffset) / sectorsize; /* 计算一次最多可以读取多少页 */
|
|
||||||
|
|
||||||
if (rsecs > (sectorcount - i))
|
|
||||||
{
|
|
||||||
rsecs = sectorcount - i; /* 最多不能超过SectorCount-i */
|
|
||||||
}
|
|
||||||
|
|
||||||
flag = nand_readpage(PhyPageNo, PageOffset, pbuffer, rsecs * sectorsize); /* 读取数据 */
|
|
||||||
|
|
||||||
if (flag == NSTA_ECC1BITERR) /* 对于1bit ecc错误,可能为坏块 */
|
|
||||||
{
|
|
||||||
flag = nand_readpage(PhyPageNo, PageOffset, pbuffer, rsecs * sectorsize); /* 重读数据,再次确认 */
|
|
||||||
|
|
||||||
if (flag == NSTA_ECC1BITERR)
|
|
||||||
{
|
|
||||||
ftl_copy_and_write_to_block(PhyPageNo, PageOffset, pbuffer, rsecs * sectorsize); /* 搬运数据 */
|
|
||||||
flag = ftl_blockcompare(PhyPageNo / nand_dev.block_pagenum, 0XFFFFFFFF); /* 全1检查,确认是否为坏块 */
|
|
||||||
|
|
||||||
if (flag == 0)
|
|
||||||
{
|
|
||||||
flag = ftl_blockcompare(PhyPageNo / nand_dev.block_pagenum, 0X00); /* 全0检查,确认是否为坏块 */
|
|
||||||
nand_eraseblock(PhyPageNo / nand_dev.block_pagenum); /* 检测完成后,擦除这个块 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag) /* 全0/全1检查出错,肯定是坏块了. */
|
|
||||||
{
|
|
||||||
ftl_badblock_mark(PhyPageNo / nand_dev.block_pagenum); /* 标记为坏块 */
|
|
||||||
ftl_create_lut(1); /* 重建LUT表 */
|
|
||||||
}
|
|
||||||
|
|
||||||
flag = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag == NSTA_ECC2BITERR)
|
|
||||||
{
|
|
||||||
flag = 0; /* 2bit ecc错误,不处理(可能是初次写入数据导致的) */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (flag)
|
|
||||||
{
|
|
||||||
return 2; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
pbuffer += sectorsize * rsecs; /* 数据缓冲区指针偏移 */
|
|
||||||
i += rsecs - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 重新创建LUT表
|
|
||||||
* @param mode : 0, 仅检查第一个坏块标记
|
|
||||||
* 1, 两个坏块标记都要检查(备份区也要检查)
|
|
||||||
* @retval 0,成功;
|
|
||||||
* 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_create_lut(uint8_t mode)
|
|
||||||
{
|
|
||||||
uint32_t i;
|
|
||||||
uint8_t buf[4];
|
|
||||||
uint32_t LBNnum = 0; /* 逻辑块号 */
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 复位LUT表,初始化为无效值,也就是0XFFFF */
|
|
||||||
{
|
|
||||||
nand_dev.lut[i] = 0XFFFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
nand_dev.good_blocknum = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++)
|
|
||||||
{
|
|
||||||
nand_readspare(i * nand_dev.block_pagenum, 0, buf, 4); /* 读取4个字节 */
|
|
||||||
|
|
||||||
if (buf[0] == 0XFF && mode)
|
|
||||||
{
|
|
||||||
nand_readspare(i * nand_dev.block_pagenum + 1, 0, buf, 1); /* 好块,且需要检查2次坏块标记 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buf[0] == 0XFF) /* 是好块 */
|
|
||||||
{
|
|
||||||
LBNnum = ((uint16_t)buf[3] << 8) + buf[2]; /* 得到逻辑块编号 */
|
|
||||||
|
|
||||||
if (LBNnum < nand_dev.block_totalnum) /* 逻辑块号肯定小于总的块数量 */
|
|
||||||
{
|
|
||||||
nand_dev.lut[LBNnum] = i; /* 更新LUT表,写LBNnum对应的物理块编号 */
|
|
||||||
}
|
|
||||||
|
|
||||||
nand_dev.good_blocknum++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
printf("bad block index:%d\r\n", i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* LUT表建立完成以后检查有效块个数 */
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++)
|
|
||||||
{
|
|
||||||
if (nand_dev.lut[i] >= nand_dev.block_totalnum)
|
|
||||||
{
|
|
||||||
nand_dev.valid_blocknum = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nand_dev.valid_blocknum < 100)
|
|
||||||
{
|
|
||||||
return 2; /* 有效块数小于100,有问题.需要重新格式化 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* LUT表创建完成 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FTL整个Block与某个数据对比
|
|
||||||
* @param blockx : block编号
|
|
||||||
* @param cmpval : 要与之对比的值
|
|
||||||
* @retval 0,检查成功,全部相等;
|
|
||||||
1,检查失败,有不相等的情况
|
|
||||||
*/
|
|
||||||
uint8_t ftl_blockcompare(uint32_t blockx, uint32_t cmpval)
|
|
||||||
{
|
|
||||||
uint8_t res;
|
|
||||||
uint16_t i, j, k;
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++) /* 允许3次机会 */
|
|
||||||
{
|
|
||||||
for (j = 0; j < nand_dev.block_pagenum; j++)
|
|
||||||
{
|
|
||||||
nand_readpagecomp(blockx * nand_dev.block_pagenum, 0, cmpval, nand_dev.page_mainsize / 4, &k);/* 检查一个page,并与0XFFFFFFFF对比 */
|
|
||||||
|
|
||||||
if (k != (nand_dev.page_mainsize / 4))break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j == nand_dev.block_pagenum)
|
|
||||||
{
|
|
||||||
return 0; /* 检查合格,直接退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
res = nand_eraseblock(blockx);
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
printf("error erase block:%d\r\n", i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (cmpval != 0XFFFFFFFF) /* 不是判断全1,则需要重写数据 */
|
|
||||||
{
|
|
||||||
for (k = 0; k < nand_dev.block_pagenum; k++)
|
|
||||||
{
|
|
||||||
nand_write_pageconst(blockx * nand_dev.block_pagenum + k, 0, 0, nand_dev.page_mainsize / 4);/* 写PAGE */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("bad block checked:%d\r\n", blockx);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief FTL初始化时,搜寻所有坏块,使用:擦-写-读 方式
|
|
||||||
* @note 512M的NAND ,需要约3分钟时间,来完成检测
|
|
||||||
* 对于RGB屏,由于频繁读写NAND,会引起屏幕乱闪
|
|
||||||
* @param 无
|
|
||||||
* @retval 好块的数量
|
|
||||||
*/
|
|
||||||
uint32_t ftl_search_badblock(void)
|
|
||||||
{
|
|
||||||
uint8_t *blktbl;
|
|
||||||
uint8_t res;
|
|
||||||
uint32_t i, j;
|
|
||||||
uint32_t goodblock = 0;
|
|
||||||
|
|
||||||
blktbl = mymalloc(SRAMIN, nand_dev.block_totalnum); /* 申请block坏块表内存,对应项:0,好块;1,坏块; */
|
|
||||||
nand_erasechip(); /* 全片擦除 */
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 第一阶段检查,检查全1 */
|
|
||||||
{
|
|
||||||
res = ftl_blockcompare(i, 0XFFFFFFFF); /* 全1检查 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
blktbl[i] = 1; /* 坏块 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
blktbl[i] = 0;/* 好块 */
|
|
||||||
|
|
||||||
for (j = 0; j < nand_dev.block_pagenum; j++)/* 写block为全0,为后面的检查准备 */
|
|
||||||
{
|
|
||||||
nand_write_pageconst(i * nand_dev.block_pagenum + j, 0, 0, nand_dev.page_mainsize / 4);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 第二阶段检查,检查全0 */
|
|
||||||
{
|
|
||||||
if (blktbl[i] == 0) /* 在第一阶段,没有被标记坏块的,才可能是好块 */
|
|
||||||
{
|
|
||||||
res = ftl_blockcompare(i, 0); /* 全0检查 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
blktbl[i] = 1; /* 标记坏块 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
goodblock++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
nand_erasechip(); /* 全片擦除 */
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 第三阶段检查,标记坏块 */
|
|
||||||
{
|
|
||||||
if (blktbl[i])
|
|
||||||
{
|
|
||||||
ftl_badblock_mark(i); /* 是坏块 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return goodblock; /* 返回好块的数量 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 格式化NAND 重建LUT表
|
|
||||||
* @param 无
|
|
||||||
* @retval 0,成功;
|
|
||||||
其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t ftl_format(void)
|
|
||||||
{
|
|
||||||
uint8_t temp;
|
|
||||||
uint8_t buf[6];
|
|
||||||
uint32_t i, n;
|
|
||||||
uint32_t goodblock = 0;
|
|
||||||
nand_dev.good_blocknum = 0;
|
|
||||||
|
|
||||||
#if FTL_USE_BAD_BLOCK_SEARCH == 1 /* 使用擦-写-读的方式,检测坏块 */
|
|
||||||
nand_dev.good_blocknum = FTL_SearchBadBlock(); /* 搜寻坏块.耗时很久 */
|
|
||||||
#else /* 直接使用NAND FLASH的出厂坏块标志(其他块,默认是好块) */
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++)
|
|
||||||
{
|
|
||||||
temp = ftl_check_badblock(i); /* 检查一个块是否为坏块 */
|
|
||||||
|
|
||||||
if (temp == 0) /* 好块 */
|
|
||||||
{
|
|
||||||
temp = nand_eraseblock(i);
|
|
||||||
|
|
||||||
if (temp) /* 擦除失败,认为坏块 */
|
|
||||||
{
|
|
||||||
printf("Bad block:%d\r\n", i);
|
|
||||||
ftl_badblock_mark(i); /* 标记是坏块 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nand_dev.good_blocknum++; /* 好块数量加一 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
printf("good_blocknum:%d\r\n", nand_dev.good_blocknum);
|
|
||||||
|
|
||||||
if (nand_dev.good_blocknum < 100)
|
|
||||||
{
|
|
||||||
return 1; /*如果好块的数量少于100,则NAND Flash报废 */
|
|
||||||
}
|
|
||||||
|
|
||||||
goodblock = (nand_dev.good_blocknum * 93) / 100;/* %93的好块用于存储数据 */
|
|
||||||
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 在好块中标记上逻辑块信息 */
|
|
||||||
{
|
|
||||||
temp = ftl_check_badblock(i); /* 检查一个块是否为坏块 */
|
|
||||||
|
|
||||||
if (temp == 0) /* 好块 */
|
|
||||||
{
|
|
||||||
nand_readspare(i * nand_dev.block_pagenum, 0, buf, 4); /* 读取spare区前四个字节 */
|
|
||||||
buf[2] = (uint8_t)n;
|
|
||||||
buf[3] = (uint8_t)(n >> 8);
|
|
||||||
|
|
||||||
nand_writespare(i * nand_dev.block_pagenum, 0, buf, 4); /* 写入逻辑块编号 */
|
|
||||||
n++; /* 逻辑块编号加1 */
|
|
||||||
|
|
||||||
if (n == goodblock) break; /* 全部标记完了 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ftl_create_lut(1))
|
|
||||||
{
|
|
||||||
return 2; /* 重建LUT表失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,53 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file ftl.h
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2022-09-06
|
|
||||||
* @brief NAND FLASH FTL层算法代码
|
|
||||||
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20220906
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __FTL_H
|
|
||||||
#define __FTL_H
|
|
||||||
|
|
||||||
#include "./SYSTEM/sys/sys.h"
|
|
||||||
|
|
||||||
|
|
||||||
/* 坏块搜索控制 */
|
|
||||||
/* 如果设置为1,将在ftl_format的时候,搜寻坏块,耗时久(512M,3分钟以上),且会导致RGB屏乱闪 */
|
|
||||||
#define FTL_USE_BAD_BLOCK_SEARCH 0 /* 定义是否使用坏块搜索 */
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
|
|
||||||
uint8_t ftl_init(void);
|
|
||||||
void ftl_badblock_mark(uint32_t blocknum);
|
|
||||||
uint8_t ftl_check_badblock(uint32_t blocknum);
|
|
||||||
uint8_t ftl_used_blockmark(uint32_t blocknum);
|
|
||||||
uint32_t ftl_find_unused_block(uint32_t sblock, uint8_t flag);
|
|
||||||
uint32_t ftl_find_same_plane_unused_block(uint32_t sblock);
|
|
||||||
uint8_t ftl_copy_and_write_to_block(uint32_t source_pagenum, uint16_t colnum, uint8_t *pbuffer, uint32_t numbyte_to_write);
|
|
||||||
uint16_t ftl_lbn_to_pbn(uint32_t lbnnum);
|
|
||||||
uint8_t ftl_write_sectors(uint8_t *pbuffer, uint32_t sectorno, uint16_t sectorsize, uint32_t sectorcount);
|
|
||||||
uint8_t ftl_read_sectors(uint8_t *pbuffer, uint32_t sectorno, uint16_t sectorsize, uint32_t sectorcount);
|
|
||||||
uint8_t ftl_create_lut(uint8_t mode);
|
|
||||||
uint8_t ftl_blockcompare(uint32_t blockx, uint32_t cmpval);
|
|
||||||
uint32_t ftl_search_badblock(void);
|
|
||||||
uint8_t ftl_format(void);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@@ -49,9 +49,7 @@ void MX_GPIO_Init(void)
|
|||||||
__HAL_RCC_GPIOC_CLK_ENABLE();
|
__HAL_RCC_GPIOC_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOH_CLK_ENABLE();
|
__HAL_RCC_GPIOH_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOA_CLK_ENABLE();
|
__HAL_RCC_GPIOA_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOE_CLK_ENABLE();
|
|
||||||
__HAL_RCC_GPIOB_CLK_ENABLE();
|
__HAL_RCC_GPIOB_CLK_ENABLE();
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE();
|
|
||||||
__HAL_RCC_GPIOG_CLK_ENABLE();
|
__HAL_RCC_GPIOG_CLK_ENABLE();
|
||||||
|
|
||||||
/*Configure GPIO pin Output Level */
|
/*Configure GPIO pin Output Level */
|
||||||
|
|||||||
@@ -24,7 +24,6 @@
|
|||||||
#include "memorymap.h"
|
#include "memorymap.h"
|
||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
#include "fmc.h"
|
|
||||||
|
|
||||||
/* Private includes ----------------------------------------------------------*/
|
/* Private includes ----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN Includes */
|
/* USER CODE BEGIN Includes */
|
||||||
@@ -35,15 +34,6 @@
|
|||||||
/* Private typedef -----------------------------------------------------------*/
|
/* Private typedef -----------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN PTD */
|
/* USER CODE BEGIN PTD */
|
||||||
|
|
||||||
extern NAND_HandleTypeDef hnand1;
|
|
||||||
|
|
||||||
#define NAND_PAGE_SIZE 2048 // ??????(??)
|
|
||||||
#define NAND_OOB_SIZE 64 // OOB ??(??)
|
|
||||||
#define NAND_BLOCK_SIZE 64 // ?? 64 ?(???)
|
|
||||||
|
|
||||||
// ????????(????,???? SRAM3 ? DTCM)
|
|
||||||
__attribute__((aligned(4))) uint8_t nand_write_buffer[NAND_PAGE_SIZE];
|
|
||||||
__attribute__((aligned(4))) uint8_t nand_read_buffer[NAND_PAGE_SIZE + NAND_OOB_SIZE];
|
|
||||||
|
|
||||||
/* USER CODE END PTD */
|
/* USER CODE END PTD */
|
||||||
|
|
||||||
@@ -75,6 +65,7 @@ void MX_FREERTOS_Init(void);
|
|||||||
/* Private user code ---------------------------------------------------------*/
|
/* Private user code ---------------------------------------------------------*/
|
||||||
/* USER CODE BEGIN 0 */
|
/* USER CODE BEGIN 0 */
|
||||||
|
|
||||||
|
|
||||||
/* USER CODE END 0 */
|
/* USER CODE END 0 */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -128,6 +119,13 @@ int main(void)
|
|||||||
g_Init();
|
g_Init();
|
||||||
Os_Init();
|
Os_Init();
|
||||||
|
|
||||||
|
/* USER CODE BEGIN 2 */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* USER CODE END 2 */
|
/* USER CODE END 2 */
|
||||||
|
|
||||||
/* Call init function for freertos objects (in cmsis_os2.c) */
|
/* Call init function for freertos objects (in cmsis_os2.c) */
|
||||||
|
|||||||
@@ -1,962 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file nand.c
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2022-09-06
|
|
||||||
* @brief NAND FLASH 驱动代码
|
|
||||||
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20220906
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "nand.h"
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
NAND_HandleTypeDef g_nand_handle; /* NAND FLASH句柄 */
|
|
||||||
nand_attriute nand_dev; /* nand重要参数结构体 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 初始化NAND FLASH
|
|
||||||
* @param 无
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
uint8_t nand_init(void)
|
|
||||||
{
|
|
||||||
FMC_NAND_PCC_TimingTypeDef comspacetiming, attspacetiming;
|
|
||||||
|
|
||||||
g_nand_handle.Instance = FMC_NAND_DEVICE;
|
|
||||||
g_nand_handle.Init.NandBank = FMC_NAND_BANK3; /* NAND挂在BANK3上 */
|
|
||||||
g_nand_handle.Init.Waitfeature = FMC_NAND_PCC_WAIT_FEATURE_DISABLE; /* 关闭等待特性 */
|
|
||||||
g_nand_handle.Init.MemoryDataWidth = FMC_NAND_PCC_MEM_BUS_WIDTH_8; /* 8位数据宽度 */
|
|
||||||
g_nand_handle.Init.EccComputation = FMC_NAND_ECC_DISABLE; /* 不使用ECC */
|
|
||||||
g_nand_handle.Init.ECCPageSize = FMC_NAND_ECC_PAGE_SIZE_512BYTE; /* ECC页大小为512字节 */
|
|
||||||
g_nand_handle.Init.TCLRSetupTime = 8; /* 设置TCLR(tCLR=CLE到RE的延时)=(TCLR+SET+2)*THCLK,THCLK=1/220M=4.5ns */
|
|
||||||
g_nand_handle.Init.TARSetupTime = 8; /* 设置TAR(tAR=ALE到RE的延时)=(TAR+SET+1)*THCLK,THCLK=1/220M=4.5ns */
|
|
||||||
|
|
||||||
comspacetiming.SetupTime = 4; /* 建立时间 */
|
|
||||||
comspacetiming.WaitSetupTime = 6; /* 等待时间 */
|
|
||||||
comspacetiming.HoldSetupTime = 2; /* 保持时间 */
|
|
||||||
comspacetiming.HiZSetupTime = 3; /* 高阻态时间 */
|
|
||||||
|
|
||||||
attspacetiming.SetupTime = 4; /* 建立时间 */
|
|
||||||
attspacetiming.WaitSetupTime = 6; /* 等待时间 */
|
|
||||||
attspacetiming.HoldSetupTime = 2; /* 保持时间 */
|
|
||||||
attspacetiming.HiZSetupTime = 3; /* 高阻态时间 */
|
|
||||||
|
|
||||||
HAL_NAND_Init(&g_nand_handle, &comspacetiming, &attspacetiming);
|
|
||||||
nand_reset(); /* 复位NAND */
|
|
||||||
delay_ms(100);
|
|
||||||
nand_dev.id = nand_readid(); /* 读取ID */
|
|
||||||
nand_modeset(4); /* 设置为MODE4,高速模式 */
|
|
||||||
|
|
||||||
if (nand_dev.id == MT29F16G08ABABA) /* NAND为MT29F16G08ABABA */
|
|
||||||
{
|
|
||||||
nand_dev.page_totalsize = 4320; /* nand一个page的总大小(包括spare区) */
|
|
||||||
nand_dev.page_mainsize = 4096; /* nand一个page的有效数据区大小 */
|
|
||||||
nand_dev.page_sparesize = 224; /* nand一个page的spare区大小 */
|
|
||||||
nand_dev.block_pagenum = 128; /* nand一个block所包含的page数目 */
|
|
||||||
nand_dev.plane_blocknum = 2048; /* nand一个plane所包含的block数目 */
|
|
||||||
nand_dev.block_totalnum = 4096; /* nand的总block数目 */
|
|
||||||
}
|
|
||||||
else if (nand_dev.id == MT29F4G08ABADA) /* NAND为MT29F4G08ABADA */
|
|
||||||
{
|
|
||||||
nand_dev.page_totalsize = 2112; /* nand一个page的总大小(包括spare区) */
|
|
||||||
nand_dev.page_mainsize = 2048; /* nand一个page的有效数据区大小 */
|
|
||||||
nand_dev.page_sparesize = 64; /* nand一个page的spare区大小 */
|
|
||||||
nand_dev.block_pagenum = 64; /* nand一个block所包含的page数目 */
|
|
||||||
nand_dev.plane_blocknum = 2048; /* nand一个plane所包含的block数目 */
|
|
||||||
nand_dev.block_totalnum = 4096; /* nand的总block数目 */
|
|
||||||
}
|
|
||||||
else if (nand_dev.id == FSNS8B004G) /* NAND为HSENSD04ATIG */
|
|
||||||
{
|
|
||||||
nand_dev.page_totalsize = 4160; /* nand一个page的总大小(包括spare区) */
|
|
||||||
nand_dev.page_mainsize = 4096; /* nand一个page的有效数据区大小 */
|
|
||||||
nand_dev.page_sparesize = 64; /* nand一个page的spare区大小 */
|
|
||||||
nand_dev.block_pagenum = 64; /* nand一个block所包含的page数目 */
|
|
||||||
nand_dev.plane_blocknum = 1024; /* nand一个plane所包含的block数目 */
|
|
||||||
nand_dev.block_totalnum = 2048; /* nand的总block数目 */
|
|
||||||
}
|
|
||||||
else return 1; /* 错误,返回 */
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief NAND FALSH底层驱动,引脚配置,时钟使能
|
|
||||||
* @note 此函数会被HAL_nand_init()调用
|
|
||||||
* @param 无
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
void HAL_NAND_MspInit(NAND_HandleTypeDef *hnand)
|
|
||||||
{
|
|
||||||
GPIO_InitTypeDef gpio_init_struct;
|
|
||||||
|
|
||||||
__HAL_RCC_FMC_CLK_ENABLE(); /* 使能FMC时钟 */
|
|
||||||
__HAL_RCC_GPIOC_CLK_ENABLE(); /* 使能GPIOC时钟 */
|
|
||||||
__HAL_RCC_GPIOD_CLK_ENABLE(); /* 使能GPIOD时钟 */
|
|
||||||
__HAL_RCC_GPIOE_CLK_ENABLE(); /* 使能GPIOE时钟 */
|
|
||||||
__HAL_RCC_GPIOG_CLK_ENABLE(); /* 使能GPIOG时钟 */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
gpio_init_struct.Pin = GPIO_PIN_6;
|
|
||||||
gpio_init_struct.Mode = GPIO_MODE_INPUT; /* 输入 */
|
|
||||||
gpio_init_struct.Pull = GPIO_PULLUP; /* 上拉 */
|
|
||||||
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
|
|
||||||
HAL_GPIO_Init(GPIOC, &gpio_init_struct);
|
|
||||||
|
|
||||||
gpio_init_struct.Pin = GPIO_PIN_8;
|
|
||||||
gpio_init_struct.Mode = GPIO_MODE_AF_PP; /* 输入 */
|
|
||||||
gpio_init_struct.Pull = GPIO_NOPULL; /* 上拉 */
|
|
||||||
gpio_init_struct.Speed = GPIO_SPEED_HIGH; /* 高速 */
|
|
||||||
gpio_init_struct.Alternate = GPIO_AF9_FMC; /* 复用为FMC */
|
|
||||||
HAL_GPIO_Init(GPIOC, &gpio_init_struct);
|
|
||||||
|
|
||||||
gpio_init_struct.Alternate = GPIO_AF12_FMC; /* 复用为FMC */
|
|
||||||
/* 初始化PD0,1,4,5,11,12,14,15 */
|
|
||||||
gpio_init_struct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5 | \
|
|
||||||
GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_14 | GPIO_PIN_15;
|
|
||||||
gpio_init_struct.Pull = GPIO_NOPULL;
|
|
||||||
HAL_GPIO_Init(GPIOD, &gpio_init_struct);
|
|
||||||
|
|
||||||
/* 初始化PE7,8,9,10*/
|
|
||||||
gpio_init_struct.Pin = GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 | GPIO_PIN_10;
|
|
||||||
HAL_GPIO_Init(GPIOE, &gpio_init_struct);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 设置NAND速度模式
|
|
||||||
* @param mode : 0~5, 表示速度模式
|
|
||||||
* @retval 0,成功; 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t nand_modeset(uint8_t mode)
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_FEATURE; /* 发送设置特性命令 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = 0X01; /* 地址为0X01,设置mode */
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = mode; /* P1参数,设置mode */
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = 0;
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = 0;
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = 0;
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() == NSTA_READY)
|
|
||||||
{
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
else return 1; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取NAND FLASH的ID
|
|
||||||
* @note 不同的NAND略有不同,请根据自己所使用的NAND FALSH数据手册来编写函数
|
|
||||||
* @param 无
|
|
||||||
* @retval NAND FLASH的ID值
|
|
||||||
*/
|
|
||||||
uint32_t nand_readid(void)
|
|
||||||
{
|
|
||||||
uint8_t deviceid[5];
|
|
||||||
uint32_t id;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = nand_readID; /* 发送读取ID命令 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = 0X00;
|
|
||||||
|
|
||||||
/* ID一共有5个字节 */
|
|
||||||
deviceid[0] = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
deviceid[1] = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
deviceid[2] = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
deviceid[3] = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
deviceid[4] = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
|
|
||||||
/* 镁光的NAND FLASH的ID一共5个字节,但是为了方便我们只取4个字节组成一个32位的ID值
|
|
||||||
根据NAND FLASH的数据手册,只要是镁光的NAND FLASH,那么一个字节ID的第一个字节都是0X2C
|
|
||||||
所以我们就可以抛弃这个0X2C,只取后面四字节的ID值。*/
|
|
||||||
id = ((uint32_t)deviceid[1]) << 24 | ((uint32_t)deviceid[2]) << 16 | ((uint32_t)deviceid[3]) << 8 | deviceid[4];
|
|
||||||
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读NAND状态
|
|
||||||
* @param 无
|
|
||||||
* @retval NAND状态值
|
|
||||||
* bit0:0,成功; 1,错误(编程/擦除/READ)
|
|
||||||
* bit6:0,Busy; 1,Ready
|
|
||||||
*/
|
|
||||||
uint8_t nand_readstatus(void)
|
|
||||||
{
|
|
||||||
__IO uint8_t data = 0;
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_READSTA; /* 发送读状态命令 */
|
|
||||||
nand_delay(NAND_TWHR_DELAY); /* 等待tWHR,再读取状态寄存器 */
|
|
||||||
data = *(__IO uint8_t *)NAND_ADDRESS; /* 读取状态值 */
|
|
||||||
|
|
||||||
return data;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 等待NAND准备好
|
|
||||||
* @param 无
|
|
||||||
* @retval NSTA_TIMEOUT 等待超时了
|
|
||||||
* NSTA_READY 已经准备好
|
|
||||||
*/
|
|
||||||
uint8_t nand_wait_for_ready(void)
|
|
||||||
{
|
|
||||||
uint8_t status = 0;
|
|
||||||
__IO uint32_t time = 0;
|
|
||||||
|
|
||||||
while (1) /* 等待ready */
|
|
||||||
{
|
|
||||||
status = nand_readstatus(); /* 获取状态值 */
|
|
||||||
|
|
||||||
if (status & NSTA_READY)break;
|
|
||||||
|
|
||||||
time++;
|
|
||||||
|
|
||||||
if (time >= 0X1FFFFFFF)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NSTA_READY; /* 准备好 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 复位NAND
|
|
||||||
* @param 无
|
|
||||||
* @retval 0,成功; 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t nand_reset(void)
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_RESET; /* 复位NAND */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() == NSTA_READY)
|
|
||||||
{
|
|
||||||
return 0; /* 复位成功 */
|
|
||||||
}
|
|
||||||
else return 1; /* 复位失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 等待RB信号为某个电平
|
|
||||||
* @param rb : 0,等待RB==0;
|
|
||||||
* 1,等待RB==1;
|
|
||||||
* @retval 0,成功; 1,超时
|
|
||||||
*/
|
|
||||||
uint8_t nand_waitrb(__IO uint8_t rb)
|
|
||||||
{
|
|
||||||
__IO uint32_t time = 0;
|
|
||||||
__IO uint8_t cnt = 0;
|
|
||||||
|
|
||||||
while (time < 0X1FFFFFF)
|
|
||||||
{
|
|
||||||
time++;
|
|
||||||
|
|
||||||
if (NAND_RB == rb)
|
|
||||||
{
|
|
||||||
cnt++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
cnt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cnt > 2)
|
|
||||||
{
|
|
||||||
return 0; /* 连续三次读取都是正确的有效电平,则认为此次数据有效!(否则-O2优化出问题!) */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief NAND延时
|
|
||||||
* @note 一个i++至少需要4ns
|
|
||||||
* @param i : 等待的时间
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
void nand_delay(__IO uint32_t i)
|
|
||||||
{
|
|
||||||
while (i > 0)
|
|
||||||
{
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取NAND Flash的指定页指定列的数据(main区和spare区都可以使用此函数)
|
|
||||||
* @param pagenum : 要读取的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要读取的列开始地址(也就是页内地址),范围:0~(page_totalsize-1)
|
|
||||||
* @param *pbuffer : 指向数据存储区
|
|
||||||
* @param numbytetoread : 读取字节数(不能跨页读)
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_readpage(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbytetoread)
|
|
||||||
{
|
|
||||||
__IO uint16_t i = 0;
|
|
||||||
uint8_t res = 0;
|
|
||||||
uint8_t eccnum = 0; /* 需要计算的ECC个数,每NAND_ECC_SECTOR_SIZE字节计算一个ecc */
|
|
||||||
uint8_t eccstart = 0; /* 第一个ECC值所属的地址范围 */
|
|
||||||
uint8_t errsta = 0;
|
|
||||||
uint8_t *p;
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_AREA_A;
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)colnum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(colnum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_AREA_TRUE1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下面两行代码是等待R/B引脚变为低电平,其实主要起延时作用的,等待NAND操作R/B引脚。因为我们是通过
|
|
||||||
* 将STM32的NWAIT引脚(NAND的R/B引脚)配置为普通IO,代码中通过读取NWAIT引脚的电平来判断NAND是否准备
|
|
||||||
* 就绪的。这个也就是模拟的方法,所以在速度很快的时候有可能NAND还没来得及操作R/B引脚来表示NAND的忙
|
|
||||||
* 闲状态,结果我们就读取了R/B引脚,这个时候肯定会出错的,事实上确实是会出错!大家也可以将下面两行
|
|
||||||
* 代码换成延时函数,只不过这里我们为了效率所以没有用延时函数。
|
|
||||||
*/
|
|
||||||
res = nand_waitrb(0); /* 等待RB=0 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 下面2行代码是真正判断NAND是否准备好的 */
|
|
||||||
res = nand_waitrb(1); /* 等待RB=1 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
if (numbytetoread % NAND_ECC_SECTOR_SIZE) /* 不是NAND_ECC_SECTOR_SIZE的整数倍,不进行ECC校验 */
|
|
||||||
{
|
|
||||||
/* 读取NAND FLASH中的值 */
|
|
||||||
for (i = 0; i < numbytetoread; i++)
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)pbuffer++ = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eccnum = numbytetoread / NAND_ECC_SECTOR_SIZE; /* 得到ecc计算次数 */
|
|
||||||
eccstart = colnum / NAND_ECC_SECTOR_SIZE;
|
|
||||||
p = pbuffer;
|
|
||||||
|
|
||||||
for (res = 0; res < eccnum; res++)
|
|
||||||
{
|
|
||||||
FMC_Bank3_R->PCR |= 1 << 6; /* 使能ECC校验 */
|
|
||||||
|
|
||||||
for (i = 0; i < NAND_ECC_SECTOR_SIZE; i++) /* 读取NAND_ECC_SECTOR_SIZE个数据 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)pbuffer++ = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!(FMC_Bank3_R -> SR & (1 << 6))); /* 等待FIFO空 */
|
|
||||||
|
|
||||||
SCB_CleanInvalidateDCache(); /* 清除无效的D-Cache */
|
|
||||||
nand_dev.ecc_hdbuf[res + eccstart] = FMC_Bank3_R -> ECCR; /* 读取硬件计算后的ECC值 */
|
|
||||||
FMC_Bank3_R -> PCR &= ~(1 << 6); /* 禁止ECC校验 */
|
|
||||||
}
|
|
||||||
|
|
||||||
i = nand_dev.page_mainsize + 0X10 + eccstart * 4; /* 从spare区的0X10位置开始读取之前存储的ecc值 */
|
|
||||||
nand_delay(NAND_TRHW_DELAY); /* 等待tRHW */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = 0X05; /* 随机读指令 */
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)i;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(i >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = 0XE0; /* 开始读数据 */
|
|
||||||
|
|
||||||
nand_delay(NAND_TWHR_DELAY); /* 等待tWHR */
|
|
||||||
pbuffer = (uint8_t *)&nand_dev.ecc_rdbuf[eccstart];
|
|
||||||
|
|
||||||
for (i = 0; i < 4 * eccnum; i++) /* 读取保存的ECC值 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)pbuffer++ = *(__IO uint8_t *)NAND_ADDRESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < eccnum; i++) /* 检验ECC */
|
|
||||||
{
|
|
||||||
if (nand_dev.ecc_rdbuf[i + eccstart] != nand_dev.ecc_hdbuf[i + eccstart]) /* 不相等,需要校正 */
|
|
||||||
{
|
|
||||||
printf("err hd,rd:0x%x,0x%x\r\n", nand_dev.ecc_hdbuf[i + eccstart], nand_dev.ecc_rdbuf[i + eccstart]);
|
|
||||||
printf("eccnum,eccstart:%d,%d\r\n", eccnum, eccstart);
|
|
||||||
printf("PageNum,ColNum:%d,%d\r\n", pagenum, colnum);
|
|
||||||
res = nand_ecc_correction(p + NAND_ECC_SECTOR_SIZE * i, nand_dev.ecc_rdbuf[i + eccstart], nand_dev.ecc_hdbuf[i + eccstart]);/* ECC校验 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
errsta = NSTA_ECC2BITERR; /* 标记2BIT及以上ECC错误 */
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
errsta = NSTA_ECC1BITERR; /* 标记1BIT ECC错误 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
errsta = NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return errsta; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取NAND Flash的指定页指定列的数据(main区和spare区都可以使用此函数),并对比(FTL管理时需要)
|
|
||||||
* @param pagenum : 要读取的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要读取的列开始地址(也就是页内地址),范围:0~(page_totalsize-1)
|
|
||||||
* @param cmpval : 要对比的值,以uint32_t为单位
|
|
||||||
* @param numbytetoread : 读取字数(以4字节为单位,不能跨页读)
|
|
||||||
* @param numbyteequal : 从初始位置持续与CmpVal值相同的数据个数
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_readpagecomp(uint32_t pagenum, uint16_t colnum, uint32_t cmpval, uint16_t numbytetoread, uint16_t *numbyteequal)
|
|
||||||
{
|
|
||||||
uint16_t i = 0;
|
|
||||||
uint8_t res = 0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_AREA_A;
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)colnum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(colnum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_AREA_TRUE1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下面两行代码是等待R/B引脚变为低电平,其实主要起延时作用的,等待NAND操作R/B引脚。因为我们是通过
|
|
||||||
* 将STM32的NWAIT引脚(NAND的R/B引脚)配置为普通IO,代码中通过读取NWAIT引脚的电平来判断NAND是否准备
|
|
||||||
* 就绪的。这个也就是模拟的方法,所以在速度很快的时候有可能NAND还没来得及操作R/B引脚来表示NAND的忙
|
|
||||||
* 闲状态,结果我们就读取了R/B引脚,这个时候肯定会出错的,事实上确实是会出错!大家也可以将下面两行
|
|
||||||
* 代码换成延时函数,只不过这里我们为了效率所以没有用延时函数。
|
|
||||||
*/
|
|
||||||
res = nand_waitrb(0); /* 等待RB=0 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 下面2行代码是真正判断NAND是否准备好的 */
|
|
||||||
res = nand_waitrb(1); /* 等待RB=1 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < numbytetoread; i++) /* 读取数据,每次读4字节 */
|
|
||||||
{
|
|
||||||
if (*(__IO uint32_t *)NAND_ADDRESS != cmpval)break; /* 如果有任何一个值,与CmpVal不相等,则退出. */
|
|
||||||
}
|
|
||||||
|
|
||||||
*numbyteequal = i; /* 与CmpVal值相同的个数 */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 在NAND一页中写入指定个字节的数据(main区和spare区都可以使用此函数)
|
|
||||||
* @param pagenum : 要写入的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要写入的列开始地址(也就是页内地址),范围:0~(page_totalsize-1)
|
|
||||||
* @param pbuffer : 指向数据存储区
|
|
||||||
* @param numbytetowrite : 要写入的字节数,该值不能超过该页剩余字节数!!!
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_writepage(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbytetowrite)
|
|
||||||
{
|
|
||||||
__IO uint16_t i = 0;
|
|
||||||
uint8_t res = 0;
|
|
||||||
uint8_t eccnum = 0; /* 需要计算的ECC个数,每NAND_ECC_SECTOR_SIZE字节计算一个ecc */
|
|
||||||
uint8_t eccstart = 0; /* 第一个ECC值所属的地址范围 */
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_WRITE0;
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)colnum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(colnum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 16);
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
|
|
||||||
if (numbytetowrite % NAND_ECC_SECTOR_SIZE) /* 不是NAND_ECC_SECTOR_SIZE的整数倍,不进行ECC校验 */
|
|
||||||
{
|
|
||||||
for (i = 0; i < numbytetowrite; i++) /* 写入数据 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eccnum = numbytetowrite / NAND_ECC_SECTOR_SIZE; /* 得到ecc计算次数 */
|
|
||||||
eccstart = colnum / NAND_ECC_SECTOR_SIZE;
|
|
||||||
|
|
||||||
for (res = 0; res < eccnum; res++)
|
|
||||||
{
|
|
||||||
FMC_Bank3_R -> PCR |= 1 << 6; /* 使能ECC校验 */
|
|
||||||
|
|
||||||
for (i = 0; i < NAND_ECC_SECTOR_SIZE; i++) /* 写入NAND_ECC_SECTOR_SIZE个数据 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!(FMC_Bank3_R -> SR & (1 << 6))); /* 等待FIFO空 */
|
|
||||||
|
|
||||||
SCB_CleanInvalidateDCache(); /* 清除无效的D-Cache */
|
|
||||||
nand_dev.ecc_hdbuf[res + eccstart] = FMC_Bank3_R -> ECCR; /* 读取硬件计算后的ECC值 */
|
|
||||||
|
|
||||||
FMC_Bank3_R -> PCR &= ~(1 << 6); /* 禁止ECC校验 */
|
|
||||||
}
|
|
||||||
|
|
||||||
i = nand_dev.page_mainsize + 0X10 + eccstart * 4; /*计算写入ECC的spare区地址 */
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = 0X85; /* 随机写指令 */
|
|
||||||
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)i;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(i >> 8);
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
pbuffer = (uint8_t *)&nand_dev.ecc_hdbuf[eccstart];
|
|
||||||
|
|
||||||
for (i = 0; i < eccnum; i++) /* 写入ECC */
|
|
||||||
{
|
|
||||||
for (res = 0; res < 4; res++)
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_WRITE_TURE1;
|
|
||||||
delay_us(NAND_TPROG_DELAY); /* 等待tPROG */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 在NAND一页中的指定地址开始,写入指定长度的恒定数字
|
|
||||||
* @param pagenum : 要写入的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要写入的列开始地址(也就是页内地址),范围:0~(page_totalsize-1)
|
|
||||||
* @param cval : 要写入的指定常数
|
|
||||||
* @param numbytetowrite : 要写入的字节数(以4字节为单位)
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_write_pageconst(uint32_t pagenum, uint16_t colnum, uint32_t cval, uint16_t numbytetowrite)
|
|
||||||
{
|
|
||||||
uint16_t i = 0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_WRITE0;
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)colnum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(colnum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(pagenum >> 16);
|
|
||||||
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
|
|
||||||
for (i = 0; i < numbytetowrite; i++) /* 写入数据,每次写4字节 */
|
|
||||||
{
|
|
||||||
*(__IO uint32_t *)NAND_ADDRESS = cval;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_WRITE_TURE1;
|
|
||||||
delay_us(NAND_TPROG_DELAY); /* 等待tPROG */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将一页数据拷贝到另一页,不写入新数据
|
|
||||||
* @note 源页和目的页要在同一个Plane内!
|
|
||||||
* @param source_pagenum : 源页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param dest_pagenum : 目的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_copypage_withoutwrite(uint32_t source_pagenum, uint32_t dest_pagenum)
|
|
||||||
{
|
|
||||||
uint8_t res = 0;
|
|
||||||
uint16_t source_block = 0, dest_block = 0;
|
|
||||||
/* 判断源页和目的页是否在同一个plane中 */
|
|
||||||
source_block = source_pagenum / nand_dev.block_pagenum;
|
|
||||||
dest_block = dest_pagenum / nand_dev.block_pagenum;
|
|
||||||
|
|
||||||
if ((source_block % 2) != (dest_block % 2))
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 不在同一个plane内 */
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD0; /* 发送命令0X00 */
|
|
||||||
/* 发送源页地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)source_pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(source_pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(source_pagenum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD1; /* 发送命令0X35 */
|
|
||||||
/**
|
|
||||||
* 下面两行代码是等待R/B引脚变为低电平,其实主要起延时作用的,等待NAND操作R/B引脚。因为我们是通过
|
|
||||||
* 将STM32的NWAIT引脚(NAND的R/B引脚)配置为普通IO,代码中通过读取NWAIT引脚的电平来判断NAND是否准备
|
|
||||||
* 就绪的。这个也就是模拟的方法,所以在速度很快的时候有可能NAND还没来得及操作R/B引脚来表示NAND的忙
|
|
||||||
* 闲状态,结果我们就读取了R/B引脚,这个时候肯定会出错的,事实上确实是会出错!大家也可以将下面两行
|
|
||||||
* 代码换成延时函数,只不过这里我们为了效率所以没有用延时函数。
|
|
||||||
*/
|
|
||||||
res = nand_waitrb(0); /* 等待RB=0 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 下面2行代码是真正判断NAND是否准备好的 */
|
|
||||||
res = nand_waitrb(1); /* 等待RB=1 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD2; /* 发送命令0X85 */
|
|
||||||
/* 发送目的页地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)dest_pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(dest_pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(dest_pagenum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD3; /* 发送命令0X10 */
|
|
||||||
delay_us(NAND_TPROG_DELAY); /* 等待tPROG */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* NAND未准备好 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将一页数据拷贝到另一页,并且可以写入数据
|
|
||||||
* @note 源页和目的页要在同一个Plane内!
|
|
||||||
* @param source_pagenum : 源页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param dest_pagenum : 目的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 页内列地址,范围:0~(page_totalsize-1)
|
|
||||||
* @param pbuffer : 要写入的数据
|
|
||||||
* @param numbytetowrite : 要写入的数据个数
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_copypage_withwrite(uint32_t source_pagenum, uint32_t dest_pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbytetowrite)
|
|
||||||
{
|
|
||||||
uint8_t res = 0;
|
|
||||||
__IO uint16_t i = 0;
|
|
||||||
uint16_t source_block = 0, dest_block = 0;
|
|
||||||
uint8_t eccnum = 0; /* 需要计算的ECC个数,每NAND_ECC_SECTOR_SIZE字节计算一个ecc */
|
|
||||||
uint8_t eccstart = 0; /* 第一个ECC值所属的地址范围 */
|
|
||||||
/* 判断源页和目的页是否在同一个plane中 */
|
|
||||||
source_block = source_pagenum / nand_dev.block_pagenum;
|
|
||||||
dest_block = dest_pagenum / nand_dev.block_pagenum;
|
|
||||||
|
|
||||||
if ((source_block % 2) != (dest_block % 2))
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 不在同一个plane内 */
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD0; /* 发送命令0X00 */
|
|
||||||
/* 发送源页地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)0;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)source_pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(source_pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(source_pagenum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD1; /* 发送命令0X35 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 下面两行代码是等待R/B引脚变为低电平,其实主要起延时作用的,等待NAND操作R/B引脚。因为我们是通过
|
|
||||||
* 将STM32的NWAIT引脚(NAND的R/B引脚)配置为普通IO,代码中通过读取NWAIT引脚的电平来判断NAND是否准备
|
|
||||||
* 就绪的。这个也就是模拟的方法,所以在速度很快的时候有可能NAND还没来得及操作R/B引脚来表示NAND的忙
|
|
||||||
* 闲状态,结果我们就读取了R/B引脚,这个时候肯定会出错的,事实上确实是会出错!大家也可以将下面两行
|
|
||||||
* 代码换成延时函数,只不过这里我们为了效率所以没有用延时函数。
|
|
||||||
*/
|
|
||||||
res = nand_waitrb(0); /* 等待RB=0 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 下面2行代码是真正判断NAND是否准备好的 */
|
|
||||||
res = nand_waitrb(1); /* 等待RB=1 */
|
|
||||||
|
|
||||||
if (res)
|
|
||||||
{
|
|
||||||
return NSTA_TIMEOUT; /* 超时退出 */
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD2; /* 发送命令0X85 */
|
|
||||||
/* 发送目的页地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)colnum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(colnum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)dest_pagenum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(dest_pagenum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(dest_pagenum >> 16);
|
|
||||||
/* 发送页内列地址 */
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
|
|
||||||
if (numbytetowrite % NAND_ECC_SECTOR_SIZE) /* 不是NAND_ECC_SECTOR_SIZE的整数倍,不进行ECC校验 */
|
|
||||||
{
|
|
||||||
for (i = 0; i < numbytetowrite; i++) /* 写入数据 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
eccnum = numbytetowrite / NAND_ECC_SECTOR_SIZE; /* 得到ecc计算次数 */
|
|
||||||
eccstart = colnum / NAND_ECC_SECTOR_SIZE;
|
|
||||||
|
|
||||||
for (res = 0; res < eccnum; res++)
|
|
||||||
{
|
|
||||||
FMC_Bank3_R -> PCR |= 1 << 6; /* 使能ECC校验 */
|
|
||||||
|
|
||||||
for (i = 0; i < NAND_ECC_SECTOR_SIZE; i++) /* 写入NAND_ECC_SECTOR_SIZE个数据 */
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!(FMC_Bank3_R -> SR & (1 << 6))); /* 等待FIFO空 */
|
|
||||||
|
|
||||||
SCB_CleanInvalidateDCache(); /* 清除无效的D-Cache */
|
|
||||||
nand_dev.ecc_hdbuf[res + eccstart] = FMC_Bank3_R -> ECCR; /* 读取硬件计算后的ECC值 */
|
|
||||||
|
|
||||||
FMC_Bank3_R -> PCR &= ~(1 << 6); /* 禁止ECC校验 */
|
|
||||||
}
|
|
||||||
|
|
||||||
i = nand_dev.page_mainsize + 0X10 + eccstart * 4; /* 计算写入ECC的spare区地址 */
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = 0X85; /* 随机写指令 */
|
|
||||||
/* 发送地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)i;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(i >> 8);
|
|
||||||
nand_delay(NAND_TADL_DELAY); /* 等待tADL */
|
|
||||||
|
|
||||||
pbuffer = (uint8_t *)&nand_dev.ecc_hdbuf[eccstart];
|
|
||||||
|
|
||||||
for (i = 0; i < eccnum; i++) /* 写入ECC */
|
|
||||||
{
|
|
||||||
for (res = 0; res < 4; res++)
|
|
||||||
{
|
|
||||||
*(__IO uint8_t *)NAND_ADDRESS = *(__IO uint8_t *)pbuffer++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_MOVEDATA_CMD3; /* 发送命令0X10 */
|
|
||||||
delay_us(NAND_TPROG_DELAY); /* 等待tPROG */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取spare区中的数据
|
|
||||||
* @param pagenum : 要写入的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要写入的spare区地址(spare区中哪个地址),范围:0~(page_sparesize-1)
|
|
||||||
* @param pbuffer : 接收数据缓冲区
|
|
||||||
* @param numbytetoread : 要读取的字节数(不大于page_sparesize)
|
|
||||||
* @retval 0,成功; 其他,错误代码
|
|
||||||
*/
|
|
||||||
uint8_t nand_readspare(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbytetoread)
|
|
||||||
{
|
|
||||||
uint8_t temp = 0;
|
|
||||||
uint8_t remainbyte = 0;
|
|
||||||
remainbyte = nand_dev.page_sparesize - colnum;
|
|
||||||
|
|
||||||
if (numbytetoread > remainbyte)
|
|
||||||
{
|
|
||||||
numbytetoread = remainbyte; /* 确保要写入的字节数不大于spare剩余的大小 */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = nand_readpage(pagenum, colnum + nand_dev.page_mainsize, pbuffer, numbytetoread); /* 读取数据 */
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 向spare区中写数据
|
|
||||||
* @param pagenum : 要写入的页地址,范围:0~(block_pagenum*block_totalnum-1)
|
|
||||||
* @param colnum : 要写入的spare区地址(spare区中哪个地址),范围:0~(page_sparesize-1)
|
|
||||||
* @param pbuffer : 要写入的数据首地址
|
|
||||||
* @param numbytetowrite : 要写入的字节数(不大于page_sparesize)
|
|
||||||
* @retval 0,成功; 其他,失败
|
|
||||||
*/
|
|
||||||
uint8_t nand_writespare(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbytetowrite)
|
|
||||||
{
|
|
||||||
uint8_t temp = 0;
|
|
||||||
uint8_t remainbyte = 0;
|
|
||||||
|
|
||||||
remainbyte = nand_dev.page_sparesize - colnum;
|
|
||||||
|
|
||||||
if (numbytetowrite > remainbyte)
|
|
||||||
{
|
|
||||||
numbytetowrite = remainbyte; /* 确保要读取的字节数不大于spare剩余的大小 */
|
|
||||||
}
|
|
||||||
|
|
||||||
temp = nand_writepage(pagenum, colnum + nand_dev.page_mainsize, pbuffer, numbytetowrite); /* 读取 */
|
|
||||||
|
|
||||||
return temp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 擦除一个块
|
|
||||||
* @param blocknum : 要擦除的BLOCK编号,范围:0-(block_totalnum-1)
|
|
||||||
* @retval 0,擦除成功; 其他,擦除失败
|
|
||||||
*/
|
|
||||||
uint8_t nand_eraseblock(uint32_t blocknum)
|
|
||||||
{
|
|
||||||
if (nand_dev.id == MT29F16G08ABABA)
|
|
||||||
{
|
|
||||||
blocknum <<= 7; /* 将块地址转换为页地址 */
|
|
||||||
}
|
|
||||||
else if (nand_dev.id == MT29F4G08ABADA)
|
|
||||||
{
|
|
||||||
blocknum <<= 6;
|
|
||||||
}
|
|
||||||
else if (nand_dev.id == FSNS8B004G)
|
|
||||||
{
|
|
||||||
blocknum <<= 6;
|
|
||||||
}
|
|
||||||
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_ERASE0;
|
|
||||||
/* 发送块地址 */
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)blocknum;
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(blocknum >> 8);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_ADDR) = (uint8_t)(blocknum >> 16);
|
|
||||||
*(__IO uint8_t *)(NAND_ADDRESS | NAND_CMD) = NAND_ERASE1;
|
|
||||||
|
|
||||||
delay_ms(NAND_TBERS_DELAY); /* 等待擦除成功 */
|
|
||||||
|
|
||||||
if (nand_wait_for_ready() != NSTA_READY)
|
|
||||||
{
|
|
||||||
return NSTA_ERROR; /* 失败 */
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0; /* 成功 */
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 全片擦除NAND FLASH
|
|
||||||
* @param 无
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
void nand_erasechip(void)
|
|
||||||
{
|
|
||||||
uint8_t status;
|
|
||||||
uint16_t i = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < nand_dev.block_totalnum; i++) /* 循环擦除所有的块 */
|
|
||||||
{
|
|
||||||
status = nand_eraseblock(i);
|
|
||||||
|
|
||||||
if (status)
|
|
||||||
{
|
|
||||||
printf("Erase %d block fail!!,错误码为%d\r\n", i, status); /* 擦除失败 */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 获取ECC的奇数位/偶数位
|
|
||||||
* @param oe : 0,偶数位; 1,奇数位
|
|
||||||
* @param eccval : 输入的ecc值
|
|
||||||
* @retval 计算后的ecc值(最多16位)
|
|
||||||
*/
|
|
||||||
uint16_t nand_ecc_get_oe(uint8_t oe, uint32_t eccval)
|
|
||||||
{
|
|
||||||
uint8_t i;
|
|
||||||
uint16_t ecctemp = 0;
|
|
||||||
|
|
||||||
for (i = 0; i < 24; i++)
|
|
||||||
{
|
|
||||||
if ((i % 2) == oe)
|
|
||||||
{
|
|
||||||
if ((eccval >> i) & 0X01)
|
|
||||||
{
|
|
||||||
ecctemp += 1 << (i >> 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ecctemp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief ECC校正函数
|
|
||||||
* @param data_buf : 数据缓存区
|
|
||||||
* @param eccrd : 读取出来, 原来保存的ECC值
|
|
||||||
* @param ecccl : 读取数据时, 硬件计算的ECC值
|
|
||||||
* @retval 0,错误已修正; 其他,ECC错误(有大于2个bit的错误,无法恢复)
|
|
||||||
*/
|
|
||||||
uint8_t nand_ecc_correction(uint8_t *data_buf, uint32_t eccrd, uint32_t ecccl)
|
|
||||||
{
|
|
||||||
uint16_t eccrdo, eccrde, eccclo, ecccle;
|
|
||||||
uint16_t eccchk = 0;
|
|
||||||
uint16_t errorpos = 0;
|
|
||||||
uint32_t bytepos = 0;
|
|
||||||
eccrdo = nand_ecc_get_oe(1, eccrd); /* 获取eccrd的奇数位 */
|
|
||||||
eccrde = nand_ecc_get_oe(0, eccrd); /* 获取eccrd的偶数位 */
|
|
||||||
eccclo = nand_ecc_get_oe(1, ecccl); /* 获取ecccl的奇数位 */
|
|
||||||
ecccle = nand_ecc_get_oe(0, ecccl); /* 获取ecccl的偶数位 */
|
|
||||||
eccchk = eccrdo ^ eccrde ^ eccclo ^ ecccle;
|
|
||||||
|
|
||||||
if (eccchk == 0XFFF) /* 全1,说明只有1bit ECC错误 */
|
|
||||||
{
|
|
||||||
errorpos = eccrdo ^ eccclo;
|
|
||||||
printf("errorpos:%d\r\n", errorpos);
|
|
||||||
bytepos = errorpos / 8;
|
|
||||||
data_buf[bytepos] ^= 1 << (errorpos % 8);
|
|
||||||
}
|
|
||||||
else /* 不是全1,说明至少有2bit ECC错误,无法修复 */
|
|
||||||
{
|
|
||||||
printf("2bit ecc error or more\r\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,137 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file nand.h
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2022-09-06
|
|
||||||
* @brief NAND FLASH 驱动代码
|
|
||||||
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20220906
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef _NAND_H
|
|
||||||
#define _NAND_H
|
|
||||||
|
|
||||||
#include "global.h"
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
|
|
||||||
/* 引脚 定义 */
|
|
||||||
#define NAND_RB_GPIO_PORT GPIOD
|
|
||||||
#define NAND_RB_GPIO_PIN GPIO_PIN_6
|
|
||||||
#define NAND_RB_GPIO_CLK_ENABLE() do{ __HAL_RCC_GPIOD_CLK_ENABLE(); }while(0) /* PD口时钟使能 */
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
|
|
||||||
/* IO操作函数 */
|
|
||||||
#define NAND_RB HAL_GPIO_ReadPin(NAND_RB_GPIO_PORT, NAND_RB_GPIO_PIN) /* NAND Flash的闲/忙引脚 */
|
|
||||||
|
|
||||||
#define NAND_MAX_PAGE_SIZE 4096 /* 定义NAND FLASH的最大的PAGE大小(不包括SPARE区),默认4096字节 */
|
|
||||||
#define NAND_ECC_SECTOR_SIZE 512 /* 执行ECC计算的单元大小,默认512字节 */
|
|
||||||
|
|
||||||
|
|
||||||
/* NAND FLASH操作相关延时函数 */
|
|
||||||
#define NAND_TADL_DELAY 30 /* tADL等待延迟,最少70ns */
|
|
||||||
#define NAND_TWHR_DELAY 25 /* tWHR等待延迟,最少60ns */
|
|
||||||
#define NAND_TRHW_DELAY 35 /* tRHW等待延迟,最少100ns */
|
|
||||||
#define NAND_TPROG_DELAY 200 /* tPROG等待延迟,典型值200us,最大需要700us */
|
|
||||||
#define NAND_TBERS_DELAY 4 /* tBERS等待延迟,典型值3.5ms,最大需要10ms */
|
|
||||||
|
|
||||||
|
|
||||||
/* NAND属性结构体 */
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
uint16_t page_totalsize; /* 每页总大小,main区和spare区总和 */
|
|
||||||
uint16_t page_mainsize; /* 每页的main区大小 */
|
|
||||||
uint16_t page_sparesize; /* 每页的spare区大小 */
|
|
||||||
uint8_t block_pagenum; /* 每个块包含的页数量 */
|
|
||||||
uint16_t plane_blocknum; /* 每个plane包含的块数量 */
|
|
||||||
uint16_t block_totalnum; /* 总的块数量 */
|
|
||||||
uint16_t good_blocknum; /* 好块数量 */
|
|
||||||
uint16_t valid_blocknum; /* 有效块数量(供文件系统使用的好块数量) */
|
|
||||||
uint32_t id; /* NAND FLAS*(vu8*)(0X80000000|(1<<17))=CMD;*(vu8*)(0X80000000|(1<<17))=CMD;H ID */
|
|
||||||
uint16_t *lut; /* LUT表,用作逻辑块-物理块转换 */
|
|
||||||
uint32_t ecc_hard; /* 硬件计算出来的ECC值 */
|
|
||||||
uint32_t ecc_hdbuf[NAND_MAX_PAGE_SIZE / NAND_ECC_SECTOR_SIZE]; /* ECC硬件计算值缓冲区 */
|
|
||||||
uint32_t ecc_rdbuf[NAND_MAX_PAGE_SIZE / NAND_ECC_SECTOR_SIZE]; /* ECC读取的值缓冲区 */
|
|
||||||
}nand_attriute;
|
|
||||||
|
|
||||||
extern nand_attriute nand_dev; /* nand重要参数结构体 */
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define NAND_ADDRESS 0X80000000 /* nand flash的访问地址,接NCE3,地址为:0X8000 0000 */
|
|
||||||
#define NAND_CMD 1 << 16 /* 发送命令 */
|
|
||||||
#define NAND_ADDR 1 << 17 /* 发送地址 */
|
|
||||||
|
|
||||||
/* NAND FLASH命令 */
|
|
||||||
#define nand_readID 0X90 /* 读ID指令 */
|
|
||||||
#define NAND_FEATURE 0XEF /* 设置特性指令 */
|
|
||||||
#define NAND_RESET 0XFF /* 复位NAND */
|
|
||||||
#define NAND_READSTA 0X70 /* 读状态 */
|
|
||||||
#define NAND_AREA_A 0X00
|
|
||||||
#define NAND_AREA_TRUE1 0X30
|
|
||||||
#define NAND_WRITE0 0X80
|
|
||||||
#define NAND_WRITE_TURE1 0X10
|
|
||||||
#define NAND_ERASE0 0X60
|
|
||||||
#define NAND_ERASE1 0XD0
|
|
||||||
#define NAND_MOVEDATA_CMD0 0X00
|
|
||||||
#define NAND_MOVEDATA_CMD1 0X35
|
|
||||||
#define NAND_MOVEDATA_CMD2 0X85
|
|
||||||
#define NAND_MOVEDATA_CMD3 0X10
|
|
||||||
|
|
||||||
/* NAND FLASH状态 */
|
|
||||||
#define NSTA_READY 0X40 /* nand已经准备好 */
|
|
||||||
#define NSTA_ERROR 0X01 /* nand错误 */
|
|
||||||
#define NSTA_TIMEOUT 0X02 /* 超时 */
|
|
||||||
#define NSTA_ECC1BITERR 0X03 /* ECC 1bit错误 */
|
|
||||||
#define NSTA_ECC2BITERR 0X04 /* ECC 2bit以上错误 */
|
|
||||||
|
|
||||||
|
|
||||||
/* NAND FLASH型号和对应的ID号 */
|
|
||||||
#define MT29F4G08ABADA 0XDC909556 /* MT29F4G08ABADA */
|
|
||||||
#define MT29F16G08ABABA 0X48002689 /* MT29F16G08ABABA */
|
|
||||||
#define FSNS8B004G 0XDC00A262 /* FSNS8B004G */
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
|
|
||||||
uint8_t nand_init(void);
|
|
||||||
uint8_t nand_modeset(uint8_t mode);
|
|
||||||
void nand_mpu_config(void);
|
|
||||||
uint32_t nand_readid(void);
|
|
||||||
uint8_t nand_readstatus(void);
|
|
||||||
uint8_t nand_wait_for_ready(void);
|
|
||||||
uint8_t nand_reset(void);
|
|
||||||
uint8_t nand_waitrb(volatile uint8_t rb);
|
|
||||||
void nand_delay(volatile uint32_t i);
|
|
||||||
uint8_t nand_readpage(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbyte_to_read);
|
|
||||||
uint8_t nand_readpagecomp(uint32_t pagenum, uint16_t colnum, uint32_t cmpval, uint16_t numbyte_to_read, uint16_t *numbyte_equal);
|
|
||||||
uint8_t nand_writepage(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbyte_to_write);
|
|
||||||
uint8_t nand_write_pageconst(uint32_t pagenum, uint16_t colnum, uint32_t cval, uint16_t numbyte_to_write);
|
|
||||||
uint8_t nand_copypage_withoutwrite(uint32_t source_pagenum, uint32_t dest_pagenum);
|
|
||||||
uint8_t nand_copypage_withwrite(uint32_t source_pagenum, uint32_t dest_pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbyte_to_write);
|
|
||||||
uint8_t nand_readspare(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbyte_to_read);
|
|
||||||
uint8_t nand_writespare(uint32_t pagenum, uint16_t colnum, uint8_t *pbuffer, uint16_t numbyte_to_write);
|
|
||||||
uint8_t nand_eraseblock(uint32_t blocknum);
|
|
||||||
void nand_erasechip(void);
|
|
||||||
|
|
||||||
uint16_t nand_ecc_get_oe(uint8_t oe, uint32_t eccval);
|
|
||||||
uint8_t nand_ecc_correction(uint8_t *data_buf, uint32_t eccrd, uint32_t ecccl);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1,239 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file nandtester.c
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2022-09-06
|
|
||||||
* @brief NAND FLASH USMART测试代码
|
|
||||||
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20220906
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include "string.h"
|
|
||||||
#include "./BSP/NAND/ftl.h"
|
|
||||||
#include "./BSP/NAND/nand.h"
|
|
||||||
#include "./MALLOC/malloc.h"
|
|
||||||
#include "./SYSTEM/usart/usart.h"
|
|
||||||
#include "./BSP/NAND/nandtester.h"
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 向NAND某一页写入指定大小的数据
|
|
||||||
* @param pagenum:要写入的页地址
|
|
||||||
* @param colnum:要写入的开始列地址(页内地址)
|
|
||||||
* @param writebytes:要写入的数据大小,MT29F16G最大为4320,MT29F4G最大为2112
|
|
||||||
* @retval 0,检查成功,全部相等;1,检查失败,有不相等的情况
|
|
||||||
*/
|
|
||||||
uint8_t test_writepage(uint32_t pagenum, uint16_t colnum, uint16_t writebytes)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
pbuf = mymalloc(SRAMIN, 5000);
|
|
||||||
|
|
||||||
for (i = 0; i < writebytes; i++) /* 准备要写入的数据,填充数据,从0开始增大 */
|
|
||||||
{
|
|
||||||
pbuf[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
sta = nand_writepage(pagenum, colnum, pbuf, writebytes); /* 向nand写入数据 */
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取NAND某一页指定大小的数据
|
|
||||||
* @param pagenum : 要读取的页地址
|
|
||||||
* @param colnum : 要读取的开始列地址(页内地址)
|
|
||||||
* @param readbytes : 要读取的数据大小,MT29F16G最大为4320,MT29F4G最大为2112
|
|
||||||
* @retval 操作结果
|
|
||||||
*/
|
|
||||||
uint8_t test_readpage(uint32_t pagenum, uint16_t colnum, uint16_t readbytes)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
|
|
||||||
pbuf = mymalloc(SRAMIN, 5000);
|
|
||||||
sta = nand_readpage(pagenum, colnum, pbuf, readbytes); /* 读取数据 */
|
|
||||||
|
|
||||||
if (sta == 0 || sta == NSTA_ECC1BITERR || sta == NSTA_ECC2BITERR) /* 读取成功 */
|
|
||||||
{
|
|
||||||
printf("read page data is:\r\n");
|
|
||||||
|
|
||||||
for (i = 0; i < readbytes; i++)
|
|
||||||
{
|
|
||||||
printf("%x ", pbuf[i]); /* 串口打印读取到的数据 */
|
|
||||||
}
|
|
||||||
printf("\r\nend\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 将一页数据拷贝到另外一页,并写入一部分内容.
|
|
||||||
* @note 源页和目标页要在同一个Plane内!(同为奇数/同为偶数)
|
|
||||||
* @param spnum : 源页地址
|
|
||||||
* @param epnum : 目标页地址
|
|
||||||
* @param colnum : 要写入的开始列地址(页内地址)
|
|
||||||
* @param writebytes : 要写入的数据大小,不能超过页大小
|
|
||||||
* @retval 操作结果
|
|
||||||
*/
|
|
||||||
uint8_t test_copypageandwrite(uint32_t spnum, uint32_t dpnum, uint16_t colnum, uint16_t writebytes)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
pbuf = mymalloc(SRAMIN, 5000);
|
|
||||||
|
|
||||||
for (i = 0; i < writebytes; i++) /* 准备要写入的数据,填充数据,从0X80开始增大 */
|
|
||||||
{
|
|
||||||
pbuf[i] = i + 0X80;
|
|
||||||
}
|
|
||||||
|
|
||||||
sta = nand_copypage_withwrite(spnum, dpnum, colnum, pbuf, writebytes); /* 向nand写入数据 */
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 读取NAND某一页Spare区指定大小的数据
|
|
||||||
* @param pagenum : 要读取的页地址
|
|
||||||
* @param colnum : 要读取的spare区开始地址
|
|
||||||
* @param readbytes : 要读取的数据大小,MT29F16G最大为64,MT29F4G最大为224
|
|
||||||
* @retval 操作结果
|
|
||||||
*/
|
|
||||||
uint8_t test_readspare(uint32_t pagenum, uint16_t colnum, uint16_t readbytes)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint16_t i = 0;
|
|
||||||
pbuf = mymalloc(SRAMIN, 512);
|
|
||||||
sta = nand_readspare(pagenum, colnum, pbuf, readbytes); /* 读取数据 */
|
|
||||||
|
|
||||||
if (sta == 0) /* 读取成功 */
|
|
||||||
{
|
|
||||||
printf("read spare data is:\r\n");
|
|
||||||
|
|
||||||
for (i = 0; i < readbytes; i++)
|
|
||||||
{
|
|
||||||
printf("%x ", pbuf[i]); /* 串口打印读取到的数据 */
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\r\nend\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从指定位置开始,读取整个NAND,每个BLOCK的第一个page的前5个字节
|
|
||||||
* @param sblock : 指定开始的block编号
|
|
||||||
* @retval 无
|
|
||||||
*/
|
|
||||||
void test_readallblockinfo(uint32_t sblock)
|
|
||||||
{
|
|
||||||
uint8_t j = 0;
|
|
||||||
uint32_t i = 0;
|
|
||||||
uint8_t sta;
|
|
||||||
uint8_t buffer[5];
|
|
||||||
|
|
||||||
for (i = sblock; i < nand_dev.block_totalnum; i++)
|
|
||||||
{
|
|
||||||
printf("block %d info:", i);
|
|
||||||
sta = nand_readspare(i * nand_dev.block_pagenum, 0, buffer, 5); /* 读取每个block,第一个page的前5个字节 */
|
|
||||||
|
|
||||||
if (sta)
|
|
||||||
{
|
|
||||||
printf("failed\r\n");
|
|
||||||
}
|
|
||||||
for (j = 0; j < 5; j++)
|
|
||||||
{
|
|
||||||
printf("%x ", buffer[j]);
|
|
||||||
}
|
|
||||||
printf("\r\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
/* FTL层测试代码 */
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从某个扇区开始,写入seccnt个扇区的数据
|
|
||||||
* @param secx : 开始的扇区编号
|
|
||||||
* @param secsize : 扇区大小
|
|
||||||
* @param seccnt : 要写入的扇区个数
|
|
||||||
* @retval 操作结果
|
|
||||||
*/
|
|
||||||
uint8_t test_ftlwritesectors(uint32_t secx, uint16_t secsize, uint16_t seccnt)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint32_t i = 0;
|
|
||||||
pbuf = mymalloc(SRAMIN, secsize * seccnt);
|
|
||||||
|
|
||||||
for (i = 0; i < secsize * seccnt; i++) /* 准备要写入的数据,填充数据,从0开始增大 */
|
|
||||||
{
|
|
||||||
pbuf[i] = i;
|
|
||||||
}
|
|
||||||
|
|
||||||
sta = ftl_write_sectors(pbuf, secx, secsize, seccnt); /* 向nand写入数据 */
|
|
||||||
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 从某个扇区开始,读出seccnt个扇区的数据
|
|
||||||
* @param secx : 开始的扇区编号
|
|
||||||
* @param secsize : 扇区大小
|
|
||||||
* @param seccnt : 要读取的扇区个数
|
|
||||||
* @retval 操作结果
|
|
||||||
*/
|
|
||||||
uint8_t test_ftlreadsectors(uint32_t secx, uint16_t secsize, uint16_t seccnt)
|
|
||||||
{
|
|
||||||
uint8_t *pbuf;
|
|
||||||
uint8_t sta = 0;
|
|
||||||
uint32_t i = 0;
|
|
||||||
|
|
||||||
pbuf = mymalloc(SRAMIN, secsize * seccnt);
|
|
||||||
sta = ftl_read_sectors(pbuf, secx, secsize, seccnt); /* 读取数据 */
|
|
||||||
|
|
||||||
if (sta == 0)
|
|
||||||
{
|
|
||||||
printf("read sec %d data is:\r\n", secx);
|
|
||||||
|
|
||||||
for (i = 0; i < secsize * seccnt; i++) /* 准备要写入的数据,填充数据,从0开始增大 */
|
|
||||||
{
|
|
||||||
printf("%x ",pbuf[i]); /* 串口打印读取到的数据 */
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("\r\nend\r\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
myfree(SRAMIN, pbuf); /* 释放内存 */
|
|
||||||
|
|
||||||
return sta;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
/**
|
|
||||||
****************************************************************************************************
|
|
||||||
* @file nandtester.h
|
|
||||||
* @author 正点原子团队(ALIENTEK)
|
|
||||||
* @version V1.0
|
|
||||||
* @date 2022-09-06
|
|
||||||
* @brief NAND FLASH USMART测试代码
|
|
||||||
* @license Copyright (c) 2020-2032, 广州市星翼电子科技有限公司
|
|
||||||
****************************************************************************************************
|
|
||||||
* @attention
|
|
||||||
*
|
|
||||||
* 实验平台:正点原子 阿波罗 H743开发板
|
|
||||||
* 在线视频:www.yuanzige.com
|
|
||||||
* 技术论坛:www.openedv.com
|
|
||||||
* 公司网址:www.alientek.com
|
|
||||||
* 购买地址:openedv.taobao.com
|
|
||||||
*
|
|
||||||
* 修改说明
|
|
||||||
* V1.0 20220906
|
|
||||||
* 第一次发布
|
|
||||||
*
|
|
||||||
****************************************************************************************************
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __NANDTESTER_H
|
|
||||||
#define __NANDTESTER_H
|
|
||||||
|
|
||||||
#include "./SYSTEM/sys/sys.h"
|
|
||||||
|
|
||||||
/******************************************************************************************/
|
|
||||||
|
|
||||||
uint8_t test_writepage(uint32_t pagenum, uint16_t colnum, uint16_t writebytes);
|
|
||||||
uint8_t test_readpage(uint32_t pagenum, uint16_t colnum, uint16_t readbytes);
|
|
||||||
uint8_t test_copypageandwrite(uint32_t spnum, uint32_t dpnum, uint16_t colnum, uint16_t writebytes);
|
|
||||||
uint8_t test_readspare(uint32_t pagenum, uint16_t colnum, uint16_t readbytes);
|
|
||||||
void test_readallblockinfo(uint32_t sblock);
|
|
||||||
uint8_t test_ftlwritesectors(uint32_t secx, uint16_t secsize, uint16_t seccnt);
|
|
||||||
uint8_t test_ftlreadsectors(uint32_t secx, uint16_t secsize, uint16_t seccnt);
|
|
||||||
|
|
||||||
#endif
|
|
||||||
132
Core/IPort.ioc
132
Core/IPort.ioc
@@ -65,24 +65,6 @@ ETH.IPParameters=MediaInterface,TxDescAddress,RxDescAddress
|
|||||||
ETH.MediaInterface=HAL_ETH_RMII_MODE
|
ETH.MediaInterface=HAL_ETH_RMII_MODE
|
||||||
ETH.RxDescAddress=0x30040000
|
ETH.RxDescAddress=0x30040000
|
||||||
ETH.TxDescAddress=0x30040060
|
ETH.TxDescAddress=0x30040060
|
||||||
FMC.AttributeSpaceHiZSetupTime1=9
|
|
||||||
FMC.AttributeSpaceHoldSetupTime1=10
|
|
||||||
FMC.AttributeSpaceSetupTime1=9
|
|
||||||
FMC.AttributeSpaceWaitSetupTime1=9
|
|
||||||
FMC.CommonSpaceHiZSetupTime1=9
|
|
||||||
FMC.CommonSpaceHoldSetupTime1=10
|
|
||||||
FMC.CommonSpaceSetupTime1=9
|
|
||||||
FMC.CommonSpaceWaitSetupTime1=9
|
|
||||||
FMC.ECCPageSize1=FMC_NAND_ECC_PAGE_SIZE_512BYTE
|
|
||||||
FMC.IPParameters=TCLRSetupTime1,TARSetupTime1,ECCPageSize1,CommonSpaceSetupTime1,CommonSpaceWaitSetupTime1,CommonSpaceHoldSetupTime1,CommonSpaceHiZSetupTime1,AttributeSpaceSetupTime1,AttributeSpaceWaitSetupTime1,AttributeSpaceHoldSetupTime1,AttributeSpaceHiZSetupTime1,NandPageSize1,NandSpareAreaSize1,NandBlockSize1,NandBlockNbr1,NandPlaneNbr1,NandPlaneSize1
|
|
||||||
FMC.NandBlockNbr1=2048
|
|
||||||
FMC.NandBlockSize1=64
|
|
||||||
FMC.NandPageSize1=2048
|
|
||||||
FMC.NandPlaneNbr1=2
|
|
||||||
FMC.NandPlaneSize1=4096
|
|
||||||
FMC.NandSpareAreaSize1=64
|
|
||||||
FMC.TARSetupTime1=9
|
|
||||||
FMC.TCLRSetupTime1=9
|
|
||||||
FREERTOS.INCLUDE_uxTaskGetStackHighWaterMark=1
|
FREERTOS.INCLUDE_uxTaskGetStackHighWaterMark=1
|
||||||
FREERTOS.INCLUDE_vTaskDelayUntil=1
|
FREERTOS.INCLUDE_vTaskDelayUntil=1
|
||||||
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,configUSE_COUNTING_SEMAPHORES,configTOTAL_HEAP_SIZE,configUSE_TICK_HOOK,configUSE_MALLOC_FAILED_HOOK,configGENERATE_RUN_TIME_STATS,configUSE_TRACE_FACILITY,configUSE_STATS_FORMATTING_FUNCTIONS,INCLUDE_vTaskDelayUntil,INCLUDE_uxTaskGetStackHighWaterMark,configMINIMAL_STACK_SIZE
|
FREERTOS.IPParameters=Tasks01,configENABLE_FPU,configUSE_COUNTING_SEMAPHORES,configTOTAL_HEAP_SIZE,configUSE_TICK_HOOK,configUSE_MALLOC_FAILED_HOOK,configGENERATE_RUN_TIME_STATS,configUSE_TRACE_FACILITY,configUSE_STATS_FORMATTING_FUNCTIONS,INCLUDE_vTaskDelayUntil,INCLUDE_uxTaskGetStackHighWaterMark,configMINIMAL_STACK_SIZE
|
||||||
@@ -134,66 +116,51 @@ Mcu.CPN=STM32H743IIT6
|
|||||||
Mcu.Family=STM32H7
|
Mcu.Family=STM32H7
|
||||||
Mcu.IP0=CORTEX_M7
|
Mcu.IP0=CORTEX_M7
|
||||||
Mcu.IP1=DEBUG
|
Mcu.IP1=DEBUG
|
||||||
Mcu.IP10=SYS
|
Mcu.IP10=USART1
|
||||||
Mcu.IP11=USART1
|
Mcu.IP11=USART3
|
||||||
Mcu.IP12=USART3
|
Mcu.IP12=USART6
|
||||||
Mcu.IP13=USART6
|
|
||||||
Mcu.IP2=DMA
|
Mcu.IP2=DMA
|
||||||
Mcu.IP3=ETH
|
Mcu.IP3=ETH
|
||||||
Mcu.IP4=FMC
|
Mcu.IP4=FREERTOS
|
||||||
Mcu.IP5=FREERTOS
|
Mcu.IP5=LWIP
|
||||||
Mcu.IP6=LWIP
|
Mcu.IP6=MEMORYMAP
|
||||||
Mcu.IP7=MEMORYMAP
|
Mcu.IP7=NVIC
|
||||||
Mcu.IP8=NVIC
|
Mcu.IP8=RCC
|
||||||
Mcu.IP9=RCC
|
Mcu.IP9=SYS
|
||||||
Mcu.IPNb=14
|
Mcu.IPNb=13
|
||||||
Mcu.Name=STM32H743IITx
|
Mcu.Name=STM32H743IITx
|
||||||
Mcu.Package=LQFP176
|
Mcu.Package=LQFP176
|
||||||
Mcu.Pin0=PC14-OSC32_IN (OSC32_IN)
|
Mcu.Pin0=PC14-OSC32_IN (OSC32_IN)
|
||||||
Mcu.Pin1=PC15-OSC32_OUT (OSC32_OUT)
|
Mcu.Pin1=PC15-OSC32_OUT (OSC32_OUT)
|
||||||
Mcu.Pin10=PC4
|
Mcu.Pin10=PC4
|
||||||
Mcu.Pin11=PC5
|
Mcu.Pin11=PC5
|
||||||
Mcu.Pin12=PE7
|
Mcu.Pin12=PB10
|
||||||
Mcu.Pin13=PE8
|
Mcu.Pin13=PB11
|
||||||
Mcu.Pin14=PE9
|
Mcu.Pin14=PH12
|
||||||
Mcu.Pin15=PE10
|
Mcu.Pin15=PB12
|
||||||
Mcu.Pin16=PB10
|
Mcu.Pin16=PB13
|
||||||
Mcu.Pin17=PB11
|
Mcu.Pin17=PB14
|
||||||
Mcu.Pin18=PH12
|
Mcu.Pin18=PB15
|
||||||
Mcu.Pin19=PB12
|
Mcu.Pin19=PA13 (JTMS/SWDIO)
|
||||||
Mcu.Pin2=PH0-OSC_IN (PH0)
|
Mcu.Pin2=PH0-OSC_IN (PH0)
|
||||||
Mcu.Pin20=PB13
|
Mcu.Pin20=PA14 (JTCK/SWCLK)
|
||||||
Mcu.Pin21=PB14
|
Mcu.Pin21=PC10
|
||||||
Mcu.Pin22=PB15
|
Mcu.Pin22=PC11
|
||||||
Mcu.Pin23=PD11
|
Mcu.Pin23=PC12
|
||||||
Mcu.Pin24=PD12
|
Mcu.Pin24=PG9
|
||||||
Mcu.Pin25=PD14
|
Mcu.Pin25=PG14
|
||||||
Mcu.Pin26=PD15
|
Mcu.Pin26=VP_FREERTOS_VS_CMSIS_V1
|
||||||
Mcu.Pin27=PC6
|
Mcu.Pin27=VP_LWIP_VS_Enabled
|
||||||
Mcu.Pin28=PC8
|
Mcu.Pin28=VP_SYS_VS_tim7
|
||||||
Mcu.Pin29=PA13 (JTMS/SWDIO)
|
Mcu.Pin29=VP_MEMORYMAP_VS_MEMORYMAP
|
||||||
Mcu.Pin3=PH1-OSC_OUT (PH1)
|
Mcu.Pin3=PH1-OSC_OUT (PH1)
|
||||||
Mcu.Pin30=PA14 (JTCK/SWCLK)
|
|
||||||
Mcu.Pin31=PC10
|
|
||||||
Mcu.Pin32=PC11
|
|
||||||
Mcu.Pin33=PC12
|
|
||||||
Mcu.Pin34=PD0
|
|
||||||
Mcu.Pin35=PD1
|
|
||||||
Mcu.Pin36=PD4
|
|
||||||
Mcu.Pin37=PD5
|
|
||||||
Mcu.Pin38=PG9
|
|
||||||
Mcu.Pin39=PG14
|
|
||||||
Mcu.Pin4=PC1
|
Mcu.Pin4=PC1
|
||||||
Mcu.Pin40=VP_FREERTOS_VS_CMSIS_V1
|
|
||||||
Mcu.Pin41=VP_LWIP_VS_Enabled
|
|
||||||
Mcu.Pin42=VP_SYS_VS_tim7
|
|
||||||
Mcu.Pin43=VP_MEMORYMAP_VS_MEMORYMAP
|
|
||||||
Mcu.Pin5=PA1
|
Mcu.Pin5=PA1
|
||||||
Mcu.Pin6=PA2
|
Mcu.Pin6=PA2
|
||||||
Mcu.Pin7=PH4
|
Mcu.Pin7=PH4
|
||||||
Mcu.Pin8=PH5
|
Mcu.Pin8=PH5
|
||||||
Mcu.Pin9=PA7
|
Mcu.Pin9=PA7
|
||||||
Mcu.PinsNb=44
|
Mcu.PinsNb=30
|
||||||
Mcu.ThirdPartyNb=0
|
Mcu.ThirdPartyNb=0
|
||||||
Mcu.UserConstants=
|
Mcu.UserConstants=
|
||||||
Mcu.UserName=STM32H743IITx
|
Mcu.UserName=STM32H743IITx
|
||||||
@@ -298,21 +265,6 @@ PC5.GPIOParameters=GPIO_Speed
|
|||||||
PC5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
PC5.GPIO_Speed=GPIO_SPEED_FREQ_VERY_HIGH
|
||||||
PC5.Mode=RMII
|
PC5.Mode=RMII
|
||||||
PC5.Signal=ETH_RXD1
|
PC5.Signal=ETH_RXD1
|
||||||
PC6.Signal=FMC_NWAIT
|
|
||||||
PC8.Mode=NandChipSelect3_1
|
|
||||||
PC8.Signal=FMC_NCE
|
|
||||||
PD0.Signal=FMC_D2_DA2
|
|
||||||
PD1.Signal=FMC_D3_DA3
|
|
||||||
PD11.Signal=FMC_A16_CLE
|
|
||||||
PD12.Signal=FMC_A17_ALE
|
|
||||||
PD14.Signal=FMC_D0_DA0
|
|
||||||
PD15.Signal=FMC_D1_DA1
|
|
||||||
PD4.Signal=FMC_NOE
|
|
||||||
PD5.Signal=FMC_NWE
|
|
||||||
PE10.Signal=FMC_D7_DA7
|
|
||||||
PE7.Signal=FMC_D4_DA4
|
|
||||||
PE8.Signal=FMC_D5_DA5
|
|
||||||
PE9.Signal=FMC_D6_DA6
|
|
||||||
PG14.Locked=true
|
PG14.Locked=true
|
||||||
PG14.Mode=Asynchronous
|
PG14.Mode=Asynchronous
|
||||||
PG14.Signal=USART6_TX
|
PG14.Signal=USART6_TX
|
||||||
@@ -455,32 +407,6 @@ RCC.VCO3OutputFreq_Value=100781250
|
|||||||
RCC.VCOInput1Freq_Value=5000000
|
RCC.VCOInput1Freq_Value=5000000
|
||||||
RCC.VCOInput2Freq_Value=781250
|
RCC.VCOInput2Freq_Value=781250
|
||||||
RCC.VCOInput3Freq_Value=781250
|
RCC.VCOInput3Freq_Value=781250
|
||||||
SH.FMC_A16_CLE.0=FMC_CLE,8b-dmux1
|
|
||||||
SH.FMC_A16_CLE.ConfNb=1
|
|
||||||
SH.FMC_A17_ALE.0=FMC_ALE,8b-dmux1
|
|
||||||
SH.FMC_A17_ALE.ConfNb=1
|
|
||||||
SH.FMC_D0_DA0.0=FMC_D0,8b-dmux1
|
|
||||||
SH.FMC_D0_DA0.ConfNb=1
|
|
||||||
SH.FMC_D1_DA1.0=FMC_D1,8b-dmux1
|
|
||||||
SH.FMC_D1_DA1.ConfNb=1
|
|
||||||
SH.FMC_D2_DA2.0=FMC_D2,8b-dmux1
|
|
||||||
SH.FMC_D2_DA2.ConfNb=1
|
|
||||||
SH.FMC_D3_DA3.0=FMC_D3,8b-dmux1
|
|
||||||
SH.FMC_D3_DA3.ConfNb=1
|
|
||||||
SH.FMC_D4_DA4.0=FMC_D4,8b-dmux1
|
|
||||||
SH.FMC_D4_DA4.ConfNb=1
|
|
||||||
SH.FMC_D5_DA5.0=FMC_D5,8b-dmux1
|
|
||||||
SH.FMC_D5_DA5.ConfNb=1
|
|
||||||
SH.FMC_D6_DA6.0=FMC_D6,8b-dmux1
|
|
||||||
SH.FMC_D6_DA6.ConfNb=1
|
|
||||||
SH.FMC_D7_DA7.0=FMC_D7,8b-dmux1
|
|
||||||
SH.FMC_D7_DA7.ConfNb=1
|
|
||||||
SH.FMC_NOE.0=FMC_NOE,8b-dmux1
|
|
||||||
SH.FMC_NOE.ConfNb=1
|
|
||||||
SH.FMC_NWAIT.0=FMC_NWAIT,Wait1
|
|
||||||
SH.FMC_NWAIT.ConfNb=1
|
|
||||||
SH.FMC_NWE.0=FMC_NWE,8b-dmux1
|
|
||||||
SH.FMC_NWE.ConfNb=1
|
|
||||||
USART1.IPParameters=VirtualMode-Asynchronous
|
USART1.IPParameters=VirtualMode-Asynchronous
|
||||||
USART1.VirtualMode-Asynchronous=VM_ASYNC
|
USART1.VirtualMode-Asynchronous=VM_ASYNC
|
||||||
USART3.IPParameters=VirtualMode-Asynchronous
|
USART3.IPParameters=VirtualMode-Asynchronous
|
||||||
|
|||||||
@@ -44,6 +44,23 @@ virtualFolder:
|
|||||||
- path: ../Middlewares/Third_Party/LwIP/src/apps/http/fs.c
|
- path: ../Middlewares/Third_Party/LwIP/src/apps/http/fs.c
|
||||||
- path: ../Middlewares/Third_Party/LwIP/src/apps/http/fsdata_custom.c
|
- path: ../Middlewares/Third_Party/LwIP/src/apps/http/fsdata_custom.c
|
||||||
folders: []
|
folders: []
|
||||||
|
- name: USB
|
||||||
|
files: []
|
||||||
|
folders:
|
||||||
|
- name: App
|
||||||
|
files:
|
||||||
|
- path: ../USB_DEVICE/App/usb_device.c
|
||||||
|
- path: ../USB_DEVICE/App/usb_device.h
|
||||||
|
- path: ../USB_DEVICE/App/usbd_cdc_if.c
|
||||||
|
- path: ../USB_DEVICE/App/usbd_cdc_if.h
|
||||||
|
- path: ../USB_DEVICE/App/usbd_desc.c
|
||||||
|
- path: ../USB_DEVICE/App/usbd_desc.h
|
||||||
|
folders: []
|
||||||
|
- name: Target
|
||||||
|
files:
|
||||||
|
- path: ../USB_DEVICE/Target/usbd_conf.c
|
||||||
|
- path: ../USB_DEVICE/Target/usbd_conf.h
|
||||||
|
folders: []
|
||||||
- name: User
|
- name: User
|
||||||
files: []
|
files: []
|
||||||
folders:
|
folders:
|
||||||
@@ -107,6 +124,11 @@ virtualFolder:
|
|||||||
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_tim_ex.c
|
||||||
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart.c
|
||||||
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_uart_ex.c
|
||||||
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd.c
|
||||||
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_pcd_ex.c
|
||||||
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_usb.c
|
||||||
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_nand.c
|
||||||
|
- path: ../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c
|
||||||
folders: []
|
folders: []
|
||||||
- name: CMSIS
|
- name: CMSIS
|
||||||
files:
|
files:
|
||||||
@@ -120,6 +142,20 @@ virtualFolder:
|
|||||||
- path: ../Drivers/BSP/Components/yt8512c/yt8512c.c
|
- path: ../Drivers/BSP/Components/yt8512c/yt8512c.c
|
||||||
- path: ../Drivers/BSP/Components/lan8742/lan8742.c
|
- path: ../Drivers/BSP/Components/lan8742/lan8742.c
|
||||||
folders: []
|
folders: []
|
||||||
|
- name: STM32_USB_Device_Library
|
||||||
|
files: []
|
||||||
|
folders:
|
||||||
|
- name: Core
|
||||||
|
files:
|
||||||
|
- path: ../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_core.c
|
||||||
|
- path: ../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ctlreq.c
|
||||||
|
- path: ../Middlewares/ST/STM32_USB_Device_Library/Core/Src/usbd_ioreq.c
|
||||||
|
folders: []
|
||||||
|
- name: CDC
|
||||||
|
files:
|
||||||
|
- path: ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc.c
|
||||||
|
- path: ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Src/usbd_cdc_if_template.c
|
||||||
|
folders: []
|
||||||
- name: Middlewares
|
- name: Middlewares
|
||||||
files: []
|
files: []
|
||||||
folders:
|
folders:
|
||||||
@@ -226,9 +262,6 @@ virtualFolder:
|
|||||||
- path: ../Middlewares/Third_Party/Ykc/server_common.c
|
- path: ../Middlewares/Third_Party/Ykc/server_common.c
|
||||||
- path: ../Middlewares/Third_Party/Ykc/server_to_charger.c
|
- path: ../Middlewares/Third_Party/Ykc/server_to_charger.c
|
||||||
folders: []
|
folders: []
|
||||||
- name: Charger
|
|
||||||
files: []
|
|
||||||
folders: []
|
|
||||||
- name: cJSON
|
- name: cJSON
|
||||||
files:
|
files:
|
||||||
- path: ../Middlewares/Third_Party/cJSON/cJSON.c
|
- path: ../Middlewares/Third_Party/cJSON/cJSON.c
|
||||||
@@ -284,9 +317,15 @@ targets:
|
|||||||
- RTE/_IPort
|
- RTE/_IPort
|
||||||
- ../Middlewares/Third_Party/Ykc
|
- ../Middlewares/Third_Party/Ykc
|
||||||
- ../Middlewares/Third_Party/cJSON
|
- ../Middlewares/Third_Party/cJSON
|
||||||
|
- ../USB_DEVICE/App
|
||||||
|
- ../USB_DEVICE/Target
|
||||||
|
- ../Middlewares/ST/STM32_USB_Device_Library/Class/CDC/Inc
|
||||||
|
- ../Middlewares/ST/STM32_USB_Device_Library/Core/Inc
|
||||||
libList: []
|
libList: []
|
||||||
excludeList:
|
excludeList:
|
||||||
- <virtual_root>/User/Hal/_hal_myi2c.c
|
- <virtual_root>/User/Hal/_hal_myi2c.c
|
||||||
|
settings:
|
||||||
|
debugger: cortex-debug
|
||||||
toolchain: AC5
|
toolchain: AC5
|
||||||
toolchainConfigMap:
|
toolchainConfigMap:
|
||||||
AC5:
|
AC5:
|
||||||
|
|||||||
@@ -28,6 +28,12 @@
|
|||||||
"editor.insertSpaces": true,
|
"editor.insertSpaces": true,
|
||||||
"editor.tabSize": 4,
|
"editor.tabSize": 4,
|
||||||
"editor.autoIndent": "advanced"
|
"editor.autoIndent": "advanced"
|
||||||
|
},
|
||||||
|
"yaml.schemas": {
|
||||||
|
"file:///c%3A/Users/Administrator/.vscode/extensions/continue.continue-1.2.22-win32-x64/config-yaml-schema.json": [
|
||||||
|
".continue/**/*.yaml",
|
||||||
|
"file:///c%3A/Users/Administrator/.continue/config.yaml"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"extensions": {
|
"extensions": {
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
|
<ProjectOpt xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_optx.xsd">
|
||||||
|
|
||||||
<SchemaVersion>1.0</SchemaVersion>
|
<SchemaVersion>1.0</SchemaVersion>
|
||||||
@@ -45,7 +45,7 @@
|
|||||||
<PageWidth>79</PageWidth>
|
<PageWidth>79</PageWidth>
|
||||||
<PageLength>66</PageLength>
|
<PageLength>66</PageLength>
|
||||||
<TabStop>8</TabStop>
|
<TabStop>8</TabStop>
|
||||||
<ListingPath></ListingPath>
|
<ListingPath />
|
||||||
</OPTLEX>
|
</OPTLEX>
|
||||||
<ListingPage>
|
<ListingPage>
|
||||||
<CreateCListing>1</CreateCListing>
|
<CreateCListing>1</CreateCListing>
|
||||||
@@ -104,16 +104,16 @@
|
|||||||
<bSchkAxf>0</bSchkAxf>
|
<bSchkAxf>0</bSchkAxf>
|
||||||
<bTchkAxf>0</bTchkAxf>
|
<bTchkAxf>0</bTchkAxf>
|
||||||
<nTsel>3</nTsel>
|
<nTsel>3</nTsel>
|
||||||
<sDll></sDll>
|
<sDll />
|
||||||
<sDllPa></sDllPa>
|
<sDllPa />
|
||||||
<sDlgDll></sDlgDll>
|
<sDlgDll />
|
||||||
<sDlgPa></sDlgPa>
|
<sDlgPa />
|
||||||
<sIfile></sIfile>
|
<sIfile />
|
||||||
<tDll></tDll>
|
<tDll />
|
||||||
<tDllPa></tDllPa>
|
<tDllPa />
|
||||||
<tDlgDll></tDlgDll>
|
<tDlgDll />
|
||||||
<tDlgPa></tDlgPa>
|
<tDlgPa />
|
||||||
<tIfile></tIfile>
|
<tIfile />
|
||||||
<pMon>BIN\CMSIS_AGDI.dll</pMon>
|
<pMon>BIN\CMSIS_AGDI.dll</pMon>
|
||||||
</DebugOpt>
|
</DebugOpt>
|
||||||
<TargetDriverDllRegistry>
|
<TargetDriverDllRegistry>
|
||||||
@@ -135,12 +135,12 @@
|
|||||||
<SetRegEntry>
|
<SetRegEntry>
|
||||||
<Number>0</Number>
|
<Number>0</Number>
|
||||||
<Key>ARMDBGFLAGS</Key>
|
<Key>ARMDBGFLAGS</Key>
|
||||||
<Name></Name>
|
<Name />
|
||||||
</SetRegEntry>
|
</SetRegEntry>
|
||||||
<SetRegEntry>
|
<SetRegEntry>
|
||||||
<Number>0</Number>
|
<Number>0</Number>
|
||||||
<Key>DLGUARM</Key>
|
<Key>DLGUARM</Key>
|
||||||
<Name></Name>
|
<Name />
|
||||||
</SetRegEntry>
|
</SetRegEntry>
|
||||||
<SetRegEntry>
|
<SetRegEntry>
|
||||||
<Number>0</Number>
|
<Number>0</Number>
|
||||||
@@ -158,7 +158,7 @@
|
|||||||
<Name>-U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(5BA02477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743IITx$CMSIS\Flash\STM32H7x_2048.FLM)</Name>
|
<Name>-U-O142 -O2254 -S0 -C0 -N00("ARM CoreSight SW-DP") -D00(5BA02477) -L00(0) -TO18 -TC10000000 -TP21 -TDS8007 -TDT0 -TDC1F -TIEFFFFFFFF -TIP8 -FO7 -FD20000000 -FC1000 -FN1 -FF0STM32H7x_2048.FLM -FS08000000 -FL0200000 -FP0($$Device:STM32H743IITx$CMSIS\Flash\STM32H7x_2048.FLM)</Name>
|
||||||
</SetRegEntry>
|
</SetRegEntry>
|
||||||
</TargetDriverDllRegistry>
|
</TargetDriverDllRegistry>
|
||||||
<Breakpoint/>
|
<Breakpoint />
|
||||||
<WatchWindow1>
|
<WatchWindow1>
|
||||||
<Ww>
|
<Ww>
|
||||||
<count>0</count>
|
<count>0</count>
|
||||||
@@ -235,19 +235,19 @@
|
|||||||
<newCpu>0</newCpu>
|
<newCpu>0</newCpu>
|
||||||
<uProt>0</uProt>
|
<uProt>0</uProt>
|
||||||
</DebugFlag>
|
</DebugFlag>
|
||||||
<LintExecutable></LintExecutable>
|
<LintExecutable />
|
||||||
<LintConfigFile></LintConfigFile>
|
<LintConfigFile />
|
||||||
<bLintAuto>0</bLintAuto>
|
<bLintAuto>0</bLintAuto>
|
||||||
<bAutoGenD>0</bAutoGenD>
|
<bAutoGenD>0</bAutoGenD>
|
||||||
<LntExFlags>0</LntExFlags>
|
<LntExFlags>0</LntExFlags>
|
||||||
<pMisraName></pMisraName>
|
<pMisraName />
|
||||||
<pszMrule></pszMrule>
|
<pszMrule />
|
||||||
<pSingCmds></pSingCmds>
|
<pSingCmds />
|
||||||
<pMultCmds></pMultCmds>
|
<pMultCmds />
|
||||||
<pMisraNamep></pMisraNamep>
|
<pMisraNamep />
|
||||||
<pszMrulep></pszMrulep>
|
<pszMrulep />
|
||||||
<pSingCmdsp></pSingCmdsp>
|
<pSingCmdsp />
|
||||||
<pMultCmdsp></pMultCmdsp>
|
<pMultCmdsp />
|
||||||
<DebugDescription>
|
<DebugDescription>
|
||||||
<Enable>1</Enable>
|
<Enable>1</Enable>
|
||||||
<EnableFlashSeq>1</EnableFlashSeq>
|
<EnableFlashSeq>1</EnableFlashSeq>
|
||||||
|
|||||||
@@ -1,10 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="project_projx.xsd">
|
<Project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" noNamespaceSchemaLocation="project_projx.xsd">
|
||||||
|
|
||||||
<SchemaVersion>2.1</SchemaVersion>
|
<SchemaVersion>2.1</SchemaVersion>
|
||||||
|
|
||||||
<Header>### uVision Project, (C) Keil Software</Header>
|
<Header>### uVision Project, (C) Keil Software</Header>
|
||||||
|
|
||||||
<Targets>
|
<Targets>
|
||||||
<Target>
|
<Target>
|
||||||
<TargetName>IPort</TargetName>
|
<TargetName>IPort</TargetName>
|
||||||
@@ -20,28 +17,28 @@
|
|||||||
<PackID>Keil.STM32H7xx_DFP.3.0.0</PackID>
|
<PackID>Keil.STM32H7xx_DFP.3.0.0</PackID>
|
||||||
<PackURL>http://www.keil.com/pack/</PackURL>
|
<PackURL>http://www.keil.com/pack/</PackURL>
|
||||||
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x24000000-0x2407FFFF) IROM(0x8000000-0x81FFFFF) CLOCK(12000000) FPU3(DFPU) CPUTYPE("Cortex-M7") ELITTLE TZ</Cpu>
|
<Cpu>IRAM(0x20000000-0x2001FFFF) IRAM2(0x24000000-0x2407FFFF) IROM(0x8000000-0x81FFFFF) CLOCK(12000000) FPU3(DFPU) CPUTYPE("Cortex-M7") ELITTLE TZ</Cpu>
|
||||||
<FlashUtilSpec></FlashUtilSpec>
|
<FlashUtilSpec />
|
||||||
<StartupFile></StartupFile>
|
<StartupFile />
|
||||||
<FlashDriverDll></FlashDriverDll>
|
<FlashDriverDll />
|
||||||
<DeviceId>0</DeviceId>
|
<DeviceId>0</DeviceId>
|
||||||
<RegisterFile></RegisterFile>
|
<RegisterFile />
|
||||||
<MemoryEnv></MemoryEnv>
|
<MemoryEnv />
|
||||||
<Cmp></Cmp>
|
<Cmp />
|
||||||
<Asm></Asm>
|
<Asm />
|
||||||
<Linker></Linker>
|
<Linker />
|
||||||
<OHString></OHString>
|
<OHString />
|
||||||
<InfinionOptionDll></InfinionOptionDll>
|
<InfinionOptionDll />
|
||||||
<SLE66CMisc></SLE66CMisc>
|
<SLE66CMisc />
|
||||||
<SLE66AMisc></SLE66AMisc>
|
<SLE66AMisc />
|
||||||
<SLE66LinkerMisc></SLE66LinkerMisc>
|
<SLE66LinkerMisc />
|
||||||
<SFDFile>$$Device:STM32H743IITx$CMSIS\SVD\STM32H743.svd</SFDFile>
|
<SFDFile>$$Device:STM32H743IITx$CMSIS\SVD\STM32H743.svd</SFDFile>
|
||||||
<bCustSvd>0</bCustSvd>
|
<bCustSvd>0</bCustSvd>
|
||||||
<UseEnv>0</UseEnv>
|
<UseEnv>0</UseEnv>
|
||||||
<BinPath></BinPath>
|
<BinPath />
|
||||||
<IncludePath></IncludePath>
|
<IncludePath />
|
||||||
<LibPath></LibPath>
|
<LibPath />
|
||||||
<RegisterFilePath></RegisterFilePath>
|
<RegisterFilePath />
|
||||||
<DBRegisterFilePath></DBRegisterFilePath>
|
<DBRegisterFilePath />
|
||||||
<TargetStatus>
|
<TargetStatus>
|
||||||
<Error>0</Error>
|
<Error>0</Error>
|
||||||
<ExitCodeStop>0</ExitCodeStop>
|
<ExitCodeStop>0</ExitCodeStop>
|
||||||
@@ -56,15 +53,15 @@
|
|||||||
<CreateHexFile>1</CreateHexFile>
|
<CreateHexFile>1</CreateHexFile>
|
||||||
<DebugInformation>1</DebugInformation>
|
<DebugInformation>1</DebugInformation>
|
||||||
<BrowseInformation>0</BrowseInformation>
|
<BrowseInformation>0</BrowseInformation>
|
||||||
<ListingPath></ListingPath>
|
<ListingPath />
|
||||||
<HexFormatSelection>1</HexFormatSelection>
|
<HexFormatSelection>1</HexFormatSelection>
|
||||||
<Merge32K>0</Merge32K>
|
<Merge32K>0</Merge32K>
|
||||||
<CreateBatchFile>0</CreateBatchFile>
|
<CreateBatchFile>0</CreateBatchFile>
|
||||||
<BeforeCompile>
|
<BeforeCompile>
|
||||||
<RunUserProg1>0</RunUserProg1>
|
<RunUserProg1>0</RunUserProg1>
|
||||||
<RunUserProg2>0</RunUserProg2>
|
<RunUserProg2>0</RunUserProg2>
|
||||||
<UserProg1Name></UserProg1Name>
|
<UserProg1Name />
|
||||||
<UserProg2Name></UserProg2Name>
|
<UserProg2Name />
|
||||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
<nStopU1X>0</nStopU1X>
|
<nStopU1X>0</nStopU1X>
|
||||||
@@ -73,8 +70,8 @@
|
|||||||
<BeforeMake>
|
<BeforeMake>
|
||||||
<RunUserProg1>0</RunUserProg1>
|
<RunUserProg1>0</RunUserProg1>
|
||||||
<RunUserProg2>0</RunUserProg2>
|
<RunUserProg2>0</RunUserProg2>
|
||||||
<UserProg1Name></UserProg1Name>
|
<UserProg1Name />
|
||||||
<UserProg2Name></UserProg2Name>
|
<UserProg2Name />
|
||||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
<nStopB1X>0</nStopB1X>
|
<nStopB1X>0</nStopB1X>
|
||||||
@@ -83,15 +80,15 @@
|
|||||||
<AfterMake>
|
<AfterMake>
|
||||||
<RunUserProg1>0</RunUserProg1>
|
<RunUserProg1>0</RunUserProg1>
|
||||||
<RunUserProg2>1</RunUserProg2>
|
<RunUserProg2>1</RunUserProg2>
|
||||||
<UserProg1Name></UserProg1Name>
|
<UserProg1Name />
|
||||||
<UserProg2Name></UserProg2Name>
|
<UserProg2Name />
|
||||||
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
<UserProg1Dos16Mode>0</UserProg1Dos16Mode>
|
||||||
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
<UserProg2Dos16Mode>0</UserProg2Dos16Mode>
|
||||||
<nStopA1X>0</nStopA1X>
|
<nStopA1X>0</nStopA1X>
|
||||||
<nStopA2X>0</nStopA2X>
|
<nStopA2X>0</nStopA2X>
|
||||||
</AfterMake>
|
</AfterMake>
|
||||||
<SelectedForBatchBuild>1</SelectedForBatchBuild>
|
<SelectedForBatchBuild>1</SelectedForBatchBuild>
|
||||||
<SVCSIdString></SVCSIdString>
|
<SVCSIdString />
|
||||||
</TargetCommonOption>
|
</TargetCommonOption>
|
||||||
<CommonProperty>
|
<CommonProperty>
|
||||||
<UseCPPCompiler>0</UseCPPCompiler>
|
<UseCPPCompiler>0</UseCPPCompiler>
|
||||||
@@ -105,8 +102,8 @@
|
|||||||
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
<AssembleAssemblyFile>0</AssembleAssemblyFile>
|
||||||
<PublicsOnly>0</PublicsOnly>
|
<PublicsOnly>0</PublicsOnly>
|
||||||
<StopOnExitCode>3</StopOnExitCode>
|
<StopOnExitCode>3</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
<CustomArgument />
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
<IncludeLibraryModules />
|
||||||
<ComprImg>0</ComprImg>
|
<ComprImg>0</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<DllOption>
|
<DllOption>
|
||||||
@@ -139,11 +136,11 @@
|
|||||||
</Flash1>
|
</Flash1>
|
||||||
<bUseTDR>1</bUseTDR>
|
<bUseTDR>1</bUseTDR>
|
||||||
<Flash2>BIN\UL2V8M.DLL</Flash2>
|
<Flash2>BIN\UL2V8M.DLL</Flash2>
|
||||||
<Flash3></Flash3>
|
<Flash3 />
|
||||||
<Flash4></Flash4>
|
<Flash4 />
|
||||||
<pFcarmOut></pFcarmOut>
|
<pFcarmOut />
|
||||||
<pFcarmGrp></pFcarmGrp>
|
<pFcarmGrp />
|
||||||
<pFcArmRoot></pFcArmRoot>
|
<pFcArmRoot />
|
||||||
<FcArmLst>0</FcArmLst>
|
<FcArmLst>0</FcArmLst>
|
||||||
</Utilities>
|
</Utilities>
|
||||||
<TargetArmAds>
|
<TargetArmAds>
|
||||||
@@ -176,7 +173,7 @@
|
|||||||
<RvctClst>0</RvctClst>
|
<RvctClst>0</RvctClst>
|
||||||
<GenPPlst>0</GenPPlst>
|
<GenPPlst>0</GenPPlst>
|
||||||
<AdsCpuType>"Cortex-M7"</AdsCpuType>
|
<AdsCpuType>"Cortex-M7"</AdsCpuType>
|
||||||
<RvctDeviceName></RvctDeviceName>
|
<RvctDeviceName />
|
||||||
<mOS>0</mOS>
|
<mOS>0</mOS>
|
||||||
<uocRom>0</uocRom>
|
<uocRom>0</uocRom>
|
||||||
<uocRam>0</uocRam>
|
<uocRam>0</uocRam>
|
||||||
@@ -310,7 +307,7 @@
|
|||||||
<Size>0x80000</Size>
|
<Size>0x80000</Size>
|
||||||
</OCR_RVCT10>
|
</OCR_RVCT10>
|
||||||
</OnChipMemories>
|
</OnChipMemories>
|
||||||
<RvctStartVector></RvctStartVector>
|
<RvctStartVector />
|
||||||
</ArmAdsMisc>
|
</ArmAdsMisc>
|
||||||
<Cads>
|
<Cads>
|
||||||
<interw>1</interw>
|
<interw>1</interw>
|
||||||
@@ -337,9 +334,9 @@
|
|||||||
<v6WtE>0</v6WtE>
|
<v6WtE>0</v6WtE>
|
||||||
<v6Rtti>0</v6Rtti>
|
<v6Rtti>0</v6Rtti>
|
||||||
<VariousControls>
|
<VariousControls>
|
||||||
<MiscControls></MiscControls>
|
<MiscControls />
|
||||||
<Define>USE_HAL_DRIVER,STM32H743xx</Define>
|
<Define>USE_HAL_DRIVER,STM32H743xx</Define>
|
||||||
<Undefine></Undefine>
|
<Undefine />
|
||||||
<IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;../User/Global;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/Driver;../User/Hal;../User/Task;../User/Os;../LWIP/App;../LWIP/Target;../Middlewares/Third_Party/LwIP/src/include;../Middlewares/Third_Party/LwIP/system;../Drivers/BSP/Components/lan8742;../Middlewares/Third_Party/LwIP/src/include/netif/ppp;../Middlewares/Third_Party/LwIP/src/include/lwip;../Middlewares/Third_Party/LwIP/src/include/lwip/apps;../Middlewares/Third_Party/LwIP/src/include/lwip/priv;../Middlewares/Third_Party/LwIP/src/include/lwip/prot;../Middlewares/Third_Party/LwIP/src/include/netif;../Middlewares/Third_Party/LwIP/src/include/compat/posix;../Middlewares/Third_Party/LwIP/src/include/compat/posix/arpa;../Middlewares/Third_Party/LwIP/src/include/compat/posix/net;../Middlewares/Third_Party/LwIP/src/include/compat/posix/sys;../Middlewares/Third_Party/LwIP/src/include/compat/stdc;../Middlewares/Third_Party/LwIP/system/arch;../Drivers/BSP/Components/yt8512c;../Middlewares/Third_Party/Ykc;../Middlewares/Third_Party/easydb/inc</IncludePath>
|
<IncludePath>../Core/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc;../Drivers/STM32H7xx_HAL_Driver/Inc/Legacy;../Drivers/CMSIS/Device/ST/STM32H7xx/Include;../Drivers/CMSIS/Include;../User/Global;../Middlewares/Third_Party/FreeRTOS/Source/include;../Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS;../Middlewares/Third_Party/FreeRTOS/Source/portable/RVDS/ARM_CM4F;../User/Driver;../User/Hal;../User/Task;../User/Os;../LWIP/App;../LWIP/Target;../Middlewares/Third_Party/LwIP/src/include;../Middlewares/Third_Party/LwIP/system;../Drivers/BSP/Components/lan8742;../Middlewares/Third_Party/LwIP/src/include/netif/ppp;../Middlewares/Third_Party/LwIP/src/include/lwip;../Middlewares/Third_Party/LwIP/src/include/lwip/apps;../Middlewares/Third_Party/LwIP/src/include/lwip/priv;../Middlewares/Third_Party/LwIP/src/include/lwip/prot;../Middlewares/Third_Party/LwIP/src/include/netif;../Middlewares/Third_Party/LwIP/src/include/compat/posix;../Middlewares/Third_Party/LwIP/src/include/compat/posix/arpa;../Middlewares/Third_Party/LwIP/src/include/compat/posix/net;../Middlewares/Third_Party/LwIP/src/include/compat/posix/sys;../Middlewares/Third_Party/LwIP/src/include/compat/stdc;../Middlewares/Third_Party/LwIP/system/arch;../Drivers/BSP/Components/yt8512c;../Middlewares/Third_Party/Ykc;../Middlewares/Third_Party/easydb/inc</IncludePath>
|
||||||
</VariousControls>
|
</VariousControls>
|
||||||
</Cads>
|
</Cads>
|
||||||
@@ -355,9 +352,9 @@
|
|||||||
<useXO>0</useXO>
|
<useXO>0</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
<VariousControls>
|
||||||
<MiscControls></MiscControls>
|
<MiscControls />
|
||||||
<Define></Define>
|
<Define />
|
||||||
<Undefine></Undefine>
|
<Undefine />
|
||||||
<IncludePath>../Core/Inc</IncludePath>
|
<IncludePath>../Core/Inc</IncludePath>
|
||||||
</VariousControls>
|
</VariousControls>
|
||||||
</Aads>
|
</Aads>
|
||||||
@@ -368,15 +365,15 @@
|
|||||||
<noStLib>0</noStLib>
|
<noStLib>0</noStLib>
|
||||||
<RepFail>1</RepFail>
|
<RepFail>1</RepFail>
|
||||||
<useFile>0</useFile>
|
<useFile>0</useFile>
|
||||||
<TextAddressRange></TextAddressRange>
|
<TextAddressRange />
|
||||||
<DataAddressRange></DataAddressRange>
|
<DataAddressRange />
|
||||||
<pXoBase></pXoBase>
|
<pXoBase />
|
||||||
<ScatterFile></ScatterFile>
|
<ScatterFile />
|
||||||
<IncludeLibs></IncludeLibs>
|
<IncludeLibs />
|
||||||
<IncludeLibsPath></IncludeLibsPath>
|
<IncludeLibsPath />
|
||||||
<Misc></Misc>
|
<Misc />
|
||||||
<LinkerInputFile></LinkerInputFile>
|
<LinkerInputFile />
|
||||||
<DisabledWarnings></DisabledWarnings>
|
<DisabledWarnings />
|
||||||
</LDads>
|
</LDads>
|
||||||
</TargetArmAds>
|
</TargetArmAds>
|
||||||
</TargetOption>
|
</TargetOption>
|
||||||
@@ -414,62 +411,6 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>../Core/Src/dma.c</FilePath>
|
<FilePath>../Core/Src/dma.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
<File>
|
|
||||||
<FileName>fmc.c</FileName>
|
|
||||||
<FileType>1</FileType>
|
|
||||||
<FilePath>../Core/Src/fmc.c</FilePath>
|
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>1</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds>
|
|
||||||
<Cads>
|
|
||||||
<interw>2</interw>
|
|
||||||
<Optim>0</Optim>
|
|
||||||
<oTime>2</oTime>
|
|
||||||
<SplitLS>2</SplitLS>
|
|
||||||
<OneElfS>2</OneElfS>
|
|
||||||
<Strict>2</Strict>
|
|
||||||
<EnumInt>2</EnumInt>
|
|
||||||
<PlainCh>2</PlainCh>
|
|
||||||
<Ropi>2</Ropi>
|
|
||||||
<Rwpi>2</Rwpi>
|
|
||||||
<wLevel>0</wLevel>
|
|
||||||
<uThumb>2</uThumb>
|
|
||||||
<uSurpInc>2</uSurpInc>
|
|
||||||
<uC99>2</uC99>
|
|
||||||
<uGnu>2</uGnu>
|
|
||||||
<useXO>2</useXO>
|
|
||||||
<v6Lang>0</v6Lang>
|
|
||||||
<v6LangP>0</v6LangP>
|
|
||||||
<vShortEn>2</vShortEn>
|
|
||||||
<vShortWch>2</vShortWch>
|
|
||||||
<v6Lto>2</v6Lto>
|
|
||||||
<v6WtE>2</v6WtE>
|
|
||||||
<v6Rtti>2</v6Rtti>
|
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
|
||||||
</FileArmAds>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
|
||||||
<File>
|
<File>
|
||||||
<FileName>memorymap.c</FileName>
|
<FileName>memorymap.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
@@ -487,8 +428,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<FileArmAds>
|
<FileArmAds>
|
||||||
@@ -516,12 +455,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
</FileArmAds>
|
</FileArmAds>
|
||||||
</FileOption>
|
</FileOption>
|
||||||
@@ -746,118 +679,6 @@
|
|||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
<FilePath>../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c</FilePath>
|
<FilePath>../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_exti.c</FilePath>
|
||||||
</File>
|
</File>
|
||||||
<File>
|
|
||||||
<FileName>stm32h7xx_ll_fmc.c</FileName>
|
|
||||||
<FileType>1</FileType>
|
|
||||||
<FilePath>../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_ll_fmc.c</FilePath>
|
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>1</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds>
|
|
||||||
<Cads>
|
|
||||||
<interw>2</interw>
|
|
||||||
<Optim>0</Optim>
|
|
||||||
<oTime>2</oTime>
|
|
||||||
<SplitLS>2</SplitLS>
|
|
||||||
<OneElfS>2</OneElfS>
|
|
||||||
<Strict>2</Strict>
|
|
||||||
<EnumInt>2</EnumInt>
|
|
||||||
<PlainCh>2</PlainCh>
|
|
||||||
<Ropi>2</Ropi>
|
|
||||||
<Rwpi>2</Rwpi>
|
|
||||||
<wLevel>0</wLevel>
|
|
||||||
<uThumb>2</uThumb>
|
|
||||||
<uSurpInc>2</uSurpInc>
|
|
||||||
<uC99>2</uC99>
|
|
||||||
<uGnu>2</uGnu>
|
|
||||||
<useXO>2</useXO>
|
|
||||||
<v6Lang>0</v6Lang>
|
|
||||||
<v6LangP>0</v6LangP>
|
|
||||||
<vShortEn>2</vShortEn>
|
|
||||||
<vShortWch>2</vShortWch>
|
|
||||||
<v6Lto>2</v6Lto>
|
|
||||||
<v6WtE>2</v6WtE>
|
|
||||||
<v6Rtti>2</v6Rtti>
|
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
|
||||||
</FileArmAds>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
|
||||||
<File>
|
|
||||||
<FileName>stm32h7xx_hal_nand.c</FileName>
|
|
||||||
<FileType>1</FileType>
|
|
||||||
<FilePath>../Drivers/STM32H7xx_HAL_Driver/Src/stm32h7xx_hal_nand.c</FilePath>
|
|
||||||
<FileOption>
|
|
||||||
<CommonProperty>
|
|
||||||
<UseCPPCompiler>2</UseCPPCompiler>
|
|
||||||
<RVCTCodeConst>0</RVCTCodeConst>
|
|
||||||
<RVCTZI>0</RVCTZI>
|
|
||||||
<RVCTOtherData>0</RVCTOtherData>
|
|
||||||
<ModuleSelection>0</ModuleSelection>
|
|
||||||
<IncludeInBuild>1</IncludeInBuild>
|
|
||||||
<AlwaysBuild>2</AlwaysBuild>
|
|
||||||
<GenerateAssemblyFile>2</GenerateAssemblyFile>
|
|
||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
|
||||||
<PublicsOnly>2</PublicsOnly>
|
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
|
||||||
</CommonProperty>
|
|
||||||
<FileArmAds>
|
|
||||||
<Cads>
|
|
||||||
<interw>2</interw>
|
|
||||||
<Optim>0</Optim>
|
|
||||||
<oTime>2</oTime>
|
|
||||||
<SplitLS>2</SplitLS>
|
|
||||||
<OneElfS>2</OneElfS>
|
|
||||||
<Strict>2</Strict>
|
|
||||||
<EnumInt>2</EnumInt>
|
|
||||||
<PlainCh>2</PlainCh>
|
|
||||||
<Ropi>2</Ropi>
|
|
||||||
<Rwpi>2</Rwpi>
|
|
||||||
<wLevel>0</wLevel>
|
|
||||||
<uThumb>2</uThumb>
|
|
||||||
<uSurpInc>2</uSurpInc>
|
|
||||||
<uC99>2</uC99>
|
|
||||||
<uGnu>2</uGnu>
|
|
||||||
<useXO>2</useXO>
|
|
||||||
<v6Lang>0</v6Lang>
|
|
||||||
<v6LangP>0</v6LangP>
|
|
||||||
<vShortEn>2</vShortEn>
|
|
||||||
<vShortWch>2</vShortWch>
|
|
||||||
<v6Lto>2</v6Lto>
|
|
||||||
<v6WtE>2</v6WtE>
|
|
||||||
<v6Rtti>2</v6Rtti>
|
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
|
||||||
</FileArmAds>
|
|
||||||
</FileOption>
|
|
||||||
</File>
|
|
||||||
<File>
|
<File>
|
||||||
<FileName>stm32h7xx_hal_tim.c</FileName>
|
<FileName>stm32h7xx_hal_tim.c</FileName>
|
||||||
<FileType>1</FileType>
|
<FileType>1</FileType>
|
||||||
@@ -905,8 +726,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<GroupArmAds>
|
<GroupArmAds>
|
||||||
@@ -934,12 +753,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
<Aads>
|
<Aads>
|
||||||
<interw>2</interw>
|
<interw>2</interw>
|
||||||
@@ -952,12 +765,6 @@
|
|||||||
<uSurpInc>2</uSurpInc>
|
<uSurpInc>2</uSurpInc>
|
||||||
<useXO>2</useXO>
|
<useXO>2</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
</Aads>
|
||||||
</GroupArmAds>
|
</GroupArmAds>
|
||||||
</GroupOption>
|
</GroupOption>
|
||||||
@@ -1029,8 +836,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<GroupArmAds>
|
<GroupArmAds>
|
||||||
@@ -1058,12 +863,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
<Aads>
|
<Aads>
|
||||||
<interw>2</interw>
|
<interw>2</interw>
|
||||||
@@ -1076,12 +875,6 @@
|
|||||||
<uSurpInc>2</uSurpInc>
|
<uSurpInc>2</uSurpInc>
|
||||||
<useXO>2</useXO>
|
<useXO>2</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
</Aads>
|
||||||
</GroupArmAds>
|
</GroupArmAds>
|
||||||
</GroupOption>
|
</GroupOption>
|
||||||
@@ -1108,8 +901,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<GroupArmAds>
|
<GroupArmAds>
|
||||||
@@ -1137,12 +928,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
<Aads>
|
<Aads>
|
||||||
<interw>2</interw>
|
<interw>2</interw>
|
||||||
@@ -1155,12 +940,6 @@
|
|||||||
<uSurpInc>2</uSurpInc>
|
<uSurpInc>2</uSurpInc>
|
||||||
<useXO>2</useXO>
|
<useXO>2</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
</Aads>
|
||||||
</GroupArmAds>
|
</GroupArmAds>
|
||||||
</GroupOption>
|
</GroupOption>
|
||||||
@@ -1187,8 +966,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<GroupArmAds>
|
<GroupArmAds>
|
||||||
@@ -1216,12 +993,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
<Aads>
|
<Aads>
|
||||||
<interw>2</interw>
|
<interw>2</interw>
|
||||||
@@ -1234,12 +1005,6 @@
|
|||||||
<uSurpInc>2</uSurpInc>
|
<uSurpInc>2</uSurpInc>
|
||||||
<useXO>2</useXO>
|
<useXO>2</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
</Aads>
|
||||||
</GroupArmAds>
|
</GroupArmAds>
|
||||||
</GroupOption>
|
</GroupOption>
|
||||||
@@ -1271,8 +1036,6 @@
|
|||||||
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
<AssembleAssemblyFile>2</AssembleAssemblyFile>
|
||||||
<PublicsOnly>2</PublicsOnly>
|
<PublicsOnly>2</PublicsOnly>
|
||||||
<StopOnExitCode>11</StopOnExitCode>
|
<StopOnExitCode>11</StopOnExitCode>
|
||||||
<CustomArgument></CustomArgument>
|
|
||||||
<IncludeLibraryModules></IncludeLibraryModules>
|
|
||||||
<ComprImg>1</ComprImg>
|
<ComprImg>1</ComprImg>
|
||||||
</CommonProperty>
|
</CommonProperty>
|
||||||
<GroupArmAds>
|
<GroupArmAds>
|
||||||
@@ -1300,12 +1063,6 @@
|
|||||||
<v6Lto>2</v6Lto>
|
<v6Lto>2</v6Lto>
|
||||||
<v6WtE>2</v6WtE>
|
<v6WtE>2</v6WtE>
|
||||||
<v6Rtti>2</v6Rtti>
|
<v6Rtti>2</v6Rtti>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Cads>
|
</Cads>
|
||||||
<Aads>
|
<Aads>
|
||||||
<interw>2</interw>
|
<interw>2</interw>
|
||||||
@@ -1318,12 +1075,6 @@
|
|||||||
<uSurpInc>2</uSurpInc>
|
<uSurpInc>2</uSurpInc>
|
||||||
<useXO>2</useXO>
|
<useXO>2</useXO>
|
||||||
<ClangAsOpt>1</ClangAsOpt>
|
<ClangAsOpt>1</ClangAsOpt>
|
||||||
<VariousControls>
|
|
||||||
<MiscControls></MiscControls>
|
|
||||||
<Define></Define>
|
|
||||||
<Undefine></Undefine>
|
|
||||||
<IncludePath></IncludePath>
|
|
||||||
</VariousControls>
|
|
||||||
</Aads>
|
</Aads>
|
||||||
</GroupArmAds>
|
</GroupArmAds>
|
||||||
</GroupOption>
|
</GroupOption>
|
||||||
@@ -1764,20 +1515,18 @@
|
|||||||
</Groups>
|
</Groups>
|
||||||
</Target>
|
</Target>
|
||||||
</Targets>
|
</Targets>
|
||||||
|
|
||||||
<RTE>
|
<RTE>
|
||||||
<apis/>
|
<apis />
|
||||||
<components>
|
<components>
|
||||||
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="4.3.0" condition="CMSIS Core">
|
<component Cclass="CMSIS" Cgroup="CORE" Cvendor="ARM" Cversion="4.3.0" condition="CMSIS Core">
|
||||||
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="4.5.0"/>
|
<package name="CMSIS" schemaVersion="1.3" url="http://www.keil.com/pack/" vendor="ARM" version="4.5.0" />
|
||||||
<targetInfos>
|
<targetInfos>
|
||||||
<targetInfo name="IPort"/>
|
<targetInfo name="IPort" />
|
||||||
</targetInfos>
|
</targetInfos>
|
||||||
</component>
|
</component>
|
||||||
</components>
|
</components>
|
||||||
<files/>
|
<files />
|
||||||
</RTE>
|
</RTE>
|
||||||
|
|
||||||
<LayerInfo>
|
<LayerInfo>
|
||||||
<Layers>
|
<Layers>
|
||||||
<Layer>
|
<Layer>
|
||||||
@@ -1786,5 +1535,5 @@
|
|||||||
</Layer>
|
</Layer>
|
||||||
</Layers>
|
</Layers>
|
||||||
</LayerInfo>
|
</LayerInfo>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@
|
|||||||
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
; <o> Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
; </h>
|
; </h>
|
||||||
|
|
||||||
Stack_Size EQU 0x2048
|
Stack_Size EQU 0x1000
|
||||||
|
|
||||||
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
AREA STACK, NOINIT, READWRITE, ALIGN=3
|
||||||
Stack_Mem SPACE Stack_Size
|
Stack_Mem SPACE Stack_Size
|
||||||
@@ -40,7 +40,7 @@ __initial_sp
|
|||||||
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
; <o> Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
|
||||||
; </h>
|
; </h>
|
||||||
|
|
||||||
Heap_Size EQU 0x20000
|
Heap_Size EQU 0x2000
|
||||||
|
|
||||||
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
AREA HEAP, NOINIT, READWRITE, ALIGN=3
|
||||||
__heap_base
|
__heap_base
|
||||||
|
|||||||
@@ -19,14 +19,13 @@ void charger_to_server_0X01(uint8_t stake_index)
|
|||||||
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
||||||
data.charger_type = CHARGER_TYPE_DC;
|
data.charger_type = CHARGER_TYPE_DC;
|
||||||
data.gun_num = GUN_NUM;
|
data.gun_num = GUN_NUM;
|
||||||
data.protocol_ver = g_charger_manager.charger_piles[0].login_info.software_ver;
|
data.protocol_ver = g_charger_manager.charger_piles[stake_index - 1].login_info.protocol_ver;
|
||||||
memcpy(data.software_ver, SOFTWARE_VERSION, strlen(SOFTWARE_VERSION));
|
memcpy(data.software_ver, SOFTWARE_VERSION, strlen(SOFTWARE_VERSION));
|
||||||
data.net_conn_type = NET_CONN_TYPE;
|
data.net_conn_type = NET_CONN_TYPE;
|
||||||
data.tele_factory = TELE_FACTORY;
|
data.tele_factory = TELE_FACTORY;
|
||||||
memcpy(data.sim, iccid_ascii, strlen(iccid_ascii));
|
memcpy(data.sim, iccid_ascii, strlen(iccid_ascii));
|
||||||
printf("Frame Type:0x01 充电桩登录认证(桩->平台)");
|
printf("北向:对电桩 %d 发送登录认证,序列号:%s\r\n", stake_index,data.charger_serial);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X01, 0, pack_serial, (uint8_t *)&data, sizeof(PACK_DATA_0X01),stake_index);
|
pack_and_send_server_data(FRAME_TYPE_0X01, stake_index, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X01),stake_index);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -37,9 +36,8 @@ void charger_to_server_0X03(uint8_t stake_index,uint8_t gun_index, uint8_t gun_s
|
|||||||
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
||||||
data.gun_index = gun_index;
|
data.gun_index = gun_index;
|
||||||
data.gun_status = gun_status;
|
data.gun_status = gun_status;
|
||||||
printf("Frame Type:0x03 充电桩心跳包(桩->平台)");
|
printf("北向:对电桩 %d 发送心跳请求,枪号:%d,状态:%d\r\n", stake_index,gun_index,gun_status);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X03, 0, pack_serial, (uint8_t *)&data, sizeof(PACK_DATA_0X03),stake_index);
|
pack_and_send_server_data(FRAME_TYPE_0X03, stake_index, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X03),stake_index);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计费模型验证请求
|
// 计费模型验证请求
|
||||||
@@ -49,9 +47,8 @@ void charger_to_server_0X05(uint16_t num,uint8_t stake_index)
|
|||||||
|
|
||||||
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
||||||
data.fee_model_no = num;
|
data.fee_model_no = num;
|
||||||
printf("Frame Type:0x05 计费模型验证请求(桩->平台)");
|
printf("北向:对电桩 %d 计费模型验证请求,模型号:%d\r\n", stake_index,num);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X05, 0, pack_serial, (uint8_t *)&data, sizeof(PACK_DATA_0X05),stake_index);
|
pack_and_send_server_data(FRAME_TYPE_0X05, stake_index, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X05),stake_index);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 充电桩计费模型请求
|
// 充电桩计费模型请求
|
||||||
@@ -60,24 +57,21 @@ void charger_to_server_0X09(uint8_t stake_index)
|
|||||||
PACK_DATA_0X09 data = {0};
|
PACK_DATA_0X09 data = {0};
|
||||||
|
|
||||||
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
||||||
printf("Frame Type:0x09 充电桩计费模型请求(桩->平台)");
|
printf("北向:对电桩 %d 计费模型请求,序列号:%s\r\n", stake_index,data.charger_serial);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X09, 0, pack_serial, (uint8_t *)&data, sizeof(PACK_DATA_0X09),stake_index);
|
pack_and_send_server_data(FRAME_TYPE_0X09, stake_index, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X09),stake_index);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// 上传实时监测数据
|
// 上传实时监测数据
|
||||||
void charger_to_server_0X13(uint8_t stake_index,uint8_t gun_index)
|
void charger_to_server_0X13(uint8_t stake_index,uint8_t gun_index)
|
||||||
{
|
{
|
||||||
PACK_DATA_0X13 data = {0};
|
|
||||||
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
|
||||||
|
|
||||||
// 加载充电桩交易序列号
|
|
||||||
const unsigned char trade_data[] = {
|
const unsigned char trade_data[] = {
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||||
0x00
|
0x00
|
||||||
};
|
};
|
||||||
|
PACK_DATA_0X13 data = {0};
|
||||||
|
load_charger_serial(stake_index,data.charger_serial); // 加载充电桩序列号
|
||||||
|
|
||||||
data.gun_index = gun_index;
|
data.gun_index = gun_index;
|
||||||
//data.gun_back = getGunBack(All_status[gun_index-1]);
|
//data.gun_back = getGunBack(All_status[gun_index-1]);
|
||||||
@@ -99,9 +93,8 @@ void charger_to_server_0X13(uint8_t stake_index,uint8_t gun_index)
|
|||||||
data.hard_fault = 0;
|
data.hard_fault = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("Frame Type:0x13 上传实时监测数据(桩->平台)");
|
printf("北向:对电桩 %d 上传实时监测数据,枪号:%d,状态:%d,返回:%d,是否插入:%d\r\n", stake_index,gun_index,data.status,data.gun_back,data.gun_is_insert);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X13, 1, pack_serial, (uint8_t *)&data, sizeof(PACK_DATA_0X13),stake_index);
|
pack_and_send_server_data(FRAME_TYPE_0X13, stake_index, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X13),stake_index);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -115,9 +108,8 @@ void charger_to_server_0X33(uint8_t stake_mark,uint8_t gun_index,uint8_t result,
|
|||||||
data.result = result;
|
data.result = result;
|
||||||
data.err_code = err_code;
|
data.err_code = err_code;
|
||||||
|
|
||||||
printf("Frame Type:0x33 平台启动回复(桩->平台)");
|
printf("北向:对电桩 %d 的平台启动回复,结果:%d,错误码:%d\r\n", stake_mark,result,err_code);
|
||||||
pack_and_send_server_data(FRAME_TYPE_0X33,0,pack_serial,(uint8_t *)&data,sizeof(PACK_DATA_0X33),stake_mark);
|
pack_and_send_server_data(FRAME_TYPE_0X33, stake_mark, 0, (uint8_t *)&data, sizeof(PACK_DATA_0X33), stake_mark);
|
||||||
pack_serial++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
22
Core/Middlewares/Third_Party/Ykc/server_common.c
vendored
22
Core/Middlewares/Third_Party/Ykc/server_common.c
vendored
@@ -214,6 +214,7 @@ void pack_and_send_server_data(uint8_t type, uint8_t encrypt, uint16_t serial, u
|
|||||||
{
|
{
|
||||||
uint8_t index = 0;
|
uint8_t index = 0;
|
||||||
uint16_t crc = 0;
|
uint16_t crc = 0;
|
||||||
|
uint16_t current_serial = 0;
|
||||||
uint8_t *buf = NULL;
|
uint8_t *buf = NULL;
|
||||||
buf = (uint8_t *)pvPortMalloc(len + 14);
|
buf = (uint8_t *)pvPortMalloc(len + 14);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
@@ -221,6 +222,12 @@ void pack_and_send_server_data(uint8_t type, uint8_t encrypt, uint16_t serial, u
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* 原子获取全局包序号,避免多任务竞争 */
|
||||||
|
taskENTER_CRITICAL();
|
||||||
|
current_serial = pack_serial;
|
||||||
|
pack_serial++;
|
||||||
|
taskEXIT_CRITICAL();
|
||||||
|
|
||||||
buf[index++] = 0x55;
|
buf[index++] = 0x55;
|
||||||
buf[index++] = 0xAA;
|
buf[index++] = 0xAA;
|
||||||
buf[index++] = 0x01;
|
buf[index++] = 0x01;
|
||||||
@@ -228,8 +235,8 @@ void pack_and_send_server_data(uint8_t type, uint8_t encrypt, uint16_t serial, u
|
|||||||
|
|
||||||
buf[index++] = SERVER_PACK_START_FLAG;
|
buf[index++] = SERVER_PACK_START_FLAG;
|
||||||
buf[index++] = len + 4;
|
buf[index++] = len + 4;
|
||||||
buf[index++] = (serial >> 8) & 0xFF;
|
buf[index++] = (current_serial >> 8) & 0xFF;
|
||||||
buf[index++] = serial & 0xFF;
|
buf[index++] = current_serial & 0xFF;
|
||||||
|
|
||||||
buf[index++] = encrypt;
|
buf[index++] = encrypt;
|
||||||
buf[index++] = type;
|
buf[index++] = type;
|
||||||
@@ -244,10 +251,10 @@ void pack_and_send_server_data(uint8_t type, uint8_t encrypt, uint16_t serial, u
|
|||||||
buf[index++] = 0xAA;
|
buf[index++] = 0xAA;
|
||||||
buf[index++] = 0x55;
|
buf[index++] = 0x55;
|
||||||
|
|
||||||
for (int i = 4; i < index - 2; i++)
|
// for (int i = 4; i < index - 2; i++)
|
||||||
{
|
// {
|
||||||
printf("%02X", buf[i]);
|
// printf("%02X", buf[i]);
|
||||||
}
|
// }
|
||||||
Air724_Message_Send(buf, index);
|
Air724_Message_Send(buf, index);
|
||||||
vPortFree(buf);
|
vPortFree(buf);
|
||||||
}
|
}
|
||||||
@@ -257,7 +264,8 @@ int get_num_from_string(const char *str, int *num)
|
|||||||
int index = 0;
|
int index = 0;
|
||||||
int t = 0;
|
int t = 0;
|
||||||
int flag = 0;
|
int flag = 0;
|
||||||
for (int i = 0; i < len; i++)
|
int i;
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
{
|
{
|
||||||
flag = 0;
|
flag = 0;
|
||||||
while ((str[i] >= '0' && str[i] <= '9') && (i < len))
|
while ((str[i] >= '0' && str[i] <= '9') && (i < len))
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ void on_cmd_frame_type_0X02(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
{
|
{
|
||||||
g_charger_manager.charger_piles[stake_index - 1].is_online = 1;
|
g_charger_manager.charger_piles[stake_index - 1].is_online = 1;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("桩ID %d 登陆成功!\r\n", stake_index);
|
printf("北向:桩ID %d 登陆成功!\r\n", stake_index);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -24,7 +24,7 @@ void on_cmd_frame_type_0X04(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
PACK_DATA_0X04 data;
|
PACK_DATA_0X04 data;
|
||||||
memcpy(&data, pack->data, sizeof(PACK_DATA_0X04));
|
memcpy(&data, pack->data, sizeof(PACK_DATA_0X04));
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("桩ID %d 收到心跳应答!\r\n", stake_index);
|
printf("北向:桩ID %d 收到心跳应答!\r\n", stake_index);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -36,7 +36,7 @@ void on_cmd_frame_type_0X06(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
if (is_my_charger_serial(stake_index, data.charger_serial))
|
if (is_my_charger_serial(stake_index, data.charger_serial))
|
||||||
{
|
{
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("接收到计费模型验证应答,模型ID:%d, 验证结果:%d\r\n", data.fee_model_no, data.result);
|
printf("北向:接收到计费模型验证应答,模型ID:%d, 验证结果:%d\r\n", data.fee_model_no, data.result);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -54,12 +54,12 @@ void on_cmd_frame_type_0X0A(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
printf("接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no);
|
printf("北向:接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no);
|
||||||
printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio);
|
printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio);
|
||||||
printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio);
|
printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio);
|
||||||
printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio);
|
printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio);
|
||||||
printf("谷电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.valley_fee_ratio, g_charger_manager.fee_model_global.valley_service_ratio);
|
printf("谷电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.valley_fee_ratio, g_charger_manager.fee_model_global.valley_service_ratio);
|
||||||
printf("计损比例:%d%%\r\n", g_charger_manager.fee_model_global.loss_ratio);
|
printf("计损比例: %d%% \r\n", g_charger_manager.fee_model_global.loss_ratio);
|
||||||
|
|
||||||
printf("\n合并后的费率时间段:\r\n");
|
printf("\n合并后的费率时间段:\r\n");
|
||||||
printf("================================================================\r\n");
|
printf("================================================================\r\n");
|
||||||
@@ -111,7 +111,7 @@ void on_cmd_frame_type_0X0A(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
end_hour = 0;
|
end_hour = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%02d:%02d-%02d:%02d 为 %s费率\r",
|
printf("%02d:%02d-%02d:%02d 为 %s 费率\r\n",
|
||||||
start_hour, start_min,
|
start_hour, start_min,
|
||||||
end_hour, end_min,
|
end_hour, end_min,
|
||||||
fee_name);
|
fee_name);
|
||||||
@@ -137,21 +137,12 @@ void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
char str[150];
|
char str[150];
|
||||||
Rs485_Message_Send("t0.txt=\"\"\xff\xff\xff", 12);
|
Rs485_Message_Send("t0.txt=\"\"\xff\xff\xff", 12);
|
||||||
printf("接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no);
|
printf("北向:接收到计费模型应答,模型ID:%d\r\n", g_charger_manager.fee_model_global.fee_model_no);
|
||||||
printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio);
|
printf("尖电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio);
|
||||||
printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio);
|
printf("峰电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio);
|
||||||
printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio);
|
printf("平电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio);
|
||||||
printf("谷电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.valley_fee_ratio, g_charger_manager.fee_model_global.valley_service_ratio);
|
printf("谷电费率:%d 服务费:%d\r\n", g_charger_manager.fee_model_global.valley_fee_ratio, g_charger_manager.fee_model_global.valley_service_ratio);
|
||||||
printf("计损比例:%d%%\r\n", g_charger_manager.fee_model_global.loss_ratio);
|
printf("计损比例: %d%% \r\n", g_charger_manager.fee_model_global.loss_ratio);
|
||||||
|
|
||||||
sprintf(str, "t0.txt+=\"尖电费 %d 服务费 %d \r\n峰电费 %d 服务费 %d \r\n平电费 %d 服务费 %d \r\n谷电费 %d 服务费 %d \r\n计损比例 %d%%\r\n\"\xff\xff\xff",
|
|
||||||
g_charger_manager.fee_model_global.shark_fee_ratio, g_charger_manager.fee_model_global.shark_service_ratio,
|
|
||||||
g_charger_manager.fee_model_global.peak_fee_ratio, g_charger_manager.fee_model_global.peak_service_ratio,
|
|
||||||
g_charger_manager.fee_model_global.flat_fee_ratio, g_charger_manager.fee_model_global.flat_service_ratio,
|
|
||||||
g_charger_manager.fee_model_global.valley_fee_ratio, g_charger_manager.fee_model_global.valley_service_ratio,
|
|
||||||
g_charger_manager.fee_model_global.loss_ratio);
|
|
||||||
Rs485_Message_Send(str, strlen(str));
|
|
||||||
|
|
||||||
printf("\n合并后的费率时间段:\r\n");
|
printf("\n合并后的费率时间段:\r\n");
|
||||||
printf("================================================================\r\n");
|
printf("================================================================\r\n");
|
||||||
|
|
||||||
@@ -202,17 +193,10 @@ void on_cmd_frame_type_0X58(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
end_hour = 0;
|
end_hour = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
printf("%02d:%02d-%02d:%02d 为 %s费率\r",
|
printf("%02d:%02d-%02d:%02d 为 %s 费率\r",
|
||||||
start_hour, start_min,
|
start_hour, start_min,
|
||||||
end_hour, end_min,
|
end_hour, end_min,
|
||||||
fee_name);
|
fee_name);
|
||||||
|
|
||||||
sprintf(str, "t0.txt+=\"%02d:%02d-%02d:%02d 为 %s费率 \r\n\"\xff\xff\xff",
|
|
||||||
start_hour, start_min,
|
|
||||||
end_hour, end_min,
|
|
||||||
fee_name);
|
|
||||||
Rs485_Message_Send(str, strlen(str));
|
|
||||||
|
|
||||||
i = j; // 跳到下一个不同费率段
|
i = j; // 跳到下一个不同费率段
|
||||||
}
|
}
|
||||||
printf("================================================================\r\n");
|
printf("================================================================\r\n");
|
||||||
@@ -227,7 +211,8 @@ void on_cmd_frame_type_0X34(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
uint8_t result = 1;
|
uint8_t result = 1;
|
||||||
uint8_t err_code = 0;
|
uint8_t err_code = 0;
|
||||||
memcpy(&data, pack->data, sizeof(PACK_DATA_0X34));
|
memcpy(&data, pack->data, sizeof(PACK_DATA_0X34));
|
||||||
set_trade_serial(data.gun_index, data.trade_serial, stake_index);
|
set_trade_serial(stake_index,data.gun_index, data.trade_serial);
|
||||||
|
printf("北向:平台控制充电,桩ID:%d, 枪ID:%d, 金额:%d\r\n", stake_index, data.gun_index, data.remain_money);
|
||||||
|
|
||||||
if (!is_my_charger_serial(stake_index, data.charger_serial))
|
if (!is_my_charger_serial(stake_index, data.charger_serial))
|
||||||
{
|
{
|
||||||
@@ -257,6 +242,7 @@ void on_cmd_frame_type_0X34(uint8_t stake_index, SERVER_PACK *pack)
|
|||||||
// set_charge_start_mode(data.gun_index - 1, CAHRGE_START_MODE_APP);
|
// set_charge_start_mode(data.gun_index - 1, CAHRGE_START_MODE_APP);
|
||||||
// update_remain_money_to_gun(data.gun_index - 1, data.remain_money);
|
// update_remain_money_to_gun(data.gun_index - 1, data.remain_money);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
charger_to_server_0X33(stake_index, data.gun_index, result, err_code);
|
charger_to_server_0X33(stake_index, data.gun_index, result, err_code);
|
||||||
}
|
}
|
||||||
#if 0
|
#if 0
|
||||||
|
|||||||
@@ -9,11 +9,34 @@
|
|||||||
*/
|
*/
|
||||||
/* Includes -------------------------------------------------------------------*/
|
/* Includes -------------------------------------------------------------------*/
|
||||||
#include "drv_init.h"
|
#include "drv_init.h"
|
||||||
// crc16_modbus.c
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
/* code -----------------------------------------------------------------------*/
|
/* code -----------------------------------------------------------------------*/
|
||||||
|
void send_cmd_to_air724(uint8_t *cmd, uint16_t len)
|
||||||
|
{
|
||||||
|
Air724_Message_Send(cmd, len);
|
||||||
|
}
|
||||||
|
void send_server_address_to_air724(void)
|
||||||
|
{
|
||||||
|
char ip[] = YKC_SERVER_IP;
|
||||||
|
char port[6];
|
||||||
|
sprintf(port, "%d", YKC_SERVER_PORT);
|
||||||
|
|
||||||
|
uint8_t len = strlen(ip) + 1 + strlen(port);
|
||||||
|
uint8_t config_cmd[256] = {0x55, 0xAA, 0x04, 0x00, len};
|
||||||
|
|
||||||
|
uint8_t pos = 5;
|
||||||
|
memcpy(&config_cmd[pos], ip, strlen(ip));
|
||||||
|
pos += strlen(ip);
|
||||||
|
config_cmd[pos++] = 0x00;
|
||||||
|
memcpy(&config_cmd[pos], port, strlen(port));
|
||||||
|
pos += strlen(port);
|
||||||
|
config_cmd[pos++] = 0xAA;
|
||||||
|
config_cmd[pos++] = 0x55;
|
||||||
|
send_cmd_to_air724(config_cmd, pos);
|
||||||
|
pos = 0;
|
||||||
|
memset(config_cmd, 0, sizeof(config_cmd));
|
||||||
|
}
|
||||||
/**
|
/**
|
||||||
* @brief drv_all_Init:所有传感器、外设芯片、外部设备初始化
|
* @brief drv_all_Init:所有传感器、外设芯片、外部设备初始化
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -10,6 +10,5 @@
|
|||||||
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
/* Exported functions prototypes ------------------------------------------------------------------------*/
|
||||||
void drv_all_Init(void);
|
void drv_all_Init(void);
|
||||||
|
|
||||||
|
|
||||||
#endif /* __DRVINIT_H */
|
#endif /* __DRVINIT_H */
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ const uint8_t piles_serial[6][7] = {
|
|||||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x03},
|
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x03},
|
||||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x04},
|
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x04},
|
||||||
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x05},
|
{0x88, 0x26, 0x01, 0x13, 0x12, 0x00, 0x05},
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
/* includes ----------------------------------------------------------------------------------------------*/
|
/* includes ----------------------------------------------------------------------------------------------*/
|
||||||
#include "global.h"
|
#include "global.h"
|
||||||
|
|
||||||
#define MAX_CHARGER_COUNT 6 // 充电桩数量
|
#define MAX_CHARGER_COUNT 2 // 充电桩数量
|
||||||
#define MAX_GUN_PER_CHARGER 2 // 每个充电桩最多枪数
|
#define MAX_GUN_PER_CHARGER 2 // 每个充电桩最多枪数
|
||||||
|
|
||||||
/* 充电枪结构体*/
|
/* 充电枪结构体*/
|
||||||
|
|||||||
@@ -28,8 +28,6 @@
|
|||||||
#include "usart.h"
|
#include "usart.h"
|
||||||
#include "gpio.h"
|
#include "gpio.h"
|
||||||
|
|
||||||
// #include "tim.h"
|
|
||||||
|
|
||||||
/* freeRTOS 相关 */
|
/* freeRTOS 相关 */
|
||||||
#include "cmsis_os.h"
|
#include "cmsis_os.h"
|
||||||
#include "FreeRTOS.h"
|
#include "FreeRTOS.h"
|
||||||
@@ -72,6 +70,9 @@
|
|||||||
|
|
||||||
#define DEBUG 1 // 调试模式
|
#define DEBUG 1 // 调试模式
|
||||||
|
|
||||||
|
#define YKC_SERVER_IP "121.43.69.62" // YKC 服务器 IP 地址
|
||||||
|
#define YKC_SERVER_PORT 8767 // YKC 服务器端口号
|
||||||
|
|
||||||
/*- I/O 输出-*/
|
/*- I/O 输出-*/
|
||||||
|
|
||||||
#define AIR724_RESET() \
|
#define AIR724_RESET() \
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ uint8_t uart1_tx_buffer[UART1_TX_BUFFER_SIZE];
|
|||||||
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
|
uint8_t uart3_rx_buffer[UART3_RX_BUFFER_SIZE];
|
||||||
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
|
uint8_t uart3_tx_buffer[UART3_TX_BUFFER_SIZE];
|
||||||
|
|
||||||
|
static SemaphoreHandle_t air724_tx_mutex = NULL;
|
||||||
|
|
||||||
/* code -----------------------------------------------------------------------*/
|
/* code -----------------------------------------------------------------------*/
|
||||||
/**
|
/**
|
||||||
* @brief fputc:printf映射
|
* @brief fputc:printf映射
|
||||||
@@ -46,7 +48,18 @@ int fputc(int ch, FILE *f)
|
|||||||
*/
|
*/
|
||||||
void Air724_Message_Send(uint8_t *data, uint16_t len)
|
void Air724_Message_Send(uint8_t *data, uint16_t len)
|
||||||
{
|
{
|
||||||
HAL_UART_Transmit(&huart1, data, len, HAL_MAX_DELAY);
|
if (air724_tx_mutex != NULL)
|
||||||
|
{
|
||||||
|
if (xSemaphoreTake(air724_tx_mutex, portMAX_DELAY) == pdTRUE)
|
||||||
|
{
|
||||||
|
HAL_UART_Transmit(&huart1, data, len, HAL_MAX_DELAY);
|
||||||
|
xSemaphoreGive(air724_tx_mutex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
HAL_UART_Transmit(&huart1, data, len, HAL_MAX_DELAY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Rs485_Message_Send(uint8_t *data, uint16_t len)
|
void Rs485_Message_Send(uint8_t *data, uint16_t len)
|
||||||
@@ -68,6 +81,7 @@ void Rs485_Message_Send(uint8_t *data, uint16_t len)
|
|||||||
|
|
||||||
void hal_usart_Init(void)
|
void hal_usart_Init(void)
|
||||||
{
|
{
|
||||||
|
air724_tx_mutex = xSemaphoreCreateMutex();
|
||||||
|
|
||||||
/* 初始化串口1 */
|
/* 初始化串口1 */
|
||||||
Air724_Message_Queue_Init(); // 初始化4G数据接收队列
|
Air724_Message_Queue_Init(); // 初始化4G数据接收队列
|
||||||
|
|||||||
@@ -89,7 +89,7 @@ void UDP_ParseTask_Function(void const *argument)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
printf("Missing 'code' field\r\n");
|
printf("Missing 'code' field from \r\n");
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
}
|
}
|
||||||
vPortFree(msg.data);
|
vPortFree(msg.data);
|
||||||
@@ -145,6 +145,7 @@ void UDPTask_Function(void const *argument)
|
|||||||
{
|
{
|
||||||
memcpy(msg.data, playload, playload_len);
|
memcpy(msg.data, playload, playload_len);
|
||||||
msg.data[playload_len] = '\0';
|
msg.data[playload_len] = '\0';
|
||||||
|
// 队列满,释放数据内存
|
||||||
if (xQueueSend(UDP_Message_Queue, &msg, 0) != pdPASS)
|
if (xQueueSend(UDP_Message_Queue, &msg, 0) != pdPASS)
|
||||||
{
|
{
|
||||||
vPortFree(msg.data);
|
vPortFree(msg.data);
|
||||||
@@ -178,6 +179,70 @@ void local_on_cmd_callback_power_on(uint8_t stake_index, cJSON *json_pack)
|
|||||||
g_charger_manager.charger_piles[stake_index - 1].is_udp_online = true; // 设置桩为本地在线状态
|
g_charger_manager.charger_piles[stake_index - 1].is_udp_online = true; // 设置桩为本地在线状态
|
||||||
|
|
||||||
cJSON *root = NULL;
|
cJSON *root = NULL;
|
||||||
|
uint8_t *str = NULL;
|
||||||
|
|
||||||
|
root = cJSON_CreateObject();
|
||||||
|
if (root == NULL)
|
||||||
|
{
|
||||||
|
printf("Failed to create JSON object for stake %d\r\n", stake_index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
|
||||||
|
cJSON_AddNumberToObject(root, "id", stake_index);
|
||||||
|
cJSON_AddStringToObject(root, "cmd", "online");
|
||||||
|
cJSON_AddStringToObject(root, "type", "response");
|
||||||
|
|
||||||
|
str = cJSON_Print(root);
|
||||||
|
udp_send_response(stake_index, str, strlen(str));
|
||||||
|
free(str);
|
||||||
|
cJSON_Delete(root);
|
||||||
|
|
||||||
|
printf("南向:对电桩 %d 上电回复成功\r\n", stake_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief 解析充电桩心跳指令
|
||||||
|
* @note 回复心跳应答
|
||||||
|
* @param stake_index 桩索引
|
||||||
|
* @param json_pack json数据包
|
||||||
|
*/
|
||||||
|
void local_on_cmd_callback_heartbeat_response(uint8_t stake_index, cJSON *json_pack)
|
||||||
|
{
|
||||||
|
if (stake_index > 6)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//心跳unpack
|
||||||
|
|
||||||
|
cJSON *gun_array = cJSON_GetObjectItem(json_pack, "gun");
|
||||||
|
// 直接判断 type 字段
|
||||||
|
if (gun_array == NULL || gun_array->type != cJSON_Array)
|
||||||
|
{
|
||||||
|
printf(" └── [error] 缺少 gun 数组\r\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int gun_count = cJSON_GetArraySize(gun_array);
|
||||||
|
for (int i = 0; i < gun_count; i++)
|
||||||
|
{
|
||||||
|
cJSON *gun = cJSON_GetArrayItem(gun_array, i);
|
||||||
|
if (!gun) continue;
|
||||||
|
|
||||||
|
cJSON *id = cJSON_GetObjectItem(gun, "id");
|
||||||
|
cJSON *state = cJSON_GetObjectItem(gun, "state");
|
||||||
|
|
||||||
|
if (!id || !state) continue;
|
||||||
|
|
||||||
|
// if (id->valueint == 1) pile->gun1_state = state->valueint;
|
||||||
|
// if (id->valueint == 2) pile->gun2_state = state->valueint;
|
||||||
|
printf(" └── [info] 桩%d 枪%d state=%d\r\n", stake_index, id->valueint, state->valueint);
|
||||||
|
}
|
||||||
|
|
||||||
|
//心跳回复组包
|
||||||
|
cJSON *root = NULL;
|
||||||
char *str = NULL;
|
char *str = NULL;
|
||||||
|
|
||||||
root = cJSON_CreateObject();
|
root = cJSON_CreateObject();
|
||||||
@@ -189,29 +254,15 @@ void local_on_cmd_callback_power_on(uint8_t stake_index, cJSON *json_pack)
|
|||||||
|
|
||||||
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
|
/* 添加一条字符串类型的JSON数据(添加一个链表节点) */
|
||||||
cJSON_AddNumberToObject(root, "id", stake_index);
|
cJSON_AddNumberToObject(root, "id", stake_index);
|
||||||
cJSON_AddStringToObject(root, "cmd", "power_on");
|
cJSON_AddStringToObject(root, "cmd", "heartbeat");
|
||||||
cJSON_AddNumberToObject(root, "code", 1);
|
cJSON_AddStringToObject(root, "type", "response");
|
||||||
|
|
||||||
str = cJSON_Print(root);
|
str = cJSON_Print(root);
|
||||||
udp_send_response(stake_index, str, strlen(str));
|
udp_send_response(stake_index, str, strlen(str));
|
||||||
free(str);
|
free(str);
|
||||||
cJSON_Delete(root);
|
cJSON_Delete(root);
|
||||||
|
|
||||||
printf("电桩 %d 上电报文\r\n", stake_index);
|
printf("南向:对电桩 %d 心跳回复成功\r\n", stake_index);
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 解析充电桩计费模型请求指令
|
|
||||||
* @note 获取云快充下发的计费模型,回复给充电桩
|
|
||||||
* @param stake_index 桩索引
|
|
||||||
* @param json_pack json数据包
|
|
||||||
*/
|
|
||||||
void local_on_cmd_callback_get_billing_model(uint8_t stake_index, cJSON *json_pack)
|
|
||||||
{
|
|
||||||
if (stake_index > 6)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -220,13 +271,17 @@ void handle_udp_downlink(uint8_t id, const char *cmd, cJSON *json_pack)
|
|||||||
{
|
{
|
||||||
if (cmd == NULL)
|
if (cmd == NULL)
|
||||||
return;
|
return;
|
||||||
if (strcmp(cmd, "power_on") == 0)
|
// 处理上电指令
|
||||||
|
if (strcmp(cmd, "online") == 0)
|
||||||
{
|
{
|
||||||
|
printf("南向:收到电桩 %d 上电指令\r\n", id);
|
||||||
local_on_cmd_callback_power_on(id, json_pack);
|
local_on_cmd_callback_power_on(id, json_pack);
|
||||||
}
|
}
|
||||||
else if (strcmp(cmd, "get_billing_model") == 0)
|
// 处理心跳指令
|
||||||
|
else if (strcmp(cmd, "heartbeat") == 0)
|
||||||
{
|
{
|
||||||
local_on_cmd_callback_get_billing_model(id, json_pack);
|
printf("南向:收到电桩 %d 心跳指令\r\n", id);
|
||||||
|
local_on_cmd_callback_heartbeat_response(id, json_pack);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -45,7 +45,6 @@ void DownLinkTask_Function(void const *argument)
|
|||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
/*---------------------------------------------------获取任务运行状态---------------------------------------------------*/
|
/*---------------------------------------------------获取任务运行状态---------------------------------------------------*/
|
||||||
|
|
||||||
TaskRunTimeStat.DownLinkTask.threads_runtime = GetTask_RunTime(DownLinkTaskID);
|
TaskRunTimeStat.DownLinkTask.threads_runtime = GetTask_RunTime(DownLinkTaskID);
|
||||||
TaskRunTimeStat.DownLinkTask.threads_counter = GetTask_Beatcnt(DownLinkTaskID);
|
TaskRunTimeStat.DownLinkTask.threads_counter = GetTask_Beatcnt(DownLinkTaskID);
|
||||||
TaskRunTimeStat.DownLinkTask.threads_freestack = Get_Free_Stack(DownLinkTaskID);
|
TaskRunTimeStat.DownLinkTask.threads_freestack = Get_Free_Stack(DownLinkTaskID);
|
||||||
@@ -74,22 +73,30 @@ void DownLinkTask_Function(void const *argument)
|
|||||||
memcpy(frame.data, ykc_downlink_frame + HEADER_LENGTH, frame.len - 4);
|
memcpy(frame.data, ykc_downlink_frame + HEADER_LENGTH, frame.len - 4);
|
||||||
frame.crc = (ykc_downlink_frame[HEADER_LENGTH + frame.len] << 8) | ykc_downlink_frame[HEADER_LENGTH + frame.len + 1];
|
frame.crc = (ykc_downlink_frame[HEADER_LENGTH + frame.len] << 8) | ykc_downlink_frame[HEADER_LENGTH + frame.len + 1];
|
||||||
|
|
||||||
printf("Raw Bytes: ");
|
// printf("Raw Bytes: ");
|
||||||
for (int i = 0; i < ykc_downlink_frame_len; i++)
|
// for (int i = 0; i < ykc_downlink_frame_len; i++)
|
||||||
{
|
// {
|
||||||
printf("%02X ", ykc_downlink_frame[i]);
|
// printf("%02X ", ykc_downlink_frame[i]);
|
||||||
if ((i + 1) % 16 == 0) // 每16字节换行
|
// if ((i + 1) % 16 == 0) // 每16字节换行
|
||||||
{
|
// {
|
||||||
printf("\r");
|
// printf("\r");
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
printf("\r");
|
// printf("\r");
|
||||||
|
|
||||||
handle_ykc_downlink(charger_index, &frame);
|
handle_ykc_downlink(charger_index, &frame);
|
||||||
|
|
||||||
vPortFree(frame.data);
|
vPortFree(frame.data);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case 0x83:
|
||||||
|
{
|
||||||
|
if (air724_rx_msg[3] == 0x01)
|
||||||
|
printf("4G:Socket %d 通道连接成功\r\n", air724_rx_msg[4]);
|
||||||
|
if (air724_rx_msg[3] == 0x02)
|
||||||
|
printf("4G:Socket %d 通道断开成功\r\n", air724_rx_msg[4]);
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,34 +13,6 @@
|
|||||||
|
|
||||||
void HeartBeat_Sign(void);
|
void HeartBeat_Sign(void);
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief 发送显示数据
|
|
||||||
* @note 发送显示数据,包括充电桩的连接状态和工作状态
|
|
||||||
*/
|
|
||||||
void Send_Display_Data(void)
|
|
||||||
{
|
|
||||||
#ifdef DEBUG
|
|
||||||
char str[128];
|
|
||||||
sprintf(str, "t1.bco=%s\xff\xff\xfft2.bco=%s\xff\xff\xfft3.bco=%s\xff\xff\xfft4.bco=%s\xff\xff\xfft5.bco=%s\xff\xff\xfft6.bco=%s\xff\xff\xff",
|
|
||||||
g_charger_manager.charger_piles[0].is_udp_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[1].is_udp_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[2].is_udp_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[3].is_udp_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[4].is_udp_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[5].is_udp_online ? "GREEN" : "RED");
|
|
||||||
Rs485_Message_Send(str, strlen(str));
|
|
||||||
|
|
||||||
sprintf(str, "t7.bco=%s\xff\xff\xfft8.bco=%s\xff\xff\xfft9.bco=%s\xff\xff\xfft10.bco=%s\xff\xff\xfft11.bco=%s\xff\xff\xfft12.bco=%s\xff\xff\xff",
|
|
||||||
g_charger_manager.charger_piles[0].is_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[1].is_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[2].is_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[3].is_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[4].is_online ? "GREEN" : "RED",
|
|
||||||
g_charger_manager.charger_piles[5].is_online ? "GREEN" : "RED");
|
|
||||||
Rs485_Message_Send(str, strlen(str));
|
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @funNm : HeartbeatTask_Function
|
* @funNm : HeartbeatTask_Function
|
||||||
@@ -69,13 +41,30 @@ void HeartbeatTask_Function(void const *argument)
|
|||||||
* @param : none
|
* @param : none
|
||||||
* @retval: void
|
* @retval: void
|
||||||
*/
|
*/
|
||||||
|
static uint32_t last_heartbeat_tick[MAX_CHARGER_COUNT] = {0};
|
||||||
|
|
||||||
void HeartBeat_Sign(void)
|
void HeartBeat_Sign(void)
|
||||||
{
|
{
|
||||||
if (g_charger_manager.charger_piles[0].is_online)
|
int i;
|
||||||
|
uint32_t now = HAL_GetTick();
|
||||||
|
bool any_online = false;
|
||||||
|
|
||||||
|
/* 6路桩独立心跳,互不影响 */
|
||||||
|
for (i = 0; i < MAX_CHARGER_COUNT; i++)
|
||||||
|
{
|
||||||
|
if (g_charger_manager.charger_piles[i].is_online)
|
||||||
|
{
|
||||||
|
any_online = true;
|
||||||
|
if ((now - last_heartbeat_tick[i]) >= 8000)
|
||||||
|
{
|
||||||
|
last_heartbeat_tick[i] = now;
|
||||||
|
charger_to_server_0X03(i + 1, 1, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (any_online)
|
||||||
{
|
{
|
||||||
RUN_EVERY(8000, tick_A, {
|
|
||||||
charger_to_server_0X03(1, 1, 0);
|
|
||||||
});
|
|
||||||
RUN_EVERY(100, tick_B, {
|
RUN_EVERY(100, tick_B, {
|
||||||
System_Mode_Led_Toggle();
|
System_Mode_Led_Toggle();
|
||||||
});
|
});
|
||||||
@@ -90,7 +79,4 @@ void HeartBeat_Sign(void)
|
|||||||
RUN_EVERY(1000, tick_D, {
|
RUN_EVERY(1000, tick_D, {
|
||||||
System_Run_Led_Toggle();
|
System_Run_Led_Toggle();
|
||||||
});
|
});
|
||||||
RUN_EVERY(500, tick_E, {
|
|
||||||
Send_Display_Data();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,8 @@ void YkcTask_Function(void const *argument)
|
|||||||
{
|
{
|
||||||
init_chargers(); /* 初始化桩结构体*/
|
init_chargers(); /* 初始化桩结构体*/
|
||||||
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); /* 等待桩通讯协议层完成*/
|
ulTaskNotifyTake(pdTRUE, portMAX_DELAY); /* 等待桩通讯协议层完成*/
|
||||||
|
osDelay(5000);
|
||||||
|
// send_server_address_to_air724();
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
TaskRunTimeStat.YkcTask.threads_runtime = GetTask_RunTime(YkcTaskID);
|
TaskRunTimeStat.YkcTask.threads_runtime = GetTask_RunTime(YkcTaskID);
|
||||||
@@ -36,36 +38,59 @@ void YkcTask_Function(void const *argument)
|
|||||||
|
|
||||||
switch (SETP)
|
switch (SETP)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
|
{
|
||||||
|
|
||||||
|
if (g_charger_manager.charger_piles[1 - 1].is_udp_online)
|
||||||
|
{
|
||||||
|
uint8_t open_cmd[] = { 0x55, 0xAA, 0x3, 0x01, 0x01, 0xAA, 0x55};
|
||||||
|
Air724_Message_Send(open_cmd, sizeof(open_cmd));
|
||||||
|
osDelay(3000);
|
||||||
|
SETP = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
printf("网关:等待桩上电指令\r\n");
|
||||||
|
osDelay(1000);
|
||||||
|
SETP = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
{
|
{
|
||||||
if (!g_charger_manager.charger_piles[1 - 1].is_online)
|
if (!g_charger_manager.charger_piles[1 - 1].is_online)
|
||||||
{
|
{
|
||||||
charger_to_server_0X01(1);
|
charger_to_server_0X01(1);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
SETP = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
{
|
|
||||||
if (!g_charger_manager.charger_piles[1 - 1].get_model)
|
|
||||||
charger_to_server_0X09(1); // 桩1计费模型请求
|
|
||||||
else
|
|
||||||
SETP = 2;
|
SETP = 2;
|
||||||
|
}
|
||||||
|
osDelay(5000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
{
|
||||||
|
if (!g_charger_manager.charger_piles[1 - 1].get_model)
|
||||||
|
charger_to_server_0X09(1); // 桩1计费模型请求
|
||||||
|
else
|
||||||
|
SETP = 3;
|
||||||
|
osDelay(3000);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
{
|
{
|
||||||
charger_to_server_0X13(1, 1); // 上传状态
|
charger_to_server_0X13(1, 1); // 上传状态
|
||||||
|
osDelay(15000);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
osDelay(2000);
|
//osDelay(2000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user