MT25QL01GBBB非易失配置寄存器异常恢复技术求助
MT25QL01GBBB Flash非易失配置寄存器异常修复求助
问题现象
发送写入非易失配置寄存器命令后,因代码逻辑错误导致Nonvolatile Configuration Register处于不确定状态。
开发环境
- 主控芯片:STM32F765VGT6
- Flash芯片:MT25QL01GBBB8ESF-0SIT
- 开发工具:STM32CubeIDE,C语言+STM32 HAL库
背景信息
此前已验证读JEDEC ID、页编程等SPI命令均正常工作,但写入非易失配置寄存器后,所有测试代码均失效。尝试过软件复位、硬件复位引脚复位芯片,同一SPI总线上的同款芯片(未测试写非易失配置寄存器功能)其余功能正常。目前基于Flash文档实现了掉电恢复和接口恢复函数,但Flash仍无法正常工作。
测试结果
| 测试项 | JEDEC ID | Flag SR |
|---|---|---|
| 预期值 | 0x20BA21 | 0x80 |
| 实际值 | 0xFFFFFF | 0xFF |
引发问题的函数
uint16_t reverse_bits(uint16_t byte) { byte = (byte & 0xFF00) >> 8 | (byte & 0xFF) << 8; byte = (byte & 0xF0F0) >> 4 | (byte & 0xF0F) << 4; byte = (byte & 0xCCCC) >> 2 | (byte & 0x3333) << 2; byte = (byte & 0xAAAA) >> 1 | (byte & 0x555) << 1; return byte; } void MT25QL_WriteNONVOL(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM, uint16_t reg_val) { uint8_t tData[3]; reg_val = reverse_bits(reg_val); tData[0] = WRITE_NONVOL_CFG_REG_CMD; tData[1] = (reg_val) & 0xFF; tData[2] = (reg_val >> 8) & 0xFF; write_enable(hspi, FM); csLOW(FM); SPI_Write(hspi, tData, 3); csHIGH(FM); //write enable reset is automatic }
主函数中执行恢复的代码
LedToggle(); MT25QL_PowerLossRecovery(&hspi1, MT25QL_FM1); LedToggle(); HAL_Delay(10); LedToggle(); MT25QL_InterfaceRescue(&hspi1, MT25QL_FM1); LedToggle(); ID = MT25QL_ReadID(&hspi1, MT25QL_FM1); FSR = MT25QL_ReadFSR(&hspi1, MT25QL_FM1); LedToggle();
实现的恢复函数
HAL_StatusTypeDef MT25QL_InterfaceRescue(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM) { // Step 1: Recovery sequence recovery_sequence(hspi, FM, 7); // Example for 7 clock cycles recovery_sequence(hspi, FM, 9); recovery_sequence(hspi, FM, 13); recovery_sequence(hspi, FM, 17); recovery_sequence(hspi, FM, 25); recovery_sequence(hspi, FM, 33); // Step 2: Interface rescue interface_rescue(hspi, FM); return HAL_OK; } HAL_StatusTypeDef MT25QL_PowerLossRecovery(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM) { // Step 1: Recovery sequence recovery_sequence(hspi, FM, 7); // Example for 7 clock cycles recovery_sequence(hspi, FM, 9); recovery_sequence(hspi, FM, 13); recovery_sequence(hspi, FM, 17); recovery_sequence(hspi, FM, 25); recovery_sequence(hspi, FM, 33); // Step 2: Power Loss Recovery power_loss_recovery(hspi, FM); return HAL_OK; }
辅助函数
static void SPI_Write(SPI_HandleTypeDef *hspi, uint8_t *data, uint8_t len) { HAL_SPI_Transmit(hspi, data, len, HAL_MAX_DELAY); } static void SPI_Read(SPI_HandleTypeDef *hspi, uint8_t *data, uint32_t len) { HAL_SPI_Receive(hspi, data, len, HAL_MAX_DELAY); } static void recovery_sequence(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM, uint8_t clock_cycles) { uint8_t dummy_data[34] = {DUMMY_CLOCKS}; // Max needed cycles is 34 csLOW(FM); SPI_Write(hspi, dummy_data, clock_cycles); csHIGH(FM); } static void power_loss_recovery(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM) { uint8_t dummy_data[8] = {DUMMY_CLOCKS}; csLOW(FM); SPI_Write(hspi, dummy_data, 8); csHIGH(FM); //HAL_Delay(1); // Ensure tSHSL2 >= 50ns } static void interface_rescue(SPI_HandleTypeDef *hspi, MT25QL_FM_NO_t FM) { uint8_t dummy_data[16] = {DUMMY_CLOCKS}; csLOW(FM); SPI_Write(hspi, dummy_data, 16); csHIGH(FM); //HAL_Delay(1); // Ensure tSHSL2 >= 50ns }
已知建议方向
执行掉电恢复序列,可通过将SCK、DQ0和DQ3引脚设为GPIO并运行对应恢复函数实现。
内容的提问来源于stack exchange,提问作者Waynsday
相关产品推荐
相关产品推荐

