448 lines
13 KiB
C
448 lines
13 KiB
C
/*
|
||
* 妯″潡鍚嶇О锛欸D5F2GQ5UE SPI NAND Flash 椹卞姩
|
||
* 妯″潡鍔熻兘锛氭彁锟?GD5F2GQ5UE SPI NAND Flash 鐨勫垵濮嬪寲銆佽<E98A86>銆佸啓銆佹摝闄ゆ帴锟? * 閫傜敤骞冲彴锛歋TM32F407ZGT6 + SPI1 纭<>欢 SPI
|
||
* 浣滆€咃細鐜嬪缓锟? * 鍒涘缓鏃ユ湡锟?026-07-16
|
||
* 淇<>敼璁板綍锟? * 2026-07-16 鐜嬪缓锟? 鍒涘缓鍒濆<E98D92>鐗堟湰
|
||
* 2026-07-17 鐜嬪缓锟? 鍒囨崲纭<E5B4B2>欢 SPI锛屼慨姝f摝闄ゅ湴鍧€锛屽弬锟?NuttX 椹卞姩
|
||
*/
|
||
|
||
/* 澶存枃浠跺寘鍚<E5AF98>尯 */
|
||
#include <string.h>
|
||
#include "gd5f2gq5ue.h"
|
||
|
||
/*
|
||
* 璋冭瘯杈撳嚭閰嶇疆
|
||
*/
|
||
#define DBG_TAG "[NAND]"
|
||
#include "dbg_log.h"
|
||
|
||
/* 绉佹湁瀹忓畾涔夊尯 */
|
||
#define GD5F_SPI_TIMEOUT 100
|
||
|
||
/* 澶栭儴 SPI 鍙ユ焺澹版槑 */
|
||
extern SPI_HandleTypeDef hspi1;
|
||
|
||
/* ======================== 绉佹湁鍑芥暟澹版槑 ======================== */
|
||
|
||
static int gd5f_wait_busy(uint32_t timeout_ms);
|
||
static int gd5f_write_enable(void);
|
||
static int gd5f_read_status(uint8_t *p_status);
|
||
static int gd5f_page_read(uint32_t page_addr);
|
||
static int gd5f_read_from_cache(uint16_t column, uint8_t *p_buf,
|
||
size_t size);
|
||
static int gd5f_page_program(uint32_t page_addr, uint16_t column,
|
||
const uint8_t *p_buf, size_t size);
|
||
static int gd5f_set_feature(uint8_t addr, uint8_t data);
|
||
static int gd5f_block_erase(uint32_t block_addr);
|
||
|
||
/* ======================== 绉佹湁鍑芥暟瀹氫箟 ======================== */
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氱瓑寰呰姱鐗囨搷浣滃畬鎴愶紙杞<E7B499><E69D9E> OIP 浣嶏級
|
||
* 鍏ュ彛鍙傛暟锛歵imeout_ms - 瓒呮椂鏃堕棿 uint32_t > 0
|
||
* 杩斿洖鍊硷細0 - 鎿嶄綔瀹屾垚锟?2 - 瓒呮椂
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬惊鐜<E6838A><E9909C>鍙栫姸鎬佸瘎瀛樺櫒鐩村埌 OIP 浣嶆竻闆舵垨瓒呮椂
|
||
*/
|
||
static int gd5f_wait_busy(uint32_t timeout_ms) {
|
||
uint8_t cmd = GD5F_CMD_GET_FEATURE;
|
||
uint8_t addr = GD5F_REG_STATUS;
|
||
uint8_t status = 0;
|
||
uint32_t tick_start = HAL_GetTick();
|
||
|
||
while (1) {
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, &cmd, 1, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Transmit(&hspi1, &addr, 1, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Receive(&hspi1, &status, 1, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
if ((status & GD5F_STATUS_OIP) == 0) {
|
||
return GD5F_OK;
|
||
}
|
||
if ((HAL_GetTick() - tick_start) >= timeout_ms) {
|
||
return GD5F_BUSY_TIMEOUT;
|
||
}
|
||
}
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氬彂閫佸啓浣胯兘鍛戒护
|
||
* 鍏ュ彛鍙傛暟锛氭棤
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛欳S# 鎷変綆鍚庡彂锟?06h 鍛戒护鍐嶆媺锟? */
|
||
static int gd5f_write_enable(void) {
|
||
uint8_t cmd = GD5F_CMD_WRITE_ENABLE;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, &cmd, 1, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氳<E9949B>鍙栫姸鎬佸瘎瀛樺櫒
|
||
* 鍏ュ彛鍙傛暟锛歱_status - 鐘舵€佸€艰緭鍑烘寚锟? uint8_t* 涓嶄负 NULL
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬彂锟?0Fh + C0h 鍦板潃鍚庤<E98D9A>锟?瀛楄妭鐘舵€侊拷? */
|
||
static int gd5f_read_status(uint8_t *p_status) {
|
||
uint8_t cmd = GD5F_CMD_GET_FEATURE;
|
||
uint8_t addr = GD5F_REG_STATUS;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, &cmd, 1, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Transmit(&hspi1, &addr, 1, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Receive(&hspi1, p_status, 1, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氶〉璇诲彇锛堝皢鏁版嵁浠庡瓨鍌ㄩ樀鍒楀姞杞藉埌鍐呴儴缂撳瓨锟? * 鍏ュ彛鍙傛暟锛歱age_addr - 椤靛湴鍧€ uint32_t
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬彂锟?13h + 3瀛楄妭琛屽湴鍧€锛岀瓑锟?OIP 娓呴浂
|
||
*/
|
||
static int gd5f_page_read(uint32_t page_addr) {
|
||
uint8_t cmd[4] = {0};
|
||
|
||
cmd[0] = GD5F_CMD_PAGE_READ;
|
||
cmd[1] = (page_addr >> 16) & 0xFF;
|
||
cmd[2] = (page_addr >> 8) & 0xFF;
|
||
cmd[3] = page_addr & 0xFF;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 4, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
return gd5f_wait_busy(100);
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氫粠鍐呴儴缂撳瓨璇诲彇鏁版嵁
|
||
* 鍏ュ彛鍙傛暟锛歝olumn - 鍒楀湴鍧€锛堥〉鍐呭亸绉伙級 uint16_t 0 - 2047
|
||
* p_buf - 鏁版嵁杈撳嚭缂撳啿锟? uint8_t* 涓嶄负 NULL
|
||
* size - 璇诲彇瀛楄妭锟? size_t > 0
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛氬繀椤诲厛璋冪敤 gd5f_page_read 瀹屾垚鏁版嵁鍔犺浇
|
||
* 鍑芥暟璇存槑锛氬彂锟?0Bh + 2瀛楄妭鍒楀湴鍧€ +1瀛楄妭 dummy 鍚庤<E98D9A>鍙栨暟锟? */
|
||
static int gd5f_read_from_cache(uint16_t column, uint8_t *p_buf,
|
||
size_t size) {
|
||
uint8_t cmd[4] = {0};
|
||
|
||
cmd[0] = GD5F_CMD_READ_FROM_CACHE;
|
||
cmd[1] = (column >> 8) & 0xFF;
|
||
cmd[2] = column & 0xFF;
|
||
cmd[3] = 0x00;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 4, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Receive(&hspi1, p_buf, size, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氶〉缂栫▼锛堝皢鏁版嵁鍐欏叆鎸囧畾椤碉級
|
||
* 鍏ュ彛鍙傛暟锛歱age_addr - 椤靛湴鍧€ uint32_t
|
||
* column - 鍒楀湴鍧€ uint16_t 0 - 2047
|
||
* p_buf - 鏁版嵁缂撳啿锟? const uint8_t*
|
||
* size - 鍐欏叆瀛楄妭锟? size_t > 0
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛氱洰鏍囧尯鍩熷凡鎿﹂櫎
|
||
* 鍑芥暟璇存槑锟?. 鍐欎娇锟?- 02h 鍔犺浇鏁版嵁 - 10h 鎵ц<E98EB5>缂栫▼ - 绛夊緟瀹屾垚
|
||
* 2. 缂栫▼瀹屾垚鍚庢<E98D9A>锟?P_FAIL 锟? */
|
||
static int gd5f_page_program(uint32_t page_addr, uint16_t column,
|
||
const uint8_t *p_buf, size_t size) {
|
||
int ret = GD5F_OK;
|
||
uint8_t cmd[4];
|
||
uint8_t status = 0;
|
||
|
||
gd5f_write_enable();
|
||
|
||
cmd[0] = GD5F_CMD_PROGRAM_LOAD;
|
||
cmd[1] = (column >> 8) & 0xFF;
|
||
cmd[2] = column & 0xFF;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 3, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Transmit(&hspi1, (uint8_t *)p_buf, size,
|
||
GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
cmd[0] = GD5F_CMD_PROGRAM_EXEC;
|
||
cmd[1] = (page_addr >> 16) & 0xFF;
|
||
cmd[2] = (page_addr >> 8) & 0xFF;
|
||
cmd[3] = page_addr & 0xFF;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 4, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
ret = gd5f_wait_busy(1000);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
gd5f_read_status(&status);
|
||
if (status & GD5F_STATUS_P_FAIL) {
|
||
return GD5F_PROGRAM_FAIL;
|
||
}
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氳<E9949B>锟?Feature 瀵勫瓨锟? * 鍏ュ彛鍙傛暟锛歛ddr - 瀵勫瓨鍣ㄥ湴鍧€ uint8_t
|
||
* data - 鍐欏叆鏁版嵁 uint8_t
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬厛鍐欎娇鑳斤紝鍙戯拷?1Fh + 鍦板潃 + 鏁版嵁锛岀瓑寰呮搷浣滃畬锟? */
|
||
static int gd5f_set_feature(uint8_t addr, uint8_t data) {
|
||
uint8_t cmd[3];
|
||
|
||
gd5f_write_enable();
|
||
|
||
cmd[0] = GD5F_CMD_SET_FEATURE;
|
||
cmd[1] = addr;
|
||
cmd[2] = data;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 3, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
gd5f_wait_busy(100);
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氬潡鎿﹂櫎锛堟摝锟?28KB鍧楋級
|
||
* 鍏ュ彛鍙傛暟锛歜lock_addr - 鍧楃紪锟? uint32_t 0 - 2047
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歡d5f2gq5ue_init() 宸茶皟锟? * 鍑芥暟璇存槑锟?. 鍐欎娇锟?- D8h + 3瀛楄妭瀛楄妭鍦板潃 - 绛夊緟瀹屾垚
|
||
* 2. 鎿﹂櫎瀹屾垚鍚庢<E98D9A>锟?E_FAIL 锟? */
|
||
static int gd5f_block_erase(uint32_t block_addr) {
|
||
int ret = GD5F_OK;
|
||
uint8_t cmd[4];
|
||
uint8_t status = 0;
|
||
uint32_t byte_addr = block_addr * GD5F_BLOCK_SIZE;
|
||
|
||
gd5f_write_enable();
|
||
|
||
cmd[0] = GD5F_CMD_BLOCK_ERASE;
|
||
cmd[1] = (byte_addr >> 16) & 0xFF;
|
||
cmd[2] = (byte_addr >> 8) & 0xFF;
|
||
cmd[3] = byte_addr & 0xFF;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, cmd, 4, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
ret = gd5f_wait_busy(5000);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
gd5f_read_status(&status);
|
||
if (status & GD5F_STATUS_E_FAIL) {
|
||
return GD5F_ERASE_FAIL;
|
||
}
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/* ======================== 鍏<>叡鍑芥暟瀹氫箟 ======================== */
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氬垵濮嬪寲 GD5F2GQ5UE
|
||
* 鍏ュ彛鍙傛暟锛氭棤
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歋PI1 鍜岀浉锟?GPIO 宸茬敱 CubeMX 鍒濆<E98D92>鍖栧畬锟? * 鍑芥暟璇存槑锟?. 鍙戦€佸<E282AC>浣嶅懡浠ゅ苟绛夊緟瀹屾垚
|
||
* 2. 璇诲彇鑺<E5BD87>墖 ID 骞舵牎锟? * 3. 浣胯兘鍐呴儴 ECC (B0h bit4)
|
||
* 4. 瑙i櫎鎵€鏈夊潡淇濇姢 (A0h = 0x00)
|
||
*/
|
||
int gd5f2gq5ue_init(void) {
|
||
int ret = GD5F_OK;
|
||
uint8_t mid = 0;
|
||
uint8_t did = 0;
|
||
|
||
GD5F_CS_HIGH();
|
||
GD5F_WP_HIGH();
|
||
GD5F_HOLD_HIGH();
|
||
|
||
HAL_Delay(10);
|
||
|
||
DBG_INFO("Resetting NAND...");
|
||
ret = gd5f2gq5ue_reset();
|
||
if (ret != GD5F_OK) {
|
||
DBG_ERROR("Reset failed: %d", ret);
|
||
return ret;
|
||
}
|
||
|
||
HAL_Delay(5);
|
||
|
||
DBG_INFO("Reading NAND ID...");
|
||
ret = gd5f2gq5ue_read_id(&mid, &did);
|
||
if (ret != GD5F_OK) {
|
||
DBG_ERROR("Read ID failed: %d", ret);
|
||
return ret;
|
||
}
|
||
|
||
DBG_INFO("NAND ID: MID=0x%02X, DID=0x%02X", mid, did);
|
||
|
||
if (mid != GD5F_MANUFACTURER_ID || did != GD5F_DEVICE_ID) {
|
||
DBG_ERROR("ID mismatch: expected MID=0x%02X DID=0x%02X, got MID=0x%02X DID=0x%02X",
|
||
GD5F_MANUFACTURER_ID, GD5F_DEVICE_ID, mid, did);
|
||
return GD5F_ID_MISMATCH;
|
||
}
|
||
|
||
DBG_INFO("Enabling ECC...");
|
||
gd5f_set_feature(0xB0, 0x10);
|
||
gd5f_wait_busy(100);
|
||
|
||
DBG_INFO("Unlocking block protection...");
|
||
gd5f_set_feature(GD5F_REG_PROTECT, 0x00);
|
||
gd5f_wait_busy(100);
|
||
|
||
DBG_INFO("NAND init OK");
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氳<E9949B>鍙栬姱锟?ID锛圡ID + DID锟? * 鍏ュ彛鍙傛暟锛歮id - 鍒堕€犲晢 ID 杈撳嚭鎸囬拡 uint8_t* 涓嶄负 NULL
|
||
* did - 璁惧<E79281> ID 杈撳嚭鎸囬拡 uint8_t* 涓嶄负 NULL
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬彂锟?9Fh 鍛戒护鍚庢帴锟?锟?dummy + MID + DID
|
||
*/
|
||
int gd5f2gq5ue_read_id(uint8_t *p_mid, uint8_t *p_did) {
|
||
uint8_t cmd = GD5F_CMD_READ_ID;
|
||
uint8_t id_buf[3] = {0};
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, &cmd, 1, GD5F_SPI_TIMEOUT);
|
||
HAL_SPI_Receive(&hspi1, id_buf, 3, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
*p_mid = id_buf[1];
|
||
*p_did = id_buf[2];
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氫粠 NAND 璇诲彇鏁版嵁锛堟敮鎸佽法椤碉級
|
||
* 鍏ュ彛鍙傛暟锛歰ffset - 璧峰<E792A7>瀛楄妭鍋忕Щ long 0 ~ 鎬诲<E98EAC>锟?1
|
||
* p_buf - 鏁版嵁缂撳啿锟? uint8_t* 涓嶄负 NULL
|
||
* size - 璇诲彇瀛楄妭锟? size_t > 0
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歡d5f2gq5ue_init() 宸叉垚鍔熻皟锟? * 鍑芥暟璇存槑锛氳嚜鍔ㄥ<E98D94>鐞嗚法椤佃<E6A4A4>锟? */
|
||
int gd5f2gq5ue_read(long offset, uint8_t *p_buf, size_t size) {
|
||
int ret = GD5F_OK;
|
||
|
||
while (size > 0) {
|
||
uint32_t page_addr = offset / GD5F_PAGE_SIZE;
|
||
uint16_t column = offset % GD5F_PAGE_SIZE;
|
||
size_t bytes = GD5F_PAGE_SIZE - column;
|
||
|
||
if (bytes > size) {
|
||
bytes = size;
|
||
}
|
||
|
||
ret = gd5f_page_read(page_addr);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
ret = gd5f_read_from_cache(column, p_buf, bytes);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
offset += bytes;
|
||
p_buf += bytes;
|
||
size -= bytes;
|
||
}
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氬悜 NAND 鍐欏叆鏁版嵁锛堟敮鎸佽法椤碉級
|
||
* 鍏ュ彛鍙傛暟锛歰ffset - 璧峰<E792A7>瀛楄妭鍋忕Щ long 0 ~ 鎬诲<E98EAC>锟?1
|
||
* p_buf - 鏁版嵁缂撳啿锟? const uint8_t* 涓嶄负 NULL
|
||
* size - 鍐欏叆瀛楄妭锟? size_t > 0
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歡d5f2gq5ue_init() 宸叉垚鍔熻皟鐢<E79A9F>紝鐩<E7B49D>爣鍖哄煙宸叉摝锟? * 鍑芥暟璇存槑锛氳嚜鍔ㄥ<E98D94>鐞嗚法椤靛啓锟? */
|
||
int gd5f2gq5ue_write(long offset, const uint8_t *p_buf, size_t size) {
|
||
int ret = GD5F_OK;
|
||
|
||
while (size > 0) {
|
||
uint32_t page_addr = offset / GD5F_PAGE_SIZE;
|
||
uint16_t column = offset % GD5F_PAGE_SIZE;
|
||
size_t bytes = GD5F_PAGE_SIZE - column;
|
||
|
||
if (bytes > size) {
|
||
bytes = size;
|
||
}
|
||
|
||
ret = gd5f_page_program(page_addr, column, p_buf, bytes);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
offset += bytes;
|
||
p_buf += bytes;
|
||
size -= bytes;
|
||
}
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氭摝闄ゅ潡锛堟寜鍧楁摝闄わ紝鏈€灏忓崟锟?128KB锟? * 鍏ュ彛鍙傛暟锛歰ffset - 璧峰<E792A7>瀛楄妭鍋忕Щ long 蹇呴』鍧楀<E98DA7>锟? * size - 鎿﹂櫎瀛楄妭锟? size_t 蹇呴』鍧楀ぇ灏忔暣鏁帮拷? * 杩斿洖鍊硷細0 - 鎴愬姛锛屽叾锟?- 閿欒<E996BF>锟? * 闄愬畾鏉′欢锛歡d5f2gq5ue_init() 宸叉垚鍔熻皟锟? * 鍑芥暟璇存槑锛氭摝闄ゆ搷浣滀互鍧椾负鍗曚綅
|
||
*/
|
||
int gd5f2gq5ue_erase(long offset, size_t size) {
|
||
int ret = GD5F_OK;
|
||
|
||
if (offset % GD5F_BLOCK_SIZE != 0) {
|
||
return GD5F_ERROR;
|
||
}
|
||
if (size % GD5F_BLOCK_SIZE != 0) {
|
||
return GD5F_ERROR;
|
||
}
|
||
|
||
while (size > 0) {
|
||
uint32_t block_addr = offset / GD5F_BLOCK_SIZE;
|
||
|
||
ret = gd5f_block_erase(block_addr);
|
||
if (ret != GD5F_OK) {
|
||
return ret;
|
||
}
|
||
|
||
offset += GD5F_BLOCK_SIZE;
|
||
size -= GD5F_BLOCK_SIZE;
|
||
}
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|
||
/*
|
||
* 鍑芥暟鍔熻兘锛氬<E9949B>浣嶈姱锟? * 鍏ュ彛鍙傛暟锛氭棤
|
||
* 杩斿洖鍊硷細0 - 鎴愬姛
|
||
* 闄愬畾鏉′欢锛歋PI 宸插垵濮嬪寲
|
||
* 鍑芥暟璇存槑锛氬彂锟?FFh 澶嶄綅鍛戒护鍚庣瓑锟?5ms
|
||
*/
|
||
int gd5f2gq5ue_reset(void) {
|
||
uint8_t cmd = GD5F_CMD_RESET;
|
||
|
||
GD5F_CS_LOW();
|
||
HAL_SPI_Transmit(&hspi1, &cmd, 1, GD5F_SPI_TIMEOUT);
|
||
GD5F_CS_HIGH();
|
||
|
||
HAL_Delay(5);
|
||
|
||
return GD5F_OK;
|
||
}
|
||
|